/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;