/pidgin/main: 1cdc641d433e: Add "NSS Preferences" plugin which a...

Daniel Atallah <[email protected]>
Newsgroups gmane.comp.gnome.gaim.cvs
Message-ID <[email protected]>
Changeset: 1cdc641d433e72e1335147f45c62dbe5958cba6b
Author:	 Daniel Atallah <[email protected]>
Date:	 2014-11-05 13:13 -0500
Branch:	 release-2.x.y
URL: https://hg.pidgin.im/pidgin/main/rev/1cdc641d433e

Description:

Add "NSS Preferences" plugin which allows configuration Min/Max TLS version and Ciphers.

 * The TLS version settings require NSS 3.14 or newer

Refs #8061

diffstat:

 ChangeLog                              |   11 +-
 libpurple/plugins/ssl/Makefile.am      |   10 +-
 libpurple/plugins/ssl/Makefile.mingw   |   16 +-
 libpurple/plugins/ssl/nss-prefs.c      |  529 +++++++++++++++++++++++++++++++++
 libpurple/plugins/ssl/ssl-nss.c        |    1 -
 pidgin/win32/nsis/pidgin-installer.nsi |    1 +
 6 files changed, 557 insertions(+), 11 deletions(-)

diffs (truncated from 693 to 300 lines):

diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,14 +1,17 @@
 Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
 
 version 2.10.11 (?/?/?):
