From: Dan Winship Date: Mon, 11 Apr 2005 15:13:06 +0000 (+0000) Subject: belatedly pull up changes from gnome-2-10 branch X-Git-Tag: LIBSOUP_2_2_5~17 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7140cafb4ad9764adc70fe4ff529c4b95eee7a1e;p=platform%2Fupstream%2Flibsoup.git belatedly pull up changes from gnome-2-10 branch --- diff --git a/ChangeLog b/ChangeLog index 14feeba..838706e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2005-03-09 Dan Winship + + * libsoup/soup-gnutls.c (soup_gnutls_read): return G_IO_STATUS_EOF + if gnutls returns 0. [#73352] + (verify_certificate): put an #ifdef around + GNUTLS_CERT_NOT_TRUSTED so it works with gnutls 1.2.x. [#57811] + 2005-01-08 Not Zed ** See ximian bug #70323. @@ -5,6 +12,30 @@ * libsoup/soup-connection-ntlm.c: replace all unsigned long/long types with guint32, as the code needs 32 bit longs. +2004-10-20 Dan Winship + + * libsoup/soup-gnutls.c: Commit the alleged changes from the 10-06 + commit, which somehow did not actually get committed then. + + * libsoup/soup-connection.c (SoupConnectionPrivate): add a flag + indicating whether or not the connection is connected. + (tunnel_connect_finished): If successful, set connected. If the + server returns a 3xx response, translate it to 407 (under the + assumption that it's trying to redirect us to an HTML login page, + as in bug 68531). Use soup_socket_start_proxy_ssl() rather than + soup_socket_start_ssl(). + (socket_connect_result, soup_connection_connect_sync): If + successful, set connected + (soup_connection_disconnect): Don't emit "disconnected" if we + aren't yet connected, or the message that was waiting for this + connection may get stranded in the queue. (also part of 68531) + + * libsoup/soup-socket.c (soup_socket_start_proxy_ssl): New, starts + SSL and lets the caller pass the expected hostname. Fixes a + problem where SSL certification validation would always fail if + you used a proxy, because it was comparing the cert against the + proxy's hostname. (68583) + 2004-10-06 Dan Winship * libsoup/soup-ssl.h (SoupSocketError): add diff --git a/libsoup/soup-connection.c b/libsoup/soup-connection.c index 3129bb7..17676f9 100644 --- a/libsoup/soup-connection.c +++ b/libsoup/soup-connection.c @@ -47,7 +47,7 @@ struct SoupConnectionPrivate { SoupMessage *cur_req; time_t last_used; - gboolean in_use; + gboolean connected, in_use; }; #define PARENT_TYPE G_TYPE_OBJECT @@ -355,8 +355,14 @@ tunnel_connect_finished (SoupMessage *msg, gpointer user_data) clear_current_request (conn); if (SOUP_STATUS_IS_SUCCESSFUL (status)) { - if (!soup_socket_start_ssl (conn->priv->socket)) + if (soup_socket_start_proxy_ssl (conn->priv->socket, + conn->priv->origin_uri->host)) + conn->priv->connected = TRUE; + else status = SOUP_STATUS_SSL_FAILED; + } else if (SOUP_STATUS_IS_REDIRECTION (status)) { + /* Oops, the proxy thinks we're a web browser. */ + status = SOUP_STATUS_PROXY_AUTHENTICATION_REQUIRED; } g_signal_emit (conn, signals[CONNECT_RESULT], 0, @@ -428,6 +434,8 @@ socket_connect_result (SoupSocket *sock, guint status, gpointer user_data) return; } + conn->priv->connected = TRUE; + done: g_signal_emit (conn, signals[CONNECT_RESULT], 0, proxified_status (conn, status)); @@ -522,7 +530,9 @@ soup_connection_connect_sync (SoupConnection *conn) g_object_unref (connect_msg); } - if (!SOUP_STATUS_IS_SUCCESSFUL (status)) { + if (SOUP_STATUS_IS_SUCCESSFUL (status)) + conn->priv->connected = TRUE; + else { fail: if (conn->priv->socket) { g_object_unref (conn->priv->socket); @@ -556,6 +566,12 @@ soup_connection_disconnect (SoupConnection *conn) soup_socket_disconnect (conn->priv->socket); g_object_unref (conn->priv->socket); conn->priv->socket = NULL; + + /* Don't emit "disconnected" if we aren't yet connected */ + if (!conn->priv->connected) + return; + + conn->priv->connected = FALSE; g_signal_emit (conn, signals[DISCONNECTED], 0); if (!conn->priv->cur_req || diff --git a/libsoup/soup-gnutls.c b/libsoup/soup-gnutls.c index 4de1ea1..4d41b59 100644 --- a/libsoup/soup-gnutls.c +++ b/libsoup/soup-gnutls.c @@ -49,32 +49,42 @@ typedef struct { } SoupGNUTLSChannel; static gboolean -verify_certificate (gnutls_session session, const char *hostname) +verify_certificate (gnutls_session session, const char *hostname, GError **err) { int status; status = gnutls_certificate_verify_peers (session); if (status == GNUTLS_E_NO_CERTIFICATE_FOUND) { - g_warning ("No certificate was sent."); + g_set_error (err, SOUP_SSL_ERROR, + SOUP_SSL_ERROR_CERTIFICATE, + "No SSL certificate was sent."); return FALSE; } if (status & GNUTLS_CERT_INVALID || +#ifdef GNUTLS_CERT_NOT_TRUSTED status & GNUTLS_CERT_NOT_TRUSTED || +#endif status & GNUTLS_CERT_REVOKED) { - g_warning ("The certificate is not trusted."); + g_set_error (err, SOUP_SSL_ERROR, + SOUP_SSL_ERROR_CERTIFICATE, + "The SSL certificate is not trusted."); return FALSE; } if (gnutls_certificate_expiration_time_peers (session) < time (0)) { - g_warning ("The certificate has expired."); + g_set_error (err, SOUP_SSL_ERROR, + SOUP_SSL_ERROR_CERTIFICATE, + "The SSL certificate has expired."); return FALSE; } if (gnutls_certificate_activation_time_peers (session) > time (0)) { - g_warning ("The certificate is not yet activated."); + g_set_error (err, SOUP_SSL_ERROR, + SOUP_SSL_ERROR_CERTIFICATE, + "The SSL certificate is not yet activated."); return FALSE; } @@ -84,7 +94,9 @@ verify_certificate (gnutls_session session, const char *hostname) gnutls_x509_crt cert; if (gnutls_x509_crt_init (&cert) < 0) { - g_warning ("Error initializing certificate."); + g_set_error (err, SOUP_SSL_ERROR, + SOUP_SSL_ERROR_CERTIFICATE, + "Error initializing SSL certificate."); return FALSE; } @@ -92,22 +104,28 @@ verify_certificate (gnutls_session session, const char *hostname) session, &cert_list_size); if (cert_list == NULL) { - g_warning ("No certificate was found."); + g_set_error (err, SOUP_SSL_ERROR, + SOUP_SSL_ERROR_CERTIFICATE, + "No SSL certificate was found."); return FALSE; } if (gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER) < 0) { - g_warning ("The certificate could not be parsed."); + g_set_error (err, SOUP_SSL_ERROR, + SOUP_SSL_ERROR_CERTIFICATE, + "The SSL certificate could not be parsed."); return FALSE; } if (!gnutls_x509_crt_check_hostname (cert, hostname)) { - g_warning ("The certificate does not match hostname."); + g_set_error (err, SOUP_SSL_ERROR, + SOUP_SSL_ERROR_CERTIFICATE, + "The SSL certificate does not match the hostname."); return FALSE; } } - + return TRUE; } @@ -135,15 +153,9 @@ do_handshake (SoupGNUTLSChannel *chan, GError **err) return G_IO_STATUS_ERROR; } - if (chan->type == SOUP_SSL_TYPE_CLIENT && - chan->cred->have_ca_file) { - if (!verify_certificate (chan->session, chan->hostname)) { - g_set_error (err, G_IO_CHANNEL_ERROR, - G_IO_CHANNEL_ERROR_FAILED, - "Unable to verify certificate"); - return G_IO_STATUS_ERROR; - } - } + if (chan->type == SOUP_SSL_TYPE_CLIENT && chan->cred->have_ca_file && + !verify_certificate (chan->session, chan->hostname, err)) + return G_IO_STATUS_ERROR; return G_IO_STATUS_NORMAL; } @@ -188,7 +200,7 @@ soup_gnutls_read (GIOChannel *channel, } else { *bytes_read = result; - return G_IO_STATUS_NORMAL; + return (result > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF; } } diff --git a/libsoup/soup-socket.c b/libsoup/soup-socket.c index 2fde20b..d1de93e 100644 --- a/libsoup/soup-socket.c +++ b/libsoup/soup-socket.c @@ -600,14 +600,29 @@ soup_socket_listen (SoupSocket *sock, SoupAddress *local_addr) gboolean soup_socket_start_ssl (SoupSocket *sock) { + return soup_socket_start_proxy_ssl (sock, soup_address_get_name (sock->priv->remote_addr)); +} + +/** + * soup_socket_start_proxy_ssl: + * @sock: the socket + * @ssl_host: hostname of the SSL server + * + * Starts using SSL on @socket, expecting to find a host named + * @ssl_host. + * + * Return value: success or failure + **/ +gboolean +soup_socket_start_proxy_ssl (SoupSocket *sock, const char *ssl_host) +{ GIOChannel *ssl_chan; get_iochannel (sock); ssl_chan = soup_ssl_wrap_iochannel ( sock->priv->iochannel, sock->priv->is_server ? SOUP_SSL_TYPE_SERVER : SOUP_SSL_TYPE_CLIENT, - soup_address_get_name (sock->priv->remote_addr), - sock->priv->ssl_creds); + ssl_host, sock->priv->ssl_creds); if (!ssl_chan) return FALSE; diff --git a/libsoup/soup-socket.h b/libsoup/soup-socket.h index 81b59b2..49e88a9 100644 --- a/libsoup/soup-socket.h +++ b/libsoup/soup-socket.h @@ -51,6 +51,8 @@ guint soup_socket_connect (SoupSocket *sock, gboolean soup_socket_listen (SoupSocket *sock, SoupAddress *local_addr); gboolean soup_socket_start_ssl (SoupSocket *sock); +gboolean soup_socket_start_proxy_ssl (SoupSocket *sock, + const char *ssl_host); void soup_socket_disconnect (SoupSocket *sock); gboolean soup_socket_is_connected (SoupSocket *sock);