navinseshadri / iksemel

Automatically exported from code.google.com/p/iksemel
GNU Lesser General Public License v2.1
0 stars 0 forks source link

[patch] ssl handshake continuation #10

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. provide ikstransport working around Debian #511808, i.e. that will do a
select() before any read() and return -1 + errno=EAGAIN if nothing
available to be read when the  read function is called
2. connect to an XMPP server supporting starttls and get the ssl handshake
triggered
3. GnuTLS wants to read data during the handshake that has not arrived yet
4. read returns -1 and errno=EAGAIN
5. gnutls_handshake() returns GNUTLS_E_AGAIN
6. libiksemel considers the handshake to have failed and closes the connection

What is the expected output? What do you see instead?
libiksemel should be able to cope with network latency (without blocking).

What version of the product are you using? On what operating system?
Irrelevant.

Please provide any additional information below.
Here's the fix (including fixes from Debian#511808):

diff -rU2 iksemel-1.3/src/stream.c libiksemel-1.3/src/stream.c
--- iksemel-1.3/src/stream.c    2007-08-02 12:45:10.000000000 +0200
+++ libiksemel-1.3/src/stream.c 2009-03-03 20:24:35.000000000 +0100
@@ -15,4 +17,5 @@
 #define SF_TRY_SECURE 2
 #define SF_SECURE 4
+#define SF_HS_SECURE_IP 8

 struct stream_data {
@@ -34,4 +37,5 @@
        gnutls_session sess;
        gnutls_certificate_credentials cred;
+       int timeout;
 #endif
 };
@@ -56,10 +60,34 @@
        int ret;

-       ret = data->trans->recv (data->sock, buffer, len, -1);
+       ret = data->trans->recv (data->sock, buffer, len, data->timeout);
        if (ret == -1) return (size_t) -1;
        return ret;
 }

 static int
+handshake_continue (struct stream_data *data)
+{
+       int ret = gnutls_handshake (data->sess);
+       if (ret != 0) {
+               if  (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED) {
+                       return IKS_OK;
+               }
+               gnutls_deinit (data->sess);
+               gnutls_certificate_free_credentials (data->cred);
+               return IKS_NET_TLSFAIL;
+       }
+
+       data->flags &= (~SF_TRY_SECURE);
+       data->flags &= ~SF_HS_SECURE_IP;
+       data->flags |= SF_SECURE;
+
+       iks_send_header (data->prs, data->server);
+
+       return IKS_OK;
+}
+
+static int
 handshake (struct stream_data *data)
 {
@@ -87,22 +113,13 @@
        gnutls_mac_set_priority(data->sess, mac_priority);
        gnutls_credentials_set (data->sess, GNUTLS_CRD_CERTIFICATE,
data->cred);
+
+       data->timeout = -1;

        gnutls_transport_set_push_function (data->sess, (gnutls_push_func)
tls_push);
        gnutls_transport_set_pull_function (data->sess, (gnutls_pull_func)
tls_pull);
        gnutls_transport_set_ptr (data->sess, data->prs);
-
-       ret = gnutls_handshake (data->sess);
-       if (ret != 0) {
-               gnutls_deinit (data->sess);
-               gnutls_certificate_free_credentials (data->cred);
-               return IKS_NET_TLSFAIL;
-       }
-
-       data->flags &= (~SF_TRY_SECURE);
-       data->flags |= SF_SECURE;
-
-       iks_send_header (data->prs, data->server);
-
-       return IKS_OK;
+       data->flags |= SF_HS_SECURE_IP;
+
+       return handshake_continue (data);
 }
 #endif
@@ -489,5 +506,11 @@
        while (1) {
 #ifdef HAVE_GNUTLS
-               if (data->flags & SF_SECURE) {
+               if (data->flags & SF_HS_SECURE_IP) {
+                       ret = handshake_continue (data);
+                       if (ret != IKS_OK)
+                               return IKS_NET_TLSFAIL;
+                       len = 0;
+               } else if (data->flags & SF_SECURE) {
+                       data->timeout = timeout;
                        len = gnutls_record_recv (data->sess, data->buf,
NET_IO_BUF_SIZE - 1);
                } else

Original issue reported on code.google.com by rkuhlm...@gmail.com on 3 Mar 2009 at 8:35

GoogleCodeExporter commented 9 years ago
Timeout is fixed in trunk. Examining continuation issue.

Original comment by meduke...@gmail.com on 7 Aug 2009 at 8:41

GoogleCodeExporter commented 9 years ago
Thanks for the patch!!!

Original comment by sethma...@gmail.com on 17 Nov 2012 at 8:38