/soc/2013/ankitkv/gobjectification: 5902dd574c6e: Merged default...

Ankit Vani <[email protected]>
Newsgroups gmane.comp.gnome.gaim.cvs
Message-ID <[email protected]>
Changeset: 5902dd574c6e3c292e9462bf58baa5af5746f404
Author:	 Ankit Vani <[email protected]>
Date:	 2014-07-09 11:42 +0530
Branch:	 soc.2013.gobjectification.plugins
URL: https://hg.pidgin.im/soc/2013/ankitkv/gobjectification/rev/5902dd574c6e

Description:

Merged default branch

diffstat:

 ChangeLog                          |    3 +
 libpurple/certificate.c            |   72 ++++++++++++++++++++--
 libpurple/certificate.h            |   11 +--
 libpurple/plugins/ssl/ssl-gnutls.c |  117 +++++++++++++++---------------------
 libpurple/plugins/ssl/ssl-nss.c    |   63 -------------------
 libpurple/protocols/jabber/iq.c    |   12 +++-
 6 files changed, 130 insertions(+), 148 deletions(-)

diffs (truncated from 400 to 300 lines):

diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -107,6 +107,9 @@ version 2.10.10 (?/?/?):
 	XMPP:
 	* Fix Facebook XMPP roster quirks. (#15041, #15957)
 
+	Yahoo:
+	* Fix login when using the GnuTLS library for TLS connections. (#16172)
+
 version 2.10.9 (2/2/2014):
 	XMPP:
 	* Fix problems logging into some servers including jabber.org and
diff --git a/libpurple/certificate.c b/libpurple/certificate.c
--- a/libpurple/certificate.c
+++ b/libpurple/certificate.c
@@ -491,21 +491,79 @@ purple_certificate_get_der_data(PurpleCe
 gchar *
 purple_certificate_get_display_string(PurpleCertificate *crt)
 {
-	PurpleCertificateScheme *scheme;
-	gchar *str;
+	gchar *sha_asc;
+	GByteArray *sha_bin;
+	gchar *cn, *issuer_id;
+	gint64 activation, expiration;
+	gchar *activ_str, *expir_str;
+	gboolean self_signed;
+	gchar *text;
+#if GLIB_CHECK_VERSION(2,26,0)
+	GDateTime *act_dt, *exp_dt;
+#endif
 
 	g_return_val_if_fail(crt, NULL);
-	g_return_val_if_fail(crt->scheme, NULL);
 
-	scheme = crt->scheme;
+	/* Pull out the SHA1 checksum */
+	sha_bin = purple_certificate_get_fingerprint_sha1(crt);
+	g_return_val_if_fail(sha_bin != NULL, NULL);
+	sha_asc = purple_base16_encode_chunked(sha_bin->data, sha_bin->len);
 
-	g_return_val_if_fail(scheme->get_display_string, NULL);
+	/* Get the cert Common Name */
+	/* TODO: Will break on CA certs */
+	cn = purple_certificate_get_subject_name(crt);
 
-	str = (scheme->get_display_string)(crt);
+	issuer_id = purple_certificate_get_issuer_unique_id(crt);
 
-	return str;
+	/* Get the certificate times */
+	/* TODO: Check the times against localtime */
+	/* TODO: errorcheck? */
+	if (!purple_certificate_get_times(crt, &activation, &expiration)) {
+		purple_debug_error("certificate",
+				   "Failed to get certificate times!\n");
+		activation = expiration = 0;
+	}
+
+#if GLIB_CHECK_VERSION(2,26,0)
+	act_dt = g_date_time_new_from_unix_local(activation);
+	activ_str = g_date_time_format(act_dt, "%c");
+	g_date_time_unref(act_dt);
+
+	exp_dt = g_date_time_new_from_unix_local(expiration);
+	expir_str = g_date_time_format(exp_dt, "%c");
+	g_date_time_unref(exp_dt);
+#else
+	activ_str = g_strdup(ctime(&activation));
+	expir_str = g_strdup(ctime(&expiration));
+#endif
+
+	self_signed = purple_certificate_signed_by(crt, crt);
+
+	/* Make messages */
+	text = g_strdup_printf(
+			_("Common name: %s\n\n"
+			  "Issued by: %s\n\n"
+			  "Fingerprint (SHA1): %s\n\n"
+			  "Activation date: %s\n"
+			  "Expiration date: %s\n"),
+			cn ? cn : "(null)",
+			self_signed ? _("(self-signed)") : (issuer_id ? issuer_id : "(null)"),
+			sha_asc ? sha_asc : "(null)",
+			activ_str ? activ_str : "(null)",
+			expir_str ? expir_str : "(null)");
+
+	/* Cleanup */
+	g_free(cn);
+	g_free(issuer_id);
+	g_free(sha_asc);
+	g_free(activ_str);
+	g_free(expir_str);
+	g_byte_array_free(sha_bin, TRUE);
+
+	return text;
 }
 
+
 GType
 purple_certificate_get_type(void)
 {
diff --git a/libpurple/certificate.h b/libpurple/certificate.h
--- a/libpurple/certificate.h
+++ b/libpurple/certificate.h
@@ -236,12 +236,6 @@ struct _PurpleCertificatePool
  *                <sbr/>@crt:    Certificate instance
  *                <sbr/>Returns: Binary DER representation of certificate - must
  *                               be freed using g_byte_array_free().
- * @get_display_string: Retrieves a string representation of the certificate
- *                      suitable for display
- *                      <sbr/>@crt:   Certificate instance
- *                      <sbr/>Returns: User-displayable string representation of
- *                                     certificate - must be freed using
- *                                     g_free().
  *
  * A certificate type.
  *
@@ -275,8 +269,6 @@ struct _PurpleCertificateScheme
 	GSList * (* import_certificates)(const gchar * filename);
 	GByteArray * (* get_der_data)(PurpleCertificate *crt);
 
-	gchar * (* get_display_string)(PurpleCertificate *crt);
-
 	/*< private >*/
 	void (*_purple_reserved1)(void);
 };
@@ -697,7 +689,8 @@ purple_certificate_pool_contains(PurpleC
  *
  * Retrieve a certificate from a pool.
  *
- * Returns: Retrieved certificate, or NULL if it wasn't there
+ * Returns: Retrieved certificate (to be freed with
+ *         purple_certificate_destroy), or NULL if it wasn't there
  */
 PurpleCertificate *
 purple_certificate_pool_retrieve(PurpleCertificatePool *pool, const gchar *id);
diff --git a/libpurple/plugins/ssl/ssl-gnutls.c b/libpurple/plugins/ssl/ssl-gnutls.c
--- a/libpurple/plugins/ssl/ssl-gnutls.c
+++ b/libpurple/plugins/ssl/ssl-gnutls.c
@@ -473,11 +473,59 @@ ssl_gnutls_read(PurpleSslConnection *gsc
 	if(s == GNUTLS_E_AGAIN || s == GNUTLS_E_INTERRUPTED) {
 		s = -1;
 		errno = EAGAIN;
+
 #ifdef GNUTLS_E_PREMATURE_TERMINATION
 	} else if (s == GNUTLS_E_PREMATURE_TERMINATION) {
-		purple_debug_warning("gnutls", "premature termination\n");
+		purple_debug_warning("gnutls", "Received a FIN on the TCP socket "
+				"for %s. This either means that the remote server closed "
+				"the socket without sending us a Close Notify alert or a "
+				"man-in-the-middle injected a FIN into the TCP stream. "
+				"Assuming it's the former.\n", gsc->host);
+#else
+	} else if (s == GNUTLS_E_UNEXPECTED_PACKET_LENGTH) {
+		purple_debug_warning("gnutls", "Received packet of unexpected "
+				"length on the TCP socket for %s. Among other "
+				"possibilities this might mean that the remote server "
+				"closed the socket without sending us a Close Notify alert. "
+				"Assuming that's the case for compatibility, however, note "
+				"that it's quite possible that we're incorrectly ignoing "
+				"a real error.\n", gsc->host);
+#endif
+		/*
+		 * Summary:
+		 * Always treat a closed TCP connection as if the remote server cleanly
+		 * terminated the SSL session.
+		 *
+		 * Background:
+		 * Most TLS servers send a Close Notify alert before sending TCP FIN
+		 * when closing a session. This informs us at the TLS layer that the
+		 * connection is being cleanly closed. Without this it's more
+		 * difficult for us to determine whether the session was closed
+		 * cleanly (we would need to resort to having the application layer
+		 * perform this check, e.g. by looking at the Content-Length HTTP
+		 * header for HTTP connections).
+		 *
+		 * There ARE servers that don't send Close Notify and we want to be
+		 * compatible with them. And so we don't require Close Notify. This
+		 * seems to match the behavior of libnss. This is a slightly
+		 * unfortunate situation. It means a malicious MITM can inject a FIN
+		 * into our TCP stream and cause our encrypted session to termiate
+		 * and we won't indicate any problem to the user.
+		 *
+		 * GnuTLS < 3.0.0 returned the UNEXPECTED_PACKET_LENGTH error on EOF.
+		 * GnuTLS >= 3.0.0 added the PREMATURE_TERMINATION error to allow us
+		 * to detect the problem more specifically.
+		 *
+		 * For historical discussion see:
+		 * https://developer.pidgin.im/ticket/16172
+		 * http://trac.adiumx.com/intertrac/ticket%3A16678
+		 * https://bugzilla.mozilla.org/show_bug.cgi?id=508698#c4
+		 * http://lists.gnu.org/archive/html/gnutls-devel/2008-03/msg00058.html
+		 * Or search for GNUTLS_E_UNEXPECTED_PACKET_LENGTH or
+		 * GNUTLS_E_PREMATURE_TERMINATION
+		 */
 		s = 0;
-#endif
+
 	} else if(s < 0) {
 		purple_debug_error("gnutls", "receive failed: %s\n",
 				gnutls_strerror(s));
@@ -1179,70 +1227,6 @@ x509_get_der_data(PurpleCertificate *crt
 	return data;
 }
 
-static gchar *
-x509_display_string(PurpleCertificate *crt)
-{
-	gchar *sha_asc;
-	GByteArray *sha_bin;
-	gchar *cn;
-	gint64 activation, expiration;
-	gchar *activ_str, *expir_str;
-	gchar *text;
-#if GLIB_CHECK_VERSION(2,26,0)
-	GDateTime *act_dt, *exp_dt;
-#endif
-
-	/* Pull out the SHA1 checksum */
-	sha_bin = x509_sha1sum(crt);
-	g_return_val_if_fail(sha_bin != NULL, NULL);
-	sha_asc = purple_base16_encode_chunked(sha_bin->data, sha_bin->len);
-
-	/* Get the cert Common Name */
-	/* TODO: Will break on CA certs */
-	cn = x509_common_name(crt);
-
-	/* Get the certificate times */
-	/* TODO: Check the times against localtime */
-	/* TODO: errorcheck? */
-	if (!x509_times(crt, &activation, &expiration)) {
-		purple_debug_error("certificate",
-				   "Failed to get certificate times!\n");
-		activation = expiration = 0;
-	}
-
-#if GLIB_CHECK_VERSION(2,26,0)
-	act_dt = g_date_time_new_from_unix_local(activation);
-	activ_str = g_date_time_format(act_dt, "%c");
-	g_date_time_unref(act_dt);
-
-	exp_dt = g_date_time_new_from_unix_local(expiration);
-	expir_str = g_date_time_format(exp_dt, "%c");
-	g_date_time_unref(exp_dt);
-#else
-	activ_str = g_strdup(ctime(&activation));
-	expir_str = g_strdup(ctime(&expiration));
-#endif
-
-	/* Make messages */
-	text = g_strdup_printf(_("Common name: %s\n\n"
-	                         "Fingerprint (SHA1): %s\n\n"
-	                         "Activation date: %s\n"
-	                         "Expiration date: %s\n"),
-	                       cn ? cn : "(null)",
-	                       sha_asc ? sha_asc : "(null)",
-	                       activ_str ? activ_str : "(null)",
-	                       expir_str ? expir_str : "(null)");
-
-	/* Cleanup */
-	g_free(cn);
-	g_free(sha_asc);
-	g_free(activ_str);
-	g_free(expir_str);
-	g_byte_array_free(sha_bin, TRUE);
-
-	return text;
-}
-
 /* X.509 certificate operations provided by this plugin */
 static PurpleCertificateScheme x509_gnutls = {
 	"x509",                          /* Scheme name */
@@ -1260,7 +1244,6 @@ static PurpleCertificateScheme x509_gnut
 	x509_times,                      /* Activation/Expiration time */
 	x509_importcerts_from_file,      /* Multiple certificates import function */
 	x509_get_der_data,               /* Binary DER data */
-	x509_display_string,             /* Display representation */
 
 	NULL
 
diff --git a/libpurple/plugins/ssl/ssl-nss.c b/libpurple/plugins/ssl/ssl-nss.c
--- a/libpurple/plugins/ssl/ssl-nss.c
+++ b/libpurple/plugins/ssl/ssl-nss.c
@@ -946,68 +946,6 @@ x509_get_der_data(PurpleCertificate *crt
 	return data;
 }
 
-static gchar *
-x509_display_string(PurpleCertificate *crt)
-{
-	gchar *sha_asc;
-	GByteArray *sha_bin;
-	gchar *cn;
-	gint64 activation, expiration;
-	gchar *activ_str, *expir_str;
-	gchar *text;
-#if GLIB_CHECK_VERSION(2,26,0)
-	GDateTime *act_dt, *exp_dt;
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.