+	General:
+	* Fix handling of Self-Signed SSL/TLS Certificates when using the NSS
+	  plugin (#16412)
+	* Improve default cipher suites used with the NSS plugin (#16262)
+	* Add NSS Preferences plugin which allows the SSL/TLS Versions and
+	  cipher suites to be configured (#8061)
+
 	Gadu-Gadu:
 	* Fix a bug that prevented plugin to load when compiled without GnuTLS.
 	  (mancha) (#16431)
 
-	General:
-	* Fix handling of Self-Signed SSL/TLS Certificates when using the NSS
-	  plugin (#16412)
-
 version 2.10.10 (10/22/14):
 	General:
 	* Check the basic constraints extension when validating SSL/TLS
diff --git a/libpurple/plugins/ssl/Makefile.am b/libpurple/plugins/ssl/Makefile.am
--- a/libpurple/plugins/ssl/Makefile.am
+++ b/libpurple/plugins/ssl/Makefile.am
@@ -6,6 +6,7 @@ plugindir = $(libdir)/purple-$(PURPLE_MA
 ssl_la_LDFLAGS        = -module -avoid-version
 ssl_gnutls_la_LDFLAGS = -module -avoid-version
 ssl_nss_la_LDFLAGS    = -module -avoid-version
+nss_prefs_la_LDFLAGS  = -module -avoid-version
 
 if PLUGINS
 
@@ -18,7 +19,8 @@ if USE_NSS
 plugin_LTLIBRARIES = \
 	ssl.la           \
 	ssl-gnutls.la    \
-	ssl-nss.la
+	ssl-nss.la		\
+	nss-prefs.la
 else
 plugin_LTLIBRARIES = \
 	ssl.la           \
@@ -28,7 +30,8 @@ else
 if USE_NSS
 plugin_LTLIBRARIES = \
 	ssl.la           \
-	ssl-nss.la
+	ssl-nss.la	\
+	nss-prefs.la
 else
 plugin_LTLIBRARIES = \
 	ssl.la
@@ -38,10 +41,12 @@ endif
 ssl_la_SOURCES        = ssl.c
 ssl_gnutls_la_SOURCES = ssl-gnutls.c
 ssl_nss_la_SOURCES    = ssl-nss.c
+nss_prefs_la_SOURCES  = nss-prefs.c
 
 ssl_la_LIBADD        = $(GLIB_LIBS)
 ssl_gnutls_la_LIBADD = $(GLIB_LIBS) $(GNUTLS_LIBS)
 ssl_nss_la_LIBADD    = $(GLIB_LIBS) $(NSS_LIBS)
+nss_prefs_la_LIBADD  = $(GLIB_LIBS) $(NSS_LIBS)
 
 endif # PLUGINS
 
@@ -56,3 +61,4 @@ AM_CPPFLAGS = \
 
 ssl_gnutls_la_CFLAGS = $(AM_CPPFLAGS) $(GNUTLS_CFLAGS)
 ssl_nss_la_CFLAGS = $(AM_CPPFLAGS) $(NSS_CFLAGS)
+nss_prefs_la_CFLAGS = $(AM_CPPFLAGS) $(NSS_CFLAGS)
diff --git a/libpurple/plugins/ssl/Makefile.mingw b/libpurple/plugins/ssl/Makefile.mingw
--- a/libpurple/plugins/ssl/Makefile.mingw
+++ b/libpurple/plugins/ssl/Makefile.mingw
@@ -12,6 +12,7 @@ include $(PIDGIN_TREE_TOP)/libpurple/win
 ##
 TARGET = ssl
 TARGET_NSS = ssl-nss
+TARGET_NSSPREEFS = nss-prefs
 
 NEEDED_DLLS = \
 			$(NSS_TOP)/lib/freebl3.dll \
@@ -22,8 +23,8 @@ NEEDED_DLLS = \
 			$(NSS_TOP)/lib/nssutil3.dll \
 			$(NSS_TOP)/lib/smime3.dll \
 			$(NSS_TOP)/lib/softokn3.dll \
-                        $(NSS_TOP)/lib/sqlite3.dll \
-			$(NSS_TOP)/lib/ssl3.dll 
+			$(NSS_TOP)/lib/sqlite3.dll \
+			$(NSS_TOP)/lib/ssl3.dll
 
 ##
 ## INCLUDE PATHS
@@ -46,8 +47,10 @@ LIB_PATHS +=		-L$(GTK_TOP)/lib \
 ##
 C_SRC =			ssl.c
 C_SRC_NSS =		ssl-nss.c
+C_SRC_NSSPREFS =	nss-prefs.c
 OBJECTS = $(C_SRC:%.c=%.o)
 OBJECTS_NSS = $(C_SRC_NSS:%.c=%.o)
+OBJECTS_NSSPREFS = $(C_SRC_NSSPREFS:%.c=%.o)
 
 ##
 ## LIBRARIES
@@ -69,11 +72,13 @@ include $(PIDGIN_COMMON_RULES)
 ##
 .PHONY: all install clean
 
-all: $(TARGET).dll $(TARGET_NSS).dll
+all: $(TARGET).dll $(TARGET_NSS).dll $(TARGET_NSSPREFS).dll
 
 install: all $(PURPLE_INSTALL_PLUGINS_DIR) $(PURPLE_INSTALL_DIR)
 	cp $(TARGET).dll $(PURPLE_INSTALL_PLUGINS_DIR)
 	cp $(TARGET_NSS).dll $(PURPLE_INSTALL_PLUGINS_DIR)
+	cp $(TARGET_NSS).dll $(PURPLE_INSTALL_PLUGINS_DIR)
+	cp $(TARGET_NSSPREFS).dll $(PURPLE_INSTALL_PLUGINS_DIR)
 	cp $(NEEDED_DLLS) $(PURPLE_INSTALL_DIR)
 
 $(OBJECTS) $(OBJECTS_NSS): $(PURPLE_CONFIG_H)
@@ -87,10 +92,13 @@ install: all $(PURPLE_INSTALL_PLUGINS_DI
 $(TARGET_NSS).dll: $(PURPLE_DLL) $(OBJECTS_NSS)
 	$(CC) -shared $(OBJECTS_NSS) $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -o $(TARGET_NSS).dll
 
+$(TARGET_NSSPREFS).dll: $(PURPLE_DLL) $(OBJECTS_NSSPREFS)
+	$(CC) -shared $(OBJECTS_NSSPREFS) $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -o $(TARGET_NSSPREFS).dll
+
 ##
 ## CLEAN RULES
 ##
 clean:
-	rm -f $(OBJECTS) $(OBJECTS_NSS) $(TARGET).dll $(TARGET_NSS).dll
+	rm -f $(OBJECTS) $(OBJECTS_NSS) $(OBJECTS_NSSPREFS) $(TARGET).dll $(TARGET_NSS).dll $(TARGET_NSSPREFS).dll
 
 include $(PIDGIN_COMMON_TARGETS)
diff --git a/libpurple/plugins/ssl/nss-prefs.c b/libpurple/plugins/ssl/nss-prefs.c
new file mode 100644
--- /dev/null
+++ b/libpurple/plugins/ssl/nss-prefs.c
@@ -0,0 +1,529 @@
+/*
+ * Plugin to configure NSS
+ *
+ * Copyright (C) 2014, Daniel Atallah <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02111-1301, USA.
+ */
+#include "internal.h"
+#include "debug.h"
+#include "plugin.h"
+#include "version.h"
+
+#ifdef _WIN32
+# ifndef HAVE_LONG_LONG
+#define HAVE_LONG_LONG
+/* WINDDK_BUILD is defined because the checks around usage of
+ * intrisic functions are wrong in nspr */
+#define WINDDK_BUILD
+# endif
+#endif
+
+#include <nspr.h>
+#include <nss.h>
+#include <nssb64.h>
+#include <ocsp.h>
+#include <pk11func.h>
+#include <prio.h>
+#include <secerr.h>
+#include <secmod.h>
+#include <ssl.h>
+#include <sslerr.h>
+#include <sslproto.h>
+
+/* There's a bug in some versions of this header that requires that some of
+   the headers above be included first. This is true for at least libnss
+   3.15.4. */
+#include <certdb.h>
+
+#define PLUGIN_ID "core-nss_prefs"
+
+#define PREF_BASE		"/plugins/core/nss_prefs"
+#define CIPHERS_PREF	PREF_BASE "/cipher_list"
+#define CIPHER_TMP_ROOT PREF_BASE "/ciphers_dummy_ui"
+#define CIPHER_TMP		CIPHER_TMP_ROOT "/0x%04x"
+#define MIN_TLS			PREF_BASE "/min_tls"
+#define MAX_TLS			PREF_BASE "/max_tls"
+
+static PurplePlugin *handle = NULL;
+static GList *tmp_prefs = NULL;
+static GList *default_ciphers = NULL;
+#if NSS_VMAJOR > 3 || ( NSS_VMAJOR == 3 && NSS_VMINOR >= 14 )
+static SSLVersionRange *default_versions = NULL;
+#endif
+
+static gchar *get_error_text(void)
+{
+	PRInt32 len = PR_GetErrorTextLength();
+	gchar *ret = NULL;
+
+	if (len > 0) {
+		ret = g_malloc(len + 1);
+		len = PR_GetErrorText(ret);
+		ret[len] = '\0';
+	}
+
+	return ret;
+}
+
+static GList *get_current_cipher_list(gboolean force_default) {
+	GList *conf_ciphers = NULL;
+	if (!force_default) {
+		conf_ciphers = purple_prefs_get_string_list(CIPHERS_PREF);
+	}
+
+	/* If we don't have any specifically configured ciphers, use the
+	 * a copy of the defaults */
+	if (!conf_ciphers) {
+		GList *tmp;
+		for(tmp = default_ciphers; tmp; tmp = tmp->next) {
+			conf_ciphers = g_list_prepend(conf_ciphers, g_strdup(tmp->data));
+		}
+	}
+
+	return conf_ciphers;
+}
+
+static void
+enable_ciphers(gboolean force_default) {
+	const PRUint16 *cipher;
+	GList *conf_ciphers, *tmp;
+	SECStatus rv;
+
+	conf_ciphers = get_current_cipher_list(force_default);
+
+	/** First disable everything */
+	for (cipher = SSL_GetImplementedCiphers(); *cipher != 0; ++cipher) {
+		rv = SSL_CipherPrefSetDefault(*cipher, PR_FALSE);
+		if (rv != SECSuccess) {
+			gchar *error_msg = get_error_text();
+			purple_debug_warning("nss-prefs",
+					"Unable to disable 0x%04x: %s\n",
+					*cipher, error_msg);
+			g_free(error_msg);
+		}
+	}
+
+	for (tmp = conf_ciphers; tmp; tmp = g_list_delete_link(tmp, tmp)) {
+		guint64 parsed = g_ascii_strtoull(tmp->data, NULL, 16);
+
+		if (parsed == 0 || parsed > PR_UINT16_MAX) {
+			purple_debug_error("nss-prefs",
+					"Cipher '%s' is not valid.\n",
+					(const char *) tmp->data);
+			g_free(tmp->data);
+			continue;
+		}
+
+		rv = SSL_CipherPrefSetDefault((PRUint16) parsed, PR_TRUE);
+		if (rv != SECSuccess) {
+			gchar *error_msg = get_error_text();
+			purple_debug_warning("nss-prefs",
+					"Unable to enable 0x%04x: %s\n",
+					*cipher, error_msg);
+			g_free(error_msg);
+		}
+		purple_debug_info("nss-prefs",
+				"Enabled Cipher 0x%04x.\n", (PRUint16) parsed);
+
+		g_free(tmp->data);
+	}
+}
+
+static void set_cipher_pref(const char *pref, PurplePrefType type,
+		gconstpointer value, gpointer user_data) {
+	const PRUint16 *cipher = user_data;
+	GList *conf_ciphers, *tmp;
+	gboolean enabled = GPOINTER_TO_INT(value);
+	gboolean found = FALSE;
+
+	purple_debug_info("nss-prefs",
+			"%s pref for Cipher 0x%04x.\n",
+			enabled ? "Adding" : "Removing", *cipher);
+
+	conf_ciphers = get_current_cipher_list(FALSE);
+
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.