Fix outgoing SSL connections.
authorJelmer Vernooij <jelmer@samba.org>
Thu, 10 Apr 2008 16:07:14 +0000 (18:07 +0200)
committerJelmer Vernooij <jelmer@samba.org>
Thu, 10 Apr 2008 16:07:14 +0000 (18:07 +0200)
NEWS
lib/network.c
src/gnutls.c

diff --git a/NEWS b/NEWS
index ab27d7d0773caf6f364e16f402cedaffcad32b0c..e6eb60428d2b436e87682640f9d008eb0e515256 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -95,6 +95,8 @@ Ctrlproxy 3.0.6 UNRELEASED
 
     * Fix occasional repeating of lines. (#75)
 
+       * Fix outgoing SSL connections. (#128)
+
   INTERNALS
 
     * A simple, single API is now used for managing modes.
index 7db721a66e9a7321149f7c337ce5685320393ab3..f5b3ea5380dec94ec4c1f496a45cbc1c241e031a 100644 (file)
@@ -512,6 +512,26 @@ static gboolean connect_current_tcp_server(struct irc_network *s)
 
        g_io_channel_set_close_on_unref(ioc, TRUE);
 
+       cs = s->connection.data.tcp.current_server;
+       if (cs->ssl) {
+#ifdef HAVE_GNUTLS
+               g_io_channel_set_close_on_unref(ioc, TRUE);
+               g_io_channel_set_flags(ioc, G_IO_FLAG_NONBLOCK, NULL);
+
+               ioc = ssl_wrap_iochannel (ioc, SSL_TYPE_CLIENT, 
+                                                                s->connection.data.tcp.current_server->host,
+                                                                s->ssl_credentials
+                                                                );
+               if (!ioc) {
+                       network_report_disconnect(s, "Couldn't connect via server %s:%s", cs->host, cs->port);
+                       reconnect(s);
+                       return FALSE;
+               }
+#else
+               network_log(LOG_WARNING, s, "SSL enabled for %s:%s, but no SSL support loaded", cs->host, cs->port);
+#endif
+       }
+
        s->connection.state = NETWORK_CONNECTION_STATE_CONNECTING;
 
        if (!connect_finished) {
@@ -697,7 +717,6 @@ static gboolean server_finish_connect(GIOChannel *ioc, GIOCondition cond,
                                                                  void *data)
 {
        struct irc_network *s = data;
-       struct tcp_server_config *cs;
 
        if (cond & G_IO_ERR) {
                network_report_disconnect(s, "Error connecting: %s", 
@@ -709,28 +728,6 @@ static gboolean server_finish_connect(GIOChannel *ioc, GIOCondition cond,
        if (cond & G_IO_OUT) {
                s->connection.state = NETWORK_CONNECTION_STATE_CONNECTED;
 
-               cs = s->connection.data.tcp.current_server;
-               if (cs->ssl) {
-#ifdef HAVE_GNUTLS
-                       g_io_channel_set_close_on_unref(ioc, TRUE);
-                       g_io_channel_set_flags(ioc, G_IO_FLAG_NONBLOCK, NULL);
-
-                       ioc = ssl_wrap_iochannel (ioc, SSL_TYPE_CLIENT, 
-                                                                        s->connection.data.tcp.current_server->host,
-                                                                        s->ssl_credentials
-                                                                        );
-                       g_assert(ioc != NULL);
-#else
-                       network_log(LOG_WARNING, s, "SSL enabled for %s:%s, but no SSL support loaded", cs->host, cs->port);
-#endif
-               }
-
-               if (!ioc) {
-                       network_report_disconnect(s, "Couldn't connect via server %s:%s", cs->host, cs->port);
-                       reconnect(s);
-                       return FALSE;
-               }
-
                s->connection.data.tcp.connect_id = 0; /* Otherwise data will be queued */
                network_set_iochannel(s, ioc);
 
index c378af3f68ac1df69f38befb5eca36692f535a23..3aa17b11ede76d3dc0f154969d74244ab727769c 100644 (file)
@@ -145,7 +145,7 @@ do_handshake (GNUTLSChannel *chan, GError **err)
        if (result < 0) {
                g_set_error (err, G_IO_CHANNEL_ERROR,
                             G_IO_CHANNEL_ERROR_FAILED,
-                            "Unable to handshake");
+                            gnutls_strerror(result));
                return G_IO_STATUS_ERROR;
        }
 
@@ -175,6 +175,8 @@ _gnutls_read (GIOChannel   *channel,
                    result == G_IO_STATUS_ERROR)
                        return result;
 
+               g_assert(result >= 0);
+
                chan->established = TRUE;
        }
 
@@ -196,7 +198,7 @@ _gnutls_read (GIOChannel   *channel,
        } else {
                *bytes_read = result;
 
-               return (result > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF;
+               return G_IO_STATUS_NORMAL;
        }
 }
 
@@ -219,6 +221,9 @@ _gnutls_write (GIOChannel   *channel,
                    result == G_IO_STATUS_ERROR)
                        return result;
 
+
+               g_assert(result >= 0);
+
                chan->established = TRUE;
        }
 
@@ -240,7 +245,7 @@ _gnutls_write (GIOChannel   *channel,
        } else {
                *bytes_written = result;
 
-               return (result > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF;
+               return G_IO_STATUS_NORMAL;
        }
 }
 
@@ -370,6 +375,9 @@ ssl_wrap_iochannel (GIOChannel *sock, SSLType type,
        g_return_val_if_fail (sock != NULL, NULL);
        g_return_val_if_fail (credentials != NULL, NULL);
 
+       g_io_channel_set_encoding(sock, NULL, NULL);
+       g_io_channel_set_buffered(sock, FALSE);
+
        sockfd = g_io_channel_unix_get_fd (sock);
        if (!sockfd) {
                g_warning ("Failed to get channel fd.");
@@ -406,7 +414,6 @@ ssl_wrap_iochannel (GIOChannel *sock, SSLType type,
        gchan->funcs = &gnutls_channel_funcs;
        g_io_channel_init (gchan);
        gchan->is_readable = gchan->is_writeable = TRUE;
-       gchan->use_buffer = FALSE;
 
        return gchan;