From 71ba6fcb9fa30a06610b426028e60ab61efa6770 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Wed, 3 Apr 2013 14:03:34 +0200 Subject: [PATCH] wininet: Added NETCON_send support for schannel-based connections. --- dlls/wininet/netconnection.c | 46 ++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/dlls/wininet/netconnection.c b/dlls/wininet/netconnection.c index cc169504a79..53308b9f03f 100644 --- a/dlls/wininet/netconnection.c +++ b/dlls/wininet/netconnection.c @@ -1127,6 +1127,34 @@ DWORD NETCON_secure_connect(netconn_t *connection, server_t *server) return res; } +#ifndef SONAME_LIBSSL +static BOOL send_ssl_chunk(netconn_t *conn, const void *msg, size_t size) +{ + SecBuffer bufs[4] = { + {conn->ssl_sizes.cbHeader, SECBUFFER_STREAM_HEADER, conn->ssl_buf}, + {size, SECBUFFER_DATA, conn->ssl_buf+conn->ssl_sizes.cbHeader}, + {conn->ssl_sizes.cbTrailer, SECBUFFER_STREAM_TRAILER, conn->ssl_buf+conn->ssl_sizes.cbHeader+size}, + {0, SECBUFFER_EMPTY, NULL} + }; + SecBufferDesc buf_desc = {SECBUFFER_VERSION, sizeof(bufs)/sizeof(*bufs), bufs}; + SECURITY_STATUS res; + + memcpy(bufs[1].pvBuffer, msg, size); + res = EncryptMessage(&conn->ssl_ctx, 0, &buf_desc, 0); + if(res != SEC_E_OK) { + WARN("EncryptMessage failed\n"); + return FALSE; + } + + if(send(conn->socket, conn->ssl_buf, bufs[0].cbBuffer+bufs[1].cbBuffer+bufs[2].cbBuffer, 0) < 1) { + WARN("send failed\n"); + return FALSE; + } + + return TRUE; +} +#endif + /****************************************************************************** * NETCON_send * Basically calls 'send()' unless we should use SSL @@ -1156,8 +1184,22 @@ DWORD NETCON_send(netconn_t *connection, const void *msg, size_t len, int flags, return ERROR_INTERNET_CONNECTION_ABORTED; return ERROR_SUCCESS; #else - FIXME("not supported on this platform\n"); - return ERROR_NOT_SUPPORTED; + const BYTE *ptr = msg; + size_t chunk_size; + + *sent = 0; + + while(len) { + chunk_size = min(len, connection->ssl_sizes.cbMaximumMessage); + if(!send_ssl_chunk(connection, ptr, chunk_size)) + return ERROR_INTERNET_SECURITY_CHANNEL_ERROR; + + *sent += chunk_size; + ptr += chunk_size; + len -= chunk_size; + } + + return ERROR_SUCCESS; #endif } }