diff options
Diffstat (limited to 'lib/vtls/schannel.c')
-rw-r--r-- | lib/vtls/schannel.c | 358 |
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 = { |