TLS: move the ALPN/NPN enable bits to the connection
Only protocols that actually have a protocol registered for ALPN and NPN should try to get that negotiated in the TLS handshake. That is only HTTPS (well, http/1.1 and http/2) right now. Previously ALPN and NPN would wrongly be used in all handshakes if libcurl was built with it enabled. Reported-by: Jay Satiro Fixes #789
This commit is contained in:
Родитель
5bf5f6ebfc
Коммит
f6767f5435
|
@ -145,7 +145,7 @@ const struct Curl_handler Curl_handler_https = {
|
|||
ZERO_NULL, /* readwrite */
|
||||
PORT_HTTPS, /* defport */
|
||||
CURLPROTO_HTTPS, /* protocol */
|
||||
PROTOPT_SSL | PROTOPT_CREDSPERREQUEST /* flags */
|
||||
PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN_NPN /* flags */
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -6167,6 +6167,15 @@ static CURLcode create_conn(struct SessionHandle *data,
|
|||
connections we are allowed to open. */
|
||||
struct connectbundle *bundle = NULL;
|
||||
|
||||
if(conn->handler->flags & PROTOPT_ALPN_NPN) {
|
||||
/* The protocol wants it, so set the bits if enabled in the easy handle
|
||||
(default) */
|
||||
if(data->set.ssl_enable_alpn)
|
||||
conn->bits.tls_enable_alpn = TRUE;
|
||||
if(data->set.ssl_enable_npn)
|
||||
conn->bits.tls_enable_npn = TRUE;
|
||||
}
|
||||
|
||||
if(waitpipe)
|
||||
/* There is a connection that *might* become usable for pipelining
|
||||
"soon", and we wait for that */
|
||||
|
|
|
@ -544,6 +544,8 @@ struct ConnectBits {
|
|||
bool multiplex; /* connection is multiplexed */
|
||||
|
||||
bool tcp_fastopen; /* use TCP Fast Open */
|
||||
bool tls_enable_npn; /* TLS NPN extension? */
|
||||
bool tls_enable_alpn; /* TLS ALPN extension? */
|
||||
};
|
||||
|
||||
struct hostname {
|
||||
|
@ -815,7 +817,7 @@ struct Curl_handler {
|
|||
url query strings (?foo=bar) ! */
|
||||
#define PROTOPT_CREDSPERREQUEST (1<<7) /* requires login credentials per
|
||||
request instead of per connection */
|
||||
|
||||
#define PROTOPT_ALPN_NPN (1<<8) /* set ALPN and/or NPN for this */
|
||||
|
||||
/* return the count of bytes sent, or -1 on error */
|
||||
typedef ssize_t (Curl_send)(struct connectdata *conn, /* connection data */
|
||||
|
@ -1671,8 +1673,8 @@ struct UserDefined {
|
|||
|
||||
size_t maxconnects; /* Max idle connections in the connection cache */
|
||||
|
||||
bool ssl_enable_npn; /* TLS NPN extension? */
|
||||
bool ssl_enable_alpn; /* TLS ALPN extension? */
|
||||
bool ssl_enable_npn; /* TLS NPN extension? */
|
||||
bool ssl_enable_alpn; /* TLS ALPN extension? */
|
||||
bool path_as_is; /* allow dotdots? */
|
||||
bool pipewait; /* wait for pipe/multiplex status before starting a
|
||||
new connection */
|
||||
|
|
|
@ -351,7 +351,7 @@ cyassl_connect_step1(struct connectdata *conn,
|
|||
}
|
||||
|
||||
#ifdef HAVE_ALPN
|
||||
if(data->set.ssl_enable_alpn) {
|
||||
if(conn->bits.tls_enable_alpn) {
|
||||
char protocols[128];
|
||||
*protocols = '\0';
|
||||
|
||||
|
@ -525,7 +525,7 @@ cyassl_connect_step2(struct connectdata *conn,
|
|||
}
|
||||
|
||||
#ifdef HAVE_ALPN
|
||||
if(data->set.ssl_enable_alpn) {
|
||||
if(conn->bits.tls_enable_alpn) {
|
||||
int rc;
|
||||
char *protocol = NULL;
|
||||
unsigned short protocol_len = 0;
|
||||
|
|
|
@ -641,7 +641,7 @@ gtls_connect_step1(struct connectdata *conn,
|
|||
#endif
|
||||
|
||||
#ifdef HAS_ALPN
|
||||
if(data->set.ssl_enable_alpn) {
|
||||
if(conn->bits.tls_enable_alpn) {
|
||||
int cur = 0;
|
||||
gnutls_datum_t protocols[2];
|
||||
|
||||
|
@ -1240,7 +1240,7 @@ gtls_connect_step3(struct connectdata *conn,
|
|||
infof(data, "\t compression: %s\n", ptr);
|
||||
|
||||
#ifdef HAS_ALPN
|
||||
if(data->set.ssl_enable_alpn) {
|
||||
if(conn->bits.tls_enable_alpn) {
|
||||
rc = gnutls_alpn_get_selected_protocol(session, &proto);
|
||||
if(rc == 0) {
|
||||
infof(data, "ALPN, server accepted to use %.*s\n", proto.size,
|
||||
|
|
|
@ -401,7 +401,7 @@ mbed_connect_step1(struct connectdata *conn,
|
|||
}
|
||||
|
||||
#ifdef HAS_ALPN
|
||||
if(data->set.ssl_enable_alpn) {
|
||||
if(conn->bits.tls_enable_alpn) {
|
||||
const char **p = &connssl->protocols[0];
|
||||
#ifdef USE_NGHTTP2
|
||||
if(data->set.httpversion >= CURL_HTTP_VERSION_2)
|
||||
|
@ -561,7 +561,7 @@ mbed_connect_step2(struct connectdata *conn,
|
|||
}
|
||||
|
||||
#ifdef HAS_ALPN
|
||||
if(data->set.ssl_enable_alpn) {
|
||||
if(conn->bits.tls_enable_alpn) {
|
||||
next_protocol = mbedtls_ssl_get_alpn_protocol(&connssl->ssl);
|
||||
|
||||
if(next_protocol) {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
|
@ -696,7 +696,7 @@ static void HandshakeCallback(PRFileDesc *sock, void *arg)
|
|||
unsigned int buflen;
|
||||
SSLNextProtoState state;
|
||||
|
||||
if(!conn->data->set.ssl_enable_npn && !conn->data->set.ssl_enable_alpn) {
|
||||
if(!conn->bits.tls_enable_npn && !conn->bits.tls_enable_alpn) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1744,14 +1744,14 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
|||
#endif
|
||||
|
||||
#ifdef SSL_ENABLE_NPN
|
||||
if(SSL_OptionSet(connssl->handle, SSL_ENABLE_NPN, data->set.ssl_enable_npn
|
||||
? PR_TRUE : PR_FALSE) != SECSuccess)
|
||||
if(SSL_OptionSet(connssl->handle, SSL_ENABLE_NPN, conn->bits.tls_enable_npn
|
||||
? PR_TRUE : PR_FALSE) != SECSuccess)
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
#ifdef SSL_ENABLE_ALPN
|
||||
if(SSL_OptionSet(connssl->handle, SSL_ENABLE_ALPN, data->set.ssl_enable_alpn
|
||||
? PR_TRUE : PR_FALSE) != SECSuccess)
|
||||
if(SSL_OptionSet(connssl->handle, SSL_ENABLE_ALPN, conn->bits.tls_enable_alpn
|
||||
? PR_TRUE : PR_FALSE) != SECSuccess)
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
|
@ -1768,7 +1768,7 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
|||
#endif
|
||||
|
||||
#if defined(SSL_ENABLE_NPN) || defined(SSL_ENABLE_ALPN)
|
||||
if(data->set.ssl_enable_npn || data->set.ssl_enable_alpn) {
|
||||
if(conn->bits.tls_enable_npn || conn->bits.tls_enable_alpn) {
|
||||
int cur = 0;
|
||||
unsigned char protocols[128];
|
||||
|
||||
|
|
|
@ -1839,12 +1839,12 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
|||
SSL_CTX_set_options(connssl->ctx, ctx_options);
|
||||
|
||||
#ifdef HAS_NPN
|
||||
if(data->set.ssl_enable_npn)
|
||||
if(conn->bits.tls_enable_npn)
|
||||
SSL_CTX_set_next_proto_select_cb(connssl->ctx, select_next_proto_cb, conn);
|
||||
#endif
|
||||
|
||||
#ifdef HAS_ALPN
|
||||
if(data->set.ssl_enable_alpn) {
|
||||
if(conn->bits.tls_enable_alpn) {
|
||||
int cur = 0;
|
||||
unsigned char protocols[128];
|
||||
|
||||
|
@ -2165,7 +2165,7 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
|
|||
/* Sets data and len to negotiated protocol, len is 0 if no protocol was
|
||||
* negotiated
|
||||
*/
|
||||
if(data->set.ssl_enable_alpn) {
|
||||
if(conn->bits.tls_enable_alpn) {
|
||||
const unsigned char* neg_protocol;
|
||||
unsigned int len;
|
||||
SSL_get0_alpn_selected(connssl->handle, &neg_protocol, &len);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
|
@ -364,7 +364,7 @@ polarssl_connect_step1(struct connectdata *conn,
|
|||
}
|
||||
|
||||
#ifdef HAS_ALPN
|
||||
if(data->set.ssl_enable_alpn) {
|
||||
if(conn->bits.tls_enable_alpn) {
|
||||
static const char* protocols[3];
|
||||
int cur = 0;
|
||||
|
||||
|
@ -519,7 +519,7 @@ polarssl_connect_step2(struct connectdata *conn,
|
|||
}
|
||||
|
||||
#ifdef HAS_ALPN
|
||||
if(data->set.ssl_enable_alpn) {
|
||||
if(conn->bits.tls_enable_alpn) {
|
||||
const char *next_protocol = ssl_get_alpn_protocol(&connssl->ssl);
|
||||
|
||||
if(next_protocol != NULL) {
|
||||
|
|
|
@ -231,7 +231,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
|
|||
}
|
||||
|
||||
#ifdef HAS_ALPN
|
||||
if(data->set.ssl_enable_alpn) {
|
||||
if(conn->bits.tls_enable_alpn) {
|
||||
int cur = 0;
|
||||
int list_start_index = 0;
|
||||
unsigned int* extension_len = NULL;
|
||||
|
@ -630,7 +630,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
|
|||
}
|
||||
|
||||
#ifdef HAS_ALPN
|
||||
if(data->set.ssl_enable_alpn) {
|
||||
if(conn->bits.tls_enable_alpn) {
|
||||
sspi_status = s_pSecFn->QueryContextAttributes(&connssl->ctxt->ctxt_handle,
|
||||
SECPKG_ATTR_APPLICATION_PROTOCOL, &alpn_result);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче