[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