winhttp: Use separate SSL read and write buffers.

Signed-off-by: Paul Gofman <pgofman@codeweavers.com>
Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Paul Gofman 2022-01-20 18:35:31 +03:00 committed by Alexandre Julliard
parent 76ac0f3406
commit 25bd67465d
2 changed files with 22 additions and 14 deletions

View File

@ -250,7 +250,8 @@ void netconn_close( struct netconn *conn )
if (conn->secure) if (conn->secure)
{ {
free( conn->peek_msg_mem ); free( conn->peek_msg_mem );
free(conn->ssl_buf); free(conn->ssl_read_buf);
free(conn->ssl_write_buf);
free(conn->extra_buf); free(conn->extra_buf);
DeleteSecurityContext(&conn->ssl_ctx); DeleteSecurityContext(&conn->ssl_ctx);
} }
@ -365,8 +366,13 @@ DWORD netconn_secure_connect( struct netconn *conn, WCHAR *hostname, DWORD secur
break; break;
} }
conn->ssl_buf = malloc(conn->ssl_sizes.cbHeader + conn->ssl_sizes.cbMaximumMessage + conn->ssl_sizes.cbTrailer); conn->ssl_read_buf = malloc(conn->ssl_sizes.cbHeader + conn->ssl_sizes.cbMaximumMessage + conn->ssl_sizes.cbTrailer);
if(!conn->ssl_buf) { if(!conn->ssl_read_buf) {
res = ERROR_OUTOFMEMORY;
break;
}
conn->ssl_write_buf = malloc(conn->ssl_sizes.cbHeader + conn->ssl_sizes.cbMaximumMessage + conn->ssl_sizes.cbTrailer);
if(!conn->ssl_write_buf) {
res = ERROR_OUTOFMEMORY; res = ERROR_OUTOFMEMORY;
break; break;
} }
@ -377,8 +383,10 @@ DWORD netconn_secure_connect( struct netconn *conn, WCHAR *hostname, DWORD secur
if(status != SEC_E_OK || res != ERROR_SUCCESS) { if(status != SEC_E_OK || res != ERROR_SUCCESS) {
WARN("Failed to initialize security context: %08x\n", status); WARN("Failed to initialize security context: %08x\n", status);
free(conn->ssl_buf); free(conn->ssl_read_buf);
conn->ssl_buf = NULL; conn->ssl_read_buf = NULL;
free(conn->ssl_write_buf);
conn->ssl_write_buf = NULL;
DeleteSecurityContext(&ctx); DeleteSecurityContext(&ctx);
return ERROR_WINHTTP_SECURE_CHANNEL_ERROR; return ERROR_WINHTTP_SECURE_CHANNEL_ERROR;
} }
@ -393,9 +401,9 @@ DWORD netconn_secure_connect( struct netconn *conn, WCHAR *hostname, DWORD secur
static DWORD send_ssl_chunk( struct netconn *conn, const void *msg, size_t size ) static DWORD send_ssl_chunk( struct netconn *conn, const void *msg, size_t size )
{ {
SecBuffer bufs[4] = { SecBuffer bufs[4] = {
{conn->ssl_sizes.cbHeader, SECBUFFER_STREAM_HEADER, conn->ssl_buf}, {conn->ssl_sizes.cbHeader, SECBUFFER_STREAM_HEADER, conn->ssl_write_buf},
{size, SECBUFFER_DATA, conn->ssl_buf+conn->ssl_sizes.cbHeader}, {size, SECBUFFER_DATA, conn->ssl_write_buf+conn->ssl_sizes.cbHeader},
{conn->ssl_sizes.cbTrailer, SECBUFFER_STREAM_TRAILER, conn->ssl_buf+conn->ssl_sizes.cbHeader+size}, {conn->ssl_sizes.cbTrailer, SECBUFFER_STREAM_TRAILER, conn->ssl_write_buf+conn->ssl_sizes.cbHeader+size},
{0, SECBUFFER_EMPTY, NULL} {0, SECBUFFER_EMPTY, NULL}
}; };
SecBufferDesc buf_desc = {SECBUFFER_VERSION, ARRAY_SIZE(bufs), bufs}; SecBufferDesc buf_desc = {SECBUFFER_VERSION, ARRAY_SIZE(bufs), bufs};
@ -408,7 +416,7 @@ static DWORD send_ssl_chunk( struct netconn *conn, const void *msg, size_t size
return res; return res;
} }
if (sock_send( conn->socket, conn->ssl_buf, bufs[0].cbBuffer + bufs[1].cbBuffer + bufs[2].cbBuffer, 0 ) < 1) if (sock_send( conn->socket, conn->ssl_write_buf, bufs[0].cbBuffer + bufs[1].cbBuffer + bufs[2].cbBuffer, 0 ) < 1)
{ {
WARN("send failed\n"); WARN("send failed\n");
return WSAGetLastError(); return WSAGetLastError();
@ -456,13 +464,13 @@ static DWORD read_ssl_chunk( struct netconn *conn, void *buf, SIZE_T buf_size, S
assert(conn->extra_len < ssl_buf_size); assert(conn->extra_len < ssl_buf_size);
if(conn->extra_len) { if(conn->extra_len) {
memcpy(conn->ssl_buf, conn->extra_buf, conn->extra_len); memcpy(conn->ssl_read_buf, conn->extra_buf, conn->extra_len);
buf_len = conn->extra_len; buf_len = conn->extra_len;
conn->extra_len = 0; conn->extra_len = 0;
free(conn->extra_buf); free(conn->extra_buf);
conn->extra_buf = NULL; conn->extra_buf = NULL;
}else { }else {
if ((buf_len = sock_recv( conn->socket, conn->ssl_buf + conn->extra_len, ssl_buf_size - conn->extra_len, 0)) < 0) if ((buf_len = sock_recv( conn->socket, conn->ssl_read_buf + conn->extra_len, ssl_buf_size - conn->extra_len, 0)) < 0)
return WSAGetLastError(); return WSAGetLastError();
if (!buf_len) if (!buf_len)
@ -479,7 +487,7 @@ static DWORD read_ssl_chunk( struct netconn *conn, void *buf, SIZE_T buf_size, S
memset(bufs, 0, sizeof(bufs)); memset(bufs, 0, sizeof(bufs));
bufs[0].BufferType = SECBUFFER_DATA; bufs[0].BufferType = SECBUFFER_DATA;
bufs[0].cbBuffer = buf_len; bufs[0].cbBuffer = buf_len;
bufs[0].pvBuffer = conn->ssl_buf; bufs[0].pvBuffer = conn->ssl_read_buf;
switch ((res = DecryptMessage( &conn->ssl_ctx, &buf_desc, 0, NULL ))) switch ((res = DecryptMessage( &conn->ssl_ctx, &buf_desc, 0, NULL )))
{ {
@ -498,7 +506,7 @@ static DWORD read_ssl_chunk( struct netconn *conn, void *buf, SIZE_T buf_size, S
case SEC_E_INCOMPLETE_MESSAGE: case SEC_E_INCOMPLETE_MESSAGE:
assert(buf_len < ssl_buf_size); assert(buf_len < ssl_buf_size);
if ((size = sock_recv( conn->socket, conn->ssl_buf + buf_len, ssl_buf_size - buf_len, 0 )) < 1) if ((size = sock_recv( conn->socket, conn->ssl_read_buf + buf_len, ssl_buf_size - buf_len, 0 )) < 1)
return SEC_E_INCOMPLETE_MESSAGE; return SEC_E_INCOMPLETE_MESSAGE;
buf_len += size; buf_len += size;

View File

@ -108,7 +108,7 @@ struct netconn
ULONGLONG keep_until; ULONGLONG keep_until;
CtxtHandle ssl_ctx; CtxtHandle ssl_ctx;
SecPkgContext_StreamSizes ssl_sizes; SecPkgContext_StreamSizes ssl_sizes;
char *ssl_buf; char *ssl_read_buf, *ssl_write_buf;
char *extra_buf; char *extra_buf;
size_t extra_len; size_t extra_len;
char *peek_msg; char *peek_msg;