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

Daniel Atallah datallah at pidgin.im
Wed Nov 5 13:15:48 EST 2014


Changeset: 1cdc641d433e72e1335147f45c62dbe5958cba6b
Author:	 Daniel Atallah <datallah at pidgin.im>
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 <datallah at pidgin.im>
+ *
+ * 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);
+



More information about the Commits mailing list