secur32: Properly handle GNUTLS_E_AGAIN in (GnuTLS) schan_imp_send().

This commit is contained in:
Henri Verbeet 2011-10-03 20:22:50 +02:00 committed by Alexandre Julliard
parent 5004c38dd5
commit 65aed972c0
3 changed files with 34 additions and 19 deletions

View file

@ -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;

View file

@ -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)

View file

@ -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;