Module: wine Branch: master Commit: 65aed972c0dac659800faf0097df190278c37883 URL: http://source.winehq.org/git/wine.git/?a=commit;h=65aed972c0dac659800faf0097...
Author: Henri Verbeet hverbeet@codeweavers.com Date: Mon Oct 3 20:22:50 2011 +0200
secur32: Properly handle GNUTLS_E_AGAIN in (GnuTLS) schan_imp_send().
---
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;