diff options
Diffstat (limited to 'Utilities/cmcurl/lib/vtls/schannel.c')
-rw-r--r-- | Utilities/cmcurl/lib/vtls/schannel.c | 67 |
1 files changed, 24 insertions, 43 deletions
diff --git a/Utilities/cmcurl/lib/vtls/schannel.c b/Utilities/cmcurl/lib/vtls/schannel.c index 7eab954..452fa40 100644 --- a/Utilities/cmcurl/lib/vtls/schannel.c +++ b/Utilities/cmcurl/lib/vtls/schannel.c @@ -5,9 +5,9 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2012 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al. - * Copyright (C) 2012 - 2016, Marc Hoersken, <info@marc-hoersken.de> - * Copyright (C) 2012, Mark Salisbury, <mark.salisbury@hp.com> + * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) Marc Hoersken, <info@marc-hoersken.de> + * Copyright (C) Mark Salisbury, <mark.salisbury@hp.com> * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -1105,7 +1105,7 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) #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. */ - backend->use_alpn = cf->conn->bits.tls_enable_alpn && + backend->use_alpn = connssl->alpn && !GetProcAddress(GetModuleHandle(TEXT("ntdll")), "wine_get_version") && curlx_verify_windows_version(6, 3, 0, PLATFORM_WINNT, @@ -1196,6 +1196,7 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) int list_start_index = 0; unsigned int *extension_len = NULL; unsigned short* list_len = NULL; + struct alpn_proto_buf proto; /* The first four bytes will be an unsigned int indicating number of bytes of data in the rest of the buffer. */ @@ -1215,25 +1216,22 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) list_start_index = cur; -#ifdef USE_HTTP2 - if(data->state.httpwant >= CURL_HTTP_VERSION_2) { - alpn_buffer[cur++] = ALPN_H2_LENGTH; - memcpy(&alpn_buffer[cur], ALPN_H2, ALPN_H2_LENGTH); - cur += ALPN_H2_LENGTH; - infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_H2); + result = Curl_alpn_to_proto_buf(&proto, connssl->alpn); + if(result) { + failf(data, "Error setting ALPN"); + return CURLE_SSL_CONNECT_ERROR; } -#endif - - alpn_buffer[cur++] = ALPN_HTTP_1_1_LENGTH; - memcpy(&alpn_buffer[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH); - cur += ALPN_HTTP_1_1_LENGTH; - infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_1); + memcpy(&alpn_buffer[cur], proto.data, proto.len); + cur += proto.len; *list_len = curlx_uitous(cur - list_start_index); *extension_len = *list_len + sizeof(unsigned int) + sizeof(unsigned short); InitSecBuffer(&inbuf, SECBUFFER_APPLICATION_PROTOCOLS, alpn_buffer, cur); InitSecBufferDesc(&inbuf_desc, &inbuf, 1); + + Curl_alpn_to_proto_str(&proto, connssl->alpn); + infof(data, VTLS_INFOF_ALPN_OFFER_1STR, proto.data); } else { InitSecBuffer(&inbuf, SECBUFFER_EMPTY, NULL, 0); @@ -1727,40 +1725,23 @@ schannel_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data) if(alpn_result.ProtoNegoStatus == SecApplicationProtocolNegotiationStatus_Success) { - unsigned char alpn = 0; - - infof(data, VTLS_INFOF_ALPN_ACCEPTED_LEN_1STR, - alpn_result.ProtocolIdSize, alpn_result.ProtocolId); + unsigned char prev_alpn = cf->conn->alpn; -#ifdef USE_HTTP2 - if(alpn_result.ProtocolIdSize == ALPN_H2_LENGTH && - !memcmp(ALPN_H2, alpn_result.ProtocolId, ALPN_H2_LENGTH)) { - alpn = CURL_HTTP_VERSION_2; - } - else -#endif - if(alpn_result.ProtocolIdSize == ALPN_HTTP_1_1_LENGTH && - !memcmp(ALPN_HTTP_1_1, alpn_result.ProtocolId, - ALPN_HTTP_1_1_LENGTH)) { - alpn = CURL_HTTP_VERSION_1_1; - } + Curl_alpn_set_negotiated(cf, data, alpn_result.ProtocolId, + alpn_result.ProtocolIdSize); if(backend->recv_renegotiating) { - if(alpn != cf->conn->alpn) { + if(prev_alpn != cf->conn->alpn && + prev_alpn != CURL_HTTP_VERSION_NONE) { + /* Renegotiation selected a different protocol now, we cannot + * deal with this */ failf(data, "schannel: server selected an ALPN protocol too late"); return CURLE_SSL_CONNECT_ERROR; } } - else - cf->conn->alpn = alpn; } else { if(!backend->recv_renegotiating) - infof(data, VTLS_INFOF_NO_ALPN); - } - - if(!backend->recv_renegotiating) { - Curl_multiuse_state(data, cf->conn->alpn == CURL_HTTP_VERSION_2 ? - BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); + Curl_alpn_set_negotiated(cf, data, NULL, 0); } } #endif @@ -1841,7 +1822,7 @@ schannel_connect_common(struct Curl_cfilter *cf, { CURLcode result; struct ssl_connect_data *connssl = cf->ctx; - curl_socket_t sockfd = cf->conn->sock[cf->sockindex]; + curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data); timediff_t timeout_ms; int what; @@ -2056,7 +2037,7 @@ schannel_send(struct Curl_cfilter *cf, struct Curl_easy *data, } else if(!timeout_ms) timeout_ms = TIMEDIFF_T_MAX; - what = SOCKET_WRITABLE(cf->conn->sock[cf->sockindex], timeout_ms); + what = SOCKET_WRITABLE(Curl_conn_cf_get_socket(cf, data), timeout_ms); if(what < 0) { /* fatal error */ failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); |