2006-09-14 [colin] 2.4.0cvs188
authorColin Leroy <colin@colino.net>
Thu, 14 Sep 2006 16:32:50 +0000 (16:32 +0000)
committerColin Leroy <colin@colino.net>
Thu, 14 Sep 2006 16:32:50 +0000 (16:32 +0000)
* src/common/socket.c
* src/common/socket.h
* src/common/ssl.c
* src/common/ssl_certificate.c
* src/common/ssl_certificate.h
* src/etpan/imap-thread.c
the get_fqdn() call done to get canonical name when
checking an SSL certificate is blocking, which is
sad as we just did a non-blocking lookup to connect.
Fix that by letting the fqdn available to the SockInfo,
and use that in ssl_certificate_check(). For IMAP,
we don't do it as the lookup's done by libetpan, but
it's less annoying as IMAP connections as much more
rare than POP3 connections.

ChangeLog
PATCHSETS
configure.ac
src/common/socket.c
src/common/socket.h
src/common/ssl.c
src/common/ssl_certificate.c
src/common/ssl_certificate.h
src/etpan/imap-thread.c

index 757345e49d953ab1094c1686d434c4ae0901da22..5c2ce562b72b147f5e3f8a30dab1ec848fab209a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2006-09-14 [colin]     2.4.0cvs188
+
+       * src/common/socket.c
+       * src/common/socket.h
+       * src/common/ssl.c
+       * src/common/ssl_certificate.c
+       * src/common/ssl_certificate.h
+       * src/etpan/imap-thread.c
+               the get_fqdn() call done to get canonical name when
+               checking an SSL certificate is blocking, which is
+               sad as we just did a non-blocking lookup to connect.
+               Fix that by letting the fqdn available to the SockInfo,
+               and use that in ssl_certificate_check(). For IMAP,
+               we don't do it as the lookup's done by libetpan, but
+               it's less annoying as IMAP connections as much more
+               rare than POP3 connections.
+
 2006-09-14 [paul]      2.4.0cvs187
 
        * manual/advanced.xml
index c4d7a2afa11d4818cd229766c93bbb87b607b5dc..661e7998703b79b7ed65daa962a1d81e69442d3c 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.1.2.6 -r 1.1.2.7 src/gedit-print.c;  cvs diff -u -r 1.94.2.105 -r 1.94.2.106 src/messageview.c;  cvs diff -u -r 1.19.2.9 -r 1.19.2.10 src/messageview.h;  cvs diff -u -r 1.395.2.248 -r 1.395.2.249 src/summaryview.c;  cvs diff -u -r 1.96.2.147 -r 1.96.2.148 src/textview.c;  ) > 2.4.0cvs185.patchset
 ( cvs diff -u -r 1.204.2.101 -r 1.204.2.102 src/prefs_common.c;  cvs diff -u -r 1.103.2.60 -r 1.103.2.61 src/prefs_common.h;  cvs diff -u -r 1.1.4.30 -r 1.1.4.31 src/gtk/gtksctree.c;  cvs diff -u -r 1.1.2.28 -r 1.1.2.29 manual/advanced.xml;  ) > 2.4.0cvs186.patchset
 ( cvs diff -u -r 1.1.2.29 -r 1.1.2.30 manual/advanced.xml;  cvs diff -u -r 1.5.2.37 -r 1.5.2.38 src/gtk/pluginwindow.c;  ) > 2.4.0cvs187.patchset
+( cvs diff -u -r 1.13.2.21 -r 1.13.2.22 src/common/socket.c;  cvs diff -u -r 1.13.2.7 -r 1.13.2.8 src/common/socket.h;  cvs diff -u -r 1.9.2.14 -r 1.9.2.15 src/common/ssl.c;  cvs diff -u -r 1.4.2.11 -r 1.4.2.12 src/common/ssl_certificate.c;  cvs diff -u -r 1.1.4.4 -r 1.1.4.5 src/common/ssl_certificate.h;  cvs diff -u -r 1.1.4.50 -r 1.1.4.51 src/etpan/imap-thread.c;  ) > 2.4.0cvs188.patchset
index 13c8f8709f7f5482deabd30b7758fc6ab92e1399..c2cd0a77bffb72b22a1e1ef13dd0e5f21ff74f8c 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=4
 MICRO_VERSION=0
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=187
+EXTRA_VERSION=188
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
index ad7dfeaac6501dc34b4794f9b056e299fb740a80..c2ecf22ef411cf63961c5b6186a29942f60d0898 100644 (file)
@@ -92,6 +92,7 @@ struct _SockConnectData {
        guint io_tag;
        SockConnectFunc func;
        gpointer data;
+       gchar *canonical_name;
 };
 
 struct _SockLookupData {
@@ -103,6 +104,7 @@ struct _SockLookupData {
        gpointer data;
        gushort port;
         gint pipe_fds[2];
+       gchar *canonical_name;
 };
 
 struct _SockAddrData {
@@ -782,6 +784,7 @@ static gboolean sock_connect_async_cb(GIOChannel *source,
        sockinfo->hostname = g_strdup(conn_data->hostname);
        sockinfo->port = conn_data->port;
        sockinfo->state = CONN_ESTABLISHED;
+       sockinfo->canonical_name = g_strdup(conn_data->canonical_name);
 
        conn_data->func(sockinfo, conn_data->data);
 
@@ -797,6 +800,8 @@ static gint sock_connect_async_get_address_info_cb(GList *addr_list,
 
        conn_data->addr_list = addr_list;
        conn_data->cur_addr = addr_list;
+       conn_data->canonical_name = conn_data->lookup_data->canonical_name;
+       conn_data->lookup_data->canonical_name = NULL;
        conn_data->lookup_data = NULL;
 
        return sock_connect_address_list_async(conn_data);
@@ -862,6 +867,7 @@ gint sock_connect_async_cancel(gint id)
                }
 
                sock_address_list_free(conn_data->addr_list);
+               g_free(conn_data->canonical_name);
                g_free(conn_data->hostname);
                g_free(conn_data);
        } else {
@@ -930,7 +936,36 @@ static gboolean sock_get_address_info_async_cb(GIOChannel *source,
        gsize bytes_read;
        gint ai_member[4];
        struct sockaddr *addr;
-
+       gchar *canonical_name = NULL;
+       gchar len = 0;
+
+       if (g_io_channel_read(source, &len, sizeof(len),
+                             &bytes_read) == G_IO_ERROR_NONE) {
+               if (bytes_read == sizeof(len) && len > 0) {
+                       gchar *cur = NULL;
+                       gint todo = len;
+                       canonical_name = g_malloc0(len + 1);
+                       cur = canonical_name;
+                       while (todo > 0) {
+                               if (g_io_channel_read(source, cur, todo,
+                                     &bytes_read) != G_IO_ERROR_NONE) {
+                                     g_warning("canonical name not read\n");
+                                     g_free(canonical_name);
+                                     canonical_name = NULL;
+                                     break;
+                               } else {
+                                       cur += bytes_read;
+                                       todo -= bytes_read;
+                               }
+                               if (bytes_read == 0) {
+                                     g_warning("canonical name not read\n");
+                                     g_free(canonical_name);
+                                     canonical_name = NULL;
+                                     break;
+                               }
+                       }
+               }             
+       }
        for (;;) {
                if (g_io_channel_read(source, (gchar *)ai_member,
                                      sizeof(ai_member), &bytes_read)
@@ -984,9 +1019,11 @@ static gboolean sock_get_address_info_async_cb(GIOChannel *source,
        kill(lookup_data->child_pid, SIGKILL);
        waitpid(lookup_data->child_pid, NULL, 0);
 #endif
+       lookup_data->canonical_name = canonical_name;
 
        lookup_data->func(addr_list, lookup_data->data);
 
+       g_free(lookup_data->canonical_name);
        g_free(lookup_data->hostname);
        g_free(lookup_data);
 
@@ -1019,7 +1056,7 @@ static void address_info_async_child(void *opaque)
 
 #ifdef INET6
         memset(&hints, 0, sizeof(hints));
-        /* hints.ai_flags = AI_CANONNAME; */
+        hints.ai_flags = AI_CANONNAME;
         hints.ai_family = AF_UNSPEC;
         hints.ai_socktype = SOCK_STREAM;
         hints.ai_protocol = IPPROTO_TCP;
@@ -1028,8 +1065,11 @@ static void address_info_async_child(void *opaque)
 
         gai_err = getaddrinfo(parm->hostname, port_str, &hints, &res);
         if (gai_err != 0) {
+               gchar len = 0;
                 g_warning("getaddrinfo for %s:%s failed: %s\n",
                           parm->hostname, port_str, gai_strerror(gai_err));
+               fd_write_all(parm->pipe_fds[1], &len,
+                     sizeof(len));
                 fd_write_all(parm->pipe_fds[1], (gchar *)ai_member,
                              sizeof(ai_member));
                 close(parm->pipe_fds[1]);
@@ -1041,6 +1081,24 @@ static void address_info_async_child(void *opaque)
 #endif
         }
 
+       if (res != NULL) {
+               if (res->ai_canonname && strlen(res->ai_canonname) < 255) {
+                       gchar len = strlen(res->ai_canonname);
+                       fd_write_all(parm->pipe_fds[1], &len,
+                             sizeof(len));
+                       fd_write_all(parm->pipe_fds[1], res->ai_canonname,
+                             len);                      
+               } else {
+                       gchar len = 0;
+                       fd_write_all(parm->pipe_fds[1], &len,
+                             sizeof(len));
+               }
+       } else {
+               gchar len = 0;
+               fd_write_all(parm->pipe_fds[1], &len,
+                     sizeof(len));
+       }
+
         for (ai = res; ai != NULL; ai = ai->ai_next) {
                 ai_member[0] = ai->ai_family;
                 ai_member[1] = ai->ai_socktype;
@@ -1058,9 +1116,12 @@ static void address_info_async_child(void *opaque)
 #else /* !INET6 */
         hp = my_gethostbyname(parm->hostname);
         if (hp == NULL || hp->h_addrtype != AF_INET) {
+               gchar len = 0;
+               fd_write_all(parm->pipe_fds[1], &len,
+                     sizeof(len));
                 fd_write_all(parm->pipe_fds[1], (gchar *)ai_member,
                              sizeof(ai_member));
-                close(parm->pipe_fds[1]);
+               close(parm->pipe_fds[1]);
                 parm->pipe_fds[1] = -1;
 #ifdef G_OS_WIN32
                 _endthread();
@@ -1078,6 +1139,17 @@ static void address_info_async_child(void *opaque)
         ad.sin_family = AF_INET;
         ad.sin_port = htons(parm->port);
 
+       if (hp->h_name && strlen(hp->h_name) < 255) {
+               gchar len = strlen(hp->h_name);
+               fd_write_all(parm->pipe_fds[1], &len,
+                     sizeof(len));
+               fd_write_all(parm->pipe_fds[1], hp->h_name,
+                     len);                      
+       } else {
+               gchar len = 0;
+               fd_write_all(parm->pipe_fds[1], &len,
+                     sizeof(len));
+       }
         for (addr_list_p = hp->h_addr_list; *addr_list_p != NULL;
              addr_list_p++) {
                 memcpy(&ad.sin_addr, *addr_list_p, hp->h_length);
@@ -1172,6 +1244,7 @@ static gint sock_get_address_info_async_cancel(SockLookupData *lookup_data)
 #endif
        }
 
+       g_free(lookup_data->canonical_name);
        g_free(lookup_data->hostname);
        g_free(lookup_data);
 
@@ -1622,6 +1695,7 @@ gint sock_close(SockInfo *sock)
        ret = fd_close(sock->sock); 
 #endif
 
+       g_free(sock->canonical_name);
        g_free(sock->hostname);
        g_free(sock);
 
index de655e80b38fca6dcf5803e5eb57aa44e4ba5584..fcec361cbf2498f34136605abeb2445597faf224 100644 (file)
@@ -67,6 +67,7 @@ struct _SockInfo
 
        SockFunc callback;
        GIOCondition condition;
+       gchar *canonical_name;
 };
 
 void refresh_resolvers                 (void);
index e16066136048565301c18e58e86f12cec378c675..49ce6b498a53a82fc18f101496e764fbd6c43653 100644 (file)
@@ -193,7 +193,7 @@ gboolean ssl_init_socket_with_method(SockInfo *sockinfo, SSLMethod method)
        }
 
 
-       if (!ssl_certificate_check(server_cert, sockinfo->hostname, sockinfo->port)) {
+       if (!ssl_certificate_check(server_cert, sockinfo->canonical_name, sockinfo->hostname, sockinfo->port)) {
                X509_free(server_cert);
                SSL_free(ssl);
                return FALSE;
index bcfd18b41775ded6dfa853c7f4fe8b5137a1a8d6..ff24372f2c58d52bd429e62fa7d1e3f3c7906a5e 100644 (file)
@@ -364,15 +364,22 @@ char *ssl_certificate_check_signer (X509 *cert)
        return NULL;
 }
 
-gboolean ssl_certificate_check (X509 *x509_cert, gchar *host, gushort port)
+gboolean ssl_certificate_check (X509 *x509_cert, gchar *fqdn, gchar *host, gushort port)
 {
        SSLCertificate *current_cert = NULL;
        SSLCertificate *known_cert;
        SSLCertHookData cert_hook_data;
        gchar *fqdn_host = NULL;        
        
-       fqdn_host = get_fqdn(host);
-
+       if (fqdn)
+               fqdn_host = g_strdup(fqdn);
+       else if (host)
+               fqdn_host = get_fqdn(host);
+       else {
+               g_warning("no host!\n");
+               return FALSE;
+       }
+               
        current_cert = ssl_certificate_new_lookup(x509_cert, fqdn_host, port, FALSE);
        
        if (current_cert == NULL) {
index 893f07a2c651df85740dfae42fc0187a03bb9593..82f10d592e20793808fdd29fd301c7a6ac73853e 100644 (file)
@@ -54,7 +54,7 @@ struct _SSLCertHookData
 
 SSLCertificate *ssl_certificate_find (gchar *host, gushort port);
 SSLCertificate *ssl_certificate_find_lookup (gchar *host, gushort port, gboolean lookup);
-gboolean ssl_certificate_check (X509 *x509_cert, gchar *host, gushort port);
+gboolean ssl_certificate_check (X509 *x509_cert, gchar *fqdn, gchar *host, gushort port);
 char* ssl_certificate_to_string(SSLCertificate *cert);
 void ssl_certificate_destroy(SSLCertificate *cert);
 void ssl_certificate_delete_from_disk(SSLCertificate *cert);
index 2634f0cd7dea0b6a140cb8151c6d9a849f4fe2cc..531df68f8d8cc9e874c561e4af97a45d0ac6d1fb 100644 (file)
@@ -418,7 +418,7 @@ static int etpan_certificate_check(const unsigned char *certificate, int len, vo
        if (cert == NULL) {
                g_warning("can't get cert\n");
                return 0;
-       } else if (ssl_certificate_check(cert, 
+       } else if (ssl_certificate_check(cert, NULL,
                (gchar *)param->server, (gushort)param->port) == TRUE) {
                X509_free(cert);
                return 0;