pidgin/pidgin

16e588dfd8c5
Merge changes from the pidgin.main release-2.x.y branch into
the private release-2.x.y.

No manual changes needed.
--- a/ChangeLog Tue Jun 17 23:14:13 2014 -0700
+++ b/ChangeLog Mon Jul 07 23:59:49 2014 -0700
@@ -35,6 +35,9 @@
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
--- a/libpurple/certificate.c Tue Jun 17 23:14:13 2014 -0700
+++ b/libpurple/certificate.c Mon Jul 07 23:59:49 2014 -0700
@@ -2153,15 +2153,34 @@
/* Scheme-specific functions */
/****************************************************************************/
+static void display_x509_issuer(gchar *issuer_id) {
+ PurpleCertificate *issuer_crt;
+
+ issuer_crt = x509_ca_get_cert(issuer_id);
+
+ if (issuer_crt) {
+ purple_certificate_display_x509(issuer_crt);
+ purple_certificate_destroy(issuer_crt);
+ } else {
+ purple_notify_info(NULL, /* TODO: Find what the handle ought to be */
+ _("Certificate Information"),
+ "",
+ _("Unable to find Issuer Certificate"));
+ }
+
+ g_free(issuer_id);
+}
+
void
purple_certificate_display_x509(PurpleCertificate *crt)
{
gchar *sha_asc;
GByteArray *sha_bin;
- gchar *cn;
+ gchar *cn, *issuer_id;
time_t activation, expiration;
gchar *activ_str, *expir_str;
gchar *secondary;
+ gboolean self_signed;
/* Pull out the SHA1 checksum */
sha_bin = purple_certificate_get_fingerprint_sha1(crt);
@@ -2173,6 +2192,8 @@
/* TODO: Will break on CA certs */
cn = purple_certificate_get_subject_name(crt);
+ issuer_id = purple_certificate_get_issuer_unique_id(crt);
+
/* Get the certificate times */
/* TODO: Check the times against localtime */
/* TODO: errorcheck? */
@@ -2184,25 +2205,41 @@
activ_str = g_strdup(ctime(&activation));
expir_str = g_strdup(ctime(&expiration));
+ self_signed = purple_certificate_signed_by(crt, crt);
+
/* Make messages */
secondary = 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)");
+ "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)");
/* Make a semi-pretty display */
- purple_notify_info(
- NULL, /* TODO: Find what the handle ought to be */
- _("Certificate Information"),
- "",
- secondary);
+ if (self_signed) {
+ purple_notify_info(NULL, /* TODO: Find what the handle ought to be */
+ _("Certificate Information"),
+ "",
+ secondary);
+ } else {
+ purple_request_action(NULL, /* TODO: Find what the handle ought to be */
+ _("Certificate Information"), _("Certificate Information"),
+ secondary, 2, NULL, NULL, NULL,
+ issuer_id, 2,
+ _("View Issuer Certificate"), PURPLE_CALLBACK(display_x509_issuer),
+ _("Close"), PURPLE_CALLBACK(g_free));
+
+ /* purple_request_action has taken ownership of issuer_id */
+ issuer_id = NULL;
+ }
/* Cleanup */
g_free(cn);
+ g_free(issuer_id);
g_free(secondary);
g_free(sha_asc);
g_free(activ_str);
--- a/libpurple/certificate.h Tue Jun 17 23:14:13 2014 -0700
+++ b/libpurple/certificate.h Mon Jul 07 23:59:49 2014 -0700
@@ -639,7 +639,8 @@
* Retrieve a certificate from a pool.
* @param pool Pool to fish in
* @param id ID to look up
- * @return Retrieved certificate, or NULL if it wasn't there
+ * @return 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);
--- a/libpurple/plugins/ssl/ssl-gnutls.c Tue Jun 17 23:14:13 2014 -0700
+++ b/libpurple/plugins/ssl/ssl-gnutls.c Mon Jul 07 23:59:49 2014 -0700
@@ -468,6 +468,59 @@
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", "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;
+
} else if(s < 0) {
purple_debug_error("gnutls", "receive failed: %s\n",
gnutls_strerror(s));
--- a/libpurple/protocols/jabber/iq.c Tue Jun 17 23:14:13 2014 -0700
+++ b/libpurple/protocols/jabber/iq.c Mon Jul 07 23:59:49 2014 -0700
@@ -290,17 +290,19 @@
* be a valid match if any of the following is true:
* - Request 'to' matches reply 'from' (including the case where
* neither are set).
- * - Request 'to' was empty and reply 'from' is server JID.
+ * - Request 'to' was my JID (bare or full) and reply 'from' is empty.
* - Request 'to' was empty and reply 'from' is my JID. The spec says
* we should only allow bare JID, but we also allow full JID for
* compatibility with some servers.
+ * - Request 'to' was empty and reply 'from' is server JID. Not allowed by
+ * any spec, but for compatibility with some servers.
*
* These rules should allow valid IQ replies while preventing spoofed
* ones.
*
* For more discussion see the "Spoofing of iq ids and misbehaving
* servers" email thread from January 2014 on the jdev and security
- * mailing lists.
+ * mailing lists. Also see https://developer.pidgin.im/ticket/15879
*
* @return TRUE if this reply is valid for the given request.
*/
@@ -311,6 +313,12 @@
return TRUE;
}
+ if (!from && purple_strequal(to->node, js->user->node)
+ && purple_strequal(to->domain, js->user->domain)) {
+ /* Request 'to' was my JID (bare or full) and reply 'from' is empty */
+ return TRUE;
+ }
+
if (!to && purple_strequal(from->domain, js->user->domain)) {
/* Request 'to' is empty and reply 'from' domain matches our domain */
--- a/po/de.po Tue Jun 17 23:14:13 2014 -0700
+++ b/po/de.po Mon Jul 07 23:59:49 2014 -0700
@@ -12,8 +12,8 @@
msgstr ""
"Project-Id-Version: de\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2014-04-01 00:00+0200\n"
-"PO-Revision-Date: 2014-03-31 23:50+0200\n"
+"POT-Creation-Date: 2014-06-20 18:24+0200\n"
+"PO-Revision-Date: 2014-06-20 18:23+0200\n"
"Last-Translator: Björn Voigt <bjoern@cs.tu-berlin.de>\n"
"Language-Team: German <de@li.org>\n"
"Language: de\n"
@@ -1690,7 +1690,6 @@
msgid "Unknown"
msgstr "Unbekannt"
-#. Changing this string? Look in add_purple_buddy_to_groups
msgid "Buddies"
msgstr "Buddys"
@@ -3231,15 +3230,15 @@
msgid "Chat _name:"
msgstr "Chat_name:"
-#, c-format
-msgid "Unable to resolve hostname '%s': %s"
-msgstr "Hostname '%s' kann nicht aufgelöst werden: %s"
-
#. 1. connect to server
#. connect to the server
msgid "Connecting"
msgstr "Verbindungsaufbau"
+#, c-format
+msgid "Unable to resolve hostname: %s"
+msgstr "Konnte den Hostnamen nicht aufgelösen: %s"
+
msgid "Chat error"
msgstr "Chatfehler"
@@ -11854,6 +11853,9 @@
msgid "Bengali-India"
msgstr "Bengali-Indien"
+msgid "Bodo"
+msgstr "Bodo"
+
msgid "Bosnian"
msgstr "Bosnisch"
@@ -11893,6 +11895,9 @@
msgid "Spanish"
msgstr "Spanisch"
+msgid "Argentine Spanish"
+msgstr "Argentinisches Spanisch"
+
msgid "Estonian"
msgstr "Estnisch"
@@ -11962,6 +11967,9 @@
msgid "Korean"
msgstr "Koreanisch"
+msgid "Kashmiri"
+msgstr "Kashmiri"
+
msgid "Kurdish"
msgstr "Kurdisch"
@@ -12031,6 +12039,9 @@
msgid "Russian"
msgstr "Russisch"
+msgid "Sindhi"
+msgstr "Sindhi"
+
msgid "Slovak"
msgstr "Slowakisch"
@@ -12073,6 +12084,9 @@
msgid "Urdu"
msgstr "Urdu"
+msgid "Uzbek"
+msgstr "Usbekisch"
+
msgid "Vietnamese"
msgstr "Vietnamesisch"
@@ -15240,6 +15254,9 @@
msgid "You do not have permission to uninstall this application."
msgstr "Sie haben keine Berechtigung, diese Anwendung zu deinstallieren."
+#~ msgid "Unable to resolve hostname '%s': %s"
+#~ msgstr "Hostname '%s' kann nicht aufgelöst werden: %s"
+
#~ msgid "Token Error"
#~ msgstr "Token-Fehler"