aboutsummaryrefslogtreecommitdiff
path: root/lib/vtls/schannel.c
diff options
context:
space:
mode:
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 = {