Jacek Caban : wininet: Fixed race in SSL connection handling.
Alexandre Julliard
julliard at winehq.org
Thu Jan 20 12:41:20 CST 2011
Module: wine
Branch: master
Commit: 59bcbb2d8b4225fed0211326662d29eb7cf56117
URL: http://source.winehq.org/git/wine.git/?a=commit;h=59bcbb2d8b4225fed0211326662d29eb7cf56117
Author: Jacek Caban <jacek at codeweavers.com>
Date: Wed Jan 19 20:16:02 2011 +0100
wininet: Fixed race in SSL connection handling.
---
dlls/wininet/netconnection.c | 56 +++++++++++++++++++++--------------------
1 files changed, 29 insertions(+), 27 deletions(-)
diff --git a/dlls/wininet/netconnection.c b/dlls/wininet/netconnection.c
index 958abfb..cfc4e7c 100644
--- a/dlls/wininet/netconnection.c
+++ b/dlls/wininet/netconnection.c
@@ -368,7 +368,7 @@ static int netconn_secure_verify(int preverify_ok, X509_STORE_CTX *ctx)
DWORD NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL)
{
- connection->useSSL = FALSE;
+ connection->useSSL = useSSL;
connection->socketFD = -1;
if (useSSL)
{
@@ -544,10 +544,7 @@ void NETCON_unload(void)
BOOL NETCON_connected(WININET_NETCONNECTION *connection)
{
- if (connection->socketFD == -1)
- return FALSE;
- else
- return TRUE;
+ return connection->socketFD != -1;
}
/* translate a unix error code into a winsock one */
@@ -625,7 +622,7 @@ DWORD NETCON_create(WININET_NETCONNECTION *connection, int domain,
int type, int protocol)
{
#ifdef SONAME_LIBSSL
- if (connection->useSSL)
+ if (connection->ssl_s)
return ERROR_NOT_SUPPORTED;
#endif
@@ -647,13 +644,11 @@ DWORD NETCON_close(WININET_NETCONNECTION *connection)
if (!NETCON_connected(connection)) return ERROR_SUCCESS;
#ifdef SONAME_LIBSSL
- if (connection->useSSL)
+ if (connection->ssl_s)
{
pSSL_shutdown(connection->ssl_s);
pSSL_free(connection->ssl_s);
connection->ssl_s = NULL;
-
- connection->useSSL = FALSE;
}
#endif
@@ -671,26 +666,26 @@ DWORD NETCON_close(WININET_NETCONNECTION *connection)
*/
DWORD NETCON_secure_connect(WININET_NETCONNECTION *connection, LPWSTR hostname)
{
+ void *ssl_s;
DWORD res = ERROR_NOT_SUPPORTED;
#ifdef SONAME_LIBSSL
/* can't connect if we are already connected */
- if (connection->useSSL)
+ if (connection->ssl_s)
{
ERR("already connected\n");
return ERROR_INTERNET_CANNOT_CONNECT;
}
- connection->ssl_s = pSSL_new(ctx);
- if (!connection->ssl_s)
+ ssl_s = pSSL_new(ctx);
+ if (!ssl_s)
{
ERR("SSL_new failed: %s\n",
pERR_error_string(pERR_get_error(), 0));
- res = ERROR_OUTOFMEMORY;
- goto fail;
+ return ERROR_OUTOFMEMORY;
}
- if (!pSSL_set_fd(connection->ssl_s, connection->socketFD))
+ if (!pSSL_set_fd(ssl_s, connection->socketFD))
{
ERR("SSL_set_fd failed: %s\n",
pERR_error_string(pERR_get_error(), 0));
@@ -698,38 +693,37 @@ DWORD NETCON_secure_connect(WININET_NETCONNECTION *connection, LPWSTR hostname)
goto fail;
}
- if (!pSSL_set_ex_data(connection->ssl_s, hostname_idx, hostname))
+ if (!pSSL_set_ex_data(ssl_s, hostname_idx, hostname))
{
ERR("SSL_set_ex_data failed: %s\n",
pERR_error_string(pERR_get_error(), 0));
res = ERROR_INTERNET_SECURITY_CHANNEL_ERROR;
goto fail;
}
- if (!pSSL_set_ex_data(connection->ssl_s, conn_idx, connection))
+ if (!pSSL_set_ex_data(ssl_s, conn_idx, connection))
{
ERR("SSL_set_ex_data failed: %s\n",
pERR_error_string(pERR_get_error(), 0));
res = ERROR_INTERNET_SECURITY_CHANNEL_ERROR;
goto fail;
}
- if (pSSL_connect(connection->ssl_s) <= 0)
+ if (pSSL_connect(ssl_s) <= 0)
{
- res = (DWORD_PTR)pSSL_get_ex_data(connection->ssl_s, error_idx);
+ res = (DWORD_PTR)pSSL_get_ex_data(ssl_s, error_idx);
if (!res)
res = ERROR_INTERNET_SECURITY_CHANNEL_ERROR;
ERR("SSL_connect failed: %d\n", res);
goto fail;
}
- connection->useSSL = TRUE;
+ connection->ssl_s = ssl_s;
return ERROR_SUCCESS;
fail:
- if (connection->ssl_s)
+ if (ssl_s)
{
- pSSL_shutdown(connection->ssl_s);
- pSSL_free(connection->ssl_s);
- connection->ssl_s = NULL;
+ pSSL_shutdown(ssl_s);
+ pSSL_free(ssl_s);
}
#endif
return res;
@@ -776,6 +770,10 @@ DWORD NETCON_send(WININET_NETCONNECTION *connection, const void *msg, size_t len
else
{
#ifdef SONAME_LIBSSL
+ if(!connection->ssl_s) {
+ FIXME("not connected\n");
+ return ERROR_NOT_SUPPORTED;
+ }
if (flags)
FIXME("SSL_write doesn't support any flags (%08x)\n", flags);
*sent = pSSL_write(connection->ssl_s, msg, len);
@@ -810,6 +808,10 @@ DWORD NETCON_recv(WININET_NETCONNECTION *connection, void *buf, size_t len, int
else
{
#ifdef SONAME_LIBSSL
+ if(!connection->ssl_s) {
+ FIXME("not connected\n");
+ return ERROR_NOT_SUPPORTED;
+ }
*recvd = pSSL_read(connection->ssl_s, buf, len);
/* Check if EOF was received */
@@ -852,7 +854,7 @@ BOOL NETCON_query_data_available(WININET_NETCONNECTION *connection, DWORD *avail
else
{
#ifdef SONAME_LIBSSL
- *available = pSSL_pending(connection->ssl_s);
+ *available = connection->ssl_s ? pSSL_pending(connection->ssl_s) : 0;
#endif
}
return TRUE;
@@ -864,7 +866,7 @@ LPCVOID NETCON_GetCert(WININET_NETCONNECTION *connection)
X509* cert;
LPCVOID r = NULL;
- if (!connection->useSSL)
+ if (!connection->ssl_s)
return NULL;
cert = pSSL_get_peer_certificate(connection->ssl_s);
@@ -885,7 +887,7 @@ int NETCON_GetCipherStrength(WININET_NETCONNECTION *connection)
#endif
int bits = 0;
- if (!connection->useSSL)
+ if (!connection->ssl_s)
return 0;
cipher = pSSL_get_current_cipher(connection->ssl_s);
if (!cipher)
More information about the wine-cvs
mailing list