Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[patch] ssl handshake continuation #10

Open
GoogleCodeExporter opened this issue Jul 4, 2015 · 2 comments
Open

[patch] ssl handshake continuation #10

GoogleCodeExporter opened this issue Jul 4, 2015 · 2 comments

Comments

@GoogleCodeExporter
Copy link

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
Copy link
Author

Timeout is fixed in trunk. Examining continuation issue.

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

  • Changed state: Started

@GoogleCodeExporter
Copy link
Author

Thanks for the patch!!!

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant