[PATCH 3/5] secur32: Properly handle GNUTLS_E_AGAIN in (GnuTLS) schan_imp_send().

Henri Verbeet hverbeet at codeweavers.com
Mon Oct 3 13:22:50 CDT 2011


---
 dlls/secur32/schannel.c        |   19 +------------------
 dlls/secur32/schannel_gnutls.c |   16 +++++++++++++++-
 dlls/secur32/secur32_priv.h    |   18 ++++++++++++++++++
 3 files changed, 34 insertions(+), 19 deletions(-)

diff --git a/dlls/secur32/schannel.c b/dlls/secur32/schannel.c
index 69ee0e6..0355982 100644
--- a/dlls/secur32/schannel.c
+++ b/dlls/secur32/schannel.c
@@ -62,23 +62,6 @@ struct schan_context
     ULONG req_ctx_attr;
 };
 
-struct schan_buffers
-{
-    SIZE_T offset;
-    SIZE_T limit;
-    const SecBufferDesc *desc;
-    int current_buffer_idx;
-    BOOL allow_buffer_resize;
-    int (*get_next_buffer)(const struct schan_transport *, struct schan_buffers *);
-};
-
-struct schan_transport
-{
-    struct schan_context *ctx;
-    struct schan_buffers in;
-    struct schan_buffers out;
-};
-
 static struct schan_handle *schan_handle_table;
 static struct schan_handle *schan_free_handles;
 static SIZE_T schan_handle_table_size;
@@ -496,7 +479,7 @@ static void schan_resize_current_buffer(const struct schan_buffers *s, SIZE_T mi
     b->pvBuffer = new_data;
 }
 
-static char *schan_get_buffer(const struct schan_transport *t, struct schan_buffers *s, SIZE_T *count)
+char *schan_get_buffer(const struct schan_transport *t, struct schan_buffers *s, SIZE_T *count)
 {
     SIZE_T max_count;
     PSecBuffer buffer;
diff --git a/dlls/secur32/schannel_gnutls.c b/dlls/secur32/schannel_gnutls.c
index 870c553..e47c022 100644
--- a/dlls/secur32/schannel_gnutls.c
+++ b/dlls/secur32/schannel_gnutls.c
@@ -65,6 +65,7 @@ MAKE_FUNCPTR(gnutls_set_default_priority);
 MAKE_FUNCPTR(gnutls_record_get_max_size);
 MAKE_FUNCPTR(gnutls_record_recv);
 MAKE_FUNCPTR(gnutls_record_send);
+MAKE_FUNCPTR(gnutls_transport_get_ptr);
 MAKE_FUNCPTR(gnutls_transport_set_errno);
 MAKE_FUNCPTR(gnutls_transport_set_ptr);
 MAKE_FUNCPTR(gnutls_transport_set_pull_function);
@@ -340,11 +341,23 @@ SECURITY_STATUS schan_imp_send(schan_imp_session session, const void *buffer,
                                SIZE_T *length)
 {
     gnutls_session_t s = (gnutls_session_t)session;
-    ssize_t ret = pgnutls_record_send(s, buffer, *length);
+    ssize_t ret;
+
+again:
+    ret = pgnutls_record_send(s, buffer, *length);
+
     if (ret >= 0)
         *length = ret;
     else if (ret == GNUTLS_E_AGAIN)
+    {
+        struct schan_transport *t = (struct schan_transport *)pgnutls_transport_get_ptr(s);
+        SIZE_T count = 0;
+
+        if (schan_get_buffer(t, &t->out, &count))
+            goto again;
+
         return SEC_I_CONTINUE_NEEDED;
+    }
     else
     {
         pgnutls_perror(ret);
@@ -432,6 +445,7 @@ BOOL schan_imp_init(void)
     LOAD_FUNCPTR(gnutls_record_get_max_size);
     LOAD_FUNCPTR(gnutls_record_recv);
     LOAD_FUNCPTR(gnutls_record_send);
+    LOAD_FUNCPTR(gnutls_transport_get_ptr)
     LOAD_FUNCPTR(gnutls_transport_set_errno)
     LOAD_FUNCPTR(gnutls_transport_set_ptr)
     LOAD_FUNCPTR(gnutls_transport_set_pull_function)
diff --git a/dlls/secur32/secur32_priv.h b/dlls/secur32/secur32_priv.h
index 3aa5af6..c6b362b 100644
--- a/dlls/secur32/secur32_priv.h
+++ b/dlls/secur32/secur32_priv.h
@@ -183,6 +183,24 @@ typedef struct schan_imp_certificate_credentials_opaque *schan_imp_certificate_c
 
 struct schan_transport;
 
+struct schan_buffers
+{
+    SIZE_T offset;
+    SIZE_T limit;
+    const SecBufferDesc *desc;
+    int current_buffer_idx;
+    BOOL allow_buffer_resize;
+    int (*get_next_buffer)(const struct schan_transport *, struct schan_buffers *);
+};
+
+struct schan_transport
+{
+    struct schan_context *ctx;
+    struct schan_buffers in;
+    struct schan_buffers out;
+};
+
+char *schan_get_buffer(const struct schan_transport *t, struct schan_buffers *s, SIZE_T *count) DECLSPEC_HIDDEN;
 extern int schan_pull(struct schan_transport *t, void *buff, size_t *buff_len) DECLSPEC_HIDDEN;
 extern int schan_push(struct schan_transport *t, const void *buff, size_t *buff_len) DECLSPEC_HIDDEN;
 
-- 
1.7.2.5




More information about the wine-patches mailing list