secur32: Properly handle GNUTLS_E_AGAIN in (GnuTLS) schan_imp_send().
This commit is contained in:
parent
5004c38dd5
commit
65aed972c0
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue