aboutsummaryrefslogtreecommitdiff
path: root/lib/vtls/schannel.c
diff options
context:
space:
mode:
authorJohannes Schindelin <johannes.schindelin@gmx.de>2017-06-21 12:41:18 +0200
committerDaniel Stenberg <daniel@haxx.se>2017-08-28 14:56:58 +0200
commitd65e6cc4fc9f68da4cbf8788c27714622ef9eead (patch)
tree83999835de729324d3c447d3b3135835885bc84f /lib/vtls/schannel.c
parent20c6cf7e951e70d4c456bd4171b9f25f04f23a87 (diff)
vtls: prepare the SSL backends for encapsulated private data
At the moment, cURL's SSL backend needs to be configured at build time. As such, it is totally okay for them to hard-code their backend-specific data in the ssl_connect_data struct. In preparation for making the SSL backend a runtime option, let's make the access of said private data a bit more abstract so that it can be adjusted later in an easy manner. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Diffstat (limited to 'lib/vtls/schannel.c')
-rw-r--r--lib/vtls/schannel.c358
1 files changed, 180 insertions, 178 deletions
diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c
index 1296267ef..4fb24504d 100644
--- a/lib/vtls/schannel.c
+++ b/lib/vtls/schannel.c
@@ -127,6 +127,8 @@
* #define failf(x, y, ...) printf(y, __VA_ARGS__)
*/
+#define BACKEND connssl
+
static Curl_recv schannel_recv;
static Curl_send schannel_send;
@@ -224,33 +226,33 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
#ifdef HAS_ALPN
/* ALPN is only supported on Windows 8.1 / Server 2012 R2 and above.
Also it doesn't seem to be supported for Wine, see curl bug #983. */
- connssl->use_alpn = conn->bits.tls_enable_alpn &&
+ BACKEND->use_alpn = conn->bits.tls_enable_alpn &&
!GetProcAddress(GetModuleHandleA("ntdll"),
"wine_get_version") &&
Curl_verify_windows_version(6, 3, PLATFORM_WINNT,
VERSION_GREATER_THAN_EQUAL);
#else
- connssl->use_alpn = false;
+ BACKEND->use_alpn = false;
#endif
- connssl->cred = NULL;
+ BACKEND->cred = NULL;
/* check for an existing re-usable credential handle */
if(SSL_SET_OPTION(primary.sessionid)) {
Curl_ssl_sessionid_lock(conn);
if(!Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL, sockindex)) {
- connssl->cred = old_cred;
+ BACKEND->cred = old_cred;
infof(data, "schannel: re-using existing credential handle\n");
/* increment the reference counter of the credential/session handle */
- connssl->cred->refcount++;
+ BACKEND->cred->refcount++;
infof(data, "schannel: incremented credential handle refcount = %d\n",
- connssl->cred->refcount);
+ BACKEND->cred->refcount);
}
Curl_ssl_sessionid_unlock(conn);
}
- if(!connssl->cred) {
+ if(!BACKEND->cred) {
/* setup Schannel API options */
memset(&schannel_cred, 0, sizeof(schannel_cred));
schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
@@ -320,14 +322,14 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
}
/* allocate memory for the re-usable credential handle */
- connssl->cred = (struct curl_schannel_cred *)
+ BACKEND->cred = (struct curl_schannel_cred *)
malloc(sizeof(struct curl_schannel_cred));
- if(!connssl->cred) {
+ if(!BACKEND->cred) {
failf(data, "schannel: unable to allocate memory");
return CURLE_OUT_OF_MEMORY;
}
- memset(connssl->cred, 0, sizeof(struct curl_schannel_cred));
- connssl->cred->refcount = 1;
+ memset(BACKEND->cred, 0, sizeof(struct curl_schannel_cred));
+ BACKEND->cred->refcount = 1;
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa374716.aspx
*/
@@ -335,8 +337,8 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *)UNISP_NAME,
SECPKG_CRED_OUTBOUND, NULL,
&schannel_cred, NULL, NULL,
- &connssl->cred->cred_handle,
- &connssl->cred->time_stamp);
+ &BACKEND->cred->cred_handle,
+ &BACKEND->cred->time_stamp);
if(sspi_status != SEC_E_OK) {
if(sspi_status == SEC_E_WRONG_PRINCIPAL)
@@ -345,7 +347,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
else
failf(data, "schannel: AcquireCredentialsHandle failed: %s",
Curl_sspi_strerror(conn, sspi_status));
- Curl_safefree(connssl->cred);
+ Curl_safefree(BACKEND->cred);
return CURLE_SSL_CONNECT_ERROR;
}
}
@@ -360,7 +362,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
}
#ifdef HAS_ALPN
- if(connssl->use_alpn) {
+ if(BACKEND->use_alpn) {
int cur = 0;
int list_start_index = 0;
unsigned int *extension_len = NULL;
@@ -418,18 +420,18 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
InitSecBufferDesc(&outbuf_desc, &outbuf, 1);
/* setup request flags */
- connssl->req_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
+ BACKEND->req_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
ISC_REQ_CONFIDENTIALITY | ISC_REQ_ALLOCATE_MEMORY |
ISC_REQ_STREAM;
/* allocate memory for the security context handle */
- connssl->ctxt = (struct curl_schannel_ctxt *)
+ BACKEND->ctxt = (struct curl_schannel_ctxt *)
malloc(sizeof(struct curl_schannel_ctxt));
- if(!connssl->ctxt) {
+ if(!BACKEND->ctxt) {
failf(data, "schannel: unable to allocate memory");
return CURLE_OUT_OF_MEMORY;
}
- memset(connssl->ctxt, 0, sizeof(struct curl_schannel_ctxt));
+ memset(BACKEND->ctxt, 0, sizeof(struct curl_schannel_ctxt));
host_name = Curl_convert_UTF8_to_tchar(hostname);
if(!host_name)
@@ -443,10 +445,10 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
us problems with inbuf regardless. https://github.com/curl/curl/issues/983
*/
sspi_status = s_pSecFn->InitializeSecurityContext(
- &connssl->cred->cred_handle, NULL, host_name, connssl->req_flags, 0, 0,
- (connssl->use_alpn ? &inbuf_desc : NULL),
- 0, &connssl->ctxt->ctxt_handle,
- &outbuf_desc, &connssl->ret_flags, &connssl->ctxt->time_stamp);
+ &BACKEND->cred->cred_handle, NULL, host_name, BACKEND->req_flags, 0, 0,
+ (BACKEND->use_alpn ? &inbuf_desc : NULL),
+ 0, &BACKEND->ctxt->ctxt_handle,
+ &outbuf_desc, &BACKEND->ret_flags, &BACKEND->ctxt->time_stamp);
Curl_unicodefree(host_name);
@@ -457,7 +459,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
else
failf(data, "schannel: initial InitializeSecurityContext failed: %s",
Curl_sspi_strerror(conn, sspi_status));
- Curl_safefree(connssl->ctxt);
+ Curl_safefree(BACKEND->ctxt);
return CURLE_SSL_CONNECT_ERROR;
}
@@ -477,10 +479,10 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
infof(data, "schannel: sent initial handshake data: "
"sent %zd bytes\n", written);
- connssl->recv_unrecoverable_err = CURLE_OK;
- connssl->recv_sspi_close_notify = false;
- connssl->recv_connection_closed = false;
- connssl->encdata_is_incomplete = false;
+ BACKEND->recv_unrecoverable_err = CURLE_OK;
+ BACKEND->recv_sspi_close_notify = false;
+ BACKEND->recv_connection_closed = false;
+ BACKEND->encdata_is_incomplete = false;
/* continue to second handshake step */
connssl->connecting_state = ssl_connect_2;
@@ -513,39 +515,39 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
infof(data, "schannel: SSL/TLS connection with %s port %hu (step 2/3)\n",
hostname, conn->remote_port);
- if(!connssl->cred || !connssl->ctxt)
+ if(!BACKEND->cred || !BACKEND->ctxt)
return CURLE_SSL_CONNECT_ERROR;
/* buffer to store previously received and decrypted data */
- if(connssl->decdata_buffer == NULL) {
- connssl->decdata_offset = 0;
- connssl->decdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
- connssl->decdata_buffer = malloc(connssl->decdata_length);
- if(connssl->decdata_buffer == NULL) {
+ if(BACKEND->decdata_buffer == NULL) {
+ BACKEND->decdata_offset = 0;
+ BACKEND->decdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
+ BACKEND->decdata_buffer = malloc(BACKEND->decdata_length);
+ if(BACKEND->decdata_buffer == NULL) {
failf(data, "schannel: unable to allocate memory");
return CURLE_OUT_OF_MEMORY;
}
}
/* buffer to store previously received and encrypted data */
- if(connssl->encdata_buffer == NULL) {
- connssl->encdata_is_incomplete = false;
- connssl->encdata_offset = 0;
- connssl->encdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
- connssl->encdata_buffer = malloc(connssl->encdata_length);
- if(connssl->encdata_buffer == NULL) {
+ if(BACKEND->encdata_buffer == NULL) {
+ BACKEND->encdata_is_incomplete = false;
+ BACKEND->encdata_offset = 0;
+ BACKEND->encdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
+ BACKEND->encdata_buffer = malloc(BACKEND->encdata_length);
+ if(BACKEND->encdata_buffer == NULL) {
failf(data, "schannel: unable to allocate memory");
return CURLE_OUT_OF_MEMORY;
}
}
/* if we need a bigger buffer to read a full message, increase buffer now */
- if(connssl->encdata_length - connssl->encdata_offset <
+ if(BACKEND->encdata_length - BACKEND->encdata_offset <
CURL_SCHANNEL_BUFFER_FREE_SIZE) {
/* increase internal encrypted data buffer */
- reallocated_length = connssl->encdata_offset +
+ reallocated_length = BACKEND->encdata_offset +
CURL_SCHANNEL_BUFFER_FREE_SIZE;
- reallocated_buffer = realloc(connssl->encdata_buffer,
+ reallocated_buffer = realloc(BACKEND->encdata_buffer,
reallocated_length);
if(reallocated_buffer == NULL) {
@@ -553,8 +555,8 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
return CURLE_OUT_OF_MEMORY;
}
else {
- connssl->encdata_buffer = reallocated_buffer;
- connssl->encdata_length = reallocated_length;
+ BACKEND->encdata_buffer = reallocated_buffer;
+ BACKEND->encdata_length = reallocated_length;
}
}
@@ -562,10 +564,10 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
if(doread) {
/* read encrypted handshake data from socket */
result = Curl_read_plain(conn->sock[sockindex],
- (char *) (connssl->encdata_buffer +
- connssl->encdata_offset),
- connssl->encdata_length -
- connssl->encdata_offset,
+ (char *) (BACKEND->encdata_buffer +
+ BACKEND->encdata_offset),
+ BACKEND->encdata_length -
+ BACKEND->encdata_offset,
&nread);
if(result == CURLE_AGAIN) {
if(connssl->connecting_state != ssl_connect_2_writing)
@@ -581,17 +583,17 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
}
/* increase encrypted data buffer offset */
- connssl->encdata_offset += nread;
- connssl->encdata_is_incomplete = false;
+ BACKEND->encdata_offset += nread;
+ BACKEND->encdata_is_incomplete = false;
infof(data, "schannel: encrypted data got %zd\n", nread);
}
infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
- connssl->encdata_offset, connssl->encdata_length);
+ BACKEND->encdata_offset, BACKEND->encdata_length);
/* setup input buffers */
- InitSecBuffer(&inbuf[0], SECBUFFER_TOKEN, malloc(connssl->encdata_offset),
- curlx_uztoul(connssl->encdata_offset));
+ InitSecBuffer(&inbuf[0], SECBUFFER_TOKEN, malloc(BACKEND->encdata_offset),
+ curlx_uztoul(BACKEND->encdata_offset));
InitSecBuffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0);
InitSecBufferDesc(&inbuf_desc, inbuf, 2);
@@ -607,8 +609,8 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
}
/* copy received handshake data into input buffer */
- memcpy(inbuf[0].pvBuffer, connssl->encdata_buffer,
- connssl->encdata_offset);
+ memcpy(inbuf[0].pvBuffer, BACKEND->encdata_buffer,
+ BACKEND->encdata_offset);
host_name = Curl_convert_UTF8_to_tchar(hostname);
if(!host_name)
@@ -617,9 +619,9 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx
*/
sspi_status = s_pSecFn->InitializeSecurityContext(
- &connssl->cred->cred_handle, &connssl->ctxt->ctxt_handle,
- host_name, connssl->req_flags, 0, 0, &inbuf_desc, 0, NULL,
- &outbuf_desc, &connssl->ret_flags, &connssl->ctxt->time_stamp);
+ &BACKEND->cred->cred_handle, &BACKEND->ctxt->ctxt_handle,
+ host_name, BACKEND->req_flags, 0, 0, &inbuf_desc, 0, NULL,
+ &outbuf_desc, &BACKEND->ret_flags, &BACKEND->ctxt->time_stamp);
Curl_unicodefree(host_name);
@@ -628,7 +630,7 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
/* check if the handshake was incomplete */
if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
- connssl->encdata_is_incomplete = true;
+ BACKEND->encdata_is_incomplete = true;
connssl->connecting_state = ssl_connect_2_reading;
infof(data, "schannel: received incomplete message, need more data\n");
return CURLE_OK;
@@ -638,8 +640,8 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
the handshake without one. This will allow connections to servers which
request a client certificate but do not require it. */
if(sspi_status == SEC_I_INCOMPLETE_CREDENTIALS &&
- !(connssl->req_flags & ISC_REQ_USE_SUPPLIED_CREDS)) {
- connssl->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
+ !(BACKEND->req_flags & ISC_REQ_USE_SUPPLIED_CREDS)) {
+ BACKEND->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
connssl->connecting_state = ssl_connect_2_writing;
infof(data, "schannel: a client certificate has been requested\n");
return CURLE_OK;
@@ -697,11 +699,11 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
*/
/* check if the remaining data is less than the total amount
and therefore begins after the already processed data */
- if(connssl->encdata_offset > inbuf[1].cbBuffer) {
- memmove(connssl->encdata_buffer,
- (connssl->encdata_buffer + connssl->encdata_offset) -
+ if(BACKEND->encdata_offset > inbuf[1].cbBuffer) {
+ memmove(BACKEND->encdata_buffer,
+ (BACKEND->encdata_buffer + BACKEND->encdata_offset) -
inbuf[1].cbBuffer, inbuf[1].cbBuffer);
- connssl->encdata_offset = inbuf[1].cbBuffer;
+ BACKEND->encdata_offset = inbuf[1].cbBuffer;
if(sspi_status == SEC_I_CONTINUE_NEEDED) {
doread = FALSE;
continue;
@@ -709,7 +711,7 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
}
}
else {
- connssl->encdata_offset = 0;
+ BACKEND->encdata_offset = 0;
}
break;
}
@@ -757,27 +759,27 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
infof(data, "schannel: SSL/TLS connection with %s port %hu (step 3/3)\n",
hostname, conn->remote_port);
- if(!connssl->cred)
+ if(!BACKEND->cred)
return CURLE_SSL_CONNECT_ERROR;
/* check if the required context attributes are met */
- if(connssl->ret_flags != connssl->req_flags) {
- if(!(connssl->ret_flags & ISC_RET_SEQUENCE_DETECT))
+ if(BACKEND->ret_flags != BACKEND->req_flags) {
+ if(!(BACKEND->ret_flags & ISC_RET_SEQUENCE_DETECT))
failf(data, "schannel: failed to setup sequence detection");
- if(!(connssl->ret_flags & ISC_RET_REPLAY_DETECT))
+ if(!(BACKEND->ret_flags & ISC_RET_REPLAY_DETECT))
failf(data, "schannel: failed to setup replay detection");
- if(!(connssl->ret_flags & ISC_RET_CONFIDENTIALITY))
+ if(!(BACKEND->ret_flags & ISC_RET_CONFIDENTIALITY))
failf(data, "schannel: failed to setup confidentiality");
- if(!(connssl->ret_flags & ISC_RET_ALLOCATED_MEMORY))
+ if(!(BACKEND->ret_flags & ISC_RET_ALLOCATED_MEMORY))
failf(data, "schannel: failed to setup memory allocation");
- if(!(connssl->ret_flags & ISC_RET_STREAM))
+ if(!(BACKEND->ret_flags & ISC_RET_STREAM))
failf(data, "schannel: failed to setup stream orientation");
return CURLE_SSL_CONNECT_ERROR;
}
#ifdef HAS_ALPN
- if(connssl->use_alpn) {
- sspi_status = s_pSecFn->QueryContextAttributes(&connssl->ctxt->ctxt_handle,
+ if(BACKEND->use_alpn) {
+ sspi_status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
SECPKG_ATTR_APPLICATION_PROTOCOL, &alpn_result);
if(sspi_status != SEC_E_OK) {
@@ -819,7 +821,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
incache = !(Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL,
sockindex));
if(incache) {
- if(old_cred != connssl->cred) {
+ if(old_cred != BACKEND->cred) {
infof(data, "schannel: old credential handle is stale, removing\n");
/* we're not taking old_cred ownership here, no refcount++ is needed */
Curl_ssl_delsessionid(conn, (void *)old_cred);
@@ -827,7 +829,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
}
}
if(!incache) {
- result = Curl_ssl_addsessionid(conn, (void *)connssl->cred,
+ result = Curl_ssl_addsessionid(conn, (void *)BACKEND->cred,
sizeof(struct curl_schannel_cred),
sockindex);
if(result) {
@@ -837,7 +839,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
}
else {
/* this cred session is now also referenced by sessionid cache */
- connssl->cred->refcount++;
+ BACKEND->cred->refcount++;
infof(data, "schannel: stored credential handle in session cache\n");
}
}
@@ -845,7 +847,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
}
if(data->set.ssl.certinfo) {
- sspi_status = s_pSecFn->QueryContextAttributes(&connssl->ctxt->ctxt_handle,
+ sspi_status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
SECPKG_ATTR_REMOTE_CERT_CONTEXT, &ccert_context);
if((sspi_status != SEC_E_OK) || (ccert_context == NULL)) {
@@ -999,11 +1001,11 @@ schannel_send(struct connectdata *conn, int sockindex,
CURLcode result;
/* check if the maximum stream sizes were queried */
- if(connssl->stream_sizes.cbMaximumMessage == 0) {
+ if(BACKEND->stream_sizes.cbMaximumMessage == 0) {
sspi_status = s_pSecFn->QueryContextAttributes(
- &connssl->ctxt->ctxt_handle,
+ &BACKEND->ctxt->ctxt_handle,
SECPKG_ATTR_STREAM_SIZES,
- &connssl->stream_sizes);
+ &BACKEND->stream_sizes);
if(sspi_status != SEC_E_OK) {
*err = CURLE_SEND_ERROR;
return -1;
@@ -1011,14 +1013,14 @@ schannel_send(struct connectdata *conn, int sockindex,
}
/* check if the buffer is longer than the maximum message length */
- if(len > connssl->stream_sizes.cbMaximumMessage) {
+ if(len > BACKEND->stream_sizes.cbMaximumMessage) {
*err = CURLE_SEND_ERROR;
return -1;
}
/* calculate the complete message length and allocate a buffer for it */
- data_len = connssl->stream_sizes.cbHeader + len +
- connssl->stream_sizes.cbTrailer;
+ data_len = BACKEND->stream_sizes.cbHeader + len +
+ BACKEND->stream_sizes.cbTrailer;
data = (unsigned char *) malloc(data_len);
if(data == NULL) {
*err = CURLE_OUT_OF_MEMORY;
@@ -1027,12 +1029,12 @@ schannel_send(struct connectdata *conn, int sockindex,
/* setup output buffers (header, data, trailer, empty) */
InitSecBuffer(&outbuf[0], SECBUFFER_STREAM_HEADER,
- data, connssl->stream_sizes.cbHeader);
+ data, BACKEND->stream_sizes.cbHeader);
InitSecBuffer(&outbuf[1], SECBUFFER_DATA,
- data + connssl->stream_sizes.cbHeader, curlx_uztoul(len));
+ data + BACKEND->stream_sizes.cbHeader, curlx_uztoul(len));
InitSecBuffer(&outbuf[2], SECBUFFER_STREAM_TRAILER,
- data + connssl->stream_sizes.cbHeader + len,
- connssl->stream_sizes.cbTrailer);
+ data + BACKEND->stream_sizes.cbHeader + len,
+ BACKEND->stream_sizes.cbTrailer);
InitSecBuffer(&outbuf[3], SECBUFFER_EMPTY, NULL, 0);
InitSecBufferDesc(&outbuf_desc, outbuf, 4);
@@ -1040,7 +1042,7 @@ schannel_send(struct connectdata *conn, int sockindex,
memcpy(outbuf[1].pvBuffer, buf, len);
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375390.aspx */
- sspi_status = s_pSecFn->EncryptMessage(&connssl->ctxt->ctxt_handle, 0,
+ sspi_status = s_pSecFn->EncryptMessage(&BACKEND->ctxt->ctxt_handle, 0,
&outbuf_desc, 0);
/* check if the message was encrypted */
@@ -1150,7 +1152,7 @@ schannel_recv(struct connectdata *conn, int sockindex,
size_t min_encdata_length = len + CURL_SCHANNEL_BUFFER_FREE_SIZE;
/****************************************************************************
- * Don't return or set connssl->recv_unrecoverable_err unless in the cleanup.
+ * Don't return or set BACKEND->recv_unrecoverable_err unless in the cleanup.
* The pattern for return error is set *err, optional infof, goto cleanup.
*
* Our priority is to always return as much decrypted data to the caller as
@@ -1162,16 +1164,16 @@ schannel_recv(struct connectdata *conn, int sockindex,
infof(data, "schannel: client wants to read %zu bytes\n", len);
*err = CURLE_OK;
- if(len && len <= connssl->decdata_offset) {
+ if(len && len <= BACKEND->decdata_offset) {
infof(data, "schannel: enough decrypted data is already available\n");
goto cleanup;
}
- else if(connssl->recv_unrecoverable_err) {
- *err = connssl->recv_unrecoverable_err;
+ else if(BACKEND->recv_unrecoverable_err) {
+ *err = BACKEND->recv_unrecoverable_err;
infof(data, "schannel: an unrecoverable error occurred in a prior call\n");
goto cleanup;
}
- else if(connssl->recv_sspi_close_notify) {
+ else if(BACKEND->recv_sspi_close_notify) {
/* once a server has indicated shutdown there is no more encrypted data */
infof(data, "schannel: server indicated shutdown in a prior call\n");
goto cleanup;
@@ -1183,17 +1185,17 @@ schannel_recv(struct connectdata *conn, int sockindex,
*/
; /* do nothing */
}
- else if(!connssl->recv_connection_closed) {
+ else if(!BACKEND->recv_connection_closed) {
/* increase enc buffer in order to fit the requested amount of data */
- size = connssl->encdata_length - connssl->encdata_offset;
+ size = BACKEND->encdata_length - BACKEND->encdata_offset;
if(size < CURL_SCHANNEL_BUFFER_FREE_SIZE ||
- connssl->encdata_length < min_encdata_length) {
- reallocated_length = connssl->encdata_offset +
+ BACKEND->encdata_length < min_encdata_length) {
+ reallocated_length = BACKEND->encdata_offset +
CURL_SCHANNEL_BUFFER_FREE_SIZE;
if(reallocated_length < min_encdata_length) {
reallocated_length = min_encdata_length;
}
- reallocated_buffer = realloc(connssl->encdata_buffer,
+ reallocated_buffer = realloc(BACKEND->encdata_buffer,
reallocated_length);
if(reallocated_buffer == NULL) {
*err = CURLE_OUT_OF_MEMORY;
@@ -1201,20 +1203,20 @@ schannel_recv(struct connectdata *conn, int sockindex,
goto cleanup;
}
- connssl->encdata_buffer = reallocated_buffer;
- connssl->encdata_length = reallocated_length;
- size = connssl->encdata_length - connssl->encdata_offset;
+ BACKEND->encdata_buffer = reallocated_buffer;
+ BACKEND->encdata_length = reallocated_length;
+ size = BACKEND->encdata_length - BACKEND->encdata_offset;
infof(data, "schannel: encdata_buffer resized %zu\n",
- connssl->encdata_length);
+ BACKEND->encdata_length);
}
infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
- connssl->encdata_offset, connssl->encdata_length);
+ BACKEND->encdata_offset, BACKEND->encdata_length);
/* read encrypted data from socket */
*err = Curl_read_plain(conn->sock[sockindex],
- (char *)(connssl->encdata_buffer +
- connssl->encdata_offset),
+ (char *)(BACKEND->encdata_buffer +
+ BACKEND->encdata_offset),
size, &nread);
if(*err) {
nread = -1;
@@ -1226,26 +1228,26 @@ schannel_recv(struct connectdata *conn, int sockindex,
infof(data, "schannel: Curl_read_plain returned error %d\n", *err);
}
else if(nread == 0) {
- connssl->recv_connection_closed = true;
+ BACKEND->recv_connection_closed = true;
infof(data, "schannel: server closed the connection\n");
}
else if(nread > 0) {
- connssl->encdata_offset += (size_t)nread;
- connssl->encdata_is_incomplete = false;
+ BACKEND->encdata_offset += (size_t)nread;
+ BACKEND->encdata_is_incomplete = false;
infof(data, "schannel: encrypted data got %zd\n", nread);
}
}
infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
- connssl->encdata_offset, connssl->encdata_length);
+ BACKEND->encdata_offset, BACKEND->encdata_length);
/* decrypt loop */
- while(connssl->encdata_offset > 0 && sspi_status == SEC_E_OK &&
- (!len || connssl->decdata_offset < len ||
- connssl->recv_connection_closed)) {
+ while(BACKEND->encdata_offset > 0 && sspi_status == SEC_E_OK &&
+ (!len || BACKEND->decdata_offset < len ||
+ BACKEND->recv_connection_closed)) {
/* prepare data buffer for DecryptMessage call */
- InitSecBuffer(&inbuf[0], SECBUFFER_DATA, connssl->encdata_buffer,
- curlx_uztoul(connssl->encdata_offset));
+ InitSecBuffer(&inbuf[0], SECBUFFER_DATA, BACKEND->encdata_buffer,
+ curlx_uztoul(BACKEND->encdata_offset));
/* we need 3 more empty input buffers for possible output */
InitSecBuffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0);
@@ -1255,7 +1257,7 @@ schannel_recv(struct connectdata *conn, int sockindex,
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375348.aspx
*/
- sspi_status = s_pSecFn->DecryptMessage(&connssl->ctxt->ctxt_handle,
+ sspi_status = s_pSecFn->DecryptMessage(&BACKEND->ctxt->ctxt_handle,
&inbuf_desc, 0, NULL);
/* check if everything went fine (server may want to renegotiate
@@ -1271,36 +1273,36 @@ schannel_recv(struct connectdata *conn, int sockindex,
/* increase buffer in order to fit the received amount of data */
size = inbuf[1].cbBuffer > CURL_SCHANNEL_BUFFER_FREE_SIZE ?
inbuf[1].cbBuffer : CURL_SCHANNEL_BUFFER_FREE_SIZE;
- if(connssl->decdata_length - connssl->decdata_offset < size ||
- connssl->decdata_length < len) {
+ if(BACKEND->decdata_length - BACKEND->decdata_offset < size ||
+ BACKEND->decdata_length < len) {
/* increase internal decrypted data buffer */
- reallocated_length = connssl->decdata_offset + size;
+ reallocated_length = BACKEND->decdata_offset + size;
/* make sure that the requested amount of data fits */
if(reallocated_length < len) {
reallocated_length = len;
}
- reallocated_buffer = realloc(connssl->decdata_buffer,
+ reallocated_buffer = realloc(BACKEND->decdata_buffer,
reallocated_length);
if(reallocated_buffer == NULL) {
*err = CURLE_OUT_OF_MEMORY;
failf(data, "schannel: unable to re-allocate memory");
goto cleanup;
}
- connssl->decdata_buffer = reallocated_buffer;
- connssl->decdata_length = reallocated_length;
+ BACKEND->decdata_buffer = reallocated_buffer;
+ BACKEND->decdata_length = reallocated_length;
}
/* copy decrypted data to internal buffer */
size = inbuf[1].cbBuffer;
if(size) {
- memcpy(connssl->decdata_buffer + connssl->decdata_offset,
+ memcpy(BACKEND->decdata_buffer + BACKEND->decdata_offset,
inbuf[1].pvBuffer, size);
- connssl->decdata_offset += size;
+ BACKEND->decdata_offset += size;
}
infof(data, "schannel: decrypted data added: %zu\n", size);
infof(data, "schannel: decrypted data cached: offset %zu length %zu\n",
- connssl->decdata_offset, connssl->decdata_length);
+ BACKEND->decdata_offset, BACKEND->decdata_length);
}
/* check for remaining encrypted data */
@@ -1311,21 +1313,21 @@ schannel_recv(struct connectdata *conn, int sockindex,
/* check if the remaining data is less than the total amount
* and therefore begins after the already processed data
*/
- if(connssl->encdata_offset > inbuf[3].cbBuffer) {
+ if(BACKEND->encdata_offset > inbuf[3].cbBuffer) {
/* move remaining encrypted data forward to the beginning of
buffer */
- memmove(connssl->encdata_buffer,
- (connssl->encdata_buffer + connssl->encdata_offset) -
+ memmove(BACKEND->encdata_buffer,
+ (BACKEND->encdata_buffer + BACKEND->encdata_offset) -
inbuf[3].cbBuffer, inbuf[3].cbBuffer);
- connssl->encdata_offset = inbuf[3].cbBuffer;
+ BACKEND->encdata_offset = inbuf[3].cbBuffer;
}
infof(data, "schannel: encrypted data cached: offset %zu length %zu\n",
- connssl->encdata_offset, connssl->encdata_length);
+ BACKEND->encdata_offset, BACKEND->encdata_length);
}
else {
/* reset encrypted buffer offset, because there is no data remaining */
- connssl->encdata_offset = 0;
+ BACKEND->encdata_offset = 0;
}
/* check if server wants to renegotiate the connection context */
@@ -1335,7 +1337,7 @@ schannel_recv(struct connectdata *conn, int sockindex,
infof(data, "schannel: can't renogotiate, an error is pending\n");
goto cleanup;
}
- if(connssl->encdata_offset) {
+ if(BACKEND->encdata_offset) {
*err = CURLE_RECV_ERROR;
infof(data, "schannel: can't renogotiate, "
"encrypted data available\n");
@@ -1359,16 +1361,16 @@ schannel_recv(struct connectdata *conn, int sockindex,
else if(sspi_status == SEC_I_CONTEXT_EXPIRED) {
/* In Windows 2000 SEC_I_CONTEXT_EXPIRED (close_notify) is not
returned so we have to work around that in cleanup. */
- connssl->recv_sspi_close_notify = true;
- if(!connssl->recv_connection_closed) {
- connssl->recv_connection_closed = true;
+ BACKEND->recv_sspi_close_notify = true;
+ if(!BACKEND->recv_connection_closed) {
+ BACKEND->recv_connection_closed = true;
infof(data, "schannel: server closed the connection\n");
}
goto cleanup;
}
}
else if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
- connssl->encdata_is_incomplete = true;
+ BACKEND->encdata_is_incomplete = true;
if(!*err)
*err = CURLE_AGAIN;
infof(data, "schannel: failed to decrypt data, need more data\n");
@@ -1383,10 +1385,10 @@ schannel_recv(struct connectdata *conn, int sockindex,
}
infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
- connssl->encdata_offset, connssl->encdata_length);
+ BACKEND->encdata_offset, BACKEND->encdata_length);
infof(data, "schannel: decrypted data buffer: offset %zu length %zu\n",
- connssl->decdata_offset, connssl->decdata_length);
+ BACKEND->decdata_offset, BACKEND->decdata_length);
cleanup:
/* Warning- there is no guarantee the encdata state is valid at this point */
@@ -1400,13 +1402,13 @@ cleanup:
return close_notify. In that case if the connection was closed we assume it
was graceful (close_notify) since there doesn't seem to be a way to tell.
*/
- if(len && !connssl->decdata_offset && connssl->recv_connection_closed &&
- !connssl->recv_sspi_close_notify) {
+ if(len && !BACKEND->decdata_offset && BACKEND->recv_connection_closed &&
+ !BACKEND->recv_sspi_close_notify) {
bool isWin2k = Curl_verify_windows_version(5, 0, PLATFORM_WINNT,
VERSION_EQUAL);
if(isWin2k && sspi_status == SEC_E_OK)
- connssl->recv_sspi_close_notify = true;
+ BACKEND->recv_sspi_close_notify = true;
else {
*err = CURLE_RECV_ERROR;
infof(data, "schannel: server closed abruptly (missing close_notify)\n");
@@ -1415,23 +1417,23 @@ cleanup:
/* Any error other than CURLE_AGAIN is an unrecoverable error. */
if(*err && *err != CURLE_AGAIN)
- connssl->recv_unrecoverable_err = *err;
+ BACKEND->recv_unrecoverable_err = *err;
- size = len < connssl->decdata_offset ? len : connssl->decdata_offset;
+ size = len < BACKEND->decdata_offset ? len : BACKEND->decdata_offset;
if(size) {
- memcpy(buf, connssl->decdata_buffer, size);
- memmove(connssl->decdata_buffer, connssl->decdata_buffer + size,
- connssl->decdata_offset - size);
- connssl->decdata_offset -= size;
+ memcpy(buf, BACKEND->decdata_buffer, size);
+ memmove(BACKEND->decdata_buffer, BACKEND->decdata_buffer + size,
+ BACKEND->decdata_offset - size);
+ BACKEND->decdata_offset -= size;
infof(data, "schannel: decrypted data returned %zu\n", size);
infof(data, "schannel: decrypted data buffer: offset %zu length %zu\n",
- connssl->decdata_offset, connssl->decdata_length);
+ BACKEND->decdata_offset, BACKEND->decdata_length);
*err = CURLE_OK;
return (ssize_t)size;
}
- if(!*err && !connssl->recv_connection_closed)
+ if(!*err && !BACKEND->recv_connection_closed)
*err = CURLE_AGAIN;
/* It's debatable what to return when !len. We could return whatever error we
@@ -1469,8 +1471,8 @@ static bool Curl_schannel_data_pending(const struct connectdata *conn,
const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
if(connssl->use) /* SSL/TLS is in use */
- return (connssl->decdata_offset > 0 ||
- (connssl->encdata_offset > 0 && !connssl->encdata_is_incomplete));
+ return (BACKEND->decdata_offset > 0 ||
+ (BACKEND->encdata_offset > 0 && !BACKEND->encdata_is_incomplete));
else
return FALSE;
}
@@ -1507,7 +1509,7 @@ static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
infof(data, "schannel: shutting down SSL/TLS connection with %s port %hu\n",
hostname, conn->remote_port);
- if(connssl->cred && connssl->ctxt) {
+ if(BACKEND->cred && BACKEND->ctxt) {
SecBufferDesc BuffDesc;
SecBuffer Buffer;
SECURITY_STATUS sspi_status;
@@ -1520,7 +1522,7 @@ static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
InitSecBuffer(&Buffer, SECBUFFER_TOKEN, &dwshut, sizeof(dwshut));
InitSecBufferDesc(&BuffDesc, &Buffer, 1);
- sspi_status = s_pSecFn->ApplyControlToken(&connssl->ctxt->ctxt_handle,
+ sspi_status = s_pSecFn->ApplyControlToken(&BACKEND->ctxt->ctxt_handle,
&BuffDesc);
if(sspi_status != SEC_E_OK)
@@ -1536,18 +1538,18 @@ static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
InitSecBufferDesc(&outbuf_desc, &outbuf, 1);
sspi_status = s_pSecFn->InitializeSecurityContext(
- &connssl->cred->cred_handle,
- &connssl->ctxt->ctxt_handle,
+ &BACKEND->cred->cred_handle,
+ &BACKEND->ctxt->ctxt_handle,
host_name,
- connssl->req_flags,
+ BACKEND->req_flags,
0,
0,
NULL,
0,
- &connssl->ctxt->ctxt_handle,
+ &BACKEND->ctxt->ctxt_handle,
&outbuf_desc,
- &connssl->ret_flags,
- &connssl->ctxt->time_stamp);
+ &BACKEND->ret_flags,
+ &BACKEND->ctxt->time_stamp);
Curl_unicodefree(host_name);
@@ -1566,33 +1568,33 @@ static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
}
/* free SSPI Schannel API security context handle */
- if(connssl->ctxt) {
+ if(BACKEND->ctxt) {
infof(data, "schannel: clear security context handle\n");
- s_pSecFn->DeleteSecurityContext(&connssl->ctxt->ctxt_handle);
- Curl_safefree(connssl->ctxt);
+ s_pSecFn->DeleteSecurityContext(&BACKEND->ctxt->ctxt_handle);
+ Curl_safefree(BACKEND->ctxt);
}
/* free SSPI Schannel API credential handle */
- if(connssl->cred) {
+ if(BACKEND->cred) {
Curl_ssl_sessionid_lock(conn);
- Curl_schannel_session_free(connssl->cred);
+ Curl_schannel_session_free(BACKEND->cred);
Curl_ssl_sessionid_unlock(conn);
- connssl->cred = NULL;
+ BACKEND->cred = NULL;
}
/* free internal buffer for received encrypted data */
- if(connssl->encdata_buffer != NULL) {
- Curl_safefree(connssl->encdata_buffer);
- connssl->encdata_length = 0;
- connssl->encdata_offset = 0;
- connssl->encdata_is_incomplete = false;
+ if(BACKEND->encdata_buffer != NULL) {
+ Curl_safefree(BACKEND->encdata_buffer);
+ BACKEND->encdata_length = 0;
+ BACKEND->encdata_offset = 0;
+ BACKEND->encdata_is_incomplete = false;
}
/* free internal buffer for received decrypted data */
- if(connssl->decdata_buffer != NULL) {
- Curl_safefree(connssl->decdata_buffer);
- connssl->decdata_length = 0;
- connssl->decdata_offset = 0;
+ if(BACKEND->decdata_buffer != NULL) {
+ Curl_safefree(BACKEND->decdata_buffer);
+ BACKEND->decdata_length = 0;
+ BACKEND->decdata_offset = 0;
}
return CURLE_OK;
@@ -1646,7 +1648,7 @@ static CURLcode verify_certificate(struct connectdata *conn, int sockindex)
conn->http_proxy.host.name :
conn->host.name;
- status = s_pSecFn->QueryContextAttributes(&connssl->ctxt->ctxt_handle,
+ status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
SECPKG_ATTR_REMOTE_CERT_CONTEXT,
&pCertContextServer);
@@ -1777,7 +1779,7 @@ static void *Curl_schannel_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
(void)info;
- return &connssl->ctxt->ctxt_handle;
+ return &BACKEND->ctxt->ctxt_handle;
}
const struct Curl_ssl Curl_ssl_schannel = {