summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorStefan Eissing <stefan@eissing.org>2022-11-22 09:55:41 +0100
committerDaniel Stenberg <daniel@haxx.se>2022-11-22 14:25:50 +0100
commitaf22c2a546ab862ab577c8d9d3609af0de178974 (patch)
treef1a0c2d3c57d45da66809894997a50db840ac9e6 /lib
parenta28a80d59e8f111fa5a23bfb76c8ff148333edb0 (diff)
downloadcurl-af22c2a546ab862ab577c8d9d3609af0de178974.tar.gz
vtls: localization of state data in filters
- almost all backend calls pass the Curl_cfilter intance instead of connectdata+sockindex - ssl_connect_data is remove from struct connectdata and made internal to vtls - ssl_connect_data is allocated in the added filter, kept at cf->ctx - added function to let a ssl filter access its ssl_primary_config and ssl_config_data this selects the propert subfields in conn and data, for filters added as plain or proxy - adjusted all backends to use the changed api - adjusted all backends to access config data via the exposed functions, no longer using conn or data directly cfilter renames for clear purpose: - methods `Curl_conn_*(data, conn, sockindex)` work on the complete filter chain at `sockindex` and connection `conn`. - methods `Curl_cf_*(cf, ...)` work on a specific Curl_cfilter instance. - methods `Curl_conn_cf()` work on/with filter instances at a connection. - rebased and resolved some naming conflicts - hostname validation (und session lookup) on SECONDARY use the same name as on FIRST (again). new debug macros and removing connectdata from function signatures where not needed. adapting schannel for new Curl_read_plain paramter. Closes #9919
Diffstat (limited to 'lib')
-rw-r--r--lib/cfilters.c208
-rw-r--r--lib/cfilters.h180
-rw-r--r--lib/connect.c95
-rw-r--r--lib/connect.h14
-rw-r--r--lib/curl_sasl.c11
-rw-r--r--lib/ftp.c41
-rw-r--r--lib/gopher.c2
-rw-r--r--lib/http.c4
-rw-r--r--lib/http2.c2
-rw-r--r--lib/http_proxy.c89
-rw-r--r--lib/http_proxy.h10
-rw-r--r--lib/imap.c12
-rw-r--r--lib/multi.c11
-rw-r--r--lib/openldap.c4
-rw-r--r--lib/pingpong.c4
-rw-r--r--lib/pop3.c12
-rw-r--r--lib/rtsp.c6
-rw-r--r--lib/sendf.c2
-rw-r--r--lib/smb.c3
-rw-r--r--lib/smtp.c12
-rw-r--r--lib/socks.c33
-rw-r--r--lib/socks.h5
-rw-r--r--lib/transfer.c6
-rw-r--r--lib/url.c84
-rw-r--r--lib/urldata.h40
-rw-r--r--lib/vquic/ngtcp2.c29
-rw-r--r--lib/vquic/quiche.c3
-rw-r--r--lib/vssh/libssh.c4
-rw-r--r--lib/vssh/libssh2.c4
-rw-r--r--lib/vssh/wolfssh.c2
-rw-r--r--lib/vtls/bearssl.c140
-rw-r--r--lib/vtls/gskit.c213
-rw-r--r--lib/vtls/gtls.c337
-rw-r--r--lib/vtls/gtls.h7
-rw-r--r--lib/vtls/mbedtls.c179
-rw-r--r--lib/vtls/nss.c325
-rw-r--r--lib/vtls/openssl.c536
-rw-r--r--lib/vtls/rustls.c83
-rw-r--r--lib/vtls/schannel.c239
-rw-r--r--lib/vtls/schannel.h5
-rw-r--r--lib/vtls/schannel_verify.c23
-rw-r--r--lib/vtls/sectransp.c258
-rw-r--r--lib/vtls/vtls.c591
-rw-r--r--lib/vtls/vtls.h115
-rw-r--r--lib/vtls/vtls_int.h108
-rw-r--r--lib/vtls/wolfssl.c215
-rw-r--r--lib/vtls/x509asn1.c30
-rw-r--r--lib/vtls/x509asn1.h3
48 files changed, 2226 insertions, 2113 deletions
diff --git a/lib/cfilters.c b/lib/cfilters.c
index 8bc02c92f..fe7624e83 100644
--- a/lib/cfilters.c
+++ b/lib/cfilters.c
@@ -47,32 +47,8 @@
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
#endif
-#ifdef DEBUGBUILD
-static void cf_debug(struct Curl_easy *data, const char *fname,
- struct connectdata *conn, int index, CURLcode result)
-{
- struct Curl_cfilter *cf;
- char chain[128];
- size_t offset = 0, len;
-
- for(cf = conn->cfilter[index]; cf; cf = cf->next) {
- len = strlen(cf->cft->name);
- if(offset + len + 2 > sizeof(chain))
- break;
- if(offset) {
- chain[offset++] = '.';
- }
- strcpy(chain + offset, cf->cft->name);
- offset += len;
- }
- chain[offset] = 0;
- infof(data, "%s(handle=%p, cfilter%d=[%s]) -> %d",
- fname, data, index, chain, result);
-}
-
-#endif
-void Curl_cf_def_destroy(struct Curl_cfilter *cf, struct Curl_easy *data)
+void Curl_cf_def_destroy_this(struct Curl_cfilter *cf, struct Curl_easy *data)
{
(void)cf;
(void)data;
@@ -115,6 +91,14 @@ CURLcode Curl_cf_def_connect(struct Curl_cfilter *cf,
return cf->next->cft->connect(cf->next, data, blocking, done);
}
+void Curl_cf_def_get_host(struct Curl_cfilter *cf, struct Curl_easy *data,
+ const char **phost, const char **pdisplay_host,
+ int *pport)
+{
+ DEBUGASSERT(cf->next);
+ cf->next->cft->get_host(cf->next, data, phost, pdisplay_host, pport);
+}
+
int Curl_cf_def_get_select_socks(struct Curl_cfilter *cf,
struct Curl_easy *data,
curl_socket_t *socks)
@@ -144,14 +128,13 @@ ssize_t Curl_cf_def_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
return cf->next->cft->do_recv(cf->next, data, buf, len, err);
}
-void Curl_cfilter_destroy(struct Curl_easy *data,
- struct connectdata *conn, int index)
+void Curl_conn_cf_discard_all(struct Curl_easy *data,
+ struct connectdata *conn, int index)
{
struct Curl_cfilter *cfn, *cf = conn->cfilter[index];
if(cf) {
- DEBUGF(infof(data, "Curl_cfilter_destroy(handle=%p, connection=%ld, "
- "index=%d)", data, conn->connection_id, index));
+ DEBUGF(infof(data, CMSGI(conn, index, "Curl_conn_cf_discard_all()")));
conn->cfilter[index] = NULL;
while(cf) {
cfn = cf->next;
@@ -162,23 +145,21 @@ void Curl_cfilter_destroy(struct Curl_easy *data,
}
}
-void Curl_cfilter_close(struct Curl_easy *data,
- struct connectdata *conn, int index)
+void Curl_conn_close(struct Curl_easy *data, int index)
{
struct Curl_cfilter *cf;
- DEBUGASSERT(conn);
+ DEBUGASSERT(data->conn);
/* it is valid to call that without filters being present */
- cf = conn->cfilter[index];
+ cf = data->conn->cfilter[index];
if(cf) {
- DEBUGF(infof(data, "Curl_cfilter_close(handle=%p, index=%d)",
- data, index));
+ DEBUGF(infof(data, DMSGI(data, index, "close()")));
cf->cft->close(cf, data);
}
}
-ssize_t Curl_cfilter_recv(struct Curl_easy *data, int num, char *buf,
- size_t len, CURLcode *code)
+ssize_t Curl_conn_recv(struct Curl_easy *data, int num, char *buf,
+ size_t len, CURLcode *code)
{
struct Curl_cfilter *cf;
ssize_t nread;
@@ -191,7 +172,7 @@ ssize_t Curl_cfilter_recv(struct Curl_easy *data, int num, char *buf,
}
if(cf) {
nread = cf->cft->do_recv(cf, data, buf, len, code);
- /* DEBUGF(infof(data, "Curl_cfilter_recv(handle=%p, index=%d)"
+ /* DEBUGF(infof(data, "Curl_conn_recv(handle=%p, index=%d)"
"-> %ld, err=%d", data, num, nread, *code));*/
return nread;
}
@@ -201,8 +182,8 @@ ssize_t Curl_cfilter_recv(struct Curl_easy *data, int num, char *buf,
return -1;
}
-ssize_t Curl_cfilter_send(struct Curl_easy *data, int num,
- const void *mem, size_t len, CURLcode *code)
+ssize_t Curl_conn_send(struct Curl_easy *data, int num,
+ const void *mem, size_t len, CURLcode *code)
{
struct Curl_cfilter *cf;
ssize_t nwritten;
@@ -215,7 +196,7 @@ ssize_t Curl_cfilter_send(struct Curl_easy *data, int num,
}
if(cf) {
nwritten = cf->cft->do_send(cf, data, mem, len, code);
- /* DEBUGF(infof(data, "Curl_cfilter_send(handle=%p, index=%d, len=%ld)"
+ /* DEBUGF(infof(data, "Curl_conn_send(handle=%p, index=%d, len=%ld)"
" -> %ld, err=%d", data, num, len, nwritten, *code));*/
return nwritten;
}
@@ -225,26 +206,19 @@ ssize_t Curl_cfilter_send(struct Curl_easy *data, int num,
return -1;
}
-CURLcode Curl_cfilter_create(struct Curl_cfilter **pcf,
- struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex,
- const struct Curl_cftype *cft,
- void *ctx)
+CURLcode Curl_cf_create(struct Curl_cfilter **pcf,
+ const struct Curl_cftype *cft,
+ void *ctx)
{
struct Curl_cfilter *cf;
CURLcode result = CURLE_OUT_OF_MEMORY;
- (void)data;
- (void)conn;
DEBUGASSERT(cft);
cf = calloc(sizeof(*cf), 1);
if(!cf)
goto out;
cf->cft = cft;
- cf->conn = conn;
- cf->sockindex = sockindex;
cf->ctx = ctx;
result = CURLE_OK;
out:
@@ -252,24 +226,45 @@ out:
return result;
}
-void Curl_cfilter_add(struct Curl_easy *data, struct connectdata *conn,
- int index, struct Curl_cfilter *cf)
+void Curl_conn_cf_add(struct Curl_easy *data, int index,
+ struct Curl_cfilter *cf)
{
(void)data;
- DEBUGF(infof(data, "Curl_cfilter_add(conn=%ld, index=%d, filter=%s)",
- conn->connection_id, index, cf->cft->name));
+ DEBUGF(infof(data, DMSGI(data, index, "cf_add(filter=%s)"),
+ cf->cft->name));
- cf->next = conn->cfilter[index];
- cf->conn = conn;
+ DEBUGASSERT(data->conn);
+ DEBUGASSERT(!cf->conn);
+ DEBUGASSERT(!cf->next);
+ cf->next = data->conn->cfilter[index];
+ cf->conn = data->conn;
cf->sockindex = index;
- conn->cfilter[index] = cf;
+ data->conn->cfilter[index] = cf;
+}
+
+void Curl_conn_cf_discard(struct Curl_cfilter *cf, struct Curl_easy *data)
+{
+ struct Curl_cfilter **pprev = &cf->conn->cfilter[cf->sockindex];
+
+ /* remove from chain if still in there */
+ DEBUGASSERT(cf);
+ while (*pprev) {
+ if (*pprev == cf) {
+ *pprev = cf->next;
+ break;
+ }
+ pprev = &((*pprev)->next);
+ }
+ cf->cft->destroy(cf, data);
+ free(cf);
}
-CURLcode Curl_cfilter_setup(struct Curl_easy *data,
- struct connectdata *conn, int sockindex,
- const struct Curl_dns_entry *remotehost,
- int ssl_mode)
+CURLcode Curl_conn_setup(struct Curl_easy *data,
+ int sockindex,
+ const struct Curl_dns_entry *remotehost,
+ int ssl_mode)
{
+ struct connectdata *conn = data->conn;
struct Curl_cfilter *cf;
CURLcode result;
@@ -285,15 +280,14 @@ CURLcode Curl_cfilter_setup(struct Curl_easy *data,
* - SSL if conn->handler has PROTOPT_SSL
*/
if(!conn->cfilter[sockindex]) {
- DEBUGF(infof(data, "Curl_cfilter_setup(conn #%ld, index=%d)",
- conn->connection_id, sockindex));
- result = Curl_cfilter_socket_set(data, conn, sockindex);
+ DEBUGF(infof(data, DMSGI(data, sockindex, "setup, init filter chain")));
+ result = Curl_conn_socket_set(data, sockindex);
if(result)
goto out;
#ifndef CURL_DISABLE_PROXY
if(conn->bits.socksproxy) {
- result = Curl_cfilter_socks_proxy_add(data, conn, sockindex);
+ result = Curl_conn_socks_proxy_add(data, sockindex);
if(result)
goto out;
}
@@ -301,7 +295,7 @@ CURLcode Curl_cfilter_setup(struct Curl_easy *data,
if(conn->bits.httpproxy) {
#ifdef USE_SSL
if(conn->http_proxy.proxytype == CURLPROXY_HTTPS) {
- result = Curl_cfilter_ssl_proxy_add(data, conn, sockindex);
+ result = Curl_ssl_cfilter_proxy_add(data, sockindex);
if(result)
goto out;
}
@@ -309,7 +303,7 @@ CURLcode Curl_cfilter_setup(struct Curl_easy *data,
#if !defined(CURL_DISABLE_HTTP)
if(conn->bits.tunnel_proxy) {
- result = Curl_cfilter_http_proxy_add(data, conn, sockindex);
+ result = Curl_conn_http_proxy_add(data, sockindex);
if(result)
goto out;
}
@@ -321,7 +315,7 @@ CURLcode Curl_cfilter_setup(struct Curl_easy *data,
if(ssl_mode == CURL_CF_SSL_ENABLE
|| (ssl_mode != CURL_CF_SSL_DISABLE
&& conn->handler->flags & PROTOPT_SSL)) {
- result = Curl_cfilter_ssl_add(data, conn, sockindex);
+ result = Curl_ssl_cfilter_add(data, sockindex);
if(result)
goto out;
}
@@ -331,7 +325,7 @@ CURLcode Curl_cfilter_setup(struct Curl_easy *data,
#if !defined(CURL_DISABLE_PROXY) && !defined(CURL_DISABLE_HTTP)
if(data->set.haproxyprotocol) {
- result = Curl_cfilter_haproxy_add(data, conn, sockindex);
+ result = Curl_conn_haproxy_add(data, sockindex);
if(result)
goto out;
}
@@ -341,35 +335,34 @@ CURLcode Curl_cfilter_setup(struct Curl_easy *data,
DEBUGASSERT(conn->cfilter[sockindex]);
cf = data->conn->cfilter[sockindex];
result = cf->cft->setup(cf, data, remotehost);
+
out:
- DEBUGF(cf_debug(data, "Curl_cfilter_setup", conn, sockindex, result));
return result;
}
-CURLcode Curl_cfilter_connect(struct Curl_easy *data,
- struct connectdata *conn, int sockindex,
- bool blocking, bool *done)
+CURLcode Curl_conn_connect(struct Curl_easy *data,
+ int sockindex,
+ bool blocking,
+ bool *done)
{
struct Curl_cfilter *cf;
CURLcode result;
DEBUGASSERT(data);
- cf = conn->cfilter[sockindex];
+ cf = data->conn->cfilter[sockindex];
DEBUGASSERT(cf);
result = cf->cft->connect(cf, data, blocking, done);
- DEBUGF(infof(data, "Curl_cfilter_connect(handle=%p, index=%d, block=%d) "
- "-> %d, done=%d", data, sockindex, blocking, result, *done));
+ DEBUGF(infof(data, DMSGI(data, sockindex, "connect(block=%d)-> %d, done=%d"),
+ blocking, result, *done));
return result;
}
-bool Curl_cfilter_is_connected(struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+bool Curl_conn_is_connected(struct connectdata *conn, int sockindex)
{
struct Curl_cfilter *cf;
- (void)data;
cf = conn->cfilter[sockindex];
return cf && cf->connected;
}
@@ -389,13 +382,17 @@ bool Curl_conn_is_ip_connected(struct Curl_easy *data, int sockindex)
return FALSE;
}
-bool Curl_cfilter_data_pending(const struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+bool Curl_conn_data_pending(struct Curl_easy *data, int sockindex)
{
struct Curl_cfilter *cf;
+ (void)data;
DEBUGASSERT(data);
- cf = conn->cfilter[sockindex];
+ DEBUGASSERT(data->conn);
+ if(Curl_recv_has_postponed_data(data->conn, sockindex))
+ return TRUE;
+
+ cf = data->conn->cfilter[sockindex];
while(cf && !cf->connected) {
cf = cf->next;
}
@@ -405,22 +402,22 @@ bool Curl_cfilter_data_pending(const struct Curl_easy *data,
return FALSE;
}
-int Curl_cfilter_get_select_socks(struct Curl_easy *data,
- struct connectdata *conn, int sockindex,
- curl_socket_t *socks)
+int Curl_conn_get_select_socks(struct Curl_easy *data, int sockindex,
+ curl_socket_t *socks)
{
struct Curl_cfilter *cf;
DEBUGASSERT(data);
- cf = conn->cfilter[sockindex];
+ DEBUGASSERT(data->conn);
+ cf = data->conn->cfilter[sockindex];
if(cf) {
return cf->cft->get_select_socks(cf, data, socks);
}
return GETSOCK_BLANK;
}
-void Curl_cfilter_attach_data(struct connectdata *conn,
- struct Curl_easy *data)
+void Curl_conn_attach_data(struct connectdata *conn,
+ struct Curl_easy *data)
{
size_t i;
struct Curl_cfilter *cf;
@@ -428,8 +425,7 @@ void Curl_cfilter_attach_data(struct connectdata *conn,
for(i = 0; i < ARRAYSIZE(conn->cfilter); ++i) {
cf = conn->cfilter[i];
if(cf) {
- DEBUGF(infof(data, "Curl_cfilter_attach(handle=%p, connection=%ld, "
- "index=%zu)", data, conn->connection_id, i));
+ DEBUGF(infof(data, DMSGI(data, i, "attach_data()")));
while(cf) {
cf->cft->attach_data(cf, data);
cf = cf->next;
@@ -438,8 +434,8 @@ void Curl_cfilter_attach_data(struct connectdata *conn,
}
}
-void Curl_cfilter_detach_data(struct connectdata *conn,
- struct Curl_easy *data)
+void Curl_conn_detach_data(struct connectdata *conn,
+ struct Curl_easy *data)
{
size_t i;
struct Curl_cfilter *cf;
@@ -447,8 +443,7 @@ void Curl_cfilter_detach_data(struct connectdata *conn,
for(i = 0; i < ARRAYSIZE(conn->cfilter); ++i) {
cf = conn->cfilter[i];
if(cf) {
- DEBUGF(infof(data, "Curl_cfilter_detach(handle=%p, connection=%ld, "
- "index=%zu)", data, conn->connection_id, i));
+ DEBUGF(infof(data, DMSGI(data, i, "detach_data()")));
while(cf) {
cf->cft->detach_data(cf, data);
cf = cf->next;
@@ -457,3 +452,26 @@ void Curl_cfilter_detach_data(struct connectdata *conn,
}
}
+void Curl_conn_get_host(struct Curl_easy *data, int sockindex,
+ const char **phost, const char **pdisplay_host,
+ int *pport)
+{
+ struct Curl_cfilter *cf;
+
+ DEBUGASSERT(data->conn);
+ cf = data->conn->cfilter[sockindex];
+ if(cf) {
+ cf->cft->get_host(cf, data, phost, pdisplay_host, pport);
+ }
+ else {
+ /* Some filter ask during shutdown for this, mainly for debugging
+ * purposes. We hand out the defaults, however this is not always
+ * accurate, as the connction might be tunneled, etc. But all that
+ * state is already gone here. */
+ *phost = data->conn->host.name;
+ *pdisplay_host = data->conn->host.dispname;
+ *pport = data->conn->remote_port;
+ }
+}
+
+
diff --git a/lib/cfilters.h b/lib/cfilters.h
index 9950b6656..7e87781b8 100644
--- a/lib/cfilters.h
+++ b/lib/cfilters.h
@@ -27,11 +27,14 @@
struct Curl_cfilter;
struct Curl_easy;
+struct Curl_dns_entry;
+struct connectdata;
-/* Destroy a filter instance. Implementations MUST NOT chain calls to cf->next.
+/* Callback to destroy resources held by this filter instance.
+ * Implementations MUST NOT chain calls to cf->next.
*/
-typedef void Curl_cf_destroy(struct Curl_cfilter *cf,
- struct Curl_easy *data);
+typedef void Curl_cf_destroy_this(struct Curl_cfilter *cf,
+ struct Curl_easy *data);
/* Setup the connection for `data`, using destination `remotehost`.
*/
@@ -45,6 +48,23 @@ typedef CURLcode Curl_cf_connect(struct Curl_cfilter *cf,
struct Curl_easy *data,
bool blocking, bool *done);
+/* Return the hostname and port the connection goes to.
+ * This may change with the connection state of filters when tunneling
+ * is involved.
+ * @param cf the filter to ask
+ * @param data the easy handle currently active
+ * @param phost on return, points to the relevant, real hostname.
+ * this is owned by the connection.
+ * @param pdisplay_host on return, points to the printable hostname.
+ * this is owned by the connection.
+ * @param pport on return, contains the port number
+ */
+typedef void Curl_cf_get_host(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ const char **phost,
+ const char **pdisplay_host,
+ int *pport);
+
/* Filters may return sockets and fdset flags they are waiting for.
* The passes array has room for up to MAX_SOCKSPEREASYHANDLE sockets.
* @return read/write fdset for index in socks
@@ -81,7 +101,7 @@ typedef void Curl_cf_detach_data(struct Curl_cfilter *cf,
* Note: there may be several `data` attached to a connection at the same
* time.
*/
-void Curl_cfilter_detach(struct connectdata *conn, struct Curl_easy *data);
+void Curl_conn_detach(struct connectdata *conn, struct Curl_easy *data);
#define CF_TYPE_IP_CONNECT (1 << 0)
#define CF_TYPE_SSL (1 << 1)
@@ -90,16 +110,17 @@ void Curl_cfilter_detach(struct connectdata *conn, struct Curl_easy *data);
struct Curl_cftype {
const char *name; /* name of the filter type */
long flags; /* flags of filter type */
- Curl_cf_destroy *destroy; /* destroy resources held */
- Curl_cf_attach_data *attach_data; /* data is being handled here */
- Curl_cf_detach_data *detach_data; /* data is no longer handled here */
+ Curl_cf_destroy_this *destroy; /* destroy resources of this cf */
Curl_cf_setup *setup; /* setup for a connection */
- Curl_cf_close *close; /* close conn */
Curl_cf_connect *connect; /* establish connection */
+ Curl_cf_close *close; /* close conn */
+ Curl_cf_get_host *get_host; /* host filter talks to */
Curl_cf_get_select_socks *get_select_socks;/* sockets to select on */
Curl_cf_data_pending *has_data_pending;/* conn has data pending */
Curl_cf_send *do_send; /* send data */
Curl_cf_recv *do_recv; /* receive data */
+ Curl_cf_attach_data *attach_data; /* data is being handled here */
+ Curl_cf_detach_data *detach_data; /* data is no longer handled here */
};
/* A connection filter instance, e.g. registered at a connection */
@@ -113,8 +134,8 @@ struct Curl_cfilter {
};
/* Default implementations for the type functions, implementing nop. */
-void Curl_cf_def_destroy(struct Curl_cfilter *cf,
- struct Curl_easy *data);
+void Curl_cf_def_destroy_this(struct Curl_cfilter *cf,
+ struct Curl_easy *data);
/* Default implementations for the type functions, implementing pass-through
* the filter chain. */
@@ -125,6 +146,9 @@ void Curl_cf_def_close(struct Curl_cfilter *cf, struct Curl_easy *data);
CURLcode Curl_cf_def_connect(struct Curl_cfilter *cf,
struct Curl_easy *data,
bool blocking, bool *done);
+void Curl_cf_def_get_host(struct Curl_cfilter *cf, struct Curl_easy *data,
+ const char **phost, const char **pdisplay_host,
+ int *pport);
int Curl_cf_def_get_select_socks(struct Curl_cfilter *cf,
struct Curl_easy *data,
curl_socket_t *socks);
@@ -139,35 +163,71 @@ void Curl_cf_def_attach_data(struct Curl_cfilter *cf,
void Curl_cf_def_detach_data(struct Curl_cfilter *cf,
struct Curl_easy *data);
+/**
+ * Create a new filter instance, unattached to the filter chain.
+ * Use Curl_conn_cf_add() to add it to the chain.
+ * @param pcf on success holds the created instance
+ * @parm cft the filter type
+ * @param ctx the type specific context to use
+ */
+CURLcode Curl_cf_create(struct Curl_cfilter **pcf,
+ const struct Curl_cftype *cft,
+ void *ctx);
-CURLcode Curl_cfilter_create(struct Curl_cfilter **pcf,
- struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex,
- const struct Curl_cftype *cft,
- void *ctx);
-
-void Curl_cfilter_destroy(struct Curl_easy *data,
- struct connectdata *conn, int index);
-
-void Curl_cfilter_add(struct Curl_easy *data,
- struct connectdata *conn, int index,
+/**
+ * Add a filter instance to the `sockindex` filter chain at connection
+ * `data->conn`. The filter must not already be attached. It is inserted at
+ * the start of the chain (top).
+ */
+void Curl_conn_cf_add(struct Curl_easy *data,
+ int sockindex,
struct Curl_cfilter *cf);
+/**
+ * Remove and destroy all filters at chain `sockindex` on connection `conn`.
+ */
+void Curl_conn_cf_discard_all(struct Curl_easy *data,
+ struct connectdata *conn,
+ int sockindex);
+
+/**
+ * Discard, e.g. remove and destroy a specific filter instance.
+ * If the filter is attached to a connection, it will be removed before
+ * it is destroyed.
+ */
+void Curl_conn_cf_discard(struct Curl_cfilter *cf, struct Curl_easy *data);
#define CURL_CF_SSL_DEFAULT -1
#define CURL_CF_SSL_DISABLE 0
#define CURL_CF_SSL_ENABLE 1
-CURLcode Curl_cfilter_setup(struct Curl_easy *data,
- struct connectdata *conn, int sockindex,
- const struct Curl_dns_entry *remotehost,
- int ssl_mode);
-CURLcode Curl_cfilter_connect(struct Curl_easy *data,
- struct connectdata *conn, int sockindex,
- bool blocking, bool *done);
-bool Curl_cfilter_is_connected(struct Curl_easy *data,
- struct connectdata *conn, int sockindex);
+/**
+ * Setup the filter chain at `sockindex` in connection `conn`, invoking
+ * the instance `setup(remotehost)` methods. If no filter chain is
+ * installed yet, inspects the configuration in `data` to install a
+ * suitable filter chain.
+ */
+CURLcode Curl_conn_setup(struct Curl_easy *data,
+ int sockindex,
+ const struct Curl_dns_entry *remotehost,
+ int ssl_mode);
+
+/**
+ * Bring the filter chain at `sockindex` for connection `data->conn` into
+ * connected state. Which will set `*done` to TRUE.
+ * This can be called on an already connected chain with no side effects.
+ * When not `blocking`, calls may return without error and `*done != TRUE`,
+ * while the individual filters negotiated the connection.
+ */
+CURLcode Curl_conn_connect(struct Curl_easy *data, int sockindex,
+ bool blocking, bool *done);
+
+/**
+ * Check if the filter chain at `sockindex` for connection `conn` is
+ * completely connected.
+ */
+bool Curl_conn_is_connected(struct connectdata *conn, int sockindex);
+
/**
* Determine if we have reached the remote host on IP level, e.g.
* have a TCP connection. This turns TRUE before a possible SSL
@@ -175,24 +235,43 @@ bool Curl_cfilter_is_connected(struct Curl_easy *data,
*/
bool Curl_conn_is_ip_connected(struct Curl_easy *data, int sockindex);
-void Curl_cfilter_close(struct Curl_easy *data,
- struct connectdata *conn, int index);
+/**
+ * Close the filter chain at `sockindex` for connection `data->conn`.
+ * Filters remain in place and may be connected again afterwards.
+ */
+void Curl_conn_close(struct Curl_easy *data, int sockindex);
+
+/**
+ * Return if data is pending in some connection filter at chain
+ * `sockindex` for connection `data->conn`.
+ */
+bool Curl_conn_data_pending(struct Curl_easy *data,
+ int sockindex);
-bool Curl_cfilter_data_pending(const struct Curl_easy *data,
- struct connectdata *conn, int sockindex);
+/**
+ * Get any select fd flags and the socket filters at chain `sockindex`
+ * at connection `conn` might be waiting for.
+ */
+int Curl_conn_get_select_socks(struct Curl_easy *data, int sockindex,
+ curl_socket_t *socks);
/**
- * Get any select fd flags and the socket filters might be waiting for.
+ * Receive data through the filter chain at `sockindex` for connection
+ * `data->conn`. Copy at most `len` bytes into `buf`. Return the
+ * actuel number of bytes copied or a negative value on error.
+ * The error code is placed into `*code`.
*/
-int Curl_cfilter_get_select_socks(struct Curl_easy *data,
- struct connectdata *conn, int sockindex,
- curl_socket_t *socks);
+ssize_t Curl_conn_recv(struct Curl_easy *data, int sockindex, char *buf,
+ size_t len, CURLcode *code);
-/* Helper function to migrate conn->recv, conn->send callback to filters */
-ssize_t Curl_cfilter_recv(struct Curl_easy *data, int num, char *buf,
- size_t len, CURLcode *code);
-ssize_t Curl_cfilter_send(struct Curl_easy *data, int num,
- const void *mem, size_t len, CURLcode *code);
+/**
+ * Send `len` bytes of data from `buf` through the filter chain `sockindex`
+ * at connection `data->conn`. Return the actual number of bytes written
+ * or a negative value on error.
+ * The error code is placed into `*code`.
+ */
+ssize_t Curl_conn_send(struct Curl_easy *data, int sockindex,
+ const void *buf, size_t len, CURLcode *code);
/**
* The easy handle `data` is being attached (served) by connection `conn`.
@@ -200,8 +279,8 @@ ssize_t Curl_cfilter_send(struct Curl_easy *data, int num,
* Note: there may be several `data` attached to a connection at the same
* time.
*/
-void Curl_cfilter_attach_data(struct connectdata *conn,
- struct Curl_easy *data);
+void Curl_conn_attach_data(struct connectdata *conn,
+ struct Curl_easy *data);
/**
* The easy handle `data` is being detached (no longer served)
@@ -210,7 +289,12 @@ void Curl_cfilter_attach_data(struct connectdata *conn,
* Note: there may be several `data` attached to a connection at the same
* time.
*/
-void Curl_cfilter_detach_data(struct connectdata *conn,
- struct Curl_easy *data);
+void Curl_conn_detach_data(struct connectdata *conn,
+ struct Curl_easy *data);
+
+void Curl_conn_get_host(struct Curl_easy *data, int sockindex,
+ const char **phost, const char **pdisplay_host,
+ int *pport);
+
#endif /* HEADER_CURL_CFILTERS_H */
diff --git a/lib/connect.c b/lib/connect.c
index 6fc711533..5404243c9 100644
--- a/lib/connect.c
+++ b/lib/connect.c
@@ -1440,12 +1440,13 @@ curl_socket_t Curl_getconnectinfo(struct Curl_easy *data,
/*
* Check if a connection seems to be alive.
*/
-bool Curl_connalive(struct connectdata *conn)
+bool Curl_connalive(struct Curl_easy *data, struct connectdata *conn)
{
+ (void)data;
/* First determine if ssl */
if(Curl_ssl_use(conn, FIRSTSOCKET)) {
/* use the SSL context */
- if(!Curl_ssl_check_cxn(conn))
+ if(!Curl_ssl_check_cxn(data, conn))
return false; /* FIN received */
}
/* Minix 3.1 doesn't support any flags on recv; just assume socket is OK */
@@ -1472,9 +1473,6 @@ bool Curl_connalive(struct connectdata *conn)
int Curl_closesocket(struct Curl_easy *data, struct connectdata *conn,
curl_socket_t sock)
{
- DEBUGF(infof(data, "Curl_closesocket(conn #%ld, sock=%d), fclosesocket=%p",
- conn ? conn->connection_id : -1,
- (int)sock, conn ? conn->fclosesocket : NULL));
if(conn && conn->fclosesocket) {
if((sock == conn->sock[SECONDARYSOCKET]) && conn->bits.sock_accepted)
/* if this socket matches the second socket, and that was created with
@@ -1636,13 +1634,6 @@ void Curl_conncontrol(struct connectdata *conn,
}
}
-/* Data received can be cached at various levels, so check them all here. */
-bool Curl_conn_data_pending(struct Curl_easy *data, int sockindex)
-{
- return Curl_recv_has_postponed_data(data->conn, sockindex)
- ||Curl_cfilter_data_pending(data, data->conn, sockindex);
-}
-
typedef enum {
SCFST_INIT,
SCFST_WAITING,
@@ -1706,9 +1697,8 @@ static CURLcode socket_cf_connect(struct Curl_cfilter *cf,
result = Curl_connecthost(data, conn, ctx->remotehost);
if(!result)
ctx->state = SCFST_WAITING;
- DEBUGF(infof(data, "socket_cf_connect(handle=%p, index=%d) -> "
- "connecthost() -> %d, done=%d",
- data, sockindex, result, *done));
+ DEBUGF(infof(data, CFMSG(cf, "connect(INIT) -> %d, done=%d"),
+ result, *done));
break;
case SCFST_WAITING:
result = is_connected(data, conn, sockindex, done);
@@ -1721,15 +1711,13 @@ static CURLcode socket_cf_connect(struct Curl_cfilter *cf,
ctx->state = SCFST_DONE;
cf->connected = TRUE;
}
- DEBUGF(infof(data, "socket_cf_connect(handle=%p, index=%d) -> "
- "is_connected() -> %d, done=%d",
- data, sockindex, result, *done));
+ DEBUGF(infof(data, CFMSG(cf, "connect(WAIT) -> %d, done=%d"),
+ result, *done));
break;
case SCFST_DONE:
*done = TRUE;
- DEBUGF(infof(data, "socket_cf_connect(handle=%p, index=%d) -> "
- "already connected-> %d, done=%d",
- data, sockindex, result, *done));
+ DEBUGF(infof(data, CFMSG(cf, "connect(DONE) -> %d, done=%d"),
+ result, *done));
break;
}
return result;
@@ -1750,8 +1738,8 @@ static CURLcode socket_cf_setup(struct Curl_cfilter *cf,
ctx->remotehost = remotehost;
}
/* we start connecting right on setup */
- DEBUGF(infof(data, "socket_cf_setup(handle=%p, remotehost=%s)",
- data, cf->conn->hostname_resolve));
+ DEBUGF(infof(data, CFMSG(cf, "setup(remotehost=%s)"),
+ cf->conn->hostname_resolve));
return socket_cf_connect(cf, data, FALSE, &done);
}
@@ -1775,6 +1763,18 @@ static void socket_cf_close(struct Curl_cfilter *cf,
ctx->state = SCFST_INIT;
}
+static void socket_cf_get_host(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ const char **phost,
+ const char **pdisplay_host,
+ int *pport)
+{
+ (void)data;
+ *phost = cf->conn->host.name;
+ *pdisplay_host = cf->conn->host.dispname;
+ *pport = cf->conn->port;
+}
+
static bool socket_cf_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data)
{
@@ -1791,8 +1791,8 @@ static ssize_t socket_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data,
{
ssize_t nwritten;
nwritten = Curl_send_plain(data, cf->sockindex, buf, len, err);
- /* DEBUGF(infof(data, "socket_cf_send(handle=%p, index=%d, len=%ld)"
- "-> %ld, code=%d", data, cf->sockindex, len, nwritten, *err));*/
+ DEBUGF(infof(data, CFMSG(cf, "send(len=%ld) -> %ld, err=%d"),
+ len, nwritten, *err));
return nwritten;
}
@@ -1801,8 +1801,7 @@ static ssize_t socket_cf_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
{
ssize_t nread;
nread = Curl_recv_plain(data, cf->sockindex, buf, len, err);
- /* DEBUGF(infof(data, "socket_cf_recv(handle=%p, index=%d) -> %ld",
- data, cf->sockindex, nread));*/
+ DEBUGF(infof(data, CFMSG(cf, "recv() -> %ld"), nread));
return nread;
}
@@ -1811,8 +1810,7 @@ static void socket_cf_destroy(struct Curl_cfilter *cf, struct Curl_easy *data)
struct socket_cf_ctx *state = cf->ctx;
(void)data;
- DEBUGF(infof(data, "socket_cf_destroy(conn #%ld, index=%d",
- cf->conn->connection_id, cf->sockindex));
+ DEBUGF(infof(data, CFMSG(cf, "destroy()")));
if(cf->connected) {
socket_cf_close(cf, data);
}
@@ -1824,37 +1822,36 @@ static const struct Curl_cftype cft_socket = {
"SOCKET",
CF_TYPE_IP_CONNECT,
socket_cf_destroy,
- Curl_cf_def_attach_data,
- Curl_cf_def_detach_data,
socket_cf_setup,
- socket_cf_close,
socket_cf_connect,
+ socket_cf_close,
+ socket_cf_get_host,
socket_cf_get_select_socks,
socket_cf_data_pending,
socket_cf_send,
socket_cf_recv,
+ Curl_cf_def_attach_data,
+ Curl_cf_def_detach_data,
};
-CURLcode Curl_cfilter_socket_set(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex)
+CURLcode Curl_conn_socket_set(struct Curl_easy *data,
+ int sockindex)
{
CURLcode result;
struct Curl_cfilter *cf = NULL;
struct socket_cf_ctx *scf_ctx = NULL;
/* Need to be first */
- DEBUGASSERT(!conn->cfilter[sockindex]);
+ DEBUGASSERT(!data->conn->cfilter[sockindex]);
scf_ctx = calloc(sizeof(*scf_ctx), 1);
if(!scf_ctx) {
result = CURLE_OUT_OF_MEMORY;
goto out;
}
- result = Curl_cfilter_create(&cf, data, conn, sockindex,
- &cft_socket, scf_ctx);
+ result = Curl_cf_create(&cf, &cft_socket, scf_ctx);
if(result)
goto out;
- Curl_cfilter_add(data, conn, sockindex, cf);
+ Curl_conn_cf_add(data, sockindex, cf);
out:
if(result) {
@@ -1895,21 +1892,22 @@ static const struct Curl_cftype cft_socket_accept = {
"SOCKET-ACCEPT",
CF_TYPE_IP_CONNECT,
socket_cf_destroy,
- Curl_cf_def_attach_data,
- Curl_cf_def_detach_data,
socket_accept_cf_setup,
- socket_cf_close,
socket_accept_cf_connect,
+ socket_cf_close,
+ socket_cf_get_host, /* TODO: not accurate */
Curl_cf_def_get_select_socks,
socket_cf_data_pending,
socket_cf_send,
socket_cf_recv,
+ Curl_cf_def_attach_data,
+ Curl_cf_def_detach_data,
};
-CURLcode Curl_cfilter_socket_accepted_set(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex, curl_socket_t *s)
+CURLcode Curl_conn_socket_accepted_set(struct Curl_easy *data,
+ int sockindex, curl_socket_t *s)
{
+ struct connectdata *conn = data->conn;
CURLcode result;
struct Curl_cfilter *cf = NULL;
struct socket_cf_ctx *scf_ctx = NULL;
@@ -1922,17 +1920,16 @@ CURLcode Curl_cfilter_socket_accepted_set(struct Curl_easy *data,
}
else {
/* replace any existing */
- Curl_cfilter_destroy(data, conn, sockindex);
+ Curl_conn_cf_discard_all(data, conn, sockindex);
scf_ctx = calloc(sizeof(*scf_ctx), 1);
if(!scf_ctx) {
result = CURLE_OUT_OF_MEMORY;
goto out;
}
- result = Curl_cfilter_create(&cf, data, conn, sockindex,
- &cft_socket_accept, scf_ctx);
+ result = Curl_cf_create(&cf, &cft_socket_accept, scf_ctx);
if(result)
goto out;
- Curl_cfilter_add(data, conn, sockindex, cf);
+ Curl_conn_cf_add(data, sockindex, cf);
}
/* close any existing socket and replace */
diff --git a/lib/connect.h b/lib/connect.h
index ea1d7af35..79f932a40 100644
--- a/lib/connect.h
+++ b/lib/connect.h
@@ -56,7 +56,7 @@ bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen,
/*
* Check if a connection seems to be alive.
*/
-bool Curl_connalive(struct connectdata *conn);
+bool Curl_connalive(struct Curl_easy *data, struct connectdata *conn);
#ifdef USE_WINSOCK
/* When you run a program that uses the Windows Sockets API, you may
@@ -148,14 +148,10 @@ void Curl_conncontrol(struct connectdata *conn,
#define connkeep(x,y) Curl_conncontrol(x, CONNCTRL_KEEP)
#endif
-bool Curl_conn_data_pending(struct Curl_easy *data, int sockindex);
+CURLcode Curl_conn_socket_set(struct Curl_easy *data,
+ int sockindex);
-CURLcode Curl_cfilter_socket_set(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex);
-
-CURLcode Curl_cfilter_socket_accepted_set(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex, curl_socket_t *s);
+CURLcode Curl_conn_socket_accepted_set(struct Curl_easy *data,
+ int sockindex, curl_socket_t *s);
#endif /* HEADER_CURL_CONNECT_H */
diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c
index 9684ee476..46ee800a4 100644
--- a/lib/curl_sasl.c
+++ b/lib/curl_sasl.c
@@ -44,6 +44,7 @@
#include "curl_base64.h"
#include "curl_md5.h"
#include "vauth/vauth.h"
+#include "cfilters.h"
#include "vtls/vtls.h"
#include "curl_hmac.h"
#include "curl_sasl.h"
@@ -340,8 +341,8 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data,
struct bufref resp;
saslstate state1 = SASL_STOP;
saslstate state2 = SASL_FINAL;
- const char * const hostname = SSL_HOST_NAME();
- const long int port = SSL_HOST_PORT();
+ const char *hostname, *disp_hostname;
+ int port;
#if defined(USE_KERBEROS5) || defined(USE_NTLM)
const char *service = data->set.str[STRING_SERVICE_NAME] ?
data->set.str[STRING_SERVICE_NAME] :
@@ -350,6 +351,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data,
const char *oauth_bearer = data->set.str[STRING_BEARER];
struct bufref nullmsg;
+ Curl_conn_get_host(data, FIRSTSOCKET, &hostname, &disp_hostname, &port);
Curl_bufref_init(&nullmsg);
Curl_bufref_init(&resp);
sasl->force_ir = force_ir; /* Latch for future use */
@@ -525,8 +527,8 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
struct connectdata *conn = data->conn;
saslstate newstate = SASL_FINAL;
struct bufref resp;
- const char * const hostname = SSL_HOST_NAME();
- const long int port = SSL_HOST_PORT();
+ const char *hostname, *disp_hostname;
+ int port;
#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \
defined(USE_NTLM)
const char *service = data->set.str[STRING_SERVICE_NAME] ?
@@ -536,6 +538,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
const char *oauth_bearer = data->set.str[STRING_BEARER];
struct bufref serverdata;
+ Curl_conn_get_host(data, FIRSTSOCKET, &hostname, &disp_hostname, &port);
Curl_bufref_init(&serverdata);
Curl_bufref_init(&resp);
*progress = SASL_INPROGRESS;
diff --git a/lib/ftp.c b/lib/ftp.c
index 00e906687..42df31252 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -219,8 +219,8 @@ const struct Curl_handler Curl_handler_ftps = {
static void close_secondarysocket(struct Curl_easy *data,
struct connectdata *conn)
{
- Curl_cfilter_close(data, conn, SECONDARYSOCKET);
- Curl_cfilter_destroy(data, conn, SECONDARYSOCKET);
+ Curl_conn_close(data, SECONDARYSOCKET);
+ Curl_conn_cf_discard_all(data, conn, SECONDARYSOCKET);
}
/*
@@ -291,7 +291,7 @@ static CURLcode AcceptServerConnect(struct Curl_easy *data)
(void)curlx_nonblock(s, TRUE); /* enable non-blocking */
/* Replace any filter on SECONDARY with one listeing on this socket */
- result = Curl_cfilter_socket_accepted_set(data, conn, SECONDARYSOCKET, &s);
+ result = Curl_conn_socket_accepted_set(data, SECONDARYSOCKET, &s);
if(result)
return result;
@@ -440,8 +440,7 @@ static CURLcode InitiateTransfer(struct Curl_easy *data)
bool connected;
DEBUGF(infof(data, "ftp InitiateTransfer()"));
- result = Curl_cfilter_connect(data, conn, SECONDARYSOCKET,
- TRUE, &connected);
+ result = Curl_conn_connect(data, SECONDARYSOCKET, TRUE, &connected);
if(result || !connected)
return result;
@@ -820,8 +819,8 @@ static int ftp_domore_getsock(struct Curl_easy *data,
DEBUGF(infof(data, "ftp_domore_getsock()"));
if(conn->cfilter[SECONDARYSOCKET]
- && !Curl_cfilter_is_connected(data, conn, SECONDARYSOCKET))
- return Curl_cfilter_get_select_socks(data, conn, SECONDARYSOCKET, socks);
+ && !Curl_conn_is_connected(conn, SECONDARYSOCKET))
+ return Curl_conn_get_select_socks(data, SECONDARYSOCKET, socks);
if(FTP_STOP == ftpc->state) {
int bits = GETSOCK_READSOCK(0);
@@ -1273,8 +1272,7 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
ftpc->count1 = fcmd;
/* Replace any filter on SECONDARY with one listeing on this socket */
- result = Curl_cfilter_socket_accepted_set(data, conn, SECONDARYSOCKET,
- &portsock);
+ result = Curl_conn_socket_accepted_set(data, SECONDARYSOCKET, &portsock);
if(result)
goto out;
portsock = CURL_SOCKET_BAD; /* now held in filter */
@@ -1789,8 +1787,8 @@ static CURLcode ftp_epsv_disable(struct Curl_easy *data,
infof(data, "Failed EPSV attempt. Disabling EPSV");
/* disable it for next transfer */
conn->bits.ftp_use_epsv = FALSE;
- Curl_cfilter_close(data, conn, SECONDARYSOCKET);
- Curl_cfilter_destroy(data, conn, SECONDARYSOCKET);
+ Curl_conn_close(data, SECONDARYSOCKET);
+ Curl_conn_cf_discard_all(data, conn, SECONDARYSOCKET);
data->state.errorbuf = FALSE; /* allow error message to get
rewritten */
result = Curl_pp_sendf(data, &conn->proto.ftpc.pp, "%s", "PASV");
@@ -1980,9 +1978,9 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data,
}
}
- result = Curl_cfilter_setup(data, conn, SECONDARYSOCKET, addr,
- conn->bits.ftp_use_data_ssl?
- CURL_CF_SSL_ENABLE : CURL_CF_SSL_DISABLE);
+ result = Curl_conn_setup(data, SECONDARYSOCKET, addr,
+ conn->bits.ftp_use_data_ssl?
+ CURL_CF_SSL_ENABLE : CURL_CF_SSL_DISABLE);
if(result) {
Curl_resolv_unlock(data, addr); /* we're done using this address */
@@ -2747,14 +2745,14 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
if((ftpcode == 234) || (ftpcode == 334)) {
/* this was BLOCKING, keep it so for now */
bool done;
- if(!Curl_cfilter_ssl_added(data, conn, FIRSTSOCKET)) {
- result = Curl_cfilter_ssl_add(data, conn, FIRSTSOCKET);
+ if(!Curl_ssl_conn_is_ssl(data, FIRSTSOCKET)) {
+ result = Curl_ssl_cfilter_add(data, FIRSTSOCKET);
if(result) {
/* we failed and bail out */
return CURLE_USE_SSL_FAILED;
}
}
- result = Curl_cfilter_connect(data, conn, FIRSTSOCKET, TRUE, &done);
+ result = Curl_conn_connect(data, FIRSTSOCKET, TRUE, &done);
if(!result) {
conn->bits.ftp_use_data_ssl = FALSE; /* clear-text data */
conn->bits.ftp_use_control_ssl = TRUE; /* SSL on control */
@@ -2820,7 +2818,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
case FTP_CCC:
if(ftpcode < 500) {
/* First shut down the SSL layer (note: this call will block) */
- result = Curl_ssl_shutdown(data, conn, FIRSTSOCKET);
+ result = Curl_ssl_cfilter_remove(data, FIRSTSOCKET);
if(result)
failf(data, "Failed to clear the command channel (CCC)");
@@ -3164,7 +3162,7 @@ static CURLcode ftp_connect(struct Curl_easy *data,
if(conn->handler->flags & PROTOPT_SSL) {
/* BLOCKING */
- result = Curl_cfilter_connect(data, conn, FIRSTSOCKET, TRUE, done);
+ result = Curl_conn_connect(data, FIRSTSOCKET, TRUE, done);
if(result)
return result;
conn->bits.ftp_use_control_ssl = TRUE;
@@ -3567,8 +3565,7 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep)
* So, when using ftps: the SSL handshake will not start until we
* tell the remote server that we are there. */
if(conn->cfilter[SECONDARYSOCKET]) {
- result = Curl_cfilter_connect(data, conn, SECONDARYSOCKET,
- FALSE, &connected);
+ result = Curl_conn_connect(data, SECONDARYSOCKET, FALSE, &connected);
if(result || !Curl_conn_is_ip_connected(data, SECONDARYSOCKET)) {
if(result && (ftpc->count1 == 0)) {
*completep = -1; /* go back to DOING please */
@@ -3727,7 +3724,7 @@ CURLcode ftp_perform(struct Curl_easy *data,
/* run the state-machine */
result = ftp_multi_statemach(data, dophase_done);
- *connected = Curl_cfilter_is_connected(data, data->conn, SECONDARYSOCKET);
+ *connected = Curl_conn_is_connected(data->conn, SECONDARYSOCKET);
infof(data, "ftp_perform ends with SECONDARY: %d", *connected);
diff --git a/lib/gopher.c b/lib/gopher.c
index 5631e7f99..6fbb7de32 100644
--- a/lib/gopher.c
+++ b/lib/gopher.c
@@ -120,7 +120,7 @@ static CURLcode gopher_connecting(struct Curl_easy *data, bool *done)
struct connectdata *conn = data->conn;
CURLcode result;
- result = Curl_cfilter_connect(data, conn, FIRSTSOCKET, TRUE, done);
+ result = Curl_conn_connect(data, FIRSTSOCKET, TRUE, done);
if(result)
connclose(conn, "Failed TLS connection");
*done = TRUE;
diff --git a/lib/http.c b/lib/http.c
index 31641c41f..1e23f901b 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -243,7 +243,7 @@ static CURLcode h3_setup_conn(struct Curl_easy *data,
DEBUGF(infof(data, "HTTP/3 direct conn setup(conn #%ld, index=%d)",
conn->connection_id, FIRSTSOCKET));
- return Curl_cfilter_socket_set(data, conn, FIRSTSOCKET);
+ return Curl_conn_socket_set(data, FIRSTSOCKET);
#else /* ENABLE_QUIC */
(void)conn;
@@ -1566,7 +1566,7 @@ CURLcode Curl_http_connect(struct Curl_easy *data, bool *done)
function to make the re-use checks properly be able to check this bit. */
connkeep(conn, "HTTP default");
- return Curl_cfilter_connect(data, conn, FIRSTSOCKET, FALSE, done);
+ return Curl_conn_connect(data, FIRSTSOCKET, FALSE, done);
}
/* this returns the socket to wait for in the DO and DOING state for the multi
diff --git a/lib/http2.c b/lib/http2.c
index 66ebafc25..b9d3245cf 100644
--- a/lib/http2.c
+++ b/lib/http2.c
@@ -191,7 +191,7 @@ static bool http2_connisdead(struct Curl_easy *data, struct connectdata *conn)
}
else if(sval & CURL_CSELECT_IN) {
/* readable with no error. could still be closed */
- dead = !Curl_connalive(conn);
+ dead = !Curl_connalive(data, conn);
if(!dead) {
/* This happens before we've sent off a request and the connection is
not in use by any other transfer, there shouldn't be any data here,
diff --git a/lib/http_proxy.c b/lib/http_proxy.c
index 0ba99d0f6..db851e0c8 100644
--- a/lib/http_proxy.c
+++ b/lib/http_proxy.c
@@ -165,14 +165,14 @@ static CURLcode tunnel_init(struct tunnel_state **pts,
return tunnel_reinit(ts, conn, data);
}
-static void tunnel_go_state(struct connectdata *conn,
+static void tunnel_go_state(struct Curl_cfilter *cf,
struct tunnel_state *ts,
tunnel_state new_state,
struct Curl_easy *data)
{
if(ts->tunnel_state == new_state)
return;
- DEBUGF(infof(data, "http-proxy: tunnel %p go_state %d -> %d",
+ DEBUGF(infof(data, CFMSG(cf, "tunnel %p go_state %d -> %d"),
ts, ts->tunnel_state, new_state));
/* leaving this one */
switch(ts->tunnel_state) {
@@ -185,7 +185,7 @@ static void tunnel_go_state(struct connectdata *conn,
/* entering this one */
switch(new_state) {
case TUNNEL_INIT:
- tunnel_reinit(ts, conn, data);
+ tunnel_reinit(ts, cf->conn, data);
break;
case TUNNEL_CONNECT:
@@ -204,9 +204,9 @@ static void tunnel_go_state(struct connectdata *conn,
case TUNNEL_ESTABLISHED:
infof(data, "CONNECT phase completed");
- if(conn)
+ if(cf->conn)
/* make sure this isn't set for the document request */
- conn->bits.rewindaftersend = FALSE;
+ cf->conn->bits.rewindaftersend = FALSE;
data->state.authproxy.done = TRUE;
data->state.authproxy.multipass = FALSE;
/* FALLTHROUGH */
@@ -235,7 +235,7 @@ static void tunnel_free(struct Curl_cfilter *cf,
{
struct tunnel_state *ts = cf->ctx;
if(ts) {
- tunnel_go_state(cf->conn, ts, TUNNEL_FAILED, data);
+ tunnel_go_state(cf, ts, TUNNEL_FAILED, data);
Curl_dyn_free(&ts->rcvbuf);
Curl_dyn_free(&ts->req);
free(ts);
@@ -982,7 +982,7 @@ static CURLcode CONNECT(struct Curl_cfilter *cf,
result = start_CONNECT(data, cf->conn, ts);
if(result)
goto out;
- tunnel_go_state(cf->conn, ts, TUNNEL_CONNECT, data);
+ tunnel_go_state(cf, ts, TUNNEL_CONNECT, data);
/* FALLTHROUGH */
case TUNNEL_CONNECT:
@@ -990,7 +990,7 @@ static CURLcode CONNECT(struct Curl_cfilter *cf,
result = send_CONNECT(data, cf->conn, ts, &done);
if(result || !done)
goto out;
- tunnel_go_state(cf->conn, ts, TUNNEL_RECEIVE, data);
+ tunnel_go_state(cf, ts, TUNNEL_RECEIVE, data);
/* FALLTHROUGH */
case TUNNEL_RECEIVE:
@@ -1004,7 +1004,7 @@ static CURLcode CONNECT(struct Curl_cfilter *cf,
if(result || !done)
goto out;
/* got it */
- tunnel_go_state(cf->conn, ts, TUNNEL_RESPONSE, data);
+ tunnel_go_state(cf, ts, TUNNEL_RESPONSE, data);
/* FALLTHROUGH */
case TUNNEL_RESPONSE:
@@ -1020,12 +1020,12 @@ static CURLcode CONNECT(struct Curl_cfilter *cf,
* to select on again.
* We return and expect to be called again. */
infof(data, "Connect me again please");
- Curl_cfilter_close(data, conn, cf->sockindex);
+ Curl_conn_close(data, cf->sockindex);
result = cf->next->cft->connect(cf->next, data, FALSE, &done);
goto out;
}
/* staying on this connection, reset state */
- tunnel_go_state(cf->conn, ts, TUNNEL_INIT, data);
+ tunnel_go_state(cf, ts, TUNNEL_INIT, data);
}
break;
@@ -1042,19 +1042,19 @@ static CURLcode CONNECT(struct Curl_cfilter *cf,
data->req.newurl = NULL;
/* failure, close this connection to avoid re-use */
streamclose(conn, "proxy CONNECT failure");
- tunnel_go_state(cf->conn, ts, TUNNEL_FAILED, data);
+ tunnel_go_state(cf, ts, TUNNEL_FAILED, data);
failf(data, "CONNECT tunnel failed, response %d", data->req.httpcode);
return CURLE_RECV_ERROR;
}
/* 2xx response, SUCCESS! */
- tunnel_go_state(cf->conn, ts, TUNNEL_ESTABLISHED, data);
+ tunnel_go_state(cf, ts, TUNNEL_ESTABLISHED, data);
infof(data, "CONNECT tunnel established, response %d",
data->info.httpproxycode);
result = CURLE_OK;
out:
if(result)
- tunnel_go_state(cf->conn, ts, TUNNEL_FAILED, data);
+ tunnel_go_state(cf, ts, TUNNEL_FAILED, data);
return result;
}
@@ -1088,7 +1088,7 @@ static CURLcode http_proxy_cf_connect(struct Curl_cfilter *cf,
cf->ctx = ts;
}
- DEBUGF(infof(data, "CONNECT(%s:%d, state=%d)",
+ DEBUGF(infof(data, CFMSG(cf, "connect(%s:%d, state=%d)"),
ts->hostname, ts->remote_port, ts->tunnel_state));
result = CONNECT(cf, data, ts);
if(result)
@@ -1101,11 +1101,28 @@ out:
cf->connected = TRUE;
tunnel_free(cf, data);
}
- DEBUGF(infof(data, "http_proxy_cf_connect(handle=%p, i=%d, block=%d) "
- "-> %d, done=%d", data, cf->sockindex, blocking, result, *done));
+ DEBUGF(infof(data, CFMSG(cf, "connect(block=%d) -> %d, done=%d"),
+ blocking, result, *done));
return result;
}
+static void http_proxy_cf_get_host(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ const char **phost,
+ const char **pdisplay_host,
+ int *pport)
+{
+ (void)data;
+ if(!cf->connected) {
+ *phost = cf->conn->http_proxy.host.name;
+ *pdisplay_host = cf->conn->http_proxy.host.dispname;
+ *pport = (int)cf->conn->http_proxy.port;
+ }
+ else {
+ cf->next->cft->get_host(cf->next, data, phost, pdisplay_host, pport);
+ }
+}
+
static int http_proxy_cf_get_select_socks(struct Curl_cfilter *cf,
struct Curl_easy *data,
curl_socket_t *socks)
@@ -1155,7 +1172,7 @@ static void http_proxy_cf_close(struct Curl_cfilter *cf,
cf->connected = FALSE;
cf->next->cft->close(cf->next, data);
if(cf->ctx) {
- tunnel_go_state(cf->conn, cf->ctx, TUNNEL_INIT, data);
+ tunnel_go_state(cf, cf->ctx, TUNNEL_INIT, data);
}
}
@@ -1164,28 +1181,27 @@ static const struct Curl_cftype cft_http_proxy = {
"HTTP-PROXY",
CF_TYPE_IP_CONNECT,
http_proxy_cf_destroy,
- Curl_cf_def_attach_data,
- http_proxy_cf_detach_data,
Curl_cf_def_setup,
- http_proxy_cf_close,
http_proxy_cf_connect,
+ http_proxy_cf_close,
+ http_proxy_cf_get_host,
http_proxy_cf_get_select_socks,
Curl_cf_def_data_pending,
Curl_cf_def_send,
Curl_cf_def_recv,
+ Curl_cf_def_attach_data,
+ http_proxy_cf_detach_data,
};
-CURLcode Curl_cfilter_http_proxy_add(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex)
+CURLcode Curl_conn_http_proxy_add(struct Curl_easy *data,
+ int sockindex)
{
struct Curl_cfilter *cf;
CURLcode result;
- result = Curl_cfilter_create(&cf, data, conn, sockindex,
- &cft_http_proxy, NULL);
+ result = Curl_cf_create(&cf, &cft_http_proxy, NULL);
if(!result)
- Curl_cfilter_add(data, conn, sockindex, cf);
+ Curl_conn_cf_add(data, sockindex, cf);
return result;
}
@@ -1248,29 +1264,28 @@ static CURLcode haproxy_cf_connect(struct Curl_cfilter *cf,
static const struct Curl_cftype cft_haproxy = {
"HAPROXY",
0,
- Curl_cf_def_destroy,
- Curl_cf_def_attach_data,
- Curl_cf_def_detach_data,
+ Curl_cf_def_destroy_this,
Curl_cf_def_setup,
- Curl_cf_def_close,
haproxy_cf_connect,
+ Curl_cf_def_close,
+ Curl_cf_def_get_host,
Curl_cf_def_get_select_socks,
Curl_cf_def_data_pending,
Curl_cf_def_send,
Curl_cf_def_recv,
+ Curl_cf_def_attach_data,
+ Curl_cf_def_detach_data,
};
-CURLcode Curl_cfilter_haproxy_add(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex)
+CURLcode Curl_conn_haproxy_add(struct Curl_easy *data,
+ int sockindex)
{
struct Curl_cfilter *cf;
CURLcode result;
- result = Curl_cfilter_create(&cf, data, conn, sockindex,
- &cft_haproxy, NULL);
+ result = Curl_cf_create(&cf, &cft_haproxy, NULL);
if(!result)
- Curl_cfilter_add(data, conn, sockindex, cf);
+ Curl_conn_cf_add(data, sockindex, cf);
return result;
}
diff --git a/lib/http_proxy.h b/lib/http_proxy.h
index d6629a970..ea5908364 100644
--- a/lib/http_proxy.h
+++ b/lib/http_proxy.h
@@ -32,14 +32,12 @@
/* Default proxy timeout in milliseconds */
#define PROXY_TIMEOUT (3600*1000)
-CURLcode Curl_cfilter_http_proxy_add(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex);
-
-CURLcode Curl_cfilter_haproxy_add(struct Curl_easy *data,
- struct connectdata *conn,
+CURLcode Curl_conn_http_proxy_add(struct Curl_easy *data,
int sockindex);
+CURLcode Curl_conn_haproxy_add(struct Curl_easy *data,
+ int sockindex);
+
#endif /* !CURL_DISABLE_PROXY && !CURL_DISABLE_HTTP */
#endif /* HEADER_CURL_HTTP_PROXY_H */
diff --git a/lib/imap.c b/lib/imap.c
index 49c5c49d7..60aa426c8 100644
--- a/lib/imap.c
+++ b/lib/imap.c
@@ -481,14 +481,13 @@ static CURLcode imap_perform_upgrade_tls(struct Curl_easy *data,
struct imap_conn *imapc = &conn->proto.imapc;
CURLcode result;
- if(!Curl_cfilter_ssl_added(data, conn, FIRSTSOCKET)) {
- result = Curl_cfilter_ssl_add(data, conn, FIRSTSOCKET);
+ if(!Curl_ssl_conn_is_ssl(data, FIRSTSOCKET)) {
+ result = Curl_ssl_cfilter_add(data, FIRSTSOCKET);
if(result)
goto out;
}
- result = Curl_cfilter_connect(data, conn, FIRSTSOCKET,
- FALSE, &imapc->ssldone);
+ result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &imapc->ssldone);
if(!result) {
if(imapc->state != IMAP_UPGRADETLS)
state(data, IMAP_UPGRADETLS);
@@ -1392,8 +1391,7 @@ static CURLcode imap_multi_statemach(struct Curl_easy *data, bool *done)
struct imap_conn *imapc = &conn->proto.imapc;
if((conn->handler->flags & PROTOPT_SSL) && !imapc->ssldone) {
- result = Curl_cfilter_connect(data, conn, FIRSTSOCKET,
- FALSE, &imapc->ssldone);
+ result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &imapc->ssldone);
if(result || !imapc->ssldone)
return result;
}
@@ -1610,7 +1608,7 @@ static CURLcode imap_perform(struct Curl_easy *data, bool *connected,
/* Run the state-machine */
result = imap_multi_statemach(data, dophase_done);
- *connected = Curl_cfilter_is_connected(data, conn, FIRSTSOCKET);
+ *connected = Curl_conn_is_connected(conn, FIRSTSOCKET);
if(*dophase_done)
DEBUGF(infof(data, "DO phase is complete"));
diff --git a/lib/multi.c b/lib/multi.c
index 14d0362aa..0e60cf3a5 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -954,7 +954,7 @@ void Curl_detach_connection(struct Curl_easy *data)
{
struct connectdata *conn = data->conn;
if(conn) {
- Curl_cfilter_detach_data(conn, data);
+ Curl_conn_detach_data(conn, data);
Curl_llist_remove(&conn->easyq, &data->conn_queue, NULL);
}
data->conn = NULL;
@@ -973,7 +973,7 @@ void Curl_attach_connection(struct Curl_easy *data,
data->conn = conn;
Curl_llist_insert_next(&conn->easyq, conn->easyq.tail, data,
&data->conn_queue);
- Curl_cfilter_attach_data(conn, data);
+ Curl_conn_attach_data(conn, data);
if(conn->handler->attach)
conn->handler->attach(data, conn);
}
@@ -1038,7 +1038,7 @@ static int multi_getsock(struct Curl_easy *data,
case MSTATE_TUNNELING:
case MSTATE_CONNECTING:
- return Curl_cfilter_get_select_socks(data, conn, FIRSTSOCKET, socks);
+ return Curl_conn_get_select_socks(data, FIRSTSOCKET, socks);
case MSTATE_DOING_MORE:
return domore_getsock(data, conn, socks);
@@ -1696,7 +1696,7 @@ static CURLcode protocol_connect(struct Curl_easy *data,
*protocol_done = FALSE;
- if(Curl_cfilter_is_connected(data, conn, FIRSTSOCKET)
+ if(Curl_conn_is_connected(conn, FIRSTSOCKET)
&& conn->bits.protoconnstart) {
/* We already are connected, get back. This may happen when the connect
worked fine in the first call, like when we connect to a local server
@@ -1982,8 +1982,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
case MSTATE_CONNECTING:
/* awaiting a completion of an asynch TCP connect */
DEBUGASSERT(data->conn);
- result = Curl_cfilter_connect(data, data->conn, FIRSTSOCKET,
- FALSE, &connected);
+ result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &connected);
if(connected && !result) {
rc = CURLM_CALL_MULTI_PERFORM;
multistate(data, MSTATE_PROTOCONNECT);
diff --git a/lib/openldap.c b/lib/openldap.c
index 3087c6a37..ab81e57c2 100644
--- a/lib/openldap.c
+++ b/lib/openldap.c
@@ -501,7 +501,7 @@ static CURLcode oldap_ssl_connect(struct Curl_easy *data, ldapstate newstate)
struct ldapconninfo *li = conn->proto.ldapc;
bool ssldone = 0;
- result = Curl_cfilter_connect(data, FIRSTSOCKET, FALSE, &ssldone);
+ result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &ssldone);
if(!result) {
state(data, newstate);
@@ -1153,7 +1153,7 @@ ldapsb_tls_ctrl(Sockbuf_IO_Desc *sbiod, int opt, void *arg)
(void)arg;
if(opt == LBER_SB_OPT_DATA_READY) {
struct Curl_easy *data = sbiod->sbiod_pvt;
- return Curl_cfilter_data_pending(data->conn, FIRSTSOCKET);
+ return Curl_conn_data_pending(data, FIRSTSOCKET);
}
return 0;
}
diff --git a/lib/pingpong.c b/lib/pingpong.c
index c116c5867..9b9558048 100644
--- a/lib/pingpong.c
+++ b/lib/pingpong.c
@@ -103,12 +103,12 @@ CURLcode Curl_pp_statemach(struct Curl_easy *data,
else
interval_ms = 0; /* immediate */
- if(Curl_cfilter_data_pending(data, conn, FIRSTSOCKET))
+ if(Curl_conn_data_pending(data, FIRSTSOCKET))
rc = 1;
else if(Curl_pp_moredata(pp))
/* We are receiving and there is data in the cache so just read it */
rc = 1;
- else if(!pp->sendleft && Curl_cfilter_data_pending(data, conn, FIRSTSOCKET))
+ else if(!pp->sendleft && Curl_conn_data_pending(data, FIRSTSOCKET))
/* We are receiving and there is data ready in the SSL library */
rc = 1;
else
diff --git a/lib/pop3.c b/lib/pop3.c
index b6ba0ea1a..a75b762c4 100644
--- a/lib/pop3.c
+++ b/lib/pop3.c
@@ -376,14 +376,13 @@ static CURLcode pop3_perform_upgrade_tls(struct Curl_easy *data,
struct pop3_conn *pop3c = &conn->proto.pop3c;
CURLcode result;
- if(!Curl_cfilter_ssl_added(data, conn, FIRSTSOCKET)) {
- result = Curl_cfilter_ssl_add(data, conn, FIRSTSOCKET);
+ if(!Curl_ssl_conn_is_ssl(data, FIRSTSOCKET)) {
+ result = Curl_ssl_cfilter_add(data, FIRSTSOCKET);
if(result)
goto out;
}
- result = Curl_cfilter_connect(data, conn, FIRSTSOCKET,
- FALSE, &pop3c->ssldone);
+ result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &pop3c->ssldone);
if(!result) {
if(pop3c->state != POP3_UPGRADETLS)
@@ -1062,8 +1061,7 @@ static CURLcode pop3_multi_statemach(struct Curl_easy *data, bool *done)
struct pop3_conn *pop3c = &conn->proto.pop3c;
if((conn->handler->flags & PROTOPT_SSL) && !pop3c->ssldone) {
- result = Curl_cfilter_connect(data, conn, FIRSTSOCKET,
- FALSE, &pop3c->ssldone);
+ result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &pop3c->ssldone);
if(result || !pop3c->ssldone)
return result;
}
@@ -1218,7 +1216,7 @@ static CURLcode pop3_perform(struct Curl_easy *data, bool *connected,
/* Run the state-machine */
result = pop3_multi_statemach(data, dophase_done);
- *connected = Curl_cfilter_is_connected(data, data->conn, FIRSTSOCKET);
+ *connected = Curl_conn_is_connected(data->conn, FIRSTSOCKET);
if(*dophase_done)
DEBUGF(infof(data, "DO phase is complete"));
diff --git a/lib/rtsp.c b/lib/rtsp.c
index 7ed2635fe..75e620d11 100644
--- a/lib/rtsp.c
+++ b/lib/rtsp.c
@@ -141,7 +141,7 @@ static CURLcode rtsp_setup_connection(struct Curl_easy *data,
* Instead, if it is readable, run Curl_connalive() to peek at the socket
* and distinguish between closed and data.
*/
-static bool rtsp_connisdead(struct connectdata *check)
+static bool rtsp_connisdead(struct Curl_easy *data, struct connectdata *check)
{
int sval;
bool ret_val = TRUE;
@@ -157,7 +157,7 @@ static bool rtsp_connisdead(struct connectdata *check)
}
else if(sval & CURL_CSELECT_IN) {
/* readable with no error. could still be closed */
- ret_val = !Curl_connalive(check);
+ ret_val = !Curl_connalive(data, check);
}
return ret_val;
@@ -174,7 +174,7 @@ static unsigned int rtsp_conncheck(struct Curl_easy *data,
(void)data;
if(checks_to_perform & CONNCHECK_ISDEAD) {
- if(rtsp_connisdead(conn))
+ if(rtsp_connisdead(data, conn))
ret_val |= CONNRESULT_DEAD;
}
diff --git a/lib/sendf.c b/lib/sendf.c
index 18724e062..63262409b 100644
--- a/lib/sendf.c
+++ b/lib/sendf.c
@@ -160,7 +160,7 @@ static CURLcode pre_receive_plain(struct Curl_easy *data,
performed before every send() if any incoming data is
available. However, skip this, if buffer is already full. */
if((conn->handler->protocol&PROTO_FAMILY_HTTP) != 0 &&
- conn->recv[num] == Curl_cfilter_recv &&
+ conn->recv[num] == Curl_conn_recv &&
(!psnd->buffer || bytestorecv)) {
const int readymask = Curl_socket_check(sockfd, CURL_SOCKET_BAD,
CURL_SOCKET_BAD, 0);
diff --git a/lib/smb.c b/lib/smb.c
index 98ee3f8da..2cfe041df 100644
--- a/lib/smb.c
+++ b/lib/smb.c
@@ -667,8 +667,7 @@ static CURLcode smb_connection_state(struct Curl_easy *data, bool *done)
#ifdef USE_SSL
if((conn->handler->flags & PROTOPT_SSL)) {
bool ssl_done = FALSE;
- result = Curl_cfilter_connect(data, conn, FIRSTSOCKET,
- FALSE, &ssl_done);
+ result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &ssl_done);
if(result && result != CURLE_AGAIN)
return result;
if(!ssl_done)
diff --git a/lib/smtp.c b/lib/smtp.c
index e70423603..ef59adce4 100644
--- a/lib/smtp.c
+++ b/lib/smtp.c
@@ -403,14 +403,13 @@ static CURLcode smtp_perform_upgrade_tls(struct Curl_easy *data)
struct smtp_conn *smtpc = &conn->proto.smtpc;
CURLcode result;
- if(!Curl_cfilter_ssl_added(data, conn, FIRSTSOCKET)) {
- result = Curl_cfilter_ssl_add(data, conn, FIRSTSOCKET);
+ if(!Curl_ssl_conn_is_ssl(data, FIRSTSOCKET)) {
+ result = Curl_ssl_cfilter_add(data, FIRSTSOCKET);
if(result)
goto out;
}
- result = Curl_cfilter_connect(data, conn, FIRSTSOCKET,
- FALSE, &smtpc->ssldone);
+ result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &smtpc->ssldone);
if(!result) {
if(smtpc->state != SMTP_UPGRADETLS)
state(data, SMTP_UPGRADETLS);
@@ -1292,8 +1291,7 @@ static CURLcode smtp_multi_statemach(struct Curl_easy *data, bool *done)
struct smtp_conn *smtpc = &conn->proto.smtpc;
if((conn->handler->flags & PROTOPT_SSL) && !smtpc->ssldone) {
- result = Curl_cfilter_connect(data, conn, FIRSTSOCKET,
- FALSE, &smtpc->ssldone);
+ result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &smtpc->ssldone);
if(result || !smtpc->ssldone)
return result;
}
@@ -1525,7 +1523,7 @@ static CURLcode smtp_perform(struct Curl_easy *data, bool *connected,
/* Run the state-machine */
result = smtp_multi_statemach(data, dophase_done);
- *connected = Curl_cfilter_is_connected(data, data->conn, FIRSTSOCKET);
+ *connected = Curl_conn_is_connected(data->conn, FIRSTSOCKET);
if(*dophase_done)
DEBUGF(infof(data, "DO phase is complete"));
diff --git a/lib/socks.c b/lib/socks.c
index 4cd86f4cc..e0b1735a6 100644
--- a/lib/socks.c
+++ b/lib/socks.c
@@ -1211,33 +1211,48 @@ static void socks_proxy_cf_detach_data(struct Curl_cfilter *cf,
socks_proxy_cf_free(cf);
}
+static void socks_cf_get_host(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ const char **phost,
+ const char **pdisplay_host,
+ int *pport)
+{
+ (void)data;
+ if(!cf->connected) {
+ *phost = cf->conn->socks_proxy.host.name;
+ *pdisplay_host = cf->conn->http_proxy.host.dispname;
+ *pport = (int)cf->conn->socks_proxy.port;
+ }
+ else {
+ cf->next->cft->get_host(cf->next, data, phost, pdisplay_host, pport);
+ }
+}
static const struct Curl_cftype cft_socks_proxy = {
"SOCKS-PROXYY",
CF_TYPE_IP_CONNECT,
socks_proxy_cf_destroy,
- Curl_cf_def_attach_data,
- socks_proxy_cf_detach_data,
Curl_cf_def_setup,
- socks_proxy_cf_close,
socks_proxy_cf_connect,
+ socks_proxy_cf_close,
+ socks_cf_get_host,
socks_cf_get_select_socks,
Curl_cf_def_data_pending,
Curl_cf_def_send,
Curl_cf_def_recv,
+ Curl_cf_def_attach_data,
+ socks_proxy_cf_detach_data,
};
-CURLcode Curl_cfilter_socks_proxy_add(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex)
+CURLcode Curl_conn_socks_proxy_add(struct Curl_easy *data,
+ int sockindex)
{
struct Curl_cfilter *cf;
CURLcode result;
- result = Curl_cfilter_create(&cf, data, conn, sockindex,
- &cft_socks_proxy, NULL);
+ result = Curl_cf_create(&cf, &cft_socks_proxy, NULL);
if(!result)
- Curl_cfilter_add(data, conn, sockindex, cf);
+ Curl_conn_cf_add(data, sockindex, cf);
return result;
}
diff --git a/lib/socks.h b/lib/socks.h
index e610b4b81..ddbb07cd7 100644
--- a/lib/socks.h
+++ b/lib/socks.h
@@ -51,9 +51,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
struct Curl_easy *data);
#endif
-CURLcode Curl_cfilter_socks_proxy_add(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex);
+CURLcode Curl_conn_socks_proxy_add(struct Curl_easy *data,
+ int sockindex);
#endif /* CURL_DISABLE_PROXY */
diff --git a/lib/transfer.c b/lib/transfer.c
index 34f837c90..c10f7e38d 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -445,7 +445,7 @@ CURLcode Curl_readrewind(struct Curl_easy *data)
return CURLE_OK;
}
-static int data_pending(const struct Curl_easy *data)
+static int data_pending(struct Curl_easy *data)
{
struct connectdata *conn = data->conn;
@@ -455,7 +455,7 @@ static int data_pending(const struct Curl_easy *data)
#endif
if(conn->handler->protocol&PROTO_FAMILY_FTP)
- return Curl_cfilter_data_pending(data, conn, SECONDARYSOCKET);
+ return Curl_conn_data_pending(data, SECONDARYSOCKET);
/* in the case of libssh2, we can never be really sure that we have emptied
its internal buffers so we MUST always try until we get EAGAIN back */
@@ -470,7 +470,7 @@ static int data_pending(const struct Curl_easy *data)
a workaround, we return nonzero here to call http2_recv. */
((conn->handler->protocol&PROTO_FAMILY_HTTP) && conn->httpversion >= 20) ||
#endif
- Curl_cfilter_data_pending(data, conn, FIRSTSOCKET);
+ Curl_conn_data_pending(data, FIRSTSOCKET);
}
/*
diff --git a/lib/url.c b/lib/url.c
index 78f01c442..719bbeda5 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -753,17 +753,16 @@ static void conn_reset_all_postponed_data(struct connectdata *conn)
#endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
-static void conn_shutdown(struct Curl_easy *data, struct connectdata *conn)
+static void conn_shutdown(struct Curl_easy *data)
{
- DEBUGASSERT(conn);
DEBUGASSERT(data);
- infof(data, "Closing connection %ld", conn->connection_id);
+ infof(data, "Closing connection %ld", data->conn->connection_id);
/* possible left-overs from the async name resolvers */
Curl_resolver_cancel(data);
- Curl_cfilter_close(data, conn, SECONDARYSOCKET);
- Curl_cfilter_close(data, conn, FIRSTSOCKET);
+ Curl_conn_close(data, SECONDARYSOCKET);
+ Curl_conn_close(data, FIRSTSOCKET);
}
static void conn_free(struct Curl_easy *data, struct connectdata *conn)
@@ -773,7 +772,7 @@ static void conn_free(struct Curl_easy *data, struct connectdata *conn)
DEBUGASSERT(conn);
for(i = 0; i < ARRAYSIZE(conn->cfilter); ++i) {
- Curl_cfilter_destroy(data, conn, (int)i);
+ Curl_conn_cf_discard_all(data, conn, (int)i);
}
Curl_free_idnconverted_hostname(&conn->host);
@@ -809,9 +808,6 @@ static void conn_free(struct Curl_easy *data, struct connectdata *conn)
Curl_safefree(conn->unix_domain_socket);
#endif
-#ifdef USE_SSL
- Curl_safefree(conn->ssl_extra);
-#endif
free(conn); /* free all the connection oriented data */
}
@@ -878,7 +874,7 @@ void Curl_disconnect(struct Curl_easy *data,
/* This is set if protocol-specific cleanups should be made */
conn->handler->disconnect(data, conn, dead_connection);
- conn_shutdown(data, conn);
+ conn_shutdown(data);
/* detach it again */
Curl_detach_connection(data);
@@ -1241,7 +1237,7 @@ ConnectionExists(struct Curl_easy *data,
}
}
- if(check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) {
+ if(!Curl_conn_is_connected(check, FIRSTSOCKET)) {
foundPendingCandidate = TRUE;
/* Don't pick a connection that hasn't connected yet */
infof(data, "Connection #%ld isn't open enough, can't reuse",
@@ -1307,15 +1303,11 @@ ConnectionExists(struct Curl_easy *data,
if(!Curl_ssl_config_matches(&needle->proxy_ssl_config,
&check->proxy_ssl_config))
continue;
- if(check->proxy_ssl[FIRSTSOCKET].state != ssl_connection_complete)
- continue;
}
if(!Curl_ssl_config_matches(&needle->ssl_config,
&check->ssl_config))
continue;
- if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete)
- continue;
}
}
#endif
@@ -1409,14 +1401,6 @@ ConnectionExists(struct Curl_easy *data,
check->connection_id));
continue;
}
- if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete) {
- foundPendingCandidate = TRUE;
- DEBUGF(infof(data,
- "Connection #%ld has not started SSL connect, "
- "can't reuse",
- check->connection_id));
- continue;
- }
}
match = TRUE;
}
@@ -1680,45 +1664,6 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
if(!conn)
return NULL;
-#ifdef USE_SSL
- /* The SSL backend-specific data (ssl_backend_data) objects are allocated as
- a separate array to ensure suitable alignment.
- Note that these backend pointers can be swapped by vtls (eg ssl backend
- data becomes proxy backend data). */
- {
- size_t onesize = Curl_ssl_get_backend_data_size(data);
- size_t totalsize = onesize;
- char *ssl;
-
-#ifndef CURL_DISABLE_FTP
- totalsize *= 2;
-#endif
-#ifndef CURL_DISABLE_PROXY
- totalsize *= 2;
-#endif
-
- ssl = calloc(1, totalsize);
- if(!ssl) {
- free(conn);
- return NULL;
- }
- conn->ssl_extra = ssl;
- conn->ssl[FIRSTSOCKET].backend = (void *)ssl;
-#ifndef CURL_DISABLE_FTP
- ssl += onesize;
- conn->ssl[SECONDARYSOCKET].backend = (void *)ssl;
-#endif
-#ifndef CURL_DISABLE_PROXY
- ssl += onesize;
- conn->proxy_ssl[FIRSTSOCKET].backend = (void *)ssl;
-#ifndef CURL_DISABLE_FTP
- ssl += onesize;
- conn->proxy_ssl[SECONDARYSOCKET].backend = (void *)ssl;
-#endif
-#endif
- }
-#endif
-
conn->handler = &Curl_handler_dummy; /* Be sure we have a handler defined
already from start to avoid NULL
situations and checks */
@@ -1826,9 +1771,6 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
Curl_llist_destroy(&conn->easyq, NULL);
free(conn->localdev);
-#ifdef USE_SSL
- free(conn->ssl_extra);
-#endif
free(conn);
return NULL;
}
@@ -3810,10 +3752,10 @@ static CURLcode create_conn(struct Curl_easy *data,
#endif
/* Setup filter for network connections */
- conn->recv[FIRSTSOCKET] = Curl_cfilter_recv;
- conn->send[FIRSTSOCKET] = Curl_cfilter_send;
- conn->recv[SECONDARYSOCKET] = Curl_cfilter_recv;
- conn->send[SECONDARYSOCKET] = Curl_cfilter_send;
+ conn->recv[FIRSTSOCKET] = Curl_conn_recv;
+ conn->send[FIRSTSOCKET] = Curl_conn_send;
+ conn->recv[SECONDARYSOCKET] = Curl_conn_recv;
+ conn->send[SECONDARYSOCKET] = Curl_conn_send;
conn->bits.tcp_fastopen = data->set.tcp_fastopen;
/* Get a cloned copy of the SSL config situation stored in the
@@ -4099,8 +4041,8 @@ CURLcode Curl_setup_conn(struct Curl_easy *data,
is later set again for the progress meter purpose */
conn->now = Curl_now();
if(!conn->bits.reuse)
- result = Curl_cfilter_setup(data, conn, FIRSTSOCKET, conn->dns_entry,
- CURL_CF_SSL_DEFAULT);
+ result = Curl_conn_setup(data, FIRSTSOCKET, conn->dns_entry,
+ CURL_CF_SSL_DEFAULT);
/* not sure we need this flag to be passed around any more */
*protocol_done = FALSE;
return result;
diff --git a/lib/urldata.h b/lib/urldata.h
index 5691fec3e..48b281f3a 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -113,6 +113,24 @@ typedef unsigned int curl_prot_t;
input easier and better. */
#define CURL_MAX_INPUT_LENGTH 8000000
+/* Macros intended for DEBUGF logging, use like:
+ * DEBUGF(infof(data, CFMSG(cf, "this filter %s rocks"), "very much"));
+ * and it will output:
+ * [CONN-1-0][CF-SSL] this filter very much rocks
+ * on connection #1 with sockindex 0 for filter of type "SSL". */
+#define DMSG(d,msg) \
+ "[CONN-%ld] "msg, (d)->conn->connection_id
+#define DMSGI(d,i,msg) \
+ "[CONN-%ld-%d] "msg, (d)->conn->connection_id, (i)
+#define CMSG(c,msg) \
+ "[CONN-%ld] "msg, (conn)->connection_id
+#define CMSGI(c,i,msg) \
+ "[CONN-%ld-%d] "msg, (conn)->connection_id, (i)
+#define CFMSG(cf,msg) \
+ "[CONN-%ld-%d][CF-%s] "msg, (cf)->conn->connection_id, \
+ (cf)->sockindex, (cf)->cft->name
+
+
#include "cookie.h"
#include "psl.h"
#include "formdata.h"
@@ -249,19 +267,6 @@ typedef enum {
/* SSL backend-specific data; declared differently by each SSL backend */
struct ssl_backend_data;
-/* struct for data related to each SSL connection */
-struct ssl_connect_data {
- ssl_connection_state state;
- ssl_connect_state connecting_state;
-#if defined(USE_SSL)
- struct ssl_backend_data *backend;
-#endif
- /* Use ssl encrypted communications TRUE/FALSE. The library is not
- necessarily using ssl at the moment but at least asked to or means to use
- it. See 'state' for the exact current state of the connection. */
- BIT(use);
-};
-
struct ssl_primary_config {
long version; /* what version the client wants to use */
long version_max; /* max supported version the client wants to use */
@@ -478,8 +483,6 @@ struct negotiatedata {
*/
struct ConnectBits {
#ifndef CURL_DISABLE_PROXY
- bool proxy_ssl_connected[2]; /* TRUE when SSL initialization for HTTPS proxy
- is complete */
BIT(httpproxy); /* if set, this transfer is done through an HTTP proxy */
BIT(socksproxy); /* if set, this transfer is done through a socks proxy */
BIT(proxy_user_passwd); /* user+password for the proxy? */
@@ -957,13 +960,6 @@ struct connectdata {
#ifdef USE_RECV_BEFORE_SEND_WORKAROUND
struct postponed_data postponed[2]; /* two buffers for two sockets */
#endif /* USE_RECV_BEFORE_SEND_WORKAROUND */
- struct ssl_connect_data ssl[2]; /* this is for ssl-stuff */
-#ifndef CURL_DISABLE_PROXY
- struct ssl_connect_data proxy_ssl[2]; /* this is for proxy ssl-stuff */
-#endif
-#ifdef USE_SSL
- void *ssl_extra; /* separately allocated backend-specific data */
-#endif
struct ssl_primary_config ssl_config;
#ifndef CURL_DISABLE_PROXY
struct ssl_primary_config proxy_ssl_config;
diff --git a/lib/vquic/ngtcp2.c b/lib/vquic/ngtcp2.c
index c386aa5fa..33cf474ae 100644
--- a/lib/vquic/ngtcp2.c
+++ b/lib/vquic/ngtcp2.c
@@ -49,6 +49,7 @@
#include "ngtcp2.h"
#include "multiif.h"
#include "strcase.h"
+#include "cfilters.h"
#include "connect.h"
#include "strerror.h"
#include "dynbuf.h"
@@ -300,17 +301,19 @@ static SSL_CTX *quic_ssl_ctx(struct Curl_easy *data)
static CURLcode quic_set_client_cert(struct Curl_easy *data,
struct quicsocket *qs)
{
- struct connectdata *conn = data->conn;
SSL_CTX *ssl_ctx = qs->sslctx;
- char *const ssl_cert = SSL_SET_OPTION(primary.clientcert);
- const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob);
- const char *const ssl_cert_type = SSL_SET_OPTION(cert_type);
+ const struct ssl_config_data *ssl_config;
+
+ ssl_config = Curl_ssl_get_config(data, FIRSTSOCKET);
+ DEBUGASSERT(ssl_config);
- if(ssl_cert || ssl_cert_blob || ssl_cert_type) {
+ if(ssl_config->primary.clientcert || ssl_config->primary.cert_blob
+ || ssl_config->cert_type) {
return Curl_ossl_set_client_cert(
- data, ssl_ctx, ssl_cert, ssl_cert_blob, ssl_cert_type,
- SSL_SET_OPTION(key), SSL_SET_OPTION(key_blob),
- SSL_SET_OPTION(key_type), SSL_SET_OPTION(key_passwd));
+ data, ssl_ctx, ssl_config->primary.clientcert,
+ ssl_config->primary.cert_blob, ssl_config->cert_type,
+ ssl_config->key, ssl_config->key_blob,
+ ssl_config->key_type, ssl_config->key_passwd);
}
return CURLE_OK;
@@ -1693,9 +1696,15 @@ static CURLcode ng_has_connected(struct Curl_easy *data,
return result;
infof(data, "Verified certificate just fine");
#elif defined(USE_GNUTLS)
- result = Curl_gtls_verifyserver(data, conn, conn->quic->ssl, FIRSTSOCKET);
+ result = Curl_gtls_verifyserver(conn->cfilter[FIRSTSOCKET],
+ data, conn->quic->ssl);
#elif defined(USE_WOLFSSL)
- char *snihost = Curl_ssl_snihost(data, SSL_HOST_NAME(), NULL);
+ const char *hostname, *disp_hostname;
+ int port;
+ char *snihost;
+
+ Curl_conn_get_host(data, FIRSTSOCKET, &hostname, &disp_hostname, &port);
+ snihost = Curl_ssl_snihost(data, hostname, NULL);
if(!snihost ||
(wolfSSL_check_domain_name(conn->quic->ssl, snihost) == SSL_FAILURE))
return CURLE_PEER_FAILED_VERIFICATION;
diff --git a/lib/vquic/quiche.c b/lib/vquic/quiche.c
index 65cc90fa2..2b9a0410f 100644
--- a/lib/vquic/quiche.c
+++ b/lib/vquic/quiche.c
@@ -348,9 +348,6 @@ CURLcode Curl_quic_connect(struct Curl_easy *data,
Curl_persistconninfo(data, conn, NULL, -1);
- /* for connection reuse purposes: */
- conn->ssl[FIRSTSOCKET].state = ssl_connection_complete;
-
{
unsigned char alpn_protocols[] = QUICHE_H3_APPLICATION_PROTOCOL;
unsigned alpn_len, offset = 0;
diff --git a/lib/vssh/libssh.c b/lib/vssh/libssh.c
index 0869c483c..43fb804b0 100644
--- a/lib/vssh/libssh.c
+++ b/lib/vssh/libssh.c
@@ -2334,7 +2334,7 @@ CURLcode scp_perform(struct Curl_easy *data,
result = myssh_multi_statemach(data, dophase_done);
- *connected = Curl_cfilter_is_connected(data, data->conn, FIRSTSOCKET);
+ *connected = Curl_conn_is_connected(data->conn, FIRSTSOCKET);
if(*dophase_done) {
DEBUGF(infof(data, "DO phase is complete"));
@@ -2515,7 +2515,7 @@ CURLcode sftp_perform(struct Curl_easy *data,
/* run the state-machine */
result = myssh_multi_statemach(data, dophase_done);
- *connected = Curl_cfilter_is_connected(data, data->conn, FIRSTSOCKET);
+ *connected = Curl_conn_is_connected(data->conn, FIRSTSOCKET);
if(*dophase_done) {
DEBUGF(infof(data, "DO phase is complete"));
diff --git a/lib/vssh/libssh2.c b/lib/vssh/libssh2.c
index 338062366..d3d266a4c 100644
--- a/lib/vssh/libssh2.c
+++ b/lib/vssh/libssh2.c
@@ -3386,7 +3386,7 @@ CURLcode scp_perform(struct Curl_easy *data,
/* run the state-machine */
result = ssh_multi_statemach(data, dophase_done);
- *connected = Curl_cfilter_is_connected(data, data->conn, FIRSTSOCKET);
+ *connected = Curl_conn_is_connected(data->conn, FIRSTSOCKET);
if(*dophase_done) {
DEBUGF(infof(data, "DO phase is complete"));
@@ -3575,7 +3575,7 @@ CURLcode sftp_perform(struct Curl_easy *data,
/* run the state-machine */
result = ssh_multi_statemach(data, dophase_done);
- *connected = Curl_cfilter_is_connected(data, data->conn, FIRSTSOCKET);
+ *connected = Curl_conn_is_connected(data->conn, FIRSTSOCKET);
if(*dophase_done) {
DEBUGF(infof(data, "DO phase is complete"));
diff --git a/lib/vssh/wolfssh.c b/lib/vssh/wolfssh.c
index 25e3112d0..6a8fb560d 100644
--- a/lib/vssh/wolfssh.c
+++ b/lib/vssh/wolfssh.c
@@ -951,7 +951,7 @@ CURLcode wsftp_perform(struct Curl_easy *data,
/* run the state-machine */
result = wssh_multi_statemach(data, dophase_done);
- *connected = Curl_cfilter_is_connected(data, data->conn, FIRSTSOCKET);
+ *connected = Curl_conn_is_connected(data->conn, FIRSTSOCKET);
if(*dophase_done) {
DEBUGF(infof(data, "DO phase is complete"));
diff --git a/lib/vtls/bearssl.c b/lib/vtls/bearssl.c
index ea945125c..3ec8c0acd 100644
--- a/lib/vtls/bearssl.c
+++ b/lib/vtls/bearssl.c
@@ -570,18 +570,20 @@ static CURLcode bearssl_set_selected_ciphers(struct Curl_easy *data,
return CURLE_OK;
}
-static CURLcode bearssl_connect_step1(struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+static CURLcode bearssl_connect_step1(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
- const struct curl_blob *ca_info_blob = SSL_CONN_CONFIG(ca_info_blob);
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
+ const struct curl_blob *ca_info_blob = conn_config->ca_info_blob;
const char * const ssl_cafile =
/* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */
- (ca_info_blob ? NULL : SSL_CONN_CONFIG(CAfile));
- const char *hostname = SSL_HOST_NAME();
- const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
- const bool verifyhost = SSL_CONN_CONFIG(verifyhost);
+ (ca_info_blob ? NULL : conn_config->CAfile);
+ const char *hostname = connssl->hostname;
+ const bool verifypeer = conn_config->verifypeer;
+ const bool verifyhost = conn_config->verifyhost;
CURLcode ret;
unsigned version_min, version_max;
#ifdef ENABLE_IPV6
@@ -592,7 +594,7 @@ static CURLcode bearssl_connect_step1(struct Curl_easy *data,
DEBUGASSERT(backend);
- switch(SSL_CONN_CONFIG(version)) {
+ switch(conn_config->version) {
case CURL_SSLVERSION_SSLv2:
failf(data, "BearSSL does not support SSLv2");
return CURLE_SSL_CONNECT_ERROR;
@@ -663,11 +665,11 @@ static CURLcode bearssl_connect_step1(struct Curl_easy *data,
br_ssl_engine_set_buffer(&backend->ctx.eng, backend->buf,
sizeof(backend->buf), 1);
- if(SSL_CONN_CONFIG(cipher_list)) {
+ if(conn_config->cipher_list) {
/* Override the ciphers as specified. For the default cipher list see the
BearSSL source code of br_ssl_client_init_full() */
ret = bearssl_set_selected_ciphers(data, &backend->ctx.eng,
- SSL_CONN_CONFIG(cipher_list));
+ conn_config->cipher_list);
if(ret)
return ret;
}
@@ -678,19 +680,18 @@ static CURLcode bearssl_connect_step1(struct Curl_easy *data,
backend->x509.verifyhost = verifyhost;
br_ssl_engine_set_x509(&backend->ctx.eng, &backend->x509.vtable);
- if(SSL_SET_OPTION(primary.sessionid)) {
+ if(ssl_config->primary.sessionid) {
void *session;
Curl_ssl_sessionid_lock(data);
- if(!Curl_ssl_getsessionid(data, conn, SSL_IS_PROXY() ? TRUE : FALSE,
- &session, NULL, sockindex)) {
+ if(!Curl_ssl_getsessionid(cf, data, &session, NULL)) {
br_ssl_engine_set_session_parameters(&backend->ctx.eng, session);
infof(data, "BearSSL: re-using session ID");
}
Curl_ssl_sessionid_unlock(data);
}
- if(conn->bits.tls_enable_alpn) {
+ if(cf->conn->bits.tls_enable_alpn) {
int cur = 0;
/* NOTE: when adding more protocols here, increase the size of the
@@ -700,7 +701,7 @@ static CURLcode bearssl_connect_step1(struct Curl_easy *data,
#ifdef USE_HTTP2
if(data->state.httpwant >= CURL_HTTP_VERSION_2
#ifndef CURL_DISABLE_PROXY
- && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
+ && (!Curl_ssl_cf_is_proxy(cf) || !cf->conn->bits.tunnel_proxy)
#endif
) {
backend->protocols[cur++] = ALPN_H2;
@@ -757,13 +758,13 @@ static CURLcode bearssl_connect_step1(struct Curl_easy *data,
return CURLE_OK;
}
-static CURLcode bearssl_run_until(struct Curl_easy *data,
- struct connectdata *conn, int sockindex,
+static CURLcode bearssl_run_until(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
unsigned target)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
- curl_socket_t sockfd = conn->sock[sockindex];
+ curl_socket_t sockfd = cf->conn->sock[cf->sockindex];
unsigned state;
unsigned char *buf;
size_t len;
@@ -837,17 +838,16 @@ static CURLcode bearssl_run_until(struct Curl_easy *data,
}
}
-static CURLcode bearssl_connect_step2(struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+static CURLcode bearssl_connect_step2(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
CURLcode ret;
DEBUGASSERT(backend);
- ret = bearssl_run_until(data, conn, sockindex,
- BR_SSL_SENDAPP | BR_SSL_RECVAPP);
+ ret = bearssl_run_until(cf, data, BR_SSL_SENDAPP | BR_SSL_RECVAPP);
if(ret == CURLE_AGAIN)
return CURLE_OK;
if(ret == CURLE_OK) {
@@ -860,17 +860,18 @@ static CURLcode bearssl_connect_step2(struct Curl_easy *data,
return ret;
}
-static CURLcode bearssl_connect_step3(struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+static CURLcode bearssl_connect_step3(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
CURLcode ret;
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
DEBUGASSERT(backend);
- if(conn->bits.tls_enable_alpn) {
+ if(cf->conn->bits.tls_enable_alpn) {
const char *protocol;
protocol = br_ssl_engine_get_selected_protocol(&backend->ctx.eng);
@@ -879,21 +880,21 @@ static CURLcode bearssl_connect_step3(struct Curl_easy *data,
#ifdef USE_HTTP2
if(!strcmp(protocol, ALPN_H2))
- conn->alpn = CURL_HTTP_VERSION_2;
+ cf->conn->alpn = CURL_HTTP_VERSION_2;
else
#endif
if(!strcmp(protocol, ALPN_HTTP_1_1))
- conn->alpn = CURL_HTTP_VERSION_1_1;
+ cf->conn->alpn = CURL_HTTP_VERSION_1_1;
else
infof(data, "ALPN, unrecognized protocol %s", protocol);
- Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ?
+ Curl_multiuse_state(data, cf->conn->alpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
else
infof(data, VTLS_INFOF_NO_ALPN);
}
- if(SSL_SET_OPTION(primary.sessionid)) {
+ if(ssl_config->primary.sessionid) {
bool incache;
bool added = FALSE;
void *oldsession;
@@ -904,14 +905,10 @@ static CURLcode bearssl_connect_step3(struct Curl_easy *data,
return CURLE_OUT_OF_MEMORY;
br_ssl_engine_get_session_parameters(&backend->ctx.eng, session);
Curl_ssl_sessionid_lock(data);
- incache = !(Curl_ssl_getsessionid(data, conn,
- SSL_IS_PROXY() ? TRUE : FALSE,
- &oldsession, NULL, sockindex));
+ incache = !(Curl_ssl_getsessionid(cf, data, &oldsession, NULL));
if(incache)
Curl_ssl_delsessionid(data, oldsession);
- ret = Curl_ssl_addsessionid(data, conn,
- SSL_IS_PROXY() ? TRUE : FALSE,
- session, 0, sockindex, &added);
+ ret = Curl_ssl_addsessionid(cf, data, session, 0, &added);
Curl_ssl_sessionid_unlock(data);
if(!added)
free(session);
@@ -925,11 +922,10 @@ static CURLcode bearssl_connect_step3(struct Curl_easy *data,
return CURLE_OK;
}
-static ssize_t bearssl_send(struct Curl_easy *data, int sockindex,
+static ssize_t bearssl_send(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *buf, size_t len, CURLcode *err)
{
- struct connectdata *conn = data->conn;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
unsigned char *app;
size_t applen;
@@ -937,7 +933,7 @@ static ssize_t bearssl_send(struct Curl_easy *data, int sockindex,
DEBUGASSERT(backend);
for(;;) {
- *err = bearssl_run_until(data, conn, sockindex, BR_SSL_SENDAPP);
+ *err = bearssl_run_until(cf, data, BR_SSL_SENDAPP);
if (*err != CURLE_OK)
return -1;
app = br_ssl_engine_sendapp_buf(&backend->ctx.eng, &applen);
@@ -960,18 +956,17 @@ static ssize_t bearssl_send(struct Curl_easy *data, int sockindex,
}
}
-static ssize_t bearssl_recv(struct Curl_easy *data, int sockindex,
+static ssize_t bearssl_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
char *buf, size_t len, CURLcode *err)
{
- struct connectdata *conn = data->conn;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
unsigned char *app;
size_t applen;
DEBUGASSERT(backend);
- *err = bearssl_run_until(data, conn, sockindex, BR_SSL_RECVAPP);
+ *err = bearssl_run_until(cf, data, BR_SSL_RECVAPP);
if(*err != CURLE_OK)
return -1;
app = br_ssl_engine_recvapp_buf(&backend->ctx.eng, &applen);
@@ -985,15 +980,14 @@ static ssize_t bearssl_recv(struct Curl_easy *data, int sockindex,
return applen;
}
-static CURLcode bearssl_connect_common(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex,
+static CURLcode bearssl_connect_common(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
bool nonblocking,
bool *done)
{
CURLcode ret;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- curl_socket_t sockfd = conn->sock[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
+ curl_socket_t sockfd = cf->conn->sock[cf->sockindex];
timediff_t timeout_ms;
int what;
@@ -1004,7 +998,7 @@ static CURLcode bearssl_connect_common(struct Curl_easy *data,
}
if(ssl_connect_1 == connssl->connecting_state) {
- ret = bearssl_connect_step1(data, conn, sockindex);
+ ret = bearssl_connect_step1(cf, data);
if(ret)
return ret;
}
@@ -1057,7 +1051,7 @@ static CURLcode bearssl_connect_common(struct Curl_easy *data,
* before step2 has completed while ensuring that a client using select()
* or epoll() will always have a valid fdset to wait on.
*/
- ret = bearssl_connect_step2(data, conn, sockindex);
+ ret = bearssl_connect_step2(cf, data);
if(ret || (nonblocking &&
(ssl_connect_2 == connssl->connecting_state ||
ssl_connect_2_reading == connssl->connecting_state ||
@@ -1066,7 +1060,7 @@ static CURLcode bearssl_connect_common(struct Curl_easy *data,
}
if(ssl_connect_3 == connssl->connecting_state) {
- ret = bearssl_connect_step3(data, conn, sockindex);
+ ret = bearssl_connect_step3(cf, data);
if(ret)
return ret;
}
@@ -1089,13 +1083,14 @@ static size_t bearssl_version(char *buffer, size_t size)
return msnprintf(buffer, size, "BearSSL");
}
-static bool bearssl_data_pending(const struct connectdata *conn,
- int connindex)
+static bool bearssl_data_pending(struct Curl_cfilter *cf,
+ const struct Curl_easy *data)
{
- const struct ssl_connect_data *connssl = &conn->ssl[connindex];
- struct ssl_backend_data *backend = connssl->backend;
- DEBUGASSERT(backend);
- return br_ssl_engine_current_state(&backend->ctx.eng) & BR_SSL_RECVAPP;
+ struct ssl_connect_data *ctx = cf->ctx;
+
+ (void)data;
+ DEBUGASSERT(ctx && ctx->backend);
+ return br_ssl_engine_current_state(&ctx->backend->ctx.eng) & BR_SSL_RECVAPP;
}
static CURLcode bearssl_random(struct Curl_easy *data UNUSED_PARAM,
@@ -1118,13 +1113,13 @@ static CURLcode bearssl_random(struct Curl_easy *data UNUSED_PARAM,
return CURLE_OK;
}
-static CURLcode bearssl_connect(struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+static CURLcode bearssl_connect(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
CURLcode ret;
bool done = FALSE;
- ret = bearssl_connect_common(data, conn, sockindex, FALSE, &done);
+ ret = bearssl_connect_common(cf, data, FALSE, &done);
if(ret)
return ret;
@@ -1133,11 +1128,11 @@ static CURLcode bearssl_connect(struct Curl_easy *data,
return CURLE_OK;
}
-static CURLcode bearssl_connect_nonblocking(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex, bool *done)
+static CURLcode bearssl_connect_nonblocking(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool *done)
{
- return bearssl_connect_common(data, conn, sockindex, TRUE, done);
+ return bearssl_connect_common(cf, data, TRUE, done);
}
static void *bearssl_get_internals(struct ssl_connect_data *connssl,
@@ -1148,10 +1143,9 @@ static void *bearssl_get_internals(struct ssl_connect_data *connssl,
return &backend->ctx;
}
-static void bearssl_close(struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+static void bearssl_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
size_t i;
@@ -1160,7 +1154,7 @@ static void bearssl_close(struct Curl_easy *data,
if(backend->active) {
backend->active = FALSE;
br_ssl_engine_close(&backend->ctx.eng);
- (void)bearssl_run_until(data, conn, sockindex, BR_SSL_CLOSED);
+ (void)bearssl_run_until(cf, data, BR_SSL_CLOSED);
}
if(backend->anchors) {
for(i = 0; i < backend->anchors_len; ++i)
@@ -1202,7 +1196,7 @@ const struct Curl_ssl Curl_ssl_bearssl = {
Curl_none_cert_status_request, /* cert_status_request */
bearssl_connect, /* connect */
bearssl_connect_nonblocking, /* connect_nonblocking */
- Curl_ssl_getsock, /* getsock */
+ Curl_ssl_get_select_socks, /* getsock */
bearssl_get_internals, /* get_internals */
bearssl_close, /* close_one */
Curl_none_close_all, /* close_all */
diff --git a/lib/vtls/gskit.c b/lib/vtls/gskit.c
index 74ff29b43..2074dcaa4 100644
--- a/lib/vtls/gskit.c
+++ b/lib/vtls/gskit.c
@@ -106,10 +106,8 @@
struct ssl_backend_data {
gsk_handle handle;
int iocport;
-#ifndef CURL_DISABLE_PROXY
int localfd;
int remotefd;
-#endif
};
#define BACKEND connssl->backend
@@ -296,11 +294,12 @@ static CURLcode set_numeric(struct Curl_easy *data,
}
-static CURLcode set_ciphers(struct Curl_easy *data,
+static CURLcode set_ciphers(struct Curl_cfilter *cf, struct Curl_easy *data,
gsk_handle h, unsigned int *protoflags)
{
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
struct connectdata *conn = data->conn;
- const char *cipherlist = SSL_CONN_CONFIG(cipher_list);
+ const char *cipherlist = conn_config->cipher_list;
const char *clp;
const struct gskit_cipher *ctp;
int i;
@@ -491,14 +490,16 @@ static CURLcode init_environment(struct Curl_easy *data,
}
-static void cancel_async_handshake(struct connectdata *conn, int sockindex)
+static void cancel_async_handshake(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
Qso_OverlappedIO_t cstat;
+ (void)data;
DEBUGASSERT(BACKEND);
- if(QsoCancelOperation(conn->sock[sockindex], 0) > 0)
+ if(QsoCancelOperation(cf->conn->sock[cf->sockindex], 0) > 0)
QsoWaitForIOCompletion(BACKEND->iocport, &cstat, (struct timeval *) NULL);
}
@@ -510,12 +511,12 @@ static void close_async_handshake(struct ssl_connect_data *connssl)
BACKEND->iocport = -1;
}
-static int pipe_ssloverssl(struct connectdata *conn, int sockindex,
- int directions)
+static int pipe_ssloverssl(struct Curl_cfilter *cf, int directions)
{
-#ifndef CURL_DISABLE_PROXY
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- struct ssl_connect_data *connproxyssl = &conn->proxy_ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
+ struct Curl_cfilter *cf_ssl_next = Curl_ssl_cf_get_ssl(cf->next);
+ struct ssl_connect_data *connssl_next = cf_ssl_next?
+ cf_ssl_next->ctx : NULL;
struct pollfd fds[2];
int n;
int m;
@@ -524,14 +525,14 @@ static int pipe_ssloverssl(struct connectdata *conn, int sockindex,
char buf[CURL_MAX_WRITE_SIZE];
DEBUGASSERT(BACKEND);
- DEBUGASSERT(connproxyssl->backend);
- if(!connssl->use || !connproxyssl->use)
+ if(!connssl_next)
return 0; /* No SSL over SSL: OK. */
+ DEBUGASSERT(connssl_next->backend);
n = 1;
fds[0].fd = BACKEND->remotefd;
- fds[1].fd = conn->sock[sockindex];
+ fds[1].fd = cf->conn->sock[cf->sockindex];
if(directions & SOS_READ) {
fds[0].events |= POLLOUT;
@@ -548,7 +549,7 @@ static int pipe_ssloverssl(struct connectdata *conn, int sockindex,
if(fds[0].revents & POLLOUT) {
/* Try getting data from HTTPS proxy and pipe it upstream. */
n = 0;
- i = gsk_secure_soc_read(connproxyssl->backend->handle,
+ i = gsk_secure_soc_read(connssl_next->backend->handle,
buf, sizeof(buf), &n);
switch(i) {
case GSK_OK:
@@ -573,7 +574,7 @@ static int pipe_ssloverssl(struct connectdata *conn, int sockindex,
if(n < 0)
return -1;
if(n) {
- i = gsk_secure_soc_write(connproxyssl->backend->handle, buf, n, &m);
+ i = gsk_secure_soc_write(connssl_next->backend->handle, buf, n, &m);
if(i != GSK_OK || n != m)
return -1;
ret = 1;
@@ -581,24 +582,21 @@ static int pipe_ssloverssl(struct connectdata *conn, int sockindex,
}
return ret; /* OK */
-#else
- return 0;
-#endif
}
-static void close_one(struct ssl_connect_data *connssl, struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+static void close_one(struct Curl_cfilter *cf, struct Curl_easy *data)
{
+ struct ssl_connect_data *connssl = cf->ctx;
+
DEBUGASSERT(BACKEND);
if(BACKEND->handle) {
gskit_status(data, gsk_secure_soc_close(&BACKEND->handle),
"gsk_secure_soc_close()", 0);
/* Last chance to drain output. */
- while(pipe_ssloverssl(conn, sockindex, SOS_WRITE) > 0)
+ while(pipe_ssloverssl(cf, SOS_WRITE) > 0)
;
BACKEND->handle = (gsk_handle) NULL;
-#ifndef CURL_DISABLE_PROXY
if(BACKEND->localfd >= 0) {
close(BACKEND->localfd);
BACKEND->localfd = -1;
@@ -607,30 +605,29 @@ static void close_one(struct ssl_connect_data *connssl, struct Curl_easy *data,
close(BACKEND->remotefd);
BACKEND->remotefd = -1;
}
-#endif
}
if(BACKEND->iocport >= 0)
close_async_handshake(connssl);
}
-static ssize_t gskit_send(struct Curl_easy *data, int sockindex,
+static ssize_t gskit_send(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *mem, size_t len, CURLcode *curlcode)
{
- struct connectdata *conn = data->conn;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct connectdata *conn = cf->conn;
+ struct ssl_connect_data *connssl = cf->ctx;
CURLcode cc = CURLE_SEND_ERROR;
int written;
DEBUGASSERT(BACKEND);
- if(pipe_ssloverssl(conn, sockindex, SOS_WRITE) >= 0) {
+ if(pipe_ssloverssl(cf, SOS_WRITE) >= 0) {
cc = gskit_status(data,
gsk_secure_soc_write(BACKEND->handle,
(char *) mem, (int) len, &written),
"gsk_secure_soc_write()", CURLE_SEND_ERROR);
if(cc == CURLE_OK)
- if(pipe_ssloverssl(conn, sockindex, SOS_WRITE) < 0)
+ if(pipe_ssloverssl(cf, SOS_WRITE) < 0)
cc = CURLE_SEND_ERROR;
}
if(cc != CURLE_OK) {
@@ -641,17 +638,18 @@ static ssize_t gskit_send(struct Curl_easy *data, int sockindex,
}
-static ssize_t gskit_recv(struct Curl_easy *data, int num, char *buf,
- size_t buffersize, CURLcode *curlcode)
+static ssize_t gskit_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
+ char *buf, size_t buffersize, CURLcode *curlcode)
{
- struct connectdata *conn = data->conn;
- struct ssl_connect_data *connssl = &conn->ssl[num];
+ struct connectdata *conn = cf->conn;
+ struct ssl_connect_data *connssl = cf->ctx;
int nread;
CURLcode cc = CURLE_RECV_ERROR;
+ (void)data;
DEBUGASSERT(BACKEND);
- if(pipe_ssloverssl(conn, num, SOS_READ) >= 0) {
+ if(pipe_ssloverssl(cf, SOS_READ) >= 0) {
int buffsize = buffersize > (size_t) INT_MAX? INT_MAX: (int) buffersize;
cc = gskit_status(data, gsk_secure_soc_read(BACKEND->handle,
buf, buffsize, &nread),
@@ -671,11 +669,14 @@ static ssize_t gskit_recv(struct Curl_easy *data, int num, char *buf,
}
static CURLcode
-set_ssl_version_min_max(unsigned int *protoflags, struct Curl_easy *data)
+set_ssl_version_min_max(unsigned int *protoflags,
+ struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
struct connectdata *conn = data->conn;
- long ssl_version = SSL_CONN_CONFIG(version);
- long ssl_version_max = SSL_CONN_CONFIG(version_max);
+ long ssl_version = conn_config->version;
+ long ssl_version_max = conn_config->version_max;
long i = ssl_version;
switch(ssl_version_max) {
case CURL_SSLVERSION_MAX_NONE:
@@ -703,35 +704,36 @@ set_ssl_version_min_max(unsigned int *protoflags, struct Curl_easy *data)
return CURLE_OK;
}
-static CURLcode gskit_connect_step1(struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+static CURLcode gskit_connect_step1(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
+ struct Curl_cfilter *cf_ssl_next = Curl_ssl_cf_get_ssl(cf->next);
+ struct ssl_connect_data *connssl_next = cf_ssl_next?
+ cf_ssl_next->ctx : NULL;
gsk_handle envir;
CURLcode result;
- const char * const keyringfile = SSL_CONN_CONFIG(CAfile);
- const char * const keyringpwd = SSL_SET_OPTION(key_passwd);
- const char * const keyringlabel = SSL_SET_OPTION(primary.clientcert);
- const long int ssl_version = SSL_CONN_CONFIG(version);
- const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
- const char * const hostname = SSL_HOST_NAME();
+ const char * const keyringfile = conn_config->CAfile;
+ const char * const keyringpwd = conn_config->key_passwd;
+ const char * const keyringlabel = ssl_config->primary.clientcert;
+ const long int ssl_version = conn_config->version;
+ const bool verifypeer = conn_config->verifypeer;
+ const char *hostname = connssl->hostname;
const char *sni;
unsigned int protoflags = 0;
Qso_OverlappedIO_t commarea;
-#ifndef CURL_DISABLE_PROXY
int sockpair[2];
static const int sobufsize = CURL_MAX_WRITE_SIZE;
-#endif
/* Create SSL environment, start (preferably asynchronous) handshake. */
DEBUGASSERT(BACKEND);
BACKEND->handle = (gsk_handle) NULL;
BACKEND->iocport = -1;
-#ifndef CURL_DISABLE_PROXY
BACKEND->localfd = -1;
BACKEND->remotefd = -1;
-#endif
/* GSKit supports two ways of specifying an SSL context: either by
* application identifier (that should have been defined at the system
@@ -770,9 +772,8 @@ static CURLcode gskit_connect_step1(struct Curl_easy *data,
if(result)
return result;
-#ifndef CURL_DISABLE_PROXY
/* Establish a pipelining socket pair for SSL over SSL. */
- if(conn->proxy_ssl[sockindex].use) {
+ if(connssl_next) {
if(Curl_socketpair(0, 0, 0, sockpair))
return CURLE_SSL_CONNECT_ERROR;
BACKEND->localfd = sockpair[0];
@@ -788,7 +789,6 @@ static CURLcode gskit_connect_step1(struct Curl_easy *data,
curlx_nonblock(BACKEND->localfd, TRUE);
curlx_nonblock(BACKEND->remotefd, TRUE);
}
-#endif
/* Determine which SSL/TLS version should be enabled. */
sni = hostname;
@@ -810,7 +810,7 @@ static CURLcode gskit_connect_step1(struct Curl_easy *data,
case CURL_SSLVERSION_TLSv1_1:
case CURL_SSLVERSION_TLSv1_2:
case CURL_SSLVERSION_TLSv1_3:
- result = set_ssl_version_min_max(&protoflags, data);
+ result = set_ssl_version_min_max(&protoflags, cf, data);
if(result != CURLE_OK)
return result;
break;
@@ -846,15 +846,10 @@ static CURLcode gskit_connect_step1(struct Curl_easy *data,
if(!result)
result = set_numeric(data, BACKEND->handle, GSK_OS400_READ_TIMEOUT, 1);
if(!result)
-#ifndef CURL_DISABLE_PROXY
result = set_numeric(data, BACKEND->handle, GSK_FD, BACKEND->localfd >= 0?
- BACKEND->localfd: conn->sock[sockindex]);
-#else
- result = set_numeric(data, BACKEND->handle, GSK_FD,
- conn->sock[sockindex]);
-#endif
+ BACKEND->localfd: cf->conn->sock[cf->sockindex]);
if(!result)
- result = set_ciphers(data, BACKEND->handle, &protoflags);
+ result = set_ciphers(cf, data, BACKEND->handle, &protoflags);
if(!protoflags) {
failf(data, "No SSL protocol/cipher combination enabled");
result = CURLE_SSL_CIPHER;
@@ -921,12 +916,10 @@ static CURLcode gskit_connect_step1(struct Curl_easy *data,
else if(errno != ENOBUFS)
result = gskit_status(data, GSK_ERROR_IO,
"QsoCreateIOCompletionPort()", 0);
-#ifndef CURL_DISABLE_PROXY
- else if(conn->proxy_ssl[sockindex].use) {
+ else if(connssl_next) {
/* Cannot pipeline while handshaking synchronously. */
result = CURLE_SSL_CONNECT_ERROR;
}
-#endif
else {
/* No more completion port available. Use synchronous IO. */
result = gskit_status(data, gsk_secure_soc_init(BACKEND->handle),
@@ -944,11 +937,11 @@ static CURLcode gskit_connect_step1(struct Curl_easy *data,
}
-static CURLcode gskit_connect_step2(struct Curl_easy *data,
- struct connectdata *conn, int sockindex,
+static CURLcode gskit_connect_step2(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
bool nonblocking)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
Qso_OverlappedIO_t cstat;
struct timeval stmv;
CURLcode result;
@@ -976,7 +969,7 @@ static CURLcode gskit_connect_step2(struct Curl_easy *data,
char buffer[STRERROR_LEN];
failf(data, "QsoWaitForIOCompletion() I/O error: %s",
Curl_strerror(errno, buffer, sizeof(buffer)));
- cancel_async_handshake(conn, sockindex);
+ cancel_async_handshake(cf, data);
close_async_handshake(connssl);
return CURLE_SSL_CONNECT_ERROR;
}
@@ -984,7 +977,7 @@ static CURLcode gskit_connect_step2(struct Curl_easy *data,
case 0: /* Handshake in progress, timeout occurred. */
if(nonblocking)
return CURLE_OK;
- cancel_async_handshake(conn, sockindex);
+ cancel_async_handshake(cf, data);
close_async_handshake(connssl);
return CURLE_OPERATION_TIMEDOUT;
}
@@ -999,15 +992,15 @@ static CURLcode gskit_connect_step2(struct Curl_easy *data,
}
-static CURLcode gskit_connect_step3(struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+static CURLcode gskit_connect_step3(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
const gsk_cert_data_elem *cdev;
int cdec;
const gsk_cert_data_elem *p;
const char *cert = (const char *) NULL;
- const char *certend;
+ const char *certend = (const char *) NULL;
const char *ptr;
CURLcode result;
@@ -1045,7 +1038,7 @@ static CURLcode gskit_connect_step3(struct Curl_easy *data,
}
/* Verify host. */
- result = Curl_verifyhost(data, conn, cert, certend);
+ result = Curl_verifyhost(cf, data, cert, certend);
if(result)
return result;
@@ -1067,7 +1060,9 @@ static CURLcode gskit_connect_step3(struct Curl_easy *data,
}
/* Check pinned public key. */
- ptr = SSL_PINNED_PUB_KEY();
+ ptr = Curl_ssl_cf_is_proxy(cf)?
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]:
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY];
if(!result && ptr) {
struct Curl_X509certificate x509;
struct Curl_asn1Element *p;
@@ -1088,11 +1083,11 @@ static CURLcode gskit_connect_step3(struct Curl_easy *data,
}
-static CURLcode gskit_connect_common(struct Curl_easy *data,
- struct connectdata *conn, int sockindex,
+static CURLcode gskit_connect_common(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
bool nonblocking, bool *done)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
timediff_t timeout_ms;
CURLcode result = CURLE_OK;
@@ -1111,12 +1106,12 @@ static CURLcode gskit_connect_common(struct Curl_easy *data,
result = CURLE_OPERATION_TIMEDOUT;
}
else
- result = gskit_connect_step1(data, conn, sockindex);
+ result = gskit_connect_step1(cf, data);
}
/* Handle handshake pipelining. */
if(!result)
- if(pipe_ssloverssl(conn, sockindex, SOS_READ | SOS_WRITE) < 0)
+ if(pipe_ssloverssl(cf, SOS_READ | SOS_WRITE) < 0)
result = CURLE_SSL_CONNECT_ERROR;
/* Step 2: check if handshake is over. */
@@ -1130,17 +1125,17 @@ static CURLcode gskit_connect_common(struct Curl_easy *data,
result = CURLE_OPERATION_TIMEDOUT;
}
else
- result = gskit_connect_step2(data, conn, sockindex, nonblocking);
+ result = gskit_connect_step2(cf, data, nonblocking);
}
/* Handle handshake pipelining. */
if(!result)
- if(pipe_ssloverssl(conn, sockindex, SOS_READ | SOS_WRITE) < 0)
+ if(pipe_ssloverssl(cf, SOS_READ | SOS_WRITE) < 0)
result = CURLE_SSL_CONNECT_ERROR;
/* Step 3: gather certificate info, verify host. */
if(!result && connssl->connecting_state == ssl_connect_3)
- result = gskit_connect_step3(data, conn, sockindex);
+ result = gskit_connect_step3(cf, data);
if(result)
close_one(connssl, data, conn, sockindex);
@@ -1154,27 +1149,29 @@ static CURLcode gskit_connect_common(struct Curl_easy *data,
}
-static CURLcode gskit_connect_nonblocking(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex, bool *done)
+static CURLcode gskit_connect_nonblocking(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool *done)
{
+ struct ssl_connect_data *connssl = cf->ctx;
CURLcode result;
- result = gskit_connect_common(data, conn, sockindex, TRUE, done);
+ result = gskit_connect_common(cf, data, TRUE, done);
if(*done || result)
- conn->ssl[sockindex].connecting_state = ssl_connect_1;
+ connssl->connecting_state = ssl_connect_1;
return result;
}
-static CURLcode gskit_connect(struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+static CURLcode gskit_connect(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
+ struct ssl_connect_data *connssl = cf->ctx;
CURLcode result;
bool done;
- conn->ssl[sockindex].connecting_state = ssl_connect_1;
- result = gskit_connect_common(data, conn, sockindex, FALSE, &done);
+ connssl->connecting_state = ssl_connect_1;
+ result = gskit_connect_common(cf, data, FALSE, &done);
if(result)
return result;
@@ -1184,20 +1181,16 @@ static CURLcode gskit_connect(struct Curl_easy *data,
}
-static void gskit_close(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+static void gskit_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
- close_one(&conn->ssl[sockindex], data, conn, sockindex);
-#ifndef CURL_DISABLE_PROXY
- close_one(&conn->proxy_ssl[sockindex], data, conn, sockindex);
-#endif
+ close_one(cf, data);
}
-static int gskit_shutdown(struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+static int gskit_shutdown(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
int what;
int rc;
char buf[120];
@@ -1213,9 +1206,9 @@ static int gskit_shutdown(struct Curl_easy *data,
return 0;
#endif
- close_one(connssl, data, conn, sockindex);
+ close_one(cf, data);
rc = 0;
- what = SOCKET_READABLE(conn->sock[sockindex],
+ what = SOCKET_READABLE(cf->conn->sock[cf->sockindex],
SSL_SHUTDOWN_TIMEOUT);
while(loop--) {
@@ -1237,7 +1230,7 @@ static int gskit_shutdown(struct Curl_easy *data,
notify alert from the server. No way to gsk_secure_soc_read() now, so
use read(). */
- nread = read(conn->sock[sockindex], buf, sizeof(buf));
+ nread = read(cf->conn->sock[cf->sockindex], buf, sizeof(buf));
if(nread < 0) {
char buffer[STRERROR_LEN];
@@ -1248,7 +1241,7 @@ static int gskit_shutdown(struct Curl_easy *data,
if(nread <= 0)
break;
- what = SOCKET_READABLE(conn->sock[sockindex], 0);
+ what = SOCKET_READABLE(cf->conn->sock[cf->sockindex], 0);
}
return rc;
@@ -1261,12 +1254,14 @@ static size_t gskit_version(char *buffer, size_t size)
}
-static int gskit_check_cxn(struct connectdata *cxn)
+static int gskit_check_cxn(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &cxn->ssl[FIRSTSOCKET];
+ struct ssl_connect_data *connssl = cf->ctx;
int err;
int errlen;
+ (void)data;
/* The only thing that can be tested here is at the socket level. */
DEBUGASSERT(BACKEND);
@@ -1310,7 +1305,7 @@ const struct Curl_ssl Curl_ssl_gskit = {
Curl_none_cert_status_request, /* cert_status_request */
gskit_connect, /* connect */
gskit_connect_nonblocking, /* connect_nonblocking */
- Curl_ssl_getsock, /* getsock */
+ Curl_ssl_get_select_socks, /* getsock */
gskit_get_internals, /* get_internals */
gskit_close, /* close_one */
Curl_none_close_all, /* close_all */
diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c
index 4fd102c33..787d04a6b 100644
--- a/lib/vtls/gtls.c
+++ b/lib/vtls/gtls.c
@@ -206,16 +206,15 @@ static void unload_file(gnutls_datum_t data)
/* this function does a SSL/TLS (re-)handshake */
-static CURLcode handshake(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex,
+static CURLcode handshake(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
bool duringconnect,
bool nonblocking)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
gnutls_session_t session;
- curl_socket_t sockfd = conn->sock[sockindex];
+ curl_socket_t sockfd = cf->conn->sock[cf->sockindex];
DEBUGASSERT(backend);
session = backend->session;
@@ -323,13 +322,14 @@ static gnutls_x509_crt_fmt_t do_file_type(const char *type)
#define GNUTLS_SRP "+SRP"
static CURLcode
-set_ssl_version_min_max(struct Curl_easy *data,
+set_ssl_version_min_max(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
const char **prioritylist,
const char *tls13support)
{
- struct connectdata *conn = data->conn;
- long ssl_version = SSL_CONN_CONFIG(version);
- long ssl_version_max = SSL_CONN_CONFIG(version_max);
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ long ssl_version = conn_config->version;
+ long ssl_version_max = conn_config->version_max;
if((ssl_version == CURL_SSLVERSION_DEFAULT) ||
(ssl_version == CURL_SSLVERSION_TLSv1))
@@ -396,12 +396,12 @@ set_ssl_version_min_max(struct Curl_easy *data,
}
static CURLcode
-gtls_connect_step1(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex)
+gtls_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
unsigned int init_flags;
gnutls_session_t session;
int rc;
@@ -416,9 +416,12 @@ gtls_connect_step1(struct Curl_easy *data,
#endif
const char *prioritylist;
const char *err = NULL;
- const char * const hostname = SSL_HOST_NAME();
- long * const certverifyresult = &SSL_SET_OPTION_LVALUE(certverifyresult);
+ const char *hostname = connssl->hostname;
+ long * const certverifyresult = &ssl_config->certverifyresult;
const char *tls13support;
+ struct Curl_cfilter *cf_ssl_next = Curl_ssl_cf_get_ssl(cf->next);
+ struct ssl_connect_data *connssl_next = cf_ssl_next?
+ cf_ssl_next->ctx : NULL;
CURLcode result;
DEBUGASSERT(backend);
@@ -434,11 +437,11 @@ gtls_connect_step1(struct Curl_easy *data,
/* Initialize certverifyresult to OK */
*certverifyresult = 0;
- if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) {
+ if(conn_config->version == CURL_SSLVERSION_SSLv2) {
failf(data, "GnuTLS does not support SSLv2");
return CURLE_SSL_CONNECT_ERROR;
}
- else if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv3)
+ else if(conn_config->version == CURL_SSLVERSION_SSLv3)
sni = FALSE; /* SSLv3 has no SNI */
/* allocate a cred struct */
@@ -449,10 +452,10 @@ gtls_connect_step1(struct Curl_easy *data,
}
#ifdef USE_GNUTLS_SRP
- if((SSL_SET_OPTION(primary.authtype) == CURL_TLSAUTH_SRP) &&
+ if((ssl_config->primary.authtype == CURL_TLSAUTH_SRP) &&
Curl_auth_allowed_to_host(data)) {
infof(data, "Using TLS-SRP username: %s",
- SSL_SET_OPTION(primary.username));
+ ssl_config->primary.username);
rc = gnutls_srp_allocate_client_credentials(&backend->srp_client_cred);
if(rc != GNUTLS_E_SUCCESS) {
@@ -462,8 +465,8 @@ gtls_connect_step1(struct Curl_easy *data,
}
rc = gnutls_srp_set_client_credentials(backend->srp_client_cred,
- SSL_SET_OPTION(primary.username),
- SSL_SET_OPTION(primary.password));
+ ssl_config->primary.username,
+ ssl_config->primary.password);
if(rc != GNUTLS_E_SUCCESS) {
failf(data, "gnutls_srp_set_client_cred() failed: %s",
gnutls_strerror(rc));
@@ -472,67 +475,67 @@ gtls_connect_step1(struct Curl_easy *data,
}
#endif
- if(SSL_CONN_CONFIG(CAfile)) {
+ if(conn_config->CAfile) {
/* set the trusted CA cert bundle file */
gnutls_certificate_set_verify_flags(backend->cred,
GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
rc = gnutls_certificate_set_x509_trust_file(backend->cred,
- SSL_CONN_CONFIG(CAfile),
+ conn_config->CAfile,
GNUTLS_X509_FMT_PEM);
if(rc < 0) {
infof(data, "error reading ca cert file %s (%s)",
- SSL_CONN_CONFIG(CAfile), gnutls_strerror(rc));
- if(SSL_CONN_CONFIG(verifypeer)) {
+ conn_config->CAfile, gnutls_strerror(rc));
+ if(conn_config->verifypeer) {
*certverifyresult = rc;
return CURLE_SSL_CACERT_BADFILE;
}
}
else
infof(data, "found %d certificates in %s", rc,
- SSL_CONN_CONFIG(CAfile));
+ conn_config->CAfile);
}
- if(SSL_CONN_CONFIG(CApath)) {
+ if(conn_config->CApath) {
/* set the trusted CA cert directory */
rc = gnutls_certificate_set_x509_trust_dir(backend->cred,
- SSL_CONN_CONFIG(CApath),
+ conn_config->CApath,
GNUTLS_X509_FMT_PEM);
if(rc < 0) {
infof(data, "error reading ca cert file %s (%s)",
- SSL_CONN_CONFIG(CApath), gnutls_strerror(rc));
- if(SSL_CONN_CONFIG(verifypeer)) {
+ conn_config->CApath, gnutls_strerror(rc));
+ if(conn_config->verifypeer) {
*certverifyresult = rc;
return CURLE_SSL_CACERT_BADFILE;
}
}
else
infof(data, "found %d certificates in %s",
- rc, SSL_CONN_CONFIG(CApath));
+ rc, conn_config->CApath);
}
#ifdef CURL_CA_FALLBACK
/* use system ca certificate store as fallback */
- if(SSL_CONN_CONFIG(verifypeer) &&
- !(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(CApath))) {
+ if(conn_config->verifypeer &&
+ !(conn_config->CAfile || conn_config->CApath)) {
/* this ignores errors on purpose */
gnutls_certificate_set_x509_system_trust(backend->cred);
}
#endif
- if(SSL_SET_OPTION(primary.CRLfile)) {
+ if(ssl_config->primary.CRLfile) {
/* set the CRL list file */
rc = gnutls_certificate_set_x509_crl_file(backend->cred,
- SSL_SET_OPTION(primary.CRLfile),
+ ssl_config->primary.CRLfile,
GNUTLS_X509_FMT_PEM);
if(rc < 0) {
failf(data, "error reading crl file %s (%s)",
- SSL_SET_OPTION(primary.CRLfile), gnutls_strerror(rc));
+ ssl_config->primary.CRLfile, gnutls_strerror(rc));
return CURLE_SSL_CRL_BADFILE;
}
else
infof(data, "found %d CRL in %s",
- rc, SSL_SET_OPTION(primary.CRLfile));
+ rc, ssl_config->primary.CRLfile);
}
/* Initialize TLS session as a client */
@@ -582,13 +585,13 @@ gtls_connect_step1(struct Curl_easy *data,
* removed if a run-time error indicates that SRP is not supported by this
* GnuTLS version */
- if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2 ||
- SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv3) {
+ if(conn_config->version == CURL_SSLVERSION_SSLv2 ||
+ conn_config->version == CURL_SSLVERSION_SSLv3) {
failf(data, "GnuTLS does not support SSLv2 or SSLv3");
return CURLE_SSL_CONNECT_ERROR;
}
- if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_TLSv1_3) {
+ if(conn_config->version == CURL_SSLVERSION_TLSv1_3) {
if(!tls13support) {
failf(data, "This GnuTLS installation does not support TLS 1.3");
return CURLE_SSL_CONNECT_ERROR;
@@ -596,14 +599,14 @@ gtls_connect_step1(struct Curl_easy *data,
}
/* At this point we know we have a supported TLS version, so set it */
- result = set_ssl_version_min_max(data, &prioritylist, tls13support);
+ result = set_ssl_version_min_max(cf, data, &prioritylist, tls13support);
if(result)
return result;
#ifdef USE_GNUTLS_SRP
/* Only add SRP to the cipher list if SRP is requested. Otherwise
* GnuTLS will disable TLS 1.3 support. */
- if(SSL_SET_OPTION(primary.authtype) == CURL_TLSAUTH_SRP) {
+ if(ssl_config->primary.authtype == CURL_TLSAUTH_SRP) {
size_t len = strlen(prioritylist);
char *prioritysrp = malloc(len + sizeof(GNUTLS_SRP) + 1);
@@ -632,14 +635,14 @@ gtls_connect_step1(struct Curl_easy *data,
return CURLE_SSL_CONNECT_ERROR;
}
- if(conn->bits.tls_enable_alpn) {
+ if(cf->conn->bits.tls_enable_alpn) {
int cur = 0;
gnutls_datum_t protocols[2];
#ifdef USE_HTTP2
if(data->state.httpwant >= CURL_HTTP_VERSION_2
#ifndef CURL_DISABLE_PROXY
- && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
+ && (!Curl_ssl_cf_is_proxy(cf) || !cf->conn->bits.tunnel_proxy)
#endif
) {
protocols[cur].data = (unsigned char *)ALPN_H2;
@@ -660,8 +663,8 @@ gtls_connect_step1(struct Curl_easy *data,
}
}
- if(SSL_SET_OPTION(primary.clientcert)) {
- if(SSL_SET_OPTION(key_passwd)) {
+ if(ssl_config->primary.clientcert) {
+ if(ssl_config->key_passwd) {
const unsigned int supported_key_encryption_algorithms =
GNUTLS_PKCS_USE_PKCS12_3DES | GNUTLS_PKCS_USE_PKCS12_ARCFOUR |
GNUTLS_PKCS_USE_PKCS12_RC2_40 | GNUTLS_PKCS_USE_PBES2_3DES |
@@ -669,11 +672,11 @@ gtls_connect_step1(struct Curl_easy *data,
GNUTLS_PKCS_USE_PBES2_AES_256;
rc = gnutls_certificate_set_x509_key_file2(
backend->cred,
- SSL_SET_OPTION(primary.clientcert),
- SSL_SET_OPTION(key) ?
- SSL_SET_OPTION(key) : SSL_SET_OPTION(primary.clientcert),
- do_file_type(SSL_SET_OPTION(cert_type)),
- SSL_SET_OPTION(key_passwd),
+ ssl_config->primary.clientcert,
+ ssl_config->key ?
+ ssl_config->key : ssl_config->primary.clientcert,
+ do_file_type(ssl_config->cert_type),
+ ssl_config->key_passwd,
supported_key_encryption_algorithms);
if(rc != GNUTLS_E_SUCCESS) {
failf(data,
@@ -685,10 +688,10 @@ gtls_connect_step1(struct Curl_easy *data,
else {
if(gnutls_certificate_set_x509_key_file(
backend->cred,
- SSL_SET_OPTION(primary.clientcert),
- SSL_SET_OPTION(key) ?
- SSL_SET_OPTION(key) : SSL_SET_OPTION(primary.clientcert),
- do_file_type(SSL_SET_OPTION(cert_type)) ) !=
+ ssl_config->primary.clientcert,
+ ssl_config->key ?
+ ssl_config->key : ssl_config->primary.clientcert,
+ do_file_type(ssl_config->cert_type) ) !=
GNUTLS_E_SUCCESS) {
failf(data, "error reading X.509 key or certificate file");
return CURLE_SSL_CONNECT_ERROR;
@@ -698,7 +701,7 @@ gtls_connect_step1(struct Curl_easy *data,
#ifdef USE_GNUTLS_SRP
/* put the credentials to the current session */
- if(SSL_SET_OPTION(primary.authtype) == CURL_TLSAUTH_SRP) {
+ if(ssl_config->primary.authtype == CURL_TLSAUTH_SRP) {
rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP,
backend->srp_client_cred);
if(rc != GNUTLS_E_SUCCESS) {
@@ -717,20 +720,15 @@ gtls_connect_step1(struct Curl_easy *data,
}
}
-#ifndef CURL_DISABLE_PROXY
- if(conn->proxy_ssl[sockindex].use) {
- struct ssl_backend_data *proxy_backend;
- proxy_backend = conn->proxy_ssl[sockindex].backend;
- DEBUGASSERT(proxy_backend);
- transport_ptr = proxy_backend->session;
+ if(connssl_next) {
+ DEBUGASSERT(connssl_next->backend);
+ transport_ptr = connssl_next->backend;
gnutls_transport_push = gtls_push_ssl;
gnutls_transport_pull = gtls_pull_ssl;
}
- else
-#endif
- {
+ else {
/* file descriptor for the socket */
- transport_ptr = &conn->sock[sockindex];
+ transport_ptr = &cf->conn->sock[cf->sockindex];
gnutls_transport_push = gtls_push;
gnutls_transport_pull = gtls_pull;
}
@@ -742,7 +740,7 @@ gtls_connect_step1(struct Curl_easy *data,
gnutls_transport_set_push_function(session, gnutls_transport_push);
gnutls_transport_set_pull_function(session, gnutls_transport_pull);
- if(SSL_CONN_CONFIG(verifystatus)) {
+ if(conn_config->verifystatus) {
rc = gnutls_ocsp_status_request_enable_client(session, NULL, 0, NULL);
if(rc != GNUTLS_E_SUCCESS) {
failf(data, "gnutls_ocsp_status_request_enable_client() failed: %d", rc);
@@ -752,14 +750,12 @@ gtls_connect_step1(struct Curl_easy *data,
/* This might be a reconnect, so we check for a session ID in the cache
to speed up things */
- if(SSL_SET_OPTION(primary.sessionid)) {
+ if(ssl_config->primary.sessionid) {
void *ssl_sessionid;
size_t ssl_idsize;
Curl_ssl_sessionid_lock(data);
- if(!Curl_ssl_getsessionid(data, conn,
- SSL_IS_PROXY() ? TRUE : FALSE,
- &ssl_sessionid, &ssl_idsize, sockindex)) {
+ if(!Curl_ssl_getsessionid(cf, data, &ssl_sessionid, &ssl_idsize)) {
/* we got a session id, use it! */
gnutls_session_set_data(session, ssl_sessionid, ssl_idsize);
@@ -830,15 +826,14 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
return result;
}
-static Curl_recv gtls_recv;
-static Curl_send gtls_send;
-
CURLcode
-Curl_gtls_verifyserver(struct Curl_easy *data,
- struct connectdata *conn,
- gnutls_session_t session,
- int sockindex)
+Curl_gtls_verifyserver(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ gnutls_session_t session)
{
+ struct ssl_connect_data *connssl = cf->ctx;
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
unsigned int cert_list_size;
const gnutls_datum_t *chainp;
unsigned int verify_status = 0;
@@ -857,8 +852,8 @@ Curl_gtls_verifyserver(struct Curl_easy *data,
unsigned int bits;
gnutls_protocol_t version = gnutls_protocol_get_version(session);
#endif
- const char * const hostname = SSL_HOST_NAME();
- long * const certverifyresult = &SSL_SET_OPTION_LVALUE(certverifyresult);
+ const char *hostname = connssl->hostname;
+ long * const certverifyresult = &ssl_config->certverifyresult;
/* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */
ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(session),
@@ -876,13 +871,13 @@ Curl_gtls_verifyserver(struct Curl_easy *data,
chainp = gnutls_certificate_get_peers(session, &cert_list_size);
if(!chainp) {
- if(SSL_CONN_CONFIG(verifypeer) ||
- SSL_CONN_CONFIG(verifyhost) ||
- SSL_CONN_CONFIG(issuercert)) {
+ if(conn_config->verifypeer ||
+ conn_config->verifyhost ||
+ conn_config->issuercert) {
#ifdef USE_GNUTLS_SRP
- if(SSL_SET_OPTION(primary.authtype) == CURL_TLSAUTH_SRP
- && SSL_SET_OPTION(primary.username)
- && !SSL_CONN_CONFIG(verifypeer)
+ if(ssl_config->primary.authtype == CURL_TLSAUTH_SRP
+ && ssl_config->primary.username
+ && !conn_config->verifypeer
&& gnutls_cipher_get(session)) {
/* no peer cert, but auth is ok if we have SRP user and cipher and no
peer verify */
@@ -916,7 +911,7 @@ Curl_gtls_verifyserver(struct Curl_easy *data,
}
}
- if(SSL_CONN_CONFIG(verifypeer)) {
+ if(conn_config->verifypeer) {
/* This function will try to verify the peer's certificate and return its
status (trusted, invalid etc.). The value of status should be one or
more of the gnutls_certificate_status_t enumerated elements bitwise
@@ -935,12 +930,12 @@ Curl_gtls_verifyserver(struct Curl_easy *data,
/* verify_status is a bitmask of gnutls_certificate_status bits */
if(verify_status & GNUTLS_CERT_INVALID) {
- if(SSL_CONN_CONFIG(verifypeer)) {
+ if(conn_config->verifypeer) {
failf(data, "server certificate verification failed. CAfile: %s "
- "CRLfile: %s", SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile):
+ "CRLfile: %s", conn_config->CAfile ? conn_config->CAfile:
"none",
- SSL_SET_OPTION(primary.CRLfile) ?
- SSL_SET_OPTION(primary.CRLfile) : "none");
+ ssl_config->primary.CRLfile ?
+ ssl_config->primary.CRLfile : "none");
return CURLE_PEER_FAILED_VERIFICATION;
}
else
@@ -952,7 +947,7 @@ Curl_gtls_verifyserver(struct Curl_easy *data,
else
infof(data, " server certificate verification SKIPPED");
- if(SSL_CONN_CONFIG(verifystatus)) {
+ if(conn_config->verifystatus) {
if(gnutls_ocsp_status_request_is_checked(session, 0) == 0) {
gnutls_datum_t status_request;
gnutls_ocsp_resp_t ocsp_resp;
@@ -1063,21 +1058,21 @@ Curl_gtls_verifyserver(struct Curl_easy *data,
gnutls_x509_crt_t format */
gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER);
- if(SSL_CONN_CONFIG(issuercert)) {
+ if(conn_config->issuercert) {
gnutls_x509_crt_init(&x509_issuer);
- issuerp = load_file(SSL_CONN_CONFIG(issuercert));
+ issuerp = load_file(conn_config->issuercert);
gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM);
rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer);
gnutls_x509_crt_deinit(x509_issuer);
unload_file(issuerp);
if(rc <= 0) {
failf(data, "server certificate issuer check failed (IssuerCert: %s)",
- SSL_CONN_CONFIG(issuercert)?SSL_CONN_CONFIG(issuercert):"none");
+ conn_config->issuercert?conn_config->issuercert:"none");
gnutls_x509_crt_deinit(x509_cert);
return CURLE_SSL_ISSUER_ERROR;
}
infof(data, " server certificate issuer check OK (Issuer Cert: %s)",
- SSL_CONN_CONFIG(issuercert)?SSL_CONN_CONFIG(issuercert):"none");
+ conn_config->issuercert?conn_config->issuercert:"none");
}
size = sizeof(certname);
@@ -1140,15 +1135,15 @@ Curl_gtls_verifyserver(struct Curl_easy *data,
}
#endif
if(!rc) {
- if(SSL_CONN_CONFIG(verifyhost)) {
+ if(conn_config->verifyhost) {
failf(data, "SSL: certificate subject name (%s) does not match "
- "target host name '%s'", certname, SSL_HOST_DISPNAME());
+ "target host name '%s'", certname, connssl->dispname);
gnutls_x509_crt_deinit(x509_cert);
return CURLE_PEER_FAILED_VERIFICATION;
}
else
infof(data, " common name: %s (does not match '%s')",
- certname, SSL_HOST_DISPNAME());
+ certname, connssl->dispname);
}
else
infof(data, " common name: %s (matched)", certname);
@@ -1157,7 +1152,7 @@ Curl_gtls_verifyserver(struct Curl_easy *data,
certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
if(certclock == (time_t)-1) {
- if(SSL_CONN_CONFIG(verifypeer)) {
+ if(conn_config->verifypeer) {
failf(data, "server cert expiration date verify failed");
*certverifyresult = GNUTLS_CERT_EXPIRED;
gnutls_x509_crt_deinit(x509_cert);
@@ -1168,7 +1163,7 @@ Curl_gtls_verifyserver(struct Curl_easy *data,
}
else {
if(certclock < time(NULL)) {
- if(SSL_CONN_CONFIG(verifypeer)) {
+ if(conn_config->verifypeer) {
failf(data, "server certificate expiration date has passed.");
*certverifyresult = GNUTLS_CERT_EXPIRED;
gnutls_x509_crt_deinit(x509_cert);
@@ -1184,7 +1179,7 @@ Curl_gtls_verifyserver(struct Curl_easy *data,
certclock = gnutls_x509_crt_get_activation_time(x509_cert);
if(certclock == (time_t)-1) {
- if(SSL_CONN_CONFIG(verifypeer)) {
+ if(conn_config->verifypeer) {
failf(data, "server cert activation date verify failed");
*certverifyresult = GNUTLS_CERT_NOT_ACTIVATED;
gnutls_x509_crt_deinit(x509_cert);
@@ -1195,7 +1190,7 @@ Curl_gtls_verifyserver(struct Curl_easy *data,
}
else {
if(certclock > time(NULL)) {
- if(SSL_CONN_CONFIG(verifypeer)) {
+ if(conn_config->verifypeer) {
failf(data, "server certificate not activated yet.");
*certverifyresult = GNUTLS_CERT_NOT_ACTIVATED;
gnutls_x509_crt_deinit(x509_cert);
@@ -1208,7 +1203,9 @@ Curl_gtls_verifyserver(struct Curl_easy *data,
infof(data, " server certificate activation date OK");
}
- ptr = SSL_PINNED_PUB_KEY();
+ ptr = Curl_ssl_cf_is_proxy(cf)?
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]:
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY];
if(ptr) {
result = pkp_pin_peer_pubkey(data, x509_cert, ptr);
if(result != CURLE_OK) {
@@ -1266,7 +1263,7 @@ Curl_gtls_verifyserver(struct Curl_easy *data,
gnutls_x509_crt_deinit(x509_cert);
- if(conn->bits.tls_enable_alpn) {
+ if(cf->conn->bits.tls_enable_alpn) {
rc = gnutls_alpn_get_selected_protocol(session, &proto);
if(rc == 0) {
infof(data, VTLS_INFOF_ALPN_ACCEPTED_LEN_1STR, proto.size,
@@ -1276,25 +1273,25 @@ Curl_gtls_verifyserver(struct Curl_easy *data,
if(proto.size == ALPN_H2_LENGTH &&
!memcmp(ALPN_H2, proto.data,
ALPN_H2_LENGTH)) {
- conn->alpn = CURL_HTTP_VERSION_2;
+ cf->conn->alpn = CURL_HTTP_VERSION_2;
}
else
#endif
if(proto.size == ALPN_HTTP_1_1_LENGTH &&
!memcmp(ALPN_HTTP_1_1, proto.data, ALPN_HTTP_1_1_LENGTH)) {
- conn->alpn = CURL_HTTP_VERSION_1_1;
+ cf->conn->alpn = CURL_HTTP_VERSION_1_1;
}
}
else
infof(data, VTLS_INFOF_NO_ALPN);
- Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ?
+ Curl_multiuse_state(data, cf->conn->alpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
- conn->ssl[sockindex].state = ssl_connection_complete;
+ connssl->state = ssl_connection_complete;
- if(SSL_SET_OPTION(primary.sessionid)) {
+ if(ssl_config->primary.sessionid) {
/* we always unconditionally get the session id here, as even if we
already got it from the cache and asked to use it in the connection, it
might've been rejected and then a new one is in use now and we need to
@@ -1315,9 +1312,7 @@ Curl_gtls_verifyserver(struct Curl_easy *data,
gnutls_session_get_data(session, connect_sessionid, &connect_idsize);
Curl_ssl_sessionid_lock(data);
- incache = !(Curl_ssl_getsessionid(data, conn,
- SSL_IS_PROXY() ? TRUE : FALSE,
- &ssl_sessionid, NULL, sockindex));
+ incache = !(Curl_ssl_getsessionid(cf, data, &ssl_sessionid, NULL));
if(incache) {
/* there was one before in the cache, so instead of risking that the
previous one was rejected, we just kill that and store the new */
@@ -1325,10 +1320,8 @@ Curl_gtls_verifyserver(struct Curl_easy *data,
}
/* store this session id */
- result = Curl_ssl_addsessionid(data, conn,
- SSL_IS_PROXY() ? TRUE : FALSE,
- connect_sessionid, connect_idsize,
- sockindex, &added);
+ result = Curl_ssl_addsessionid(cf, data, connect_sessionid,
+ connect_idsize, &added);
Curl_ssl_sessionid_unlock(data);
if(!added)
free(connect_sessionid);
@@ -1354,23 +1347,22 @@ Curl_gtls_verifyserver(struct Curl_easy *data,
'ssl_connect_2_writing' (waiting to be able to write).
*/
static CURLcode
-gtls_connect_common(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex,
+gtls_connect_common(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
bool nonblocking,
bool *done)
{
int rc;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
/* Initiate the connection, if not already done */
if(ssl_connect_1 == connssl->connecting_state) {
- rc = gtls_connect_step1(data, conn, sockindex);
+ rc = gtls_connect_step1(cf, data);
if(rc)
return rc;
}
- rc = handshake(data, conn, sockindex, TRUE, nonblocking);
+ rc = handshake(cf, data, TRUE, nonblocking);
if(rc)
/* handshake() sets its own error message with failf() */
return rc;
@@ -1381,7 +1373,7 @@ gtls_connect_common(struct Curl_easy *data,
gnutls_session_t session;
DEBUGASSERT(backend);
session = backend->session;
- rc = Curl_gtls_verifyserver(data, conn, session, sockindex);
+ rc = Curl_gtls_verifyserver(cf, data, session);
if(rc)
return rc;
}
@@ -1391,20 +1383,20 @@ gtls_connect_common(struct Curl_easy *data,
return CURLE_OK;
}
-static CURLcode gtls_connect_nonblocking(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex, bool *done)
+static CURLcode gtls_connect_nonblocking(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool *done)
{
- return gtls_connect_common(data, conn, sockindex, TRUE, done);
+ return gtls_connect_common(cf, data, TRUE, done);
}
-static CURLcode gtls_connect(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+static CURLcode gtls_connect(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
CURLcode result;
bool done = FALSE;
- result = gtls_connect_common(data, conn, sockindex, FALSE, &done);
+ result = gtls_connect_common(cf, data, FALSE, &done);
if(result)
return result;
@@ -1413,42 +1405,30 @@ static CURLcode gtls_connect(struct Curl_easy *data, struct connectdata *conn,
return CURLE_OK;
}
-static bool gtls_data_pending(const struct connectdata *conn,
- int connindex)
+static bool gtls_data_pending(struct Curl_cfilter *cf,
+ const struct Curl_easy *data)
{
- const struct ssl_connect_data *connssl = &conn->ssl[connindex];
- bool res = FALSE;
- struct ssl_backend_data *backend = connssl->backend;
+ struct ssl_connect_data *ctx = cf->ctx;
- DEBUGASSERT(backend);
-
- if(backend->session &&
- 0 != gnutls_record_check_pending(backend->session))
- res = TRUE;
-
-#ifndef CURL_DISABLE_PROXY
- connssl = &conn->proxy_ssl[connindex];
- backend = connssl->backend;
- DEBUGASSERT(backend);
- if(backend->session &&
- 0 != gnutls_record_check_pending(backend->session))
- res = TRUE;
-#endif
-
- return res;
+ (void)data;
+ DEBUGASSERT(ctx && ctx->backend);
+ if(ctx->backend->session &&
+ 0 != gnutls_record_check_pending(ctx->backend->session))
+ return TRUE;
+ return FALSE;
}
-static ssize_t gtls_send(struct Curl_easy *data,
- int sockindex,
+static ssize_t gtls_send(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
const void *mem,
size_t len,
CURLcode *curlcode)
{
- struct connectdata *conn = data->conn;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
ssize_t rc;
+ (void)data;
DEBUGASSERT(backend);
rc = gnutls_record_send(backend->session, mem, len);
@@ -1463,9 +1443,13 @@ static ssize_t gtls_send(struct Curl_easy *data,
return rc;
}
-static void close_one(struct ssl_connect_data *connssl)
+static void gtls_close(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
+
+ (void) data;
DEBUGASSERT(backend);
if(backend->session) {
@@ -1489,24 +1473,15 @@ static void close_one(struct ssl_connect_data *connssl)
#endif
}
-static void gtls_close(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
-{
- (void) data;
- close_one(&conn->ssl[sockindex]);
-#ifndef CURL_DISABLE_PROXY
- close_one(&conn->proxy_ssl[sockindex]);
-#endif
-}
-
/*
* This function is called to shut down the SSL layer but keep the
* socket open (CCC - Clear Command Channel)
*/
-static int gtls_shutdown(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+static int gtls_shutdown(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
struct ssl_backend_data *backend = connssl->backend;
int retval = 0;
@@ -1528,7 +1503,7 @@ static int gtls_shutdown(struct Curl_easy *data, struct connectdata *conn,
char buf[120];
while(!done) {
- int what = SOCKET_READABLE(conn->sock[sockindex],
+ int what = SOCKET_READABLE(cf->conn->sock[cf->sockindex],
SSL_SHUTDOWN_TIMEOUT);
if(what > 0) {
/* Something to read, let's do it and hope that it is the close
@@ -1568,8 +1543,8 @@ static int gtls_shutdown(struct Curl_easy *data, struct connectdata *conn,
gnutls_certificate_free_credentials(backend->cred);
#ifdef USE_GNUTLS_SRP
- if(SSL_SET_OPTION(primary.authtype) == CURL_TLSAUTH_SRP
- && SSL_SET_OPTION(primary.username) != NULL)
+ if(ssl_config->primary.authtype == CURL_TLSAUTH_SRP
+ && ssl_config->primary.username != NULL)
gnutls_srp_free_client_credentials(backend->srp_client_cred);
#endif
@@ -1579,17 +1554,17 @@ static int gtls_shutdown(struct Curl_easy *data, struct connectdata *conn,
return retval;
}
-static ssize_t gtls_recv(struct Curl_easy *data, /* connection data */
- int num, /* socketindex */
- char *buf, /* store read data here */
- size_t buffersize, /* max amount to read */
+static ssize_t gtls_recv(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ char *buf,
+ size_t buffersize,
CURLcode *curlcode)
{
- struct connectdata *conn = data->conn;
- struct ssl_connect_data *connssl = &conn->ssl[num];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
ssize_t ret;
+ (void)data;
DEBUGASSERT(backend);
ret = gnutls_record_recv(backend->session, buf, buffersize);
@@ -1601,7 +1576,7 @@ static ssize_t gtls_recv(struct Curl_easy *data, /* connection data */
if(ret == GNUTLS_E_REHANDSHAKE) {
/* BLOCKING call, this is bad but a work-around for now. Fixing this "the
proper way" takes a whole lot of work. */
- CURLcode result = handshake(data, conn, num, FALSE, FALSE);
+ CURLcode result = handshake(cf, data, FALSE, FALSE);
if(result)
/* handshake() writes error message on its own */
*curlcode = result;
@@ -1687,7 +1662,7 @@ const struct Curl_ssl Curl_ssl_gnutls = {
gtls_cert_status_request, /* cert_status_request */
gtls_connect, /* connect */
gtls_connect_nonblocking, /* connect_nonblocking */
- Curl_ssl_getsock, /* getsock */
+ Curl_ssl_get_select_socks, /* getsock */
gtls_get_internals, /* get_internals */
gtls_close, /* close_one */
Curl_none_close_all, /* close_all */
diff --git a/lib/vtls/gtls.h b/lib/vtls/gtls.h
index abade73f8..af00b4543 100644
--- a/lib/vtls/gtls.h
+++ b/lib/vtls/gtls.h
@@ -29,11 +29,12 @@
#ifdef USE_GNUTLS
#include "urldata.h"
+#include "cfilters.h"
#include <gnutls/gnutls.h>
CURLcode
-Curl_gtls_verifyserver(struct Curl_easy *data, struct connectdata *conn,
- gnutls_session_t session,
- int sockindex);
+Curl_gtls_verifyserver(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ gnutls_session_t session);
extern const struct Curl_ssl Curl_ssl_gnutls;
#endif /* USE_GNUTLS */
diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c
index a6d1d979a..f919a842e 100644
--- a/lib/vtls/mbedtls.c
+++ b/lib/vtls/mbedtls.c
@@ -182,9 +182,6 @@ static const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_fr =
#define PUB_DER_MAX_BYTES (RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES)
-static Curl_recv mbed_recv;
-static Curl_send mbed_send;
-
static CURLcode mbedtls_version_from_curl(int *mbedver, long version)
{
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
@@ -217,11 +214,11 @@ static CURLcode mbedtls_version_from_curl(int *mbedver, long version)
}
static CURLcode
-set_ssl_version_min_max(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+set_ssl_version_min_max(struct Curl_cfilter *cf, struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
int mbedtls_ver_min = MBEDTLS_SSL_MINOR_VERSION_3;
int mbedtls_ver_max = MBEDTLS_SSL_MINOR_VERSION_3;
@@ -229,8 +226,8 @@ set_ssl_version_min_max(struct Curl_easy *data, struct connectdata *conn,
int mbedtls_ver_min = MBEDTLS_SSL_MINOR_VERSION_1;
int mbedtls_ver_max = MBEDTLS_SSL_MINOR_VERSION_1;
#endif
- long ssl_version = SSL_CONN_CONFIG(version);
- long ssl_version_max = SSL_CONN_CONFIG(version_max);
+ long ssl_version = conn_config->version;
+ long ssl_version_max = conn_config->version_max;
CURLcode result = CURLE_OK;
DEBUGASSERT(backend);
@@ -269,31 +266,29 @@ set_ssl_version_min_max(struct Curl_easy *data, struct connectdata *conn,
}
static CURLcode
-mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
- const struct curl_blob *ca_info_blob = SSL_CONN_CONFIG(ca_info_blob);
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ const struct curl_blob *ca_info_blob = conn_config->ca_info_blob;
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
const char * const ssl_cafile =
/* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */
- (ca_info_blob ? NULL : SSL_CONN_CONFIG(CAfile));
- const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
- const char * const ssl_capath = SSL_CONN_CONFIG(CApath);
- char * const ssl_cert = SSL_SET_OPTION(primary.clientcert);
- const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob);
- const char * const ssl_crlfile = SSL_SET_OPTION(primary.CRLfile);
- const char * const hostname = SSL_HOST_NAME();
-#ifndef CURL_DISABLE_VERBOSE_STRINGS
- const long int port = SSL_HOST_PORT();
-#endif
+ (ca_info_blob ? NULL : conn_config->CAfile);
+ const bool verifypeer = conn_config->verifypeer;
+ const char * const ssl_capath = conn_config->CApath;
+ char * const ssl_cert = ssl_config->primary.clientcert;
+ const struct curl_blob *ssl_cert_blob = ssl_config->primary.cert_blob;
+ const char * const ssl_crlfile = ssl_config->primary.CRLfile;
+ const char *hostname = connssl->hostname;
int ret = -1;
char errorbuf[128];
DEBUGASSERT(backend);
- if((SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) ||
- (SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv3)) {
+ if((conn_config->version == CURL_SSLVERSION_SSLv2) ||
+ (conn_config->version == CURL_SSLVERSION_SSLv3)) {
failf(data, "Not supported SSL version");
return CURLE_NOT_BUILT_IN;
}
@@ -417,7 +412,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
if(ret) {
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
failf(data, "Error reading private key %s - mbedTLS: (-0x%04X) %s",
- SSL_SET_OPTION(key), -ret, errorbuf);
+ ssl_config->key, -ret, errorbuf);
return CURLE_SSL_CERTPROBLEM;
}
}
@@ -425,23 +420,23 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
/* Load the client private key */
mbedtls_pk_init(&backend->pk);
- if(SSL_SET_OPTION(key) || SSL_SET_OPTION(key_blob)) {
- if(SSL_SET_OPTION(key)) {
+ if(ssl_config->key || ssl_config->key_blob) {
+ if(ssl_config->key) {
#ifdef MBEDTLS_FS_IO
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
- ret = mbedtls_pk_parse_keyfile(&backend->pk, SSL_SET_OPTION(key),
- SSL_SET_OPTION(key_passwd),
+ ret = mbedtls_pk_parse_keyfile(&backend->pk, ssl_config->key,
+ ssl_config->key_passwd,
mbedtls_ctr_drbg_random,
&backend->ctr_drbg);
#else
- ret = mbedtls_pk_parse_keyfile(&backend->pk, SSL_SET_OPTION(key),
- SSL_SET_OPTION(key_passwd));
+ ret = mbedtls_pk_parse_keyfile(&backend->pk, ssl_config->key,
+ ssl_config->key_passwd);
#endif
if(ret) {
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
failf(data, "Error reading private key %s - mbedTLS: (-0x%04X) %s",
- SSL_SET_OPTION(key), -ret, errorbuf);
+ ssl_config->key, -ret, errorbuf);
return CURLE_SSL_CERTPROBLEM;
}
#else
@@ -450,10 +445,10 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
#endif
}
else {
- const struct curl_blob *ssl_key_blob = SSL_SET_OPTION(key_blob);
+ const struct curl_blob *ssl_key_blob = ssl_config->key_blob;
const unsigned char *key_data =
(const unsigned char *)ssl_key_blob->data;
- const char *passwd = SSL_SET_OPTION(key_passwd);
+ const char *passwd = ssl_config->key_passwd;
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
ret = mbedtls_pk_parse_key(&backend->pk, key_data, ssl_key_blob->len,
(const unsigned char *)passwd,
@@ -506,7 +501,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
}
#endif
- infof(data, "mbedTLS: Connecting to %s:%ld", hostname, port);
+ infof(data, "mbedTLS: Connecting to %s:%ld", hostname, connssl->port);
mbedtls_ssl_config_init(&backend->config);
ret = mbedtls_ssl_config_defaults(&backend->config,
@@ -528,7 +523,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
mbedtls_ssl_conf_cert_profile(&backend->config,
&mbedtls_x509_crt_profile_fr);
- switch(SSL_CONN_CONFIG(version)) {
+ switch(conn_config->version) {
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
#if MBEDTLS_VERSION_NUMBER < 0x03000000
@@ -542,7 +537,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
case CURL_SSLVERSION_TLSv1_2:
case CURL_SSLVERSION_TLSv1_3:
{
- CURLcode result = set_ssl_version_min_max(data, conn, sockindex);
+ CURLcode result = set_ssl_version_min_max(cf, data);
if(result != CURLE_OK)
return result;
break;
@@ -556,7 +551,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
mbedtls_ssl_conf_rng(&backend->config, mbedtls_ctr_drbg_random,
&backend->ctr_drbg);
- mbedtls_ssl_set_bio(&backend->ssl, &conn->sock[sockindex],
+ mbedtls_ssl_set_bio(&backend->ssl, &cf->conn->sock[cf->sockindex],
mbedtls_net_send,
mbedtls_net_recv,
NULL /* rev_timeout() */);
@@ -575,13 +570,11 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
#endif
/* Check if there's a cached ID we can/should use here! */
- if(SSL_SET_OPTION(primary.sessionid)) {
+ if(ssl_config->primary.sessionid) {
void *old_session = NULL;
Curl_ssl_sessionid_lock(data);
- if(!Curl_ssl_getsessionid(data, conn,
- SSL_IS_PROXY() ? TRUE : FALSE,
- &old_session, NULL, sockindex)) {
+ if(!Curl_ssl_getsessionid(cf, data, &old_session, NULL)) {
ret = mbedtls_ssl_set_session(&backend->ssl, old_session);
if(ret) {
Curl_ssl_sessionid_unlock(data);
@@ -601,7 +594,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
NULL);
#endif
- if(SSL_SET_OPTION(key) || SSL_SET_OPTION(key_blob)) {
+ if(ssl_config->key || ssl_config->key_blob) {
mbedtls_ssl_conf_own_cert(&backend->config,
&backend->clicert, &backend->pk);
}
@@ -617,7 +610,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
}
#ifdef HAS_ALPN
- if(conn->bits.tls_enable_alpn) {
+ if(cf->conn->bits.tls_enable_alpn) {
const char **p = &backend->protocols[0];
#ifdef USE_HTTP2
if(data->state.httpwant >= CURL_HTTP_VERSION_2)
@@ -665,14 +658,16 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
}
static CURLcode
-mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+mbed_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
{
int ret;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
const mbedtls_x509_crt *peercert;
- const char * const pinnedpubkey = SSL_PINNED_PUB_KEY();
+ const char * const pinnedpubkey = Curl_ssl_cf_is_proxy(cf)?
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]:
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY];
DEBUGASSERT(backend);
@@ -699,11 +694,11 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn,
ret = mbedtls_ssl_get_verify_result(&backend->ssl);
- if(!SSL_CONN_CONFIG(verifyhost))
+ if(!conn_config->verifyhost)
/* Ignore hostname errors if verifyhost is disabled */
ret &= ~MBEDTLS_X509_BADCERT_CN_MISMATCH;
- if(ret && SSL_CONN_CONFIG(verifypeer)) {
+ if(ret && conn_config->verifypeer) {
if(ret & MBEDTLS_X509_BADCERT_EXPIRED)
failf(data, "Cert verify failed: BADCERT_EXPIRED");
@@ -811,7 +806,7 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn,
}
#ifdef HAS_ALPN
- if(conn->bits.tls_enable_alpn) {
+ if(cf->conn->bits.tls_enable_alpn) {
const char *next_protocol = mbedtls_ssl_get_alpn_protocol(&backend->ssl);
if(next_protocol) {
@@ -819,19 +814,19 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn,
#ifdef USE_HTTP2
if(!strncmp(next_protocol, ALPN_H2, ALPN_H2_LENGTH) &&
!next_protocol[ALPN_H2_LENGTH]) {
- conn->alpn = CURL_HTTP_VERSION_2;
+ cf->conn->alpn = CURL_HTTP_VERSION_2;
}
else
#endif
if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH) &&
!next_protocol[ALPN_HTTP_1_1_LENGTH]) {
- conn->alpn = CURL_HTTP_VERSION_1_1;
+ cf->conn->alpn = CURL_HTTP_VERSION_1_1;
}
}
else {
infof(data, VTLS_INFOF_NO_ALPN);
}
- Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ?
+ Curl_multiuse_state(data, cf->conn->alpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
#endif
@@ -843,21 +838,20 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn,
}
static CURLcode
-mbed_connect_step3(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+mbed_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data)
{
CURLcode retcode = CURLE_OK;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
DEBUGASSERT(backend);
- if(SSL_SET_OPTION(primary.sessionid)) {
+ if(ssl_config->primary.sessionid) {
int ret;
mbedtls_ssl_session *our_ssl_sessionid;
void *old_ssl_sessionid = NULL;
- bool isproxy = SSL_IS_PROXY() ? TRUE : FALSE;
bool added = FALSE;
our_ssl_sessionid = malloc(sizeof(mbedtls_ssl_session));
@@ -877,12 +871,11 @@ mbed_connect_step3(struct Curl_easy *data, struct connectdata *conn,
/* If there's already a matching session in the cache, delete it */
Curl_ssl_sessionid_lock(data);
- if(!Curl_ssl_getsessionid(data, conn, isproxy, &old_ssl_sessionid, NULL,
- sockindex))
+ if(!Curl_ssl_getsessionid(cf, data, &old_ssl_sessionid, NULL))
Curl_ssl_delsessionid(data, old_ssl_sessionid);
- retcode = Curl_ssl_addsessionid(data, conn, isproxy, our_ssl_sessionid,
- 0, sockindex, &added);
+ retcode = Curl_ssl_addsessionid(cf, data, our_ssl_sessionid,
+ 0, &added);
Curl_ssl_sessionid_unlock(data);
if(!added) {
mbedtls_ssl_session_free(our_ssl_sessionid);
@@ -899,15 +892,15 @@ mbed_connect_step3(struct Curl_easy *data, struct connectdata *conn,
return CURLE_OK;
}
-static ssize_t mbed_send(struct Curl_easy *data, int sockindex,
+static ssize_t mbed_send(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *mem, size_t len,
CURLcode *curlcode)
{
- struct connectdata *conn = data->conn;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
int ret = -1;
+ (void)data;
DEBUGASSERT(backend);
ret = mbedtls_ssl_write(&backend->ssl, (unsigned char *)mem, len);
@@ -926,10 +919,9 @@ static void mbedtls_close_all(struct Curl_easy *data)
(void)data;
}
-static void mbedtls_close(struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+static void mbedtls_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
char buf[32];
(void) data;
@@ -954,16 +946,16 @@ static void mbedtls_close(struct Curl_easy *data,
#endif /* THREADING_SUPPORT */
}
-static ssize_t mbed_recv(struct Curl_easy *data, int num,
+static ssize_t mbed_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
char *buf, size_t buffersize,
CURLcode *curlcode)
{
- struct connectdata *conn = data->conn;
- struct ssl_connect_data *connssl = &conn->ssl[num];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
int ret = -1;
ssize_t len = -1;
+ (void)data;
DEBUGASSERT(backend);
ret = mbedtls_ssl_read(&backend->ssl, (unsigned char *)buf,
@@ -1046,15 +1038,13 @@ static CURLcode mbedtls_random(struct Curl_easy *data,
}
static CURLcode
-mbed_connect_common(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex,
+mbed_connect_common(struct Curl_cfilter *cf, struct Curl_easy *data,
bool nonblocking,
bool *done)
{
CURLcode retcode;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- curl_socket_t sockfd = conn->sock[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
+ curl_socket_t sockfd = cf->conn->sock[cf->sockindex];
timediff_t timeout_ms;
int what;
@@ -1073,7 +1063,7 @@ mbed_connect_common(struct Curl_easy *data,
failf(data, "SSL connection timeout");
return CURLE_OPERATION_TIMEDOUT;
}
- retcode = mbed_connect_step1(data, conn, sockindex);
+ retcode = mbed_connect_step1(cf, data);
if(retcode)
return retcode;
}
@@ -1128,7 +1118,7 @@ mbed_connect_common(struct Curl_easy *data,
* ensuring that a client using select() or epoll() will always
* have a valid fdset to wait on.
*/
- retcode = mbed_connect_step2(data, conn, sockindex);
+ retcode = mbed_connect_step2(cf, data);
if(retcode || (nonblocking &&
(ssl_connect_2 == connssl->connecting_state ||
ssl_connect_2_reading == connssl->connecting_state ||
@@ -1138,7 +1128,7 @@ mbed_connect_common(struct Curl_easy *data,
} /* repeat step2 until all transactions are done. */
if(ssl_connect_3 == connssl->connecting_state) {
- retcode = mbed_connect_step3(data, conn, sockindex);
+ retcode = mbed_connect_step3(cf, data);
if(retcode)
return retcode;
}
@@ -1156,21 +1146,21 @@ mbed_connect_common(struct Curl_easy *data,
return CURLE_OK;
}
-static CURLcode mbedtls_connect_nonblocking(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex, bool *done)
+static CURLcode mbedtls_connect_nonblocking(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool *done)
{
- return mbed_connect_common(data, conn, sockindex, TRUE, done);
+ return mbed_connect_common(cf, data, TRUE, done);
}
-static CURLcode mbedtls_connect(struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+static CURLcode mbedtls_connect(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
CURLcode retcode;
bool done = FALSE;
- retcode = mbed_connect_common(data, conn, sockindex, FALSE, &done);
+ retcode = mbed_connect_common(cf, data, FALSE, &done);
if(retcode)
return retcode;
@@ -1193,13 +1183,14 @@ static void mbedtls_cleanup(void)
(void)Curl_mbedtlsthreadlock_thread_cleanup();
}
-static bool mbedtls_data_pending(const struct connectdata *conn,
- int sockindex)
+static bool mbedtls_data_pending(struct Curl_cfilter *cf,
+ const struct Curl_easy *data)
{
- const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- struct ssl_backend_data *backend = connssl->backend;
- DEBUGASSERT(backend);
- return mbedtls_ssl_get_bytes_avail(&backend->ssl) != 0;
+ struct ssl_connect_data *ctx = cf->ctx;
+
+ (void)data;
+ DEBUGASSERT(ctx && ctx->backend);
+ return mbedtls_ssl_get_bytes_avail(&ctx->backend->ssl) != 0;
}
static CURLcode mbedtls_sha256sum(const unsigned char *input,
@@ -1252,7 +1243,7 @@ const struct Curl_ssl Curl_ssl_mbedtls = {
Curl_none_cert_status_request, /* cert_status_request */
mbedtls_connect, /* connect */
mbedtls_connect_nonblocking, /* connect_nonblocking */
- Curl_ssl_getsock, /* getsock */
+ Curl_ssl_get_select_socks, /* getsock */
mbedtls_get_internals, /* get_internals */
mbedtls_close, /* close_one */
mbedtls_close_all, /* close_all */
diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c
index 340cddae9..03694d22b 100644
--- a/lib/vtls/nss.c
+++ b/lib/vtls/nss.c
@@ -696,17 +696,18 @@ fail:
return CURLE_SSL_CRL_BADFILE;
}
-static CURLcode nss_load_key(struct Curl_easy *data, struct connectdata *conn,
- int sockindex, char *key_file)
+static CURLcode nss_load_key(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ char *key_file)
{
+ struct ssl_connect_data *connssl = cf->ctx;
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
PK11SlotInfo *slot, *tmp;
SECStatus status;
CURLcode result;
- struct ssl_connect_data *ssl = conn->ssl;
- (void)sockindex; /* unused */
-
- result = nss_create_object(ssl, CKO_PRIVATE_KEY, key_file, FALSE);
+ (void)data;
+ result = nss_create_object(connssl, CKO_PRIVATE_KEY, key_file, FALSE);
if(result) {
PR_SetError(SEC_ERROR_BAD_KEY, 0);
return result;
@@ -725,7 +726,7 @@ static CURLcode nss_load_key(struct Curl_easy *data, struct connectdata *conn,
return CURLE_SSL_CERTPROBLEM;
}
- status = PK11_Authenticate(slot, PR_TRUE, SSL_SET_OPTION(key_passwd));
+ status = PK11_Authenticate(slot, PR_TRUE, ssl_config->key_passwd);
PK11_FreeSlot(slot);
return (SECSuccess == status) ? CURLE_OK : CURLE_SSL_CERTPROBLEM;
@@ -747,13 +748,15 @@ static int display_error(struct Curl_easy *data, PRInt32 err,
return 0; /* The caller will print a generic error */
}
-static CURLcode cert_stuff(struct Curl_easy *data, struct connectdata *conn,
- int sockindex, char *cert_file, char *key_file)
+static CURLcode cert_stuff(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ char *cert_file, char *key_file)
{
+ struct ssl_connect_data *connssl = cf->ctx;
CURLcode result;
if(cert_file) {
- result = nss_load_cert(&conn->ssl[sockindex], cert_file, PR_FALSE);
+ result = nss_load_cert(connssl, cert_file, PR_FALSE);
if(result) {
const PRErrorCode err = PR_GetError();
if(!display_error(data, err, cert_file)) {
@@ -767,10 +770,10 @@ static CURLcode cert_stuff(struct Curl_easy *data, struct connectdata *conn,
if(key_file || (is_file(cert_file))) {
if(key_file)
- result = nss_load_key(data, conn, sockindex, key_file);
+ result = nss_load_key(cf, data, key_file);
else
/* In case the cert file also has the key */
- result = nss_load_key(data, conn, sockindex, cert_file);
+ result = nss_load_key(cf, data, cert_file);
if(result) {
const PRErrorCode err = PR_GetError();
if(!display_error(data, err, key_file)) {
@@ -800,11 +803,14 @@ static char *nss_get_password(PK11SlotInfo *slot, PRBool retry, void *arg)
static SECStatus nss_auth_cert_hook(void *arg, PRFileDesc *fd, PRBool checksig,
PRBool isServer)
{
- struct Curl_easy *data = (struct Curl_easy *)arg;
- struct connectdata *conn = data->conn;
+ struct Curl_cfilter *cf = (struct Curl_cfilter *)arg;
+ struct ssl_connect_data *connssl = cf->ctx;
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ struct Curl_easy *data = connssl->backend->data;
+ DEBUGASSERT(data);
#ifdef SSL_ENABLE_OCSP_STAPLING
- if(SSL_CONN_CONFIG(verifystatus)) {
+ if(conn_config->verifystatus) {
SECStatus cacheResult;
const SECItemArray *csa = SSL_PeerStapledOCSPResponses(fd);
@@ -830,7 +836,7 @@ static SECStatus nss_auth_cert_hook(void *arg, PRFileDesc *fd, PRBool checksig,
}
#endif
- if(!SSL_CONN_CONFIG(verifypeer)) {
+ if(!conn_config->verifypeer) {
infof(data, "skipping SSL peer certificate verification");
return SECSuccess;
}
@@ -843,13 +849,16 @@ static SECStatus nss_auth_cert_hook(void *arg, PRFileDesc *fd, PRBool checksig,
*/
static void HandshakeCallback(PRFileDesc *sock, void *arg)
{
- struct Curl_easy *data = (struct Curl_easy *)arg;
- struct connectdata *conn = data->conn;
+ struct Curl_cfilter *cf = (struct Curl_cfilter *)arg;
+ struct ssl_connect_data *connssl = cf->ctx;
+ struct Curl_easy *data = connssl->backend->data;
+ struct connectdata *conn = cf->conn;
unsigned int buflenmax = 50;
unsigned char buf[50];
unsigned int buflen;
SSLNextProtoState state;
+ DEBUGASSERT(data);
if(!conn->bits.tls_enable_alpn) {
return;
}
@@ -879,13 +888,13 @@ static void HandshakeCallback(PRFileDesc *sock, void *arg)
#ifdef USE_HTTP2
if(buflen == ALPN_H2_LENGTH &&
!memcmp(ALPN_H2, buf, ALPN_H2_LENGTH)) {
- conn->alpn = CURL_HTTP_VERSION_2;
+ cf->conn->alpn = CURL_HTTP_VERSION_2;
}
else
#endif
if(buflen == ALPN_HTTP_1_1_LENGTH &&
!memcmp(ALPN_HTTP_1_1, buf, ALPN_HTTP_1_1_LENGTH)) {
- conn->alpn = CURL_HTTP_VERSION_1_1;
+ cf->conn->alpn = CURL_HTTP_VERSION_1_1;
}
/* This callback might get called when PR_Recv() is used within
@@ -893,7 +902,7 @@ static void HandshakeCallback(PRFileDesc *sock, void *arg)
* be any "bundle" associated with the connection anymore.
*/
if(conn->bundle)
- Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ?
+ Curl_multiuse_state(data, cf->conn->alpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
}
@@ -1064,15 +1073,20 @@ static CURLcode display_conn_info(struct Curl_easy *data, PRFileDesc *sock)
static SECStatus BadCertHandler(void *arg, PRFileDesc *sock)
{
- struct Curl_easy *data = (struct Curl_easy *)arg;
- struct connectdata *conn = data->conn;
+ struct Curl_cfilter *cf = (struct Curl_cfilter *)arg;
+ struct ssl_connect_data *connssl = cf->ctx;
+ struct Curl_easy *data = connssl->backend->data;
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ struct ssl_config_data *ssl_config;
PRErrorCode err = PR_GetError();
CERTCertificate *cert;
+ DEBUGASSERT(data);
+ ssl_config = Curl_ssl_cf_get_config(cf, data);
/* remember the cert verification result */
- SSL_SET_OPTION_LVALUE(certverifyresult) = err;
+ ssl_config->certverifyresult = err;
- if(err == SSL_ERROR_BAD_CERT_DOMAIN && !SSL_CONN_CONFIG(verifyhost))
+ if(err == SSL_ERROR_BAD_CERT_DOMAIN && !conn_config->verifyhost)
/* we are asked not to verify the host name */
return SECSuccess;
@@ -1549,13 +1563,14 @@ static void nss_cleanup(void)
* 0 means the connection has been closed
* -1 means the connection status is unknown
*/
-static int nss_check_cxn(struct connectdata *conn)
+static int nss_check_cxn(struct Curl_cfilter *cf, struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
int rc;
char buf;
+ (void)data;
DEBUGASSERT(backend);
rc =
@@ -1612,41 +1627,20 @@ static void close_one(struct ssl_connect_data *connssl)
/*
* This function is called when an SSL connection is closed.
*/
-static void nss_close(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+static void nss_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-#ifndef CURL_DISABLE_PROXY
- struct ssl_connect_data *connssl_proxy = &conn->proxy_ssl[sockindex];
-#endif
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
(void)data;
-
DEBUGASSERT(backend);
-#ifndef CURL_DISABLE_PROXY
- DEBUGASSERT(connssl_proxy->backend != NULL);
-#endif
- if(backend->handle
-#ifndef CURL_DISABLE_PROXY
- || connssl_proxy->backend->handle
-#endif
- ) {
+ if(backend->handle) {
/* NSS closes the socket we previously handed to it, so we must mark it
as closed to avoid double close */
- fake_sclose(conn->sock[sockindex]);
- conn->sock[sockindex] = CURL_SOCKET_BAD;
+ fake_sclose(cf->conn->sock[cf->sockindex]);
+ cf->conn->sock[cf->sockindex] = CURL_SOCKET_BAD;
}
-#ifndef CURL_DISABLE_PROXY
- if(backend->handle)
- /* nss_close(connssl) will transitively close also
- connssl_proxy->backend->handle if both are used. Clear it to avoid
- a double close leading to crash. */
- connssl_proxy->backend->handle = NULL;
-
- close_one(connssl_proxy);
-#endif
close_one(connssl);
}
@@ -1680,15 +1674,13 @@ static bool is_cc_error(PRInt32 err)
}
}
-static Curl_recv nss_recv;
-static Curl_send nss_send;
-
-static CURLcode nss_load_ca_certificates(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex)
+static CURLcode nss_load_ca_certificates(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- const char *cafile = SSL_CONN_CONFIG(CAfile);
- const char *capath = SSL_CONN_CONFIG(CApath);
+ struct ssl_connect_data *connssl = cf->ctx;
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ const char *cafile = conn_config->CAfile;
+ const char *capath = conn_config->CApath;
bool use_trust_module;
CURLcode result = CURLE_OK;
@@ -1723,7 +1715,7 @@ static CURLcode nss_load_ca_certificates(struct Curl_easy *data,
PR_Unlock(nss_trustload_lock);
if(cafile)
- result = nss_load_cert(&conn->ssl[sockindex], cafile, PR_TRUE);
+ result = nss_load_cert(connssl, cafile, PR_TRUE);
if(result)
return result;
@@ -1747,7 +1739,7 @@ static CURLcode nss_load_ca_certificates(struct Curl_easy *data,
return CURLE_OUT_OF_MEMORY;
}
- if(CURLE_OK != nss_load_cert(&conn->ssl[sockindex], fullpath, PR_TRUE))
+ if(CURLE_OK != nss_load_cert(connssl, fullpath, PR_TRUE))
/* This is purposefully tolerant of errors so non-PEM files can
* be in the same directory */
infof(data, "failed to load '%s' from CURLOPT_CAPATH", fullpath);
@@ -1808,12 +1800,13 @@ static CURLcode nss_sslver_from_curl(PRUint16 *nssver, long version)
}
static CURLcode nss_init_sslver(SSLVersionRange *sslver,
- struct Curl_easy *data,
- struct connectdata *conn)
+ struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
CURLcode result;
- const long min = SSL_CONN_CONFIG(version);
- const long max = SSL_CONN_CONFIG(version_max);
+ const long min = conn_config->version;
+ const long max = conn_config->version_max;
SSLVersionRange vrange;
switch(min) {
@@ -1848,10 +1841,11 @@ static CURLcode nss_init_sslver(SSLVersionRange *sslver,
return CURLE_OK;
}
-static CURLcode nss_fail_connect(struct ssl_connect_data *connssl,
+static CURLcode nss_fail_connect(struct Curl_cfilter *cf,
struct Curl_easy *data,
CURLcode curlerr)
{
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
@@ -1876,10 +1870,11 @@ static CURLcode nss_fail_connect(struct ssl_connect_data *connssl,
}
/* Switch the SSL socket into blocking or non-blocking mode. */
-static CURLcode nss_set_blocking(struct ssl_connect_data *connssl,
+static CURLcode nss_set_blocking(struct Curl_cfilter *cf,
struct Curl_easy *data,
bool blocking)
{
+ struct ssl_connect_data *connssl = cf->ctx;
PRSocketOptionData sock_opt;
struct ssl_backend_data *backend = connssl->backend;
@@ -1889,22 +1884,27 @@ static CURLcode nss_set_blocking(struct ssl_connect_data *connssl,
sock_opt.value.non_blocking = !blocking;
if(PR_SetSocketOption(backend->handle, &sock_opt) != PR_SUCCESS)
- return nss_fail_connect(connssl, data, CURLE_SSL_CONNECT_ERROR);
+ return nss_fail_connect(cf, data, CURLE_SSL_CONNECT_ERROR);
return CURLE_OK;
}
-static CURLcode nss_setup_connect(struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+static CURLcode nss_setup_connect(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
PRFileDesc *model = NULL;
PRFileDesc *nspr_io = NULL;
PRFileDesc *nspr_io_stub = NULL;
PRBool ssl_no_cache;
PRBool ssl_cbc_random_iv;
- curl_socket_t sockfd = conn->sock[sockindex];
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ curl_socket_t sockfd = cf->conn->sock[cf->sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
+ struct Curl_cfilter *cf_ssl_next = Curl_ssl_cf_get_ssl(cf->next);
+ struct ssl_connect_data *connssl_next = cf_ssl_next?
+ cf_ssl_next->ctx : NULL;
CURLcode result;
bool second_layer = FALSE;
SSLVersionRange sslver_supported;
@@ -1920,7 +1920,10 @@ static CURLcode nss_setup_connect(struct Curl_easy *data,
SSL_LIBRARY_VERSION_TLS_1_0
#endif
};
- char *snihost = Curl_ssl_snihost(data, SSL_HOST_NAME(), NULL);
+ const char *hostname = connssl->hostname;
+ char *snihost;
+
+ snihost = Curl_ssl_snihost(data, hostname, NULL);
if(!snihost) {
failf(data, "Failed to set SNI");
return CURLE_SSL_CONNECT_ERROR;
@@ -1965,13 +1968,13 @@ static CURLcode nss_setup_connect(struct Curl_easy *data,
goto error;
/* do not use SSL cache if disabled or we are not going to verify peer */
- ssl_no_cache = (SSL_SET_OPTION(primary.sessionid)
- && SSL_CONN_CONFIG(verifypeer)) ? PR_FALSE : PR_TRUE;
+ ssl_no_cache = (ssl_config->primary.sessionid
+ && conn_config->verifypeer) ? PR_FALSE : PR_TRUE;
if(SSL_OptionSet(model, SSL_NO_CACHE, ssl_no_cache) != SECSuccess)
goto error;
/* enable/disable the requested SSL version(s) */
- if(nss_init_sslver(&sslver, data, conn) != CURLE_OK)
+ if(nss_init_sslver(&sslver, cf, data) != CURLE_OK)
goto error;
if(SSL_VersionRangeGetSupported(ssl_variant_stream,
&sslver_supported) != SECSuccess)
@@ -1990,7 +1993,7 @@ static CURLcode nss_setup_connect(struct Curl_easy *data,
if(SSL_VersionRangeSet(model, &sslver) != SECSuccess)
goto error;
- ssl_cbc_random_iv = !SSL_SET_OPTION(enable_beast);
+ ssl_cbc_random_iv = !ssl_config->enable_beast;
#ifdef SSL_CBC_RANDOM_IV
/* unless the user explicitly asks to allow the protocol vulnerability, we
use the work-around */
@@ -2002,33 +2005,33 @@ static CURLcode nss_setup_connect(struct Curl_easy *data,
infof(data, "WARNING: support for SSL_CBC_RANDOM_IV not compiled in");
#endif
- if(SSL_CONN_CONFIG(cipher_list)) {
- if(set_ciphers(data, model, SSL_CONN_CONFIG(cipher_list)) != SECSuccess) {
+ if(conn_config->cipher_list) {
+ if(set_ciphers(data, model, conn_config->cipher_list) != SECSuccess) {
result = CURLE_SSL_CIPHER;
goto error;
}
}
- if(!SSL_CONN_CONFIG(verifypeer) && SSL_CONN_CONFIG(verifyhost))
+ if(!conn_config->verifypeer && conn_config->verifyhost)
infof(data, "WARNING: ignoring value of ssl.verifyhost");
/* bypass the default SSL_AuthCertificate() hook in case we do not want to
* verify peer */
- if(SSL_AuthCertificateHook(model, nss_auth_cert_hook, data) != SECSuccess)
+ if(SSL_AuthCertificateHook(model, nss_auth_cert_hook, cf) != SECSuccess)
goto error;
/* not checked yet */
- SSL_SET_OPTION_LVALUE(certverifyresult) = 0;
+ ssl_config->certverifyresult = 0;
- if(SSL_BadCertHook(model, BadCertHandler, data) != SECSuccess)
+ if(SSL_BadCertHook(model, BadCertHandler, cf) != SECSuccess)
goto error;
- if(SSL_HandshakeCallback(model, HandshakeCallback, data) != SECSuccess)
+ if(SSL_HandshakeCallback(model, HandshakeCallback, cf) != SECSuccess)
goto error;
{
- const CURLcode rv = nss_load_ca_certificates(data, conn, sockindex);
- if((rv == CURLE_SSL_CACERT_BADFILE) && !SSL_CONN_CONFIG(verifypeer))
+ const CURLcode rv = nss_load_ca_certificates(cf, data);
+ if((rv == CURLE_SSL_CACERT_BADFILE) && !conn_config->verifypeer)
/* not a fatal error because we are not going to verify the peer */
infof(data, "WARNING: CA certificates failed to load");
else if(rv) {
@@ -2037,25 +2040,25 @@ static CURLcode nss_setup_connect(struct Curl_easy *data,
}
}
- if(SSL_SET_OPTION(primary.CRLfile)) {
- const CURLcode rv = nss_load_crl(SSL_SET_OPTION(primary.CRLfile));
+ if(ssl_config->primary.CRLfile) {
+ const CURLcode rv = nss_load_crl(ssl_config->primary.CRLfile);
if(rv) {
result = rv;
goto error;
}
- infof(data, " CRLfile: %s", SSL_SET_OPTION(primary.CRLfile));
+ infof(data, " CRLfile: %s", ssl_config->primary.CRLfile);
}
- if(SSL_SET_OPTION(primary.clientcert)) {
- char *nickname = dup_nickname(data, SSL_SET_OPTION(primary.clientcert));
+ if(ssl_config->primary.clientcert) {
+ char *nickname = dup_nickname(data, ssl_config->primary.clientcert);
if(nickname) {
/* we are not going to use libnsspem.so to read the client cert */
backend->obj_clicert = NULL;
}
else {
- CURLcode rv = cert_stuff(data, conn, sockindex,
- SSL_SET_OPTION(primary.clientcert),
- SSL_SET_OPTION(key));
+ CURLcode rv = cert_stuff(cf, data,
+ ssl_config->primary.clientcert,
+ ssl_config->key);
if(rv) {
/* failf() is already done in cert_stuff() */
result = rv;
@@ -2075,17 +2078,19 @@ static CURLcode nss_setup_connect(struct Curl_easy *data,
goto error;
}
-#ifndef CURL_DISABLE_PROXY
- if(conn->proxy_ssl[sockindex].use) {
- struct ssl_backend_data *proxy_backend;
- proxy_backend = conn->proxy_ssl[sockindex].backend;
- DEBUGASSERT(ssl_connection_complete == conn->proxy_ssl[sockindex].state);
- DEBUGASSERT(proxy_backend);
- DEBUGASSERT(proxy_backend->handle);
- nspr_io = proxy_backend->handle;
+ /* Is there an SSL filter "in front" of us or are we writing directly
+ * to the socket? */
+ if(connssl_next) {
+ /* The filter should be connected by now, with full handshake */
+ DEBUGASSERT(connssl_next->backend->handle);
+ DEBUGASSERT(ssl_connection_complete == connssl_next->state);
+ /* We tell our NSS instance to use do IO with the 'next' NSS
+ * instance. This NSS instance will take ownership of the next
+ * one, including its destruction. We therefore need to `disown`
+ * the next filter's handle, once import succeeds. */
+ nspr_io = connssl_next->backend->handle;
second_layer = TRUE;
}
-#endif
else {
/* wrap OS file descriptor by NSPR's file descriptor abstraction */
nspr_io = PR_ImportTCPSocket(sockfd);
@@ -2122,14 +2127,16 @@ static CURLcode nss_setup_connect(struct Curl_easy *data,
PR_Close(model); /* We don't need this any more */
model = NULL;
+ if(connssl_next) /* steal the NSS handle we just imported successfully */
+ connssl_next->backend->handle = NULL;
/* This is the password associated with the cert that we're using */
- if(SSL_SET_OPTION(key_passwd)) {
- SSL_SetPKCS11PinArg(backend->handle, SSL_SET_OPTION(key_passwd));
+ if(ssl_config->key_passwd) {
+ SSL_SetPKCS11PinArg(backend->handle, ssl_config->key_passwd);
}
#ifdef SSL_ENABLE_OCSP_STAPLING
- if(SSL_CONN_CONFIG(verifystatus)) {
+ if(conn_config->verifystatus) {
if(SSL_OptionSet(backend->handle, SSL_ENABLE_OCSP_STAPLING, PR_TRUE)
!= SECSuccess)
goto error;
@@ -2137,8 +2144,9 @@ static CURLcode nss_setup_connect(struct Curl_easy *data,
#endif
#ifdef SSL_ENABLE_ALPN
- if(SSL_OptionSet(backend->handle, SSL_ENABLE_ALPN, conn->bits.tls_enable_alpn
- ? PR_TRUE : PR_FALSE) != SECSuccess)
+ if(SSL_OptionSet(backend->handle, SSL_ENABLE_ALPN,
+ cf->conn->bits.tls_enable_alpn ? PR_TRUE : PR_FALSE)
+ != SECSuccess)
goto error;
#endif
@@ -2155,14 +2163,14 @@ static CURLcode nss_setup_connect(struct Curl_easy *data,
#endif
#if defined(SSL_ENABLE_ALPN)
- if(conn->bits.tls_enable_alpn) {
+ if(cf->conn->bits.tls_enable_alpn) {
int cur = 0;
unsigned char protocols[128];
#ifdef USE_HTTP2
if(data->state.httpwant >= CURL_HTTP_VERSION_2
#ifndef CURL_DISABLE_PROXY
- && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
+ && (!Curl_ssl_cf_is_proxy(cf) || !cf->conn->bits.tunnel_proxy)
#endif
) {
protocols[cur++] = ALPN_H2_LENGTH;
@@ -2199,14 +2207,16 @@ error:
if(model)
PR_Close(model);
- return nss_fail_connect(connssl, data, result);
+ return nss_fail_connect(cf, data, result);
}
-static CURLcode nss_do_connect(struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+static CURLcode nss_do_connect(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
CURLcode result = CURLE_SSL_CONNECT_ERROR;
PRUint32 timeout;
@@ -2226,9 +2236,9 @@ static CURLcode nss_do_connect(struct Curl_easy *data,
if(PR_GetError() == PR_WOULD_BLOCK_ERROR)
/* blocking direction is updated by nss_update_connecting_state() */
return CURLE_AGAIN;
- else if(SSL_SET_OPTION(certverifyresult) == SSL_ERROR_BAD_CERT_DOMAIN)
+ else if(ssl_config->certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN)
result = CURLE_PEER_FAILED_VERIFICATION;
- else if(SSL_SET_OPTION(certverifyresult) != 0)
+ else if(ssl_config->certverifyresult)
result = CURLE_PEER_FAILED_VERIFICATION;
goto error;
}
@@ -2237,9 +2247,9 @@ static CURLcode nss_do_connect(struct Curl_easy *data,
if(result)
goto error;
- if(SSL_CONN_CONFIG(issuercert)) {
+ if(conn_config->issuercert) {
SECStatus ret = SECFailure;
- char *nickname = dup_nickname(data, SSL_CONN_CONFIG(issuercert));
+ char *nickname = dup_nickname(data, conn_config->issuercert);
if(nickname) {
/* we support only nicknames in case of issuercert for now */
ret = check_issuer_cert(backend->handle, nickname);
@@ -2256,7 +2266,9 @@ static CURLcode nss_do_connect(struct Curl_easy *data,
}
}
- result = cmp_peer_pubkey(connssl, SSL_PINNED_PUB_KEY());
+ result = cmp_peer_pubkey(connssl, Curl_ssl_cf_is_proxy(cf)?
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]:
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY]);
if(result)
/* status already printed */
goto error;
@@ -2264,14 +2276,14 @@ static CURLcode nss_do_connect(struct Curl_easy *data,
return CURLE_OK;
error:
- return nss_fail_connect(connssl, data, result);
+ return nss_fail_connect(cf, data, result);
}
-static CURLcode nss_connect_common(struct Curl_easy *data,
- struct connectdata *conn, int sockindex,
+static CURLcode nss_connect_common(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
bool *done)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
const bool blocking = (done == NULL);
CURLcode result;
@@ -2282,7 +2294,7 @@ static CURLcode nss_connect_common(struct Curl_easy *data,
}
if(connssl->connecting_state == ssl_connect_1) {
- result = nss_setup_connect(data, conn, sockindex);
+ result = nss_setup_connect(cf, data);
if(result)
/* we do not expect CURLE_AGAIN from nss_setup_connect() */
return result;
@@ -2291,11 +2303,11 @@ static CURLcode nss_connect_common(struct Curl_easy *data,
}
/* enable/disable blocking mode before handshake */
- result = nss_set_blocking(connssl, data, blocking);
+ result = nss_set_blocking(cf, data, blocking);
if(result)
return result;
- result = nss_do_connect(data, conn, sockindex);
+ result = nss_do_connect(cf, data);
switch(result) {
case CURLE_OK:
break;
@@ -2311,7 +2323,7 @@ static CURLcode nss_connect_common(struct Curl_easy *data,
if(blocking) {
/* in blocking mode, set NSS non-blocking mode _after_ SSL handshake */
- result = nss_set_blocking(connssl, data, /* blocking */ FALSE);
+ result = nss_set_blocking(cf, data, /* blocking */ FALSE);
if(result)
return result;
}
@@ -2327,30 +2339,30 @@ static CURLcode nss_connect_common(struct Curl_easy *data,
return CURLE_OK;
}
-static CURLcode nss_connect(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+static CURLcode nss_connect(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- return nss_connect_common(data, conn, sockindex, /* blocking */ NULL);
+ return nss_connect_common(cf, data, /* blocking */ NULL);
}
-static CURLcode nss_connect_nonblocking(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex, bool *done)
+static CURLcode nss_connect_nonblocking(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool *done)
{
- return nss_connect_common(data, conn, sockindex, done);
+ return nss_connect_common(cf, data, done);
}
-static ssize_t nss_send(struct Curl_easy *data, /* transfer */
- int sockindex, /* socketindex */
+static ssize_t nss_send(struct Curl_cfilter *cf,
+ struct Curl_easy *data, /* transfer */
const void *mem, /* send this data */
size_t len, /* amount to write */
CURLcode *curlcode)
{
- struct connectdata *conn = data->conn;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
ssize_t rc;
+ (void)data;
DEBUGASSERT(backend);
/* The SelectClientCert() hook uses this for infof() and failf() but the
@@ -2381,17 +2393,17 @@ static ssize_t nss_send(struct Curl_easy *data, /* transfer */
return rc; /* number of bytes */
}
-static ssize_t nss_recv(struct Curl_easy *data, /* transfer */
- int sockindex, /* socketindex */
+static ssize_t nss_recv(struct Curl_cfilter *cf,
+ struct Curl_easy *data, /* transfer */
char *buf, /* store read data here */
size_t buffersize, /* max amount to read */
CURLcode *curlcode)
{
- struct connectdata *conn = data->conn;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
ssize_t nread;
+ (void)data;
DEBUGASSERT(backend);
/* The SelectClientCert() hook uses this for infof() and failf() but the
@@ -2496,6 +2508,25 @@ static void *nss_get_internals(struct ssl_connect_data *connssl,
return backend->handle;
}
+static bool nss_attach_data(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
+{
+ struct ssl_connect_data *connssl = cf->ctx;
+
+ if(!connssl->backend->data)
+ connssl->backend->data = data;
+ return TRUE;
+}
+
+static void nss_detach_data(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
+{
+ struct ssl_connect_data *connssl = cf->ctx;
+
+ if(connssl->backend->data == data)
+ connssl->backend->data = NULL;
+}
+
const struct Curl_ssl Curl_ssl_nss = {
{ CURLSSLBACKEND_NSS, "nss" }, /* info */
@@ -2517,7 +2548,7 @@ const struct Curl_ssl Curl_ssl_nss = {
nss_cert_status_request, /* cert_status_request */
nss_connect, /* connect */
nss_connect_nonblocking, /* connect_nonblocking */
- Curl_ssl_getsock, /* getsock */
+ Curl_ssl_get_select_socks, /* getsock */
nss_get_internals, /* get_internals */
nss_close, /* close_one */
Curl_none_close_all, /* close_all */
@@ -2528,8 +2559,8 @@ const struct Curl_ssl Curl_ssl_nss = {
Curl_none_engines_list, /* engines_list */
nss_false_start, /* false_start */
nss_sha256sum, /* sha256sum */
- NULL, /* associate_connection */
- NULL, /* disassociate_connection */
+ nss_attach_data, /* associate_connection */
+ nss_detach_data, /* disassociate_connection */
NULL, /* free_multi_ssl_backend_data */
nss_recv, /* recv decrypted data */
nss_send, /* send data to encrypt */
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index 70a761bc1..2c4f3dff1 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -269,6 +269,13 @@
#define HAVE_SSL_X509_STORE_SHARE
#endif
+/* What API version do we use? */
+#if defined(LIBRESSL_VERSION_NUMBER)
+#define USE_PRE_1_1_API (LIBRESSL_VERSION_NUMBER < 0x2070000f)
+#else /* !LIBRESSL_VERSION_NUMBER */
+#define USE_PRE_1_1_API (OPENSSL_VERSION_NUMBER < 0x10100000L)
+#endif /* !LIBRESSL_VERSION_NUMBER */
+
struct ssl_backend_data {
struct Curl_easy *logger; /* transfer handle to pass trace logs to, only
using sockindex 0 */
@@ -628,9 +635,8 @@ CURLcode Curl_ossl_certchain(struct Curl_easy *data, SSL *ssl)
#ifdef USE_OPENSSL
-static bool ossl_associate_connection(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex);
+static bool ossl_attach_data(struct Curl_cfilter *cf,
+ struct Curl_easy *data);
/*
* Number of bytes to read from the random number seed file. This must be
@@ -762,16 +768,16 @@ static int ossl_get_ssl_data_index(void)
return ssl_ex_data_data_index;
}
-/* Return an extra data index for the connection data.
+/* Return an extra data index for the associated Curl_cfilter instance.
* This index can be used with SSL_get_ex_data() and SSL_set_ex_data().
*/
-static int ossl_get_ssl_conn_index(void)
+static int ossl_get_ssl_cf_index(void)
{
- static int ssl_ex_data_conn_index = -1;
- if(ssl_ex_data_conn_index < 0) {
- ssl_ex_data_conn_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
+ static int ssl_ex_data_cf_index = -1;
+ if(ssl_ex_data_cf_index < 0) {
+ ssl_ex_data_cf_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
}
- return ssl_ex_data_conn_index;
+ return ssl_ex_data_cf_index;
}
/* Return an extra data index for the sockindex.
@@ -1599,7 +1605,7 @@ static int ossl_init(void)
Curl_tls_keylog_open();
/* Initialize the extra data indexes */
- if(ossl_get_ssl_data_index() < 0 || ossl_get_ssl_conn_index() < 0 ||
+ if(ossl_get_ssl_data_index() < 0 || ossl_get_ssl_cf_index() < 0 ||
ossl_get_ssl_sockindex_index() < 0 || ossl_get_proxy_index() < 0)
return 0;
@@ -1651,15 +1657,16 @@ static void ossl_cleanup(void)
* 0 means the connection has been closed
* -1 means the connection status is unknown
*/
-static int ossl_check_cxn(struct connectdata *conn)
+static int ossl_check_cxn(struct Curl_cfilter *cf, struct Curl_easy *data)
{
/* SSL_peek takes data out of the raw recv buffer without peeking so we use
recv MSG_PEEK instead. Bug #795 */
#ifdef MSG_PEEK
char buf;
ssize_t nread;
- nread = recv((RECV_TYPE_ARG1)conn->sock[FIRSTSOCKET], (RECV_TYPE_ARG2)&buf,
- (RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK);
+ nread = recv((RECV_TYPE_ARG1)cf->conn->sock[cf->sockindex],
+ (RECV_TYPE_ARG2)&buf, (RECV_TYPE_ARG3)1,
+ (RECV_TYPE_ARG4)MSG_PEEK);
if(nread == 0)
return 0; /* connection has been closed */
if(nread == 1)
@@ -1692,6 +1699,7 @@ static int ossl_check_cxn(struct connectdata *conn)
return 0; /* connection has been closed */
}
#endif
+ (void)data;
return -1; /* connection status unknown */
}
@@ -1784,26 +1792,25 @@ static struct curl_slist *ossl_engines_list(struct Curl_easy *data)
return list;
}
-#define set_logger(conn, data) \
- conn->ssl[0].backend->logger = data
+#define set_logger(connssl, data) \
+ connssl->backend->logger = data
-static void ossl_closeone(struct Curl_easy *data,
- struct connectdata *conn,
- struct ssl_connect_data *connssl)
+static void ossl_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
if(backend->handle) {
char buf[32];
- set_logger(conn, data);
+ set_logger(connssl, data);
/*
* The conn->sock[0] socket is passed to openssl with SSL_set_fd(). Make
* sure the socket is not closed before calling OpenSSL functions that
* will use it.
*/
- DEBUGASSERT(conn->sock[FIRSTSOCKET] != CURL_SOCKET_BAD);
+ DEBUGASSERT(cf->conn->sock[FIRSTSOCKET] != CURL_SOCKET_BAD);
/* Maybe the server has already sent a close notify alert.
Read it to avoid an RST on the TCP connection. */
@@ -1822,26 +1829,14 @@ static void ossl_closeone(struct Curl_easy *data,
}
/*
- * This function is called when an SSL connection is closed.
- */
-static void ossl_close(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
-{
- ossl_closeone(data, conn, &conn->ssl[sockindex]);
-#ifndef CURL_DISABLE_PROXY
- ossl_closeone(data, conn, &conn->proxy_ssl[sockindex]);
-#endif
-}
-
-/*
* This function is called to shut down the SSL layer but keep the
* socket open (CCC - Clear Command Channel)
*/
-static int ossl_shutdown(struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+static int ossl_shutdown(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
int retval = 0;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
char buf[256]; /* We will use this for the OpenSSL error buffer, so it has
to be at least 256 bytes long. */
unsigned long sslerror;
@@ -1867,7 +1862,7 @@ static int ossl_shutdown(struct Curl_easy *data,
if(backend->handle) {
buffsize = (int)sizeof(buf);
while(!done && loop--) {
- int what = SOCKET_READABLE(conn->sock[sockindex],
+ int what = SOCKET_READABLE(cf->conn->sock[cf->sockindex],
SSL_SHUTDOWN_TIMEOUT);
if(what > 0) {
ERR_clear_error();
@@ -2033,9 +2028,12 @@ CURLcode Curl_ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
CURLcode result = CURLE_OK;
bool dNSName = FALSE; /* if a dNSName field exists in the cert */
bool iPAddress = FALSE; /* if a iPAddress field exists in the cert */
- const char * const hostname = SSL_HOST_NAME();
- const char * const dispname = SSL_HOST_DISPNAME();
- size_t hostlen = strlen(hostname);
+ const char *hostname, *dispname;
+ int port;
+ size_t hostlen;
+
+ Curl_conn_get_host(data, FIRSTSOCKET, &hostname, &dispname, &port);
+ hostlen = strlen(hostname);
#ifdef ENABLE_IPV6
if(conn->bits.ipv6_ip &&
@@ -2211,9 +2209,10 @@ CURLcode Curl_ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
!defined(OPENSSL_NO_OCSP)
-static CURLcode verifystatus(struct Curl_easy *data,
- struct ssl_connect_data *connssl)
+static CURLcode verifystatus(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
+ struct ssl_connect_data *connssl = cf->ctx;
int i, ocsp_status;
unsigned char *status;
const unsigned char *p;
@@ -2494,18 +2493,24 @@ static void ossl_trace(int direction, int ssl_ver, int content_type,
char unknown[32];
const char *verstr = NULL;
struct connectdata *conn = userp;
- struct ssl_connect_data *connssl = &conn->ssl[0];
- struct ssl_backend_data *backend = connssl->backend;
+ int cf_idx = ossl_get_ssl_cf_index();
+ struct ssl_connect_data *connssl;
struct Curl_easy *data = NULL;
+ struct Curl_cfilter *cf;
- DEBUGASSERT(backend);
- data = backend->logger;
+ DEBUGASSERT(cf_idx >= 0);
+ cf = (struct Curl_cfilter*) SSL_get_ex_data(ssl, cf_idx);
+ DEBUGASSERT(cf);
+ connssl = cf->ctx;
+ DEBUGASSERT(connssl);
+ DEBUGASSERT(connssl->backend);
+ data = connssl->backend->logger;
if(!conn || !data || !data->set.fdebug ||
(direction != 0 && direction != 1))
return;
- switch(ssl_ver) {
+ switch(ssl_ver) {
#ifdef SSL2_VERSION /* removed in recent versions */
case SSL2_VERSION:
verstr = "SSLv2";
@@ -2581,7 +2586,8 @@ static void ossl_trace(int direction, int ssl_ver, int content_type,
msg_name = ssl_msg_type(ssl_ver, msg_type);
}
- txt_len = msnprintf(ssl_buf, sizeof(ssl_buf), "%s (%s), %s, %s (%d):\n",
+ txt_len = msnprintf(ssl_buf, sizeof(ssl_buf),
+ CFMSG(cf, "%s (%s), %s, %s (%d):\n"),
verstr, direction?"OUT":"IN",
tls_rt_name, msg_name, msg_type);
if(0 <= txt_len && (unsigned)txt_len < sizeof(ssl_buf)) {
@@ -2613,10 +2619,11 @@ static void ossl_trace(int direction, int ssl_ver, int content_type,
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */
static CURLcode
-set_ssl_version_min_max(SSL_CTX *ctx, struct connectdata *conn)
+set_ssl_version_min_max(struct Curl_cfilter *cf, SSL_CTX *ctx)
{
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
/* first, TLS min version... */
- long curl_ssl_version_min = SSL_CONN_CONFIG(version);
+ long curl_ssl_version_min = conn_config->version;
long curl_ssl_version_max;
/* convert curl min SSL version option to OpenSSL constant */
@@ -2660,7 +2667,7 @@ set_ssl_version_min_max(SSL_CTX *ctx, struct connectdata *conn)
}
/* ... then, TLS max version */
- curl_ssl_version_max = SSL_CONN_CONFIG(version_max);
+ curl_ssl_version_max = conn_config->version_max;
/* convert curl max SSL version option to OpenSSL constant */
switch(curl_ssl_version_max) {
@@ -2708,11 +2715,12 @@ typedef long ctx_option_t;
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) /* 1.1.0 */
static CURLcode
set_ssl_version_min_max_legacy(ctx_option_t *ctx_options,
- struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+ struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- long ssl_version = SSL_CONN_CONFIG(version);
- long ssl_version_max = SSL_CONN_CONFIG(version_max);
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ long ssl_version = conn_config->version;
+ long ssl_version_max = conn_config->version_max;
(void) data; /* In case it's unused. */
@@ -2720,14 +2728,12 @@ set_ssl_version_min_max_legacy(ctx_option_t *ctx_options,
case CURL_SSLVERSION_TLSv1_3:
#ifdef TLS1_3_VERSION
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- struct ssl_backend_data *backend = connssl->backend;
- DEBUGASSERT(backend);
- SSL_CTX_set_max_proto_version(backend->ctx, TLS1_3_VERSION);
+ struct ssl_connect_data *connssl = cf->ctx;
+ DEBUGASSERT(connssl->backend);
+ SSL_CTX_set_max_proto_version(connssl->backend->ctx, TLS1_3_VERSION);
*ctx_options |= SSL_OP_NO_TLSv1_2;
}
#else
- (void)sockindex;
(void)ctx_options;
failf(data, OSSL_PACKAGE " was built without TLS 1.3 support");
return CURLE_NOT_BUILT_IN;
@@ -2788,31 +2794,30 @@ set_ssl_version_min_max_legacy(ctx_option_t *ctx_options,
static int ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid)
{
int res = 0;
- struct connectdata *conn;
struct Curl_easy *data;
- int sockindex;
+ struct Curl_cfilter *cf;
+ const struct ssl_config_data *config;
curl_socket_t *sockindex_ptr;
int data_idx = ossl_get_ssl_data_index();
- int connectdata_idx = ossl_get_ssl_conn_index();
+ int cf_idx = ossl_get_ssl_cf_index();
int sockindex_idx = ossl_get_ssl_sockindex_index();
int proxy_idx = ossl_get_proxy_index();
bool isproxy;
- if(data_idx < 0 || connectdata_idx < 0 || sockindex_idx < 0 || proxy_idx < 0)
+ if(data_idx < 0 || cf_idx < 0 || sockindex_idx < 0 || proxy_idx < 0)
return 0;
- conn = (struct connectdata*) SSL_get_ex_data(ssl, connectdata_idx);
+ cf = (struct Curl_cfilter*) SSL_get_ex_data(ssl, cf_idx);
data = (struct Curl_easy *) SSL_get_ex_data(ssl, data_idx);
/* The sockindex has been stored as a pointer to an array element */
sockindex_ptr = (curl_socket_t*) SSL_get_ex_data(ssl, sockindex_idx);
- if(!conn || !data || !sockindex_ptr)
+ if(!cf || !data || !sockindex_ptr)
return 0;
- sockindex = (int)(sockindex_ptr - conn->sock);
-
- isproxy = SSL_get_ex_data(ssl, proxy_idx) ? TRUE : FALSE;
+ isproxy = Curl_ssl_cf_is_proxy(cf);
- if(SSL_SET_OPTION(primary.sessionid)) {
+ config = Curl_ssl_cf_get_config(cf, data);
+ if(config->primary.sessionid) {
bool incache;
bool added = FALSE;
void *old_ssl_sessionid = NULL;
@@ -2821,8 +2826,7 @@ static int ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid)
if(isproxy)
incache = FALSE;
else
- incache = !(Curl_ssl_getsessionid(data, conn, isproxy,
- &old_ssl_sessionid, NULL, sockindex));
+ incache = !(Curl_ssl_getsessionid(cf, data, &old_ssl_sessionid, NULL));
if(incache) {
if(old_ssl_sessionid != ssl_sessionid) {
infof(data, "old SSL session ID is stale, removing");
@@ -2832,8 +2836,8 @@ static int ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid)
}
if(!incache) {
- if(!Curl_ssl_addsessionid(data, conn, isproxy, ssl_sessionid,
- 0 /* unknown size */, sockindex, &added)) {
+ if(!Curl_ssl_addsessionid(cf, data, ssl_sessionid,
+ 0 /* unknown size */, &added)) {
if(added) {
/* the session has been put into the session cache */
res = 1;
@@ -2904,19 +2908,21 @@ static CURLcode load_cacert_from_memory(X509_STORE *store,
return (count > 0 ? CURLE_OK : CURLE_SSL_CACERT_BADFILE);
}
-static CURLcode populate_x509_store(struct Curl_easy *data,
- struct connectdata *conn,
+static CURLcode populate_x509_store(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
X509_STORE *store)
{
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
CURLcode result = CURLE_OK;
X509_LOOKUP *lookup = NULL;
- const struct curl_blob *ca_info_blob = SSL_CONN_CONFIG(ca_info_blob);
+ const struct curl_blob *ca_info_blob = conn_config->ca_info_blob;
const char * const ssl_cafile =
/* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */
- (ca_info_blob ? NULL : SSL_CONN_CONFIG(CAfile));
- const char * const ssl_capath = SSL_CONN_CONFIG(CApath);
- const char * const ssl_crlfile = SSL_SET_OPTION(primary.CRLfile);
- const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
+ (ca_info_blob ? NULL : conn_config->CAfile);
+ const char * const ssl_capath = conn_config->CApath;
+ const char * const ssl_crlfile = ssl_config->primary.CRLfile;
+ const bool verifypeer = conn_config->verifypeer;
bool imported_native_ca = false;
if(!store)
@@ -2927,8 +2933,8 @@ static CURLcode populate_x509_store(struct Curl_easy *data,
https://stackoverflow.com/questions/9507184/
https://github.com/d3x0r/SACK/blob/master/src/netlib/ssl_layer.c#L1037
https://datatracker.ietf.org/doc/html/rfc5280 */
- if((SSL_CONN_CONFIG(verifypeer) || SSL_CONN_CONFIG(verifyhost)) &&
- (SSL_SET_OPTION(native_ca_store))) {
+ if((conn_config->verifypeer || conn_config->verifyhost) &&
+ (ssl_config->native_ca_store)) {
HCERTSTORE hStore = CertOpenSystemStore(0, TEXT("ROOT"));
if(hStore) {
@@ -3147,7 +3153,7 @@ static CURLcode populate_x509_store(struct Curl_easy *data,
X509_STORE_set_flags(store, X509_V_FLAG_TRUSTED_FIRST);
#endif
#ifdef X509_V_FLAG_PARTIAL_CHAIN
- if(!SSL_SET_OPTION(no_partialchain) && !ssl_crlfile) {
+ if(!ssl_config->no_partialchain && !ssl_crlfile) {
/* Have intermediate certificates in the trust store be treated as
trust-anchors, in the same way as self-signed root CA certificates
are. This allows users to verify servers using the intermediate cert
@@ -3180,17 +3186,18 @@ static bool cached_x509_store_expired(const struct Curl_easy *data,
}
static bool cached_x509_store_different(
- const struct multi_ssl_backend_data *mb,
- const struct connectdata *conn)
+ struct Curl_cfilter *cf,
+ const struct multi_ssl_backend_data *mb)
{
- if(!mb->CAfile || !SSL_CONN_CONFIG(CAfile))
- return mb->CAfile != SSL_CONN_CONFIG(CAfile);
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ if(!mb->CAfile || !conn_config->CAfile)
+ return mb->CAfile != conn_config->CAfile;
- return strcmp(mb->CAfile, SSL_CONN_CONFIG(CAfile));
+ return strcmp(mb->CAfile, conn_config->CAfile);
}
-static X509_STORE *get_cached_x509_store(const struct Curl_easy *data,
- const struct connectdata *conn)
+static X509_STORE *get_cached_x509_store(struct Curl_cfilter *cf,
+ const struct Curl_easy *data)
{
struct Curl_multi *multi = data->multi_easy ? data->multi_easy : data->multi;
X509_STORE *store = NULL;
@@ -3199,17 +3206,18 @@ static X509_STORE *get_cached_x509_store(const struct Curl_easy *data,
multi->ssl_backend_data &&
multi->ssl_backend_data->store &&
!cached_x509_store_expired(data, multi->ssl_backend_data) &&
- !cached_x509_store_different(multi->ssl_backend_data, conn)) {
+ !cached_x509_store_different(cf, multi->ssl_backend_data)) {
store = multi->ssl_backend_data->store;
}
return store;
}
-static void set_cached_x509_store(const struct Curl_easy *data,
- const struct connectdata *conn,
+static void set_cached_x509_store(struct Curl_cfilter *cf,
+ const struct Curl_easy *data,
X509_STORE *store)
{
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
struct Curl_multi *multi = data->multi_easy ? data->multi_easy : data->multi;
struct multi_ssl_backend_data *mbackend;
@@ -3227,8 +3235,8 @@ static void set_cached_x509_store(const struct Curl_easy *data,
if(X509_STORE_up_ref(store)) {
char *CAfile = NULL;
- if(SSL_CONN_CONFIG(CAfile)) {
- CAfile = strdup(SSL_CONN_CONFIG(CAfile));
+ if(conn_config->CAfile) {
+ CAfile = strdup(conn_config->CAfile);
if(!CAfile) {
X509_STORE_free(store);
return;
@@ -3246,10 +3254,12 @@ static void set_cached_x509_store(const struct Curl_easy *data,
}
}
-static CURLcode set_up_x509_store(struct Curl_easy *data,
- struct connectdata *conn,
+static CURLcode set_up_x509_store(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
struct ssl_backend_data *backend)
{
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
CURLcode result = CURLE_OK;
X509_STORE *cached_store;
bool cache_criteria_met;
@@ -3258,52 +3268,57 @@ static CURLcode set_up_x509_store(struct Curl_easy *data,
or no source is provided and we are falling back to openssl's built-in
default. */
cache_criteria_met = (data->set.general_ssl.ca_cache_timeout != 0) &&
- SSL_CONN_CONFIG(verifypeer) &&
- !SSL_CONN_CONFIG(CApath) &&
- !SSL_CONN_CONFIG(ca_info_blob) &&
- !SSL_SET_OPTION(primary.CRLfile) &&
- !SSL_SET_OPTION(native_ca_store);
+ conn_config->verifypeer &&
+ !conn_config->CApath &&
+ !conn_config->ca_info_blob &&
+ !ssl_config->primary.CRLfile &&
+ !ssl_config->native_ca_store;
- cached_store = get_cached_x509_store(data, conn);
+ cached_store = get_cached_x509_store(cf, data);
if(cached_store && cache_criteria_met && X509_STORE_up_ref(cached_store)) {
SSL_CTX_set_cert_store(backend->ctx, cached_store);
}
else {
X509_STORE *store = SSL_CTX_get_cert_store(backend->ctx);
- result = populate_x509_store(data, conn, store);
+ result = populate_x509_store(cf, data, store);
if(result == CURLE_OK && cache_criteria_met) {
- set_cached_x509_store(data, conn, store);
+ set_cached_x509_store(cf, data, store);
}
}
return result;
}
#else /* HAVE_SSL_X509_STORE_SHARE */
-static CURLcode set_up_x509_store(struct Curl_easy *data,
- struct connectdata *conn,
+static CURLcode set_up_x509_store(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
struct ssl_backend_data *backend)
{
X509_STORE *store = SSL_CTX_get_cert_store(backend->ctx);
- return populate_x509_store(data, conn, store);
+ return populate_x509_store(cf, data, store);
}
#endif /* HAVE_SSL_X509_STORE_SHARE */
-static CURLcode ossl_connect_step1(struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+static CURLcode ossl_connect_step1(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
CURLcode result = CURLE_OK;
char *ciphers;
SSL_METHOD_QUAL SSL_METHOD *req_method = NULL;
- curl_socket_t sockfd = conn->sock[sockindex];
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ curl_socket_t sockfd = cf->conn->sock[cf->sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
ctx_option_t ctx_options = 0;
void *ssl_sessionid = NULL;
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
+ struct Curl_cfilter *cf_ssl_next = Curl_ssl_cf_get_ssl(cf->next);
+ struct ssl_connect_data *connssl_next = cf_ssl_next?
+ cf_ssl_next->ctx : NULL;
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
bool sni;
- const char * const hostname = SSL_HOST_NAME();
+ const char *hostname = connssl->hostname;
#ifdef ENABLE_IPV6
struct in6_addr addr;
@@ -3311,14 +3326,14 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
struct in_addr addr;
#endif
#endif
- const long int ssl_version = SSL_CONN_CONFIG(version);
+ const long int ssl_version = conn_config->version;
#ifdef USE_OPENSSL_SRP
- const enum CURL_TLSAUTH ssl_authtype = SSL_SET_OPTION(primary.authtype);
+ const enum CURL_TLSAUTH ssl_authtype = ssl_config->primary.authtype;
#endif
- char * const ssl_cert = SSL_SET_OPTION(primary.clientcert);
- const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob);
- const char * const ssl_cert_type = SSL_SET_OPTION(cert_type);
- const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
+ char * const ssl_cert = ssl_config->primary.clientcert;
+ const struct curl_blob *ssl_cert_blob = ssl_config->primary.cert_blob;
+ const char * const ssl_cert_type = ssl_config->cert_type;
+ const bool verifypeer = conn_config->verifypeer;
char error_buffer[256];
struct ssl_backend_data *backend = connssl->backend;
@@ -3330,7 +3345,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
if(result)
return result;
- SSL_SET_OPTION_LVALUE(certverifyresult) = !X509_V_OK;
+ ssl_config->certverifyresult = !X509_V_OK;
/* check to see if we've been told to use an explicit SSL/TLS version */
@@ -3377,8 +3392,8 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
if(data->set.fdebug && data->set.verbose) {
/* the SSL trace callback is only used for verbose logging */
SSL_CTX_set_msg_callback(backend->ctx, ossl_trace);
- SSL_CTX_set_msg_callback_arg(backend->ctx, conn);
- set_logger(conn, data);
+ SSL_CTX_set_msg_callback_arg(backend->ctx, cf->conn);
+ set_logger(connssl, data);
}
#endif
@@ -3436,7 +3451,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
/* unless the user explicitly asks to allow the protocol vulnerability we
use the work-around */
- if(!SSL_SET_OPTION(enable_beast))
+ if(!ssl_config->enable_beast)
ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
#endif
@@ -3458,10 +3473,9 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
ctx_options |= SSL_OP_NO_SSLv3;
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */
- result = set_ssl_version_min_max(backend->ctx, conn);
+ result = set_ssl_version_min_max(cf, backend->ctx);
#else
- result = set_ssl_version_min_max_legacy(&ctx_options, data, conn,
- sockindex);
+ result = set_ssl_version_min_max_legacy(&ctx_options, cf, data);
#endif
if(result != CURLE_OK)
return result;
@@ -3475,14 +3489,14 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
SSL_CTX_set_options(backend->ctx, ctx_options);
#ifdef HAS_ALPN
- if(conn->bits.tls_enable_alpn) {
+ if(cf->conn->bits.tls_enable_alpn) {
int cur = 0;
unsigned char protocols[128];
#ifdef USE_HTTP2
if(data->state.httpwant >= CURL_HTTP_VERSION_2
#ifndef CURL_DISABLE_PROXY
- && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
+ && (!Curl_ssl_cf_is_proxy(cf) || !cf->conn->bits.tunnel_proxy)
#endif
) {
protocols[cur++] = ALPN_H2_LENGTH;
@@ -3512,15 +3526,15 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
if(!result &&
!cert_stuff(data, backend->ctx,
ssl_cert, ssl_cert_blob, ssl_cert_type,
- SSL_SET_OPTION(key), SSL_SET_OPTION(key_blob),
- SSL_SET_OPTION(key_type), SSL_SET_OPTION(key_passwd)))
+ ssl_config->key, ssl_config->key_blob,
+ ssl_config->key_type, ssl_config->key_passwd))
result = CURLE_SSL_CERTPROBLEM;
if(result)
/* failf() is already done in cert_stuff() */
return result;
}
- ciphers = SSL_CONN_CONFIG(cipher_list);
+ ciphers = conn_config->cipher_list;
if(!ciphers)
ciphers = (char *)DEFAULT_CIPHER_SELECTION;
if(ciphers) {
@@ -3533,7 +3547,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
{
- char *ciphers13 = SSL_CONN_CONFIG(cipher_list13);
+ char *ciphers13 = conn_config->cipher_list13;
if(ciphers13) {
if(!SSL_CTX_set_ciphersuites(backend->ctx, ciphers13)) {
failf(data, "failed setting TLS 1.3 cipher suite: %s", ciphers13);
@@ -3551,7 +3565,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
#ifdef HAVE_SSL_CTX_SET_EC_CURVES
{
- char *curves = SSL_CONN_CONFIG(curves);
+ char *curves = conn_config->curves;
if(curves) {
if(!SSL_CTX_set1_curves_list(backend->ctx, curves)) {
failf(data, "failed setting curves list: '%s'", curves);
@@ -3564,8 +3578,8 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
#ifdef USE_OPENSSL_SRP
if((ssl_authtype == CURL_TLSAUTH_SRP) &&
Curl_auth_allowed_to_host(data)) {
- char * const ssl_username = SSL_SET_OPTION(primary.username);
- char * const ssl_password = SSL_SET_OPTION(primary.password);
+ char * const ssl_username = ssl_config->primary.username;
+ char * const ssl_password = ssl_config->primary.password;
infof(data, "Using TLS-SRP username: %s", ssl_username);
if(!SSL_CTX_set_srp_username(backend->ctx, ssl_username)) {
@@ -3576,7 +3590,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
failf(data, "failed setting SRP password");
return CURLE_BAD_FUNCTION_ARGUMENT;
}
- if(!SSL_CONN_CONFIG(cipher_list)) {
+ if(!conn_config->cipher_list) {
infof(data, "Setting cipher list SRP");
if(!SSL_CTX_set_cipher_list(backend->ctx, "SRP")) {
@@ -3587,7 +3601,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
}
#endif
- result = set_up_x509_store(data, conn, backend);
+ result = set_up_x509_store(cf, data, backend);
if(result)
return result;
@@ -3636,7 +3650,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
!defined(OPENSSL_NO_OCSP)
- if(SSL_CONN_CONFIG(verifystatus))
+ if(conn_config->verifystatus)
SSL_set_tlsext_status_type(backend->handle, TLSEXT_STATUSTYPE_ocsp);
#endif
@@ -3661,18 +3675,17 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
}
#endif
- if(!ossl_associate_connection(data, conn, sockindex)) {
+ if(!ossl_attach_data(cf, data)) {
/* Maybe the internal errors of SSL_get_ex_new_index or SSL_set_ex_data */
- failf(data, "SSL: ossl_associate_connection failed: %s",
+ failf(data, "SSL: ossl_attach_data failed: %s",
ossl_strerror(ERR_get_error(), error_buffer,
sizeof(error_buffer)));
return CURLE_SSL_CONNECT_ERROR;
}
- if(SSL_SET_OPTION(primary.sessionid)) {
+ if(ssl_config->primary.sessionid) {
Curl_ssl_sessionid_lock(data);
- if(!Curl_ssl_getsessionid(data, conn, SSL_IS_PROXY() ? TRUE : FALSE,
- &ssl_sessionid, NULL, sockindex)) {
+ if(!Curl_ssl_getsessionid(cf, data, &ssl_sessionid, NULL)) {
/* we got a session id, use it! */
if(!SSL_set_session(backend->handle, ssl_sessionid)) {
Curl_ssl_sessionid_unlock(data);
@@ -3688,17 +3701,13 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
}
#ifndef CURL_DISABLE_PROXY
- if(conn->proxy_ssl[sockindex].use) {
+ if(connssl_next) {
BIO *const bio = BIO_new(BIO_f_ssl());
- struct ssl_backend_data *proxy_backend;
- SSL* handle = NULL;
- proxy_backend = conn->proxy_ssl[sockindex].backend;
- DEBUGASSERT(proxy_backend);
- handle = proxy_backend->handle;
- DEBUGASSERT(ssl_connection_complete == conn->proxy_ssl[sockindex].state);
- DEBUGASSERT(handle != NULL);
+ DEBUGASSERT(connssl_next->backend);
+ DEBUGASSERT(ssl_connection_complete == connssl_next->state);
+ DEBUGASSERT(connssl_next->backend->handle != NULL);
DEBUGASSERT(bio != NULL);
- BIO_set_ssl(bio, handle, FALSE);
+ BIO_set_ssl(bio, connssl_next->backend->handle, FALSE);
SSL_set_bio(backend->handle, bio, bio);
}
else
@@ -3715,12 +3724,13 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
return CURLE_OK;
}
-static CURLcode ossl_connect_step2(struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+static CURLcode ossl_connect_step2(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
int err;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
|| ssl_connect_2_reading == connssl->connecting_state
|| ssl_connect_2_writing == connssl->connecting_state);
@@ -3785,7 +3795,7 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data,
lerr = SSL_get_verify_result(backend->handle);
if(lerr != X509_V_OK) {
- SSL_SET_OPTION_LVALUE(certverifyresult) = lerr;
+ ssl_config->certverifyresult = lerr;
msnprintf(error_buffer, sizeof(error_buffer),
"SSL certificate problem: %s",
X509_verify_cert_error_string(lerr));
@@ -3820,15 +3830,14 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data,
* the SO_ERROR is also lost.
*/
if(CURLE_SSL_CONNECT_ERROR == result && errdetail == 0) {
- const char * const hostname = SSL_HOST_NAME();
- const long int port = SSL_HOST_PORT();
char extramsg[80]="";
int sockerr = SOCKERRNO;
+
if(sockerr && detail == SSL_ERROR_SYSCALL)
Curl_strerror(sockerr, extramsg, sizeof(extramsg));
failf(data, OSSL_PACKAGE " SSL_connect: %s in connection to %s:%ld ",
extramsg[0] ? extramsg : SSL_ERROR_to_str(detail),
- hostname, port);
+ connssl->hostname, connssl->port);
return result;
}
@@ -3851,7 +3860,7 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data,
/* Sets data and len to negotiated protocol, len is 0 if no protocol was
* negotiated
*/
- if(conn->bits.tls_enable_alpn) {
+ if(cf->conn->bits.tls_enable_alpn) {
const unsigned char *neg_protocol;
unsigned int len;
SSL_get0_alpn_selected(backend->handle, &neg_protocol, &len);
@@ -3861,19 +3870,19 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data,
#ifdef USE_HTTP2
if(len == ALPN_H2_LENGTH &&
!memcmp(ALPN_H2, neg_protocol, len)) {
- conn->alpn = CURL_HTTP_VERSION_2;
+ cf->conn->alpn = CURL_HTTP_VERSION_2;
}
else
#endif
if(len == ALPN_HTTP_1_1_LENGTH &&
!memcmp(ALPN_HTTP_1_1, neg_protocol, ALPN_HTTP_1_1_LENGTH)) {
- conn->alpn = CURL_HTTP_VERSION_1_1;
+ cf->conn->alpn = CURL_HTTP_VERSION_1_1;
}
}
else
infof(data, VTLS_INFOF_NO_ALPN);
- Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ?
+ Curl_multiuse_state(data, cf->conn->alpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
#endif
@@ -3948,11 +3957,14 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, X509* cert,
* We check certificates to authenticate the server; otherwise we risk
* man-in-the-middle attack.
*/
-static CURLcode servercert(struct Curl_easy *data,
- struct connectdata *conn,
- struct ssl_connect_data *connssl,
+static CURLcode servercert(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
bool strict)
{
+ struct connectdata *conn = cf->conn;
+ struct ssl_connect_data *connssl = cf->ctx;
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
CURLcode result = CURLE_OK;
int rc;
long lerr;
@@ -3989,7 +4001,8 @@ static CURLcode servercert(struct Curl_easy *data,
return CURLE_PEER_FAILED_VERIFICATION;
}
- infof(data, "%s certificate:", SSL_IS_PROXY() ? "Proxy" : "Server");
+ infof(data, "%s certificate:",
+ Curl_ssl_cf_is_proxy(cf)? "Proxy" : "Server");
rc = x509_name_oneline(X509_get_subject_name(backend->server_cert),
buffer, sizeof(buffer));
@@ -4012,7 +4025,7 @@ static CURLcode servercert(struct Curl_easy *data,
BIO_free(mem);
- if(SSL_CONN_CONFIG(verifyhost)) {
+ if(conn_config->verifyhost) {
result = Curl_ossl_verifyhost(data, conn, backend->server_cert);
if(result) {
X509_free(backend->server_cert);
@@ -4035,10 +4048,10 @@ static CURLcode servercert(struct Curl_easy *data,
deallocating the certificate. */
/* e.g. match issuer name with provided issuer certificate */
- if(SSL_CONN_CONFIG(issuercert) || SSL_CONN_CONFIG(issuercert_blob)) {
- if(SSL_CONN_CONFIG(issuercert_blob)) {
- fp = BIO_new_mem_buf(SSL_CONN_CONFIG(issuercert_blob)->data,
- (int)SSL_CONN_CONFIG(issuercert_blob)->len);
+ if(conn_config->issuercert || conn_config->issuercert_blob) {
+ if(conn_config->issuercert_blob) {
+ fp = BIO_new_mem_buf(conn_config->issuercert_blob->data,
+ (int)conn_config->issuercert_blob->len);
if(!fp) {
failf(data,
"BIO_new_mem_buf NULL, " OSSL_PACKAGE
@@ -4063,10 +4076,10 @@ static CURLcode servercert(struct Curl_easy *data,
return CURLE_OUT_OF_MEMORY;
}
- if(BIO_read_filename(fp, SSL_CONN_CONFIG(issuercert)) <= 0) {
+ if(BIO_read_filename(fp, conn_config->issuercert) <= 0) {
if(strict)
failf(data, "SSL: Unable to open issuer cert (%s)",
- SSL_CONN_CONFIG(issuercert));
+ conn_config->issuercert);
BIO_free(fp);
X509_free(backend->server_cert);
backend->server_cert = NULL;
@@ -4078,7 +4091,7 @@ static CURLcode servercert(struct Curl_easy *data,
if(!issuer) {
if(strict)
failf(data, "SSL: Unable to read issuer cert (%s)",
- SSL_CONN_CONFIG(issuercert));
+ conn_config->issuercert);
BIO_free(fp);
X509_free(issuer);
X509_free(backend->server_cert);
@@ -4089,7 +4102,7 @@ static CURLcode servercert(struct Curl_easy *data,
if(X509_check_issued(issuer, backend->server_cert) != X509_V_OK) {
if(strict)
failf(data, "SSL: Certificate issuer check failed (%s)",
- SSL_CONN_CONFIG(issuercert));
+ conn_config->issuercert);
BIO_free(fp);
X509_free(issuer);
X509_free(backend->server_cert);
@@ -4098,15 +4111,15 @@ static CURLcode servercert(struct Curl_easy *data,
}
infof(data, " SSL certificate issuer check ok (%s)",
- SSL_CONN_CONFIG(issuercert));
+ conn_config->issuercert);
BIO_free(fp);
X509_free(issuer);
}
lerr = SSL_get_verify_result(backend->handle);
- SSL_SET_OPTION_LVALUE(certverifyresult) = lerr;
+ ssl_config->certverifyresult = lerr;
if(lerr != X509_V_OK) {
- if(SSL_CONN_CONFIG(verifypeer)) {
+ if(conn_config->verifypeer) {
/* We probably never reach this, because SSL_connect() will fail
and we return earlier if verifypeer is set? */
if(strict)
@@ -4125,8 +4138,8 @@ static CURLcode servercert(struct Curl_easy *data,
#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
!defined(OPENSSL_NO_OCSP)
- if(SSL_CONN_CONFIG(verifystatus)) {
- result = verifystatus(data, connssl);
+ if(conn_config->verifystatus) {
+ result = verifystatus(cf, data);
if(result) {
X509_free(backend->server_cert);
backend->server_cert = NULL;
@@ -4139,7 +4152,9 @@ static CURLcode servercert(struct Curl_easy *data,
/* when not strict, we don't bother about the verify cert problems */
result = CURLE_OK;
- ptr = SSL_PINNED_PUB_KEY();
+ ptr = Curl_ssl_cf_is_proxy(cf)?
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]:
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY];
if(!result && ptr) {
result = pkp_pin_peer_pubkey(data, backend->server_cert, ptr);
if(result)
@@ -4153,11 +4168,12 @@ static CURLcode servercert(struct Curl_easy *data,
return result;
}
-static CURLcode ossl_connect_step3(struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+static CURLcode ossl_connect_step3(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
CURLcode result = CURLE_OK;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
@@ -4168,8 +4184,8 @@ static CURLcode ossl_connect_step3(struct Curl_easy *data,
* operations.
*/
- result = servercert(data, conn, connssl, (SSL_CONN_CONFIG(verifypeer) ||
- SSL_CONN_CONFIG(verifyhost)));
+ result = servercert(cf, data, conn_config->verifypeer ||
+ conn_config->verifyhost);
if(!result)
connssl->connecting_state = ssl_connect_done;
@@ -4177,18 +4193,14 @@ static CURLcode ossl_connect_step3(struct Curl_easy *data,
return result;
}
-static Curl_recv ossl_recv;
-static Curl_send ossl_send;
-
-static CURLcode ossl_connect_common(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex,
+static CURLcode ossl_connect_common(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
bool nonblocking,
bool *done)
{
CURLcode result;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- curl_socket_t sockfd = conn->sock[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
+ curl_socket_t sockfd = cf->conn->sock[cf->sockindex];
int what;
/* check if the connection has already been established */
@@ -4207,7 +4219,7 @@ static CURLcode ossl_connect_common(struct Curl_easy *data,
return CURLE_OPERATION_TIMEDOUT;
}
- result = ossl_connect_step1(data, conn, sockindex);
+ result = ossl_connect_step1(cf, data);
if(result)
return result;
}
@@ -4259,7 +4271,7 @@ static CURLcode ossl_connect_common(struct Curl_easy *data,
* before step2 has completed while ensuring that a client using select()
* or epoll() will always have a valid fdset to wait on.
*/
- result = ossl_connect_step2(data, conn, sockindex);
+ result = ossl_connect_step2(cf, data);
if(result || (nonblocking &&
(ssl_connect_2 == connssl->connecting_state ||
ssl_connect_2_reading == connssl->connecting_state ||
@@ -4269,7 +4281,7 @@ static CURLcode ossl_connect_common(struct Curl_easy *data,
} /* repeat step2 until all transactions are done. */
if(ssl_connect_3 == connssl->connecting_state) {
- result = ossl_connect_step3(data, conn, sockindex);
+ result = ossl_connect_step3(cf, data);
if(result)
return result;
}
@@ -4287,21 +4299,20 @@ static CURLcode ossl_connect_common(struct Curl_easy *data,
return CURLE_OK;
}
-static CURLcode ossl_connect_nonblocking(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex,
+static CURLcode ossl_connect_nonblocking(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
bool *done)
{
- return ossl_connect_common(data, conn, sockindex, TRUE, done);
+ return ossl_connect_common(cf, data, TRUE, done);
}
-static CURLcode ossl_connect(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+static CURLcode ossl_connect(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
CURLcode result;
bool done = FALSE;
- result = ossl_connect_common(data, conn, sockindex, FALSE, &done);
+ result = ossl_connect_common(cf, data, FALSE, &done);
if(result)
return result;
@@ -4310,28 +4321,22 @@ static CURLcode ossl_connect(struct Curl_easy *data, struct connectdata *conn,
return CURLE_OK;
}
-static bool ossl_data_pending(const struct connectdata *conn,
- int connindex)
+static bool ossl_data_pending(struct Curl_cfilter *cf,
+ const struct Curl_easy *data)
{
- const struct ssl_connect_data *connssl = &conn->ssl[connindex];
- DEBUGASSERT(connssl->backend);
- if(connssl->backend->handle && SSL_pending(connssl->backend->handle))
+ struct ssl_connect_data *ctx = cf->ctx;
+
+ (void)data;
+ DEBUGASSERT(ctx && ctx->backend);
+ if(ctx->backend->handle && SSL_pending(ctx->backend->handle))
return TRUE;
-#ifndef CURL_DISABLE_PROXY
- {
- const struct ssl_connect_data *proxyssl = &conn->proxy_ssl[connindex];
- DEBUGASSERT(proxyssl->backend);
- if(proxyssl->backend->handle && SSL_pending(proxyssl->backend->handle))
- return TRUE;
- }
-#endif
return FALSE;
}
static size_t ossl_version(char *buffer, size_t size);
-static ssize_t ossl_send(struct Curl_easy *data,
- int sockindex,
+static ssize_t ossl_send(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
const void *mem,
size_t len,
CURLcode *curlcode)
@@ -4343,16 +4348,16 @@ static ssize_t ossl_send(struct Curl_easy *data,
unsigned long sslerror;
int memlen;
int rc;
- struct connectdata *conn = data->conn;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
+ (void)data;
DEBUGASSERT(backend);
ERR_clear_error();
memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
- set_logger(conn, data);
+ set_logger(connssl, data);
rc = SSL_write(backend->handle, mem, memlen);
if(rc <= 0) {
@@ -4383,16 +4388,17 @@ static ssize_t ossl_send(struct Curl_easy *data,
*curlcode = CURLE_SEND_ERROR;
return -1;
}
- case SSL_ERROR_SSL:
+ case SSL_ERROR_SSL: {
/* A failure in the SSL library occurred, usually a protocol error.
The OpenSSL error queue contains more information on the error. */
+ struct Curl_cfilter *cf_ssl_next = Curl_ssl_cf_get_ssl(cf->next);
+ struct ssl_connect_data *connssl_next = cf_ssl_next?
+ cf_ssl_next->ctx : NULL;
sslerror = ERR_get_error();
if(ERR_GET_LIB(sslerror) == ERR_LIB_SSL &&
ERR_GET_REASON(sslerror) == SSL_R_BIO_NOT_SET &&
- conn->ssl[sockindex].state == ssl_connection_complete
-#ifndef CURL_DISABLE_PROXY
- && conn->proxy_ssl[sockindex].state == ssl_connection_complete
-#endif
+ connssl->state == ssl_connection_complete &&
+ (connssl_next && connssl_next->state == ssl_connection_complete)
) {
char ver[120];
(void)ossl_version(ver, sizeof(ver));
@@ -4404,18 +4410,20 @@ static ssize_t ossl_send(struct Curl_easy *data,
*curlcode = CURLE_SEND_ERROR;
return -1;
}
- /* a true error */
- failf(data, OSSL_PACKAGE " SSL_write: %s, errno %d",
- SSL_ERROR_to_str(err), SOCKERRNO);
- *curlcode = CURLE_SEND_ERROR;
- return -1;
+ default:
+ /* a true error */
+ failf(data, OSSL_PACKAGE " SSL_write: %s, errno %d",
+ SSL_ERROR_to_str(err), SOCKERRNO);
+ *curlcode = CURLE_SEND_ERROR;
+ return -1;
+ }
}
*curlcode = CURLE_OK;
return (ssize_t)rc; /* number of bytes */
}
-static ssize_t ossl_recv(struct Curl_easy *data, /* transfer */
- int num, /* socketindex */
+static ssize_t ossl_recv(struct Curl_cfilter *cf,
+ struct Curl_easy *data, /* transfer */
char *buf, /* store read data here */
size_t buffersize, /* max amount to read */
CURLcode *curlcode)
@@ -4424,16 +4432,17 @@ static ssize_t ossl_recv(struct Curl_easy *data, /* transfer */
unsigned long sslerror;
ssize_t nread;
int buffsize;
- struct connectdata *conn = data->conn;
- struct ssl_connect_data *connssl = &conn->ssl[num];
+ struct connectdata *conn = cf->conn;
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
+ (void)data;
DEBUGASSERT(backend);
ERR_clear_error();
buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
- set_logger(conn, data);
+ set_logger(connssl, data);
nread = (ssize_t)SSL_read(backend->handle, buf, buffsize);
if(nread <= 0) {
/* failed SSL_read */
@@ -4444,7 +4453,7 @@ static ssize_t ossl_recv(struct Curl_easy *data, /* transfer */
break;
case SSL_ERROR_ZERO_RETURN: /* no more data */
/* close_notify alert */
- if(num == FIRSTSOCKET)
+ if(cf->sockindex == FIRSTSOCKET)
/* mark the connection for close if it is indeed the control
connection */
connclose(conn, "TLS close_notify");
@@ -4640,41 +4649,44 @@ static void *ossl_get_internals(struct ssl_connect_data *connssl,
(void *)backend->ctx : (void *)backend->handle;
}
-static bool ossl_associate_connection(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex)
+static bool ossl_attach_data(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
+ const struct ssl_config_data *config;
+
DEBUGASSERT(backend);
/* If we don't have SSL context, do nothing. */
if(!backend->handle)
return FALSE;
- if(SSL_SET_OPTION(primary.sessionid)) {
+ config = Curl_ssl_cf_get_config(cf, data);
+ if(config->primary.sessionid) {
int data_idx = ossl_get_ssl_data_index();
- int connectdata_idx = ossl_get_ssl_conn_index();
+ int cf_idx = ossl_get_ssl_cf_index();
int sockindex_idx = ossl_get_ssl_sockindex_index();
int proxy_idx = ossl_get_proxy_index();
- if(data_idx >= 0 && connectdata_idx >= 0 && sockindex_idx >= 0 &&
+ if(data_idx >= 0 && cf_idx >= 0 && sockindex_idx >= 0 &&
proxy_idx >= 0) {
- int data_status, conn_status, sockindex_status, proxy_status;
+ int data_status, cf_status, sockindex_status, proxy_status;
/* Store the data needed for the "new session" callback.
* The sockindex is stored as a pointer to an array element. */
data_status = SSL_set_ex_data(backend->handle, data_idx, data);
- conn_status = SSL_set_ex_data(backend->handle, connectdata_idx, conn);
+ cf_status = SSL_set_ex_data(backend->handle, cf_idx, cf);
sockindex_status = SSL_set_ex_data(backend->handle, sockindex_idx,
- conn->sock + sockindex);
+ cf->conn->sock + cf->sockindex);
#ifndef CURL_DISABLE_PROXY
proxy_status = SSL_set_ex_data(backend->handle, proxy_idx,
- SSL_IS_PROXY() ? (void *) 1 : NULL);
+ Curl_ssl_cf_is_proxy(cf)?
+ (void *) 1 : NULL);
#else
proxy_status = SSL_set_ex_data(backend->handle, proxy_idx, NULL);
#endif
- if(data_status && conn_status && sockindex_status && proxy_status)
+ if(data_status && cf_status && sockindex_status && proxy_status)
return TRUE;
}
return FALSE;
@@ -4690,11 +4702,11 @@ static bool ossl_associate_connection(struct Curl_easy *data,
* transfer that might still be using the same connection.
*/
-static void ossl_disassociate_connection(struct Curl_easy *data,
- int sockindex)
+static void ossl_detach_data(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- struct connectdata *conn = data->conn;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
@@ -4702,18 +4714,18 @@ static void ossl_disassociate_connection(struct Curl_easy *data,
if(!backend->handle)
return;
- if(SSL_SET_OPTION(primary.sessionid)) {
+ if(ssl_config->primary.sessionid) {
int data_idx = ossl_get_ssl_data_index();
- int connectdata_idx = ossl_get_ssl_conn_index();
+ int cf_idx = ossl_get_ssl_cf_index();
int sockindex_idx = ossl_get_ssl_sockindex_index();
int proxy_idx = ossl_get_proxy_index();
- if(data_idx >= 0 && connectdata_idx >= 0 && sockindex_idx >= 0 &&
+ if(data_idx >= 0 && cf_idx >= 0 && sockindex_idx >= 0 &&
proxy_idx >= 0) {
/* Disable references to data in "new session" callback to avoid
* accessing a stale pointer. */
SSL_set_ex_data(backend->handle, data_idx, NULL);
- SSL_set_ex_data(backend->handle, connectdata_idx, NULL);
+ SSL_set_ex_data(backend->handle, cf_idx, NULL);
SSL_set_ex_data(backend->handle, sockindex_idx, NULL);
SSL_set_ex_data(backend->handle, proxy_idx, NULL);
}
@@ -4759,7 +4771,7 @@ const struct Curl_ssl Curl_ssl_openssl = {
ossl_cert_status_request, /* cert_status_request */
ossl_connect, /* connect */
ossl_connect_nonblocking, /* connect_nonblocking */
- Curl_ssl_getsock, /* getsock */
+ Curl_ssl_get_select_socks,/* getsock */
ossl_get_internals, /* get_internals */
ossl_close, /* close_one */
ossl_close_all, /* close_all */
@@ -4773,8 +4785,8 @@ const struct Curl_ssl Curl_ssl_openssl = {
#else
NULL, /* sha256sum */
#endif
- ossl_associate_connection, /* associate_connection */
- ossl_disassociate_connection, /* disassociate_connection */
+ ossl_attach_data, /* use of data in this connection */
+ ossl_detach_data, /* remote of data from this connection */
ossl_free_multi_ssl_backend_data, /* free_multi_ssl_backend_data */
ossl_recv, /* recv decrypted data */
ossl_send, /* send data to encrypt */
diff --git a/lib/vtls/rustls.c b/lib/vtls/rustls.c
index 771b927bc..36cc08207 100644
--- a/lib/vtls/rustls.c
+++ b/lib/vtls/rustls.c
@@ -64,18 +64,18 @@ static CURLcode map_error(rustls_result r)
}
static bool
-cr_data_pending(const struct connectdata *conn, int sockindex)
+cr_data_pending(struct Curl_cfilter *cf, const struct Curl_easy *data)
{
- const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- struct ssl_backend_data *backend = connssl->backend;
- DEBUGASSERT(backend);
- return backend->data_pending;
+ struct ssl_connect_data *ctx = cf->ctx;
+
+ (void)data;
+ DEBUGASSERT(ctx && ctx->backend);
+ return ctx->backend->data_pending;
}
static CURLcode
-cr_connect(struct Curl_easy *data UNUSED_PARAM,
- struct connectdata *conn UNUSED_PARAM,
- int sockindex UNUSED_PARAM)
+cr_connect(struct Curl_cfilter *cf UNUSED_PARAM,
+ struct Curl_easy *data UNUSED_PARAM)
{
infof(data, "rustls_connect: unimplemented");
return CURLE_SSL_CONNECT_ERROR;
@@ -116,11 +116,10 @@ write_cb(void *userdata, const uint8_t *buf, uintptr_t len, uintptr_t *out_n)
* output buffer.
*/
static ssize_t
-cr_recv(struct Curl_easy *data, int sockindex,
+cr_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
char *plainbuf, size_t plainlen, CURLcode *err)
{
- struct connectdata *conn = data->conn;
- struct ssl_connect_data *const connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *const connssl = cf->ctx;
struct ssl_backend_data *const backend = connssl->backend;
struct rustls_connection *rconn = NULL;
@@ -135,7 +134,7 @@ cr_recv(struct Curl_easy *data, int sockindex,
rconn = backend->conn;
io_error = rustls_connection_read_tls(rconn, read_cb,
- &conn->sock[sockindex], &tls_bytes_read);
+ &cf->conn->sock[cf->sockindex], &tls_bytes_read);
if(io_error == EAGAIN || io_error == EWOULDBLOCK) {
infof(data, "sread: EAGAIN or EWOULDBLOCK");
}
@@ -217,11 +216,10 @@ cr_recv(struct Curl_easy *data, int sockindex,
* It will only drain rustls' plaintext output buffer into the socket.
*/
static ssize_t
-cr_send(struct Curl_easy *data, int sockindex,
+cr_send(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *plainbuf, size_t plainlen, CURLcode *err)
{
- struct connectdata *conn = data->conn;
- struct ssl_connect_data *const connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *const connssl = cf->ctx;
struct ssl_backend_data *const backend = connssl->backend;
struct rustls_connection *rconn = NULL;
size_t plainwritten = 0;
@@ -252,7 +250,7 @@ cr_send(struct Curl_easy *data, int sockindex,
while(rustls_connection_wants_write(rconn)) {
io_error = rustls_connection_write_tls(rconn, write_cb,
- &conn->sock[sockindex], &tlswritten);
+ &cf->conn->sock[cf->sockindex], &tlswritten);
if(io_error == EAGAIN || io_error == EWOULDBLOCK) {
infof(data, "swrite: EAGAIN after %ld bytes", tlswritten_total);
*err = CURLE_AGAIN;
@@ -303,18 +301,20 @@ cr_hostname_is_ip(const char *hostname)
}
static CURLcode
-cr_init_backend(struct Curl_easy *data, struct connectdata *conn,
+cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data,
struct ssl_backend_data *const backend)
{
+ struct ssl_connect_data *connssl = cf->ctx;
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
struct rustls_connection *rconn = NULL;
struct rustls_client_config_builder *config_builder = NULL;
struct rustls_root_cert_store *roots = NULL;
- const struct curl_blob *ca_info_blob = SSL_CONN_CONFIG(ca_info_blob);
+ const struct curl_blob *ca_info_blob = conn_config->ca_info_blob;
const char * const ssl_cafile =
/* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */
- (ca_info_blob ? NULL : SSL_CONN_CONFIG(CAfile));
- const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
- const char *hostname = conn->host.name;
+ (ca_info_blob ? NULL : conn_config->CAfile);
+ const bool verifypeer = conn_config->verifypeer;
+ const char *hostname = connssl->hostname;
char errorbuf[256];
size_t errorlen;
int result;
@@ -401,7 +401,7 @@ cr_init_backend(struct Curl_easy *data, struct connectdata *conn,
}
static void
-cr_set_negotiated_alpn(struct Curl_easy *data, struct connectdata *conn,
+cr_set_negotiated_alpn(struct Curl_cfilter *cf, struct Curl_easy *data,
const struct rustls_connection *rconn)
{
const uint8_t *protocol = NULL;
@@ -416,29 +416,29 @@ cr_set_negotiated_alpn(struct Curl_easy *data, struct connectdata *conn,
#ifdef USE_HTTP2
if(len == ALPN_H2_LENGTH && 0 == memcmp(ALPN_H2, protocol, len)) {
infof(data, VTLS_INFOF_ALPN_ACCEPTED_1STR, ALPN_H2);
- conn->alpn = CURL_HTTP_VERSION_2;
+ cf->conn->alpn = CURL_HTTP_VERSION_2;
}
else
#endif
if(len == ALPN_HTTP_1_1_LENGTH &&
0 == memcmp(ALPN_HTTP_1_1, protocol, len)) {
infof(data, VTLS_INFOF_ALPN_ACCEPTED_1STR, ALPN_HTTP_1_1);
- conn->alpn = CURL_HTTP_VERSION_1_1;
+ cf->conn->alpn = CURL_HTTP_VERSION_1_1;
}
else {
infof(data, "ALPN, negotiated an unrecognized protocol");
}
- Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ?
+ Curl_multiuse_state(data, cf->conn->alpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
static CURLcode
-cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn,
- int sockindex, bool *done)
+cr_connect_nonblocking(struct Curl_cfilter *cf,
+ struct Curl_easy *data, bool *done)
{
- struct ssl_connect_data *const connssl = &conn->ssl[sockindex];
- curl_socket_t sockfd = conn->sock[sockindex];
+ struct ssl_connect_data *const connssl = cf->ctx;
+ curl_socket_t sockfd = cf->conn->sock[cf->sockindex];
struct ssl_backend_data *const backend = connssl->backend;
struct rustls_connection *rconn = NULL;
CURLcode tmperr = CURLE_OK;
@@ -452,7 +452,7 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn,
DEBUGASSERT(backend);
if(ssl_connection_none == connssl->state) {
- result = cr_init_backend(data, conn, connssl->backend);
+ result = cr_init_backend(cf, data, connssl->backend);
if(result != CURLE_OK) {
return result;
}
@@ -472,7 +472,7 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn,
/* Done with the handshake. Set up callbacks to send/receive data. */
connssl->state = ssl_connection_complete;
- cr_set_negotiated_alpn(data, conn, rconn);
+ cr_set_negotiated_alpn(cf, data, rconn);
*done = TRUE;
return CURLE_OK;
@@ -501,7 +501,7 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn,
if(wants_write) {
infof(data, "rustls_connection wants us to write_tls.");
- cr_send(data, sockindex, NULL, 0, &tmperr);
+ cr_send(cf, data, NULL, 0, &tmperr);
if(tmperr == CURLE_AGAIN) {
infof(data, "writing would block");
/* fall through */
@@ -514,7 +514,7 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn,
if(wants_read) {
infof(data, "rustls_connection wants us to read_tls.");
- cr_recv(data, sockindex, NULL, 0, &tmperr);
+ cr_recv(cf, data, NULL, 0, &tmperr);
if(tmperr == CURLE_AGAIN) {
infof(data, "reading would block");
/* fall through */
@@ -538,13 +538,15 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn,
/* returns a bitmap of flags for this connection's first socket indicating
whether we want to read or write */
static int
-cr_getsock(struct connectdata *conn, curl_socket_t *socks)
+cr_get_select_socks(struct Curl_cfilter *cf, struct Curl_easy *data,
+ curl_socket_t *socks)
{
- struct ssl_connect_data *const connssl = &conn->ssl[FIRSTSOCKET];
- curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
+ struct ssl_connect_data *const connssl = cf->ctx;
+ curl_socket_t sockfd = cf->conn->sock[cf->sockindex];
struct ssl_backend_data *const backend = connssl->backend;
struct rustls_connection *rconn = NULL;
+ (void)data;
DEBUGASSERT(backend);
rconn = backend->conn;
@@ -570,10 +572,9 @@ cr_get_internals(struct ssl_connect_data *connssl,
}
static void
-cr_close(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+cr_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
CURLcode tmperr = CURLE_OK;
ssize_t n = 0;
@@ -582,7 +583,7 @@ cr_close(struct Curl_easy *data, struct connectdata *conn,
if(backend->conn) {
rustls_connection_send_close_notify(backend->conn);
- n = cr_send(data, sockindex, NULL, 0, &tmperr);
+ n = cr_send(cf, data, NULL, 0, &tmperr);
if(n < 0) {
failf(data, "error sending close notify: %d", tmperr);
}
@@ -618,7 +619,7 @@ const struct Curl_ssl Curl_ssl_rustls = {
Curl_none_cert_status_request, /* cert_status_request */
cr_connect, /* connect */
cr_connect_nonblocking, /* connect_nonblocking */
- cr_getsock, /* cr_getsock */
+ cr_get_select_socks, /* get_select_socks */
cr_get_internals, /* get_internals */
cr_close, /* close_one */
Curl_none_close_all, /* close_all */
diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c
index 6b35efdce..ef9a66382 100644
--- a/lib/vtls/schannel.c
+++ b/lib/vtls/schannel.c
@@ -186,11 +186,8 @@
#define PKCS12_NO_PERSIST_KEY 0x00008000
#endif
-static Curl_recv schannel_recv;
-static Curl_send schannel_send;
-
-static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
- struct connectdata *conn, int sockindex,
+static CURLcode pkp_pin_peer_pubkey(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
const char *pinnedpubkey);
static void InitSecBuffer(SecBuffer *buffer, unsigned long BufType,
@@ -210,11 +207,13 @@ static void InitSecBufferDesc(SecBufferDesc *desc, SecBuffer *BufArr,
}
static CURLcode
-set_ssl_version_min_max(DWORD *enabled_protocols, struct Curl_easy *data,
- struct connectdata *conn)
+set_ssl_version_min_max(DWORD *enabled_protocols,
+ struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- long ssl_version = SSL_CONN_CONFIG(version);
- long ssl_version_max = SSL_CONN_CONFIG(version_max);
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ long ssl_version = conn_config->version;
+ long ssl_version_max = conn_config->version_max;
long i = ssl_version;
switch(ssl_version_max) {
@@ -478,11 +477,12 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path,
}
#endif
static CURLcode
-schannel_acquire_credential_handle(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex)
+schannel_acquire_credential_handle(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
#ifdef HAS_CLIENT_CERT_PATH
PCCERT_CONTEXT client_certs[1] = { NULL };
@@ -499,7 +499,7 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
DEBUGASSERT(backend);
- if(conn->ssl_config.verifypeer) {
+ if(conn_config->verifypeer) {
#ifdef HAS_MANUAL_VERIFY_API
if(backend->use_manual_cred_validation)
flags = SCH_CRED_MANUAL_CRED_VALIDATION;
@@ -507,14 +507,14 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
#endif
flags = SCH_CRED_AUTO_CRED_VALIDATION;
- if(SSL_SET_OPTION(no_revoke)) {
+ if(ssl_config->no_revoke) {
flags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
SCH_CRED_IGNORE_REVOCATION_OFFLINE;
DEBUGF(infof(data, "schannel: disabled server certificate revocation "
"checks"));
}
- else if(SSL_SET_OPTION(revoke_best_effort)) {
+ else if(ssl_config->revoke_best_effort) {
flags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
SCH_CRED_IGNORE_REVOCATION_OFFLINE | SCH_CRED_REVOCATION_CHECK_CHAIN;
@@ -535,14 +535,14 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
"schannel: disabled server cert revocation checks"));
}
- if(!conn->ssl_config.verifyhost) {
+ if(!conn_config->verifyhost) {
flags |= SCH_CRED_NO_SERVERNAME_CHECK;
DEBUGF(infof(data, "schannel: verifyhost setting prevents Schannel from "
"comparing the supplied target name with the subject "
"names in server certificates."));
}
- if(!SSL_SET_OPTION(auto_client_cert)) {
+ if(!ssl_config->auto_client_cert) {
flags &= ~SCH_CRED_USE_DEFAULT_CREDS;
flags |= SCH_CRED_NO_DEFAULT_CREDS;
infof(data, "schannel: disabled automatic use of client certificate");
@@ -550,7 +550,7 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
else
infof(data, "schannel: enabled automatic use of client certificate");
- switch(conn->ssl_config.version) {
+ switch(conn_config->version) {
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
case CURL_SSLVERSION_TLSv1_0:
@@ -558,7 +558,7 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
case CURL_SSLVERSION_TLSv1_2:
case CURL_SSLVERSION_TLSv1_3:
{
- result = set_ssl_version_min_max(&enabled_protocols, data, conn);
+ result = set_ssl_version_min_max(&enabled_protocols, cf, data);
if(result != CURLE_OK)
return result;
break;
@@ -813,7 +813,7 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
* disable all the ciphers and re-enable which
* ciphers the user has provided.
*/
- ciphers13 = SSL_CONN_CONFIG(cipher_list13);
+ ciphers13 = conn_config->cipher_list13;
if(ciphers13) {
const int remaining_ciphers = 5;
@@ -1007,7 +1007,7 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
else {
/* Pre-Windows 10 1809 */
ALG_ID algIds[NUM_CIPHERS];
- char *ciphers = SSL_CONN_CONFIG(cipher_list);
+ char *ciphers = conn_config->cipher_list;
SCHANNEL_CRED schannel_cred = { 0 };
schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
schannel_cred.dwFlags = flags;
@@ -1016,7 +1016,7 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
if(ciphers) {
result = set_ssl_ciphers(&schannel_cred, ciphers, algIds);
if(CURLE_OK != result) {
- failf(data, "Unable to set ciphers to passed via SSL_CONN_CONFIG");
+ failf(data, "Unable to set ciphers to from connection ssl config");
return result;
}
}
@@ -1066,11 +1066,13 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
}
static CURLcode
-schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
{
ssize_t written = -1;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
+ struct ssl_backend_data *backend = connssl->backend;
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
SecBuffer outbuf;
SecBufferDesc outbuf_desc;
SecBuffer inbuf;
@@ -1085,14 +1087,12 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
struct in6_addr addr6;
#endif
CURLcode result;
- char * const hostname = SSL_HOST_NAME();
- struct ssl_backend_data *backend = connssl->backend;
+ const char *hostname = connssl->hostname;
DEBUGASSERT(backend);
-
DEBUGF(infof(data,
- "schannel: SSL/TLS connection with %s port %hu (step 1/3)",
- hostname, conn->remote_port));
+ "schannel: SSL/TLS connection with %s port %d (step 1/3)",
+ hostname, connssl->port));
if(curlx_verify_windows_version(5, 1, 0, PLATFORM_WINNT,
VERSION_LESS_THAN_EQUAL)) {
@@ -1105,7 +1105,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
#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 = conn->bits.tls_enable_alpn &&
+ backend->use_alpn = cf->conn->bits.tls_enable_alpn &&
!GetProcAddress(GetModuleHandle(TEXT("ntdll")),
"wine_get_version") &&
curlx_verify_windows_version(6, 3, 0, PLATFORM_WINNT,
@@ -1124,7 +1124,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
#endif
#else
#ifdef HAS_MANUAL_VERIFY_API
- if(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) {
+ if(conn_config->CAfile || conn_config->ca_info_blob) {
if(curlx_verify_windows_version(6, 1, 0, PLATFORM_WINNT,
VERSION_GREATER_THAN_EQUAL)) {
backend->use_manual_cred_validation = true;
@@ -1138,7 +1138,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
else
backend->use_manual_cred_validation = false;
#else
- if(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) {
+ if(conn_config->CAfile || conn_config->ca_info_blob) {
failf(data, "schannel: CA cert support not built in");
return CURLE_NOT_BUILT_IN;
}
@@ -1148,11 +1148,9 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
backend->cred = NULL;
/* check for an existing re-usable credential handle */
- if(SSL_SET_OPTION(primary.sessionid)) {
+ if(ssl_config->primary.sessionid) {
Curl_ssl_sessionid_lock(data);
- if(!Curl_ssl_getsessionid(data, conn,
- SSL_IS_PROXY() ? TRUE : FALSE,
- (void **)&old_cred, NULL, sockindex)) {
+ if(!Curl_ssl_getsessionid(cf, data, (void **)&old_cred, NULL)) {
backend->cred = old_cred;
DEBUGF(infof(data, "schannel: re-using existing credential handle"));
@@ -1167,13 +1165,13 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
if(!backend->cred) {
char *snihost;
- result = schannel_acquire_credential_handle(data, conn, sockindex);
+ result = schannel_acquire_credential_handle(cf, data);
if(result != CURLE_OK) {
return result;
}
/* A hostname associated with the credential is needed by
InitializeSecurityContext for SNI and other reasons. */
- snihost = Curl_ssl_snihost(data, SSL_HOST_NAME(), NULL);
+ snihost = Curl_ssl_snihost(data, hostname, NULL);
if(!snihost) {
failf(data, "Failed to set SNI");
return CURLE_SSL_CONNECT_ERROR;
@@ -1255,7 +1253,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
ISC_REQ_CONFIDENTIALITY | ISC_REQ_ALLOCATE_MEMORY |
ISC_REQ_STREAM;
- if(!SSL_SET_OPTION(auto_client_cert)) {
+ if(!ssl_config->auto_client_cert) {
backend->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
}
@@ -1315,8 +1313,8 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
"sending %lu bytes.", outbuf.cbBuffer));
/* send initial handshake data which is now stored in output buffer */
- result = Curl_write_plain(data, conn->sock[sockindex], outbuf.pvBuffer,
- outbuf.cbBuffer, &written);
+ result = Curl_write_plain(data, cf->conn->sock[cf->sockindex],
+ outbuf.pvBuffer, outbuf.cbBuffer, &written);
s_pSecFn->FreeContextBuffer(outbuf.pvBuffer);
if((result != CURLE_OK) || (outbuf.cbBuffer != (size_t) written)) {
failf(data, "schannel: failed to send initial handshake data: "
@@ -1340,12 +1338,13 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
}
static CURLcode
-schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+schannel_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
{
+ struct ssl_connect_data *connssl = cf->ctx;
+ struct ssl_backend_data *backend = connssl->backend;
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
int i;
ssize_t nread = -1, written = -1;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
unsigned char *reallocated_buffer;
SecBuffer outbuf[3];
SecBufferDesc outbuf_desc;
@@ -1355,15 +1354,14 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
CURLcode result;
bool doread;
const char *pubkey_ptr;
- struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE;
DEBUGF(infof(data,
- "schannel: SSL/TLS connection with %s port %hu (step 2/3)",
- SSL_HOST_NAME(), conn->remote_port));
+ "schannel: SSL/TLS connection with %s port %d (step 2/3)",
+ connssl->hostname, connssl->port));
if(!backend->cred || !backend->ctxt)
return CURLE_SSL_CONNECT_ERROR;
@@ -1413,7 +1411,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
for(;;) {
if(doread) {
/* read encrypted handshake data from socket */
- result = Curl_read_plain(data, conn->sock[sockindex],
+ result = Curl_read_plain(data, cf->conn->sock[cf->sockindex],
(char *) (backend->encdata_buffer +
backend->encdata_offset),
backend->encdata_length -
@@ -1502,7 +1500,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
"sending %lu bytes.", outbuf[i].cbBuffer));
/* send handshake token to server */
- result = Curl_write_plain(data, conn->sock[sockindex],
+ result = Curl_write_plain(data, cf->conn->sock[cf->sockindex],
outbuf[i].pvBuffer, outbuf[i].cbBuffer,
&written);
if((result != CURLE_OK) ||
@@ -1597,9 +1595,11 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
DEBUGF(infof(data, "schannel: SSL/TLS handshake complete"));
}
- pubkey_ptr = SSL_PINNED_PUB_KEY();
+ pubkey_ptr = Curl_ssl_cf_is_proxy(cf)?
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]:
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY];
if(pubkey_ptr) {
- result = pkp_pin_peer_pubkey(data, conn, sockindex, pubkey_ptr);
+ result = pkp_pin_peer_pubkey(cf, data, pubkey_ptr);
if(result) {
failf(data, "SSL: public key does not match pinned public key");
return result;
@@ -1607,8 +1607,8 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
}
#ifdef HAS_MANUAL_VERIFY_API
- if(conn->ssl_config.verifypeer && backend->use_manual_cred_validation) {
- return Curl_verify_certificate(data, conn, sockindex);
+ if(conn_config->verifypeer && backend->use_manual_cred_validation) {
+ return Curl_verify_certificate(cf, data);
}
#endif
@@ -1675,28 +1675,24 @@ add_cert_to_certinfo(const CERT_CONTEXT *ccert_context, void *raw_arg)
}
static CURLcode
-schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+schannel_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data)
{
+ struct ssl_connect_data *connssl = cf->ctx;
+ struct ssl_backend_data *backend = connssl->backend;
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
CURLcode result = CURLE_OK;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
SECURITY_STATUS sspi_status = SEC_E_OK;
CERT_CONTEXT *ccert_context = NULL;
- bool isproxy = SSL_IS_PROXY();
-#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
- const char * const hostname = SSL_HOST_NAME();
-#endif
#ifdef HAS_ALPN
SecPkgContext_ApplicationProtocol alpn_result;
#endif
- struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
DEBUGASSERT(backend);
DEBUGF(infof(data,
- "schannel: SSL/TLS connection with %s port %hu (step 3/3)",
- hostname, conn->remote_port));
+ "schannel: SSL/TLS connection with %s port %d (step 3/3)",
+ connssl->hostname, connssl->port));
if(!backend->cred)
return CURLE_SSL_CONNECT_ERROR;
@@ -1748,13 +1744,13 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
alpn = CURL_HTTP_VERSION_1_1;
}
if(backend->recv_renegotiating) {
- if(alpn != conn->alpn) {
+ if(alpn != cf->conn->alpn) {
failf(data, "schannel: server selected an ALPN protocol too late");
return CURLE_SSL_CONNECT_ERROR;
}
}
else
- conn->alpn = alpn;
+ cf->conn->alpn = alpn;
}
else {
if(!backend->recv_renegotiating)
@@ -1762,21 +1758,20 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
}
if(!backend->recv_renegotiating) {
- Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ?
+ Curl_multiuse_state(data, cf->conn->alpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
}
#endif
/* save the current session data for possible re-use */
- if(SSL_SET_OPTION(primary.sessionid)) {
+ if(ssl_config->primary.sessionid) {
bool incache;
bool added = FALSE;
struct Curl_schannel_cred *old_cred = NULL;
Curl_ssl_sessionid_lock(data);
- incache = !(Curl_ssl_getsessionid(data, conn, isproxy, (void **)&old_cred,
- NULL, sockindex));
+ incache = !(Curl_ssl_getsessionid(cf, data, (void **)&old_cred, NULL));
if(incache) {
if(old_cred != backend->cred) {
DEBUGF(infof(data,
@@ -1787,9 +1782,9 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
}
}
if(!incache) {
- result = Curl_ssl_addsessionid(data, conn, isproxy, backend->cred,
+ result = Curl_ssl_addsessionid(cf, data, backend->cred,
sizeof(struct Curl_schannel_cred),
- sockindex, &added);
+ &added);
if(result) {
Curl_ssl_sessionid_unlock(data);
failf(data, "schannel: failed to store credential handle");
@@ -1839,12 +1834,13 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
}
static CURLcode
-schannel_connect_common(struct Curl_easy *data, struct connectdata *conn,
- int sockindex, bool nonblocking, bool *done)
+schannel_connect_common(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool nonblocking, bool *done)
{
CURLcode result;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- curl_socket_t sockfd = conn->sock[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
+ curl_socket_t sockfd = cf->conn->sock[cf->sockindex];
timediff_t timeout_ms;
int what;
@@ -1864,7 +1860,7 @@ schannel_connect_common(struct Curl_easy *data, struct connectdata *conn,
return CURLE_OPERATION_TIMEDOUT;
}
- result = schannel_connect_step1(data, conn, sockindex);
+ result = schannel_connect_step1(cf, data);
if(result)
return result;
}
@@ -1919,7 +1915,7 @@ schannel_connect_common(struct Curl_easy *data, struct connectdata *conn,
* ensuring that a client using select() or epoll() will always
* have a valid fdset to wait on.
*/
- result = schannel_connect_step2(data, conn, sockindex);
+ result = schannel_connect_step2(cf, data);
if(result || (nonblocking &&
(ssl_connect_2 == connssl->connecting_state ||
ssl_connect_2_reading == connssl->connecting_state ||
@@ -1929,7 +1925,7 @@ schannel_connect_common(struct Curl_easy *data, struct connectdata *conn,
} /* repeat step2 until all transactions are done. */
if(ssl_connect_3 == connssl->connecting_state) {
- result = schannel_connect_step3(data, conn, sockindex);
+ result = schannel_connect_step3(cf, data);
if(result)
return result;
}
@@ -1946,7 +1942,7 @@ schannel_connect_common(struct Curl_easy *data, struct connectdata *conn,
{
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
- conn->sslContext = &backend->ctxt->ctxt_handle;
+ cf->conn->sslContext = &backend->ctxt->ctxt_handle;
}
#endif
@@ -1962,14 +1958,14 @@ schannel_connect_common(struct Curl_easy *data, struct connectdata *conn,
}
static ssize_t
-schannel_send(struct Curl_easy *data, int sockindex,
+schannel_send(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *buf, size_t len, CURLcode *err)
{
ssize_t written = -1;
size_t data_len = 0;
unsigned char *ptr = NULL;
- struct connectdata *conn = data->conn;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct connectdata *conn = cf->conn;
+ struct ssl_connect_data *connssl = cf->ctx;
SecBuffer outbuf[4];
SecBufferDesc outbuf_desc;
SECURITY_STATUS sspi_status = SEC_E_OK;
@@ -2060,7 +2056,7 @@ schannel_send(struct Curl_easy *data, int sockindex,
}
else if(!timeout_ms)
timeout_ms = TIMEDIFF_T_MAX;
- what = SOCKET_WRITABLE(conn->sock[sockindex], timeout_ms);
+ what = SOCKET_WRITABLE(cf->conn->sock[cf->sockindex], timeout_ms);
if(what < 0) {
/* fatal error */
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
@@ -2077,8 +2073,8 @@ schannel_send(struct Curl_easy *data, int sockindex,
}
/* socket is writable */
- result = Curl_write_plain(data, conn->sock[sockindex], ptr + written,
- len - written, &this_write);
+ result = Curl_write_plain(data, conn->sock[cf->sockindex],
+ ptr + written, len - written, &this_write);
if(result == CURLE_AGAIN)
continue;
else if(result != CURLE_OK) {
@@ -2108,13 +2104,12 @@ schannel_send(struct Curl_easy *data, int sockindex,
}
static ssize_t
-schannel_recv(struct Curl_easy *data, int sockindex,
+schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
char *buf, size_t len, CURLcode *err)
{
size_t size = 0;
ssize_t nread = -1;
- struct connectdata *conn = data->conn;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
unsigned char *reallocated_buffer;
size_t reallocated_length;
bool done = FALSE;
@@ -2190,7 +2185,7 @@ schannel_recv(struct Curl_easy *data, int sockindex,
backend->encdata_offset, backend->encdata_length));
/* read encrypted data from socket */
- *err = Curl_read_plain(data, conn->sock[sockindex],
+ *err = Curl_read_plain(data, cf->conn->sock[cf->sockindex],
(char *)(backend->encdata_buffer +
backend->encdata_offset),
size, &nread);
@@ -2323,7 +2318,7 @@ schannel_recv(struct Curl_easy *data, int sockindex,
connssl->state = ssl_connection_negotiating;
connssl->connecting_state = ssl_connect_2_writing;
backend->recv_renegotiating = true;
- *err = schannel_connect_common(data, conn, sockindex, FALSE, &done);
+ *err = schannel_connect_common(cf, data, FALSE, &done);
backend->recv_renegotiating = false;
if(*err) {
infof(data, "schannel: renegotiation failed");
@@ -2431,20 +2426,20 @@ schannel_recv(struct Curl_easy *data, int sockindex,
return *err ? -1 : 0;
}
-static CURLcode schannel_connect_nonblocking(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex, bool *done)
+static CURLcode schannel_connect_nonblocking(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool *done)
{
- return schannel_connect_common(data, conn, sockindex, TRUE, done);
+ return schannel_connect_common(cf, data, TRUE, done);
}
-static CURLcode schannel_connect(struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+static CURLcode schannel_connect(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
CURLcode result;
bool done = FALSE;
- result = schannel_connect_common(data, conn, sockindex, FALSE, &done);
+ result = schannel_connect_common(cf, data, FALSE, &done);
if(result)
return result;
@@ -2453,15 +2448,16 @@ static CURLcode schannel_connect(struct Curl_easy *data,
return CURLE_OK;
}
-static bool schannel_data_pending(const struct connectdata *conn,
- int sockindex)
+static bool schannel_data_pending(struct Curl_cfilter *cf,
+ const struct Curl_easy *data)
{
- const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ const struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
+ (void)data;
DEBUGASSERT(backend);
- if(connssl->use) /* SSL/TLS is in use */
+ if(connssl->backend->ctxt) /* SSL/TLS is in use */
return (backend->decdata_offset > 0 ||
(backend->encdata_offset > 0 && !backend->encdata_is_incomplete));
else
@@ -2492,25 +2488,24 @@ static void schannel_session_free(void *ptr)
/* shut down the SSL connection and clean up related memory.
this function can be called multiple times on the same connection including
if the SSL connection failed (eg connection made but failed handshake). */
-static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+static int schannel_shutdown(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
/* See https://msdn.microsoft.com/en-us/library/windows/desktop/aa380138.aspx
* Shutting Down an Schannel Connection
*/
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- char * const hostname = SSL_HOST_NAME();
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(data);
DEBUGASSERT(backend);
- if(connssl->use) {
- infof(data, "schannel: shutting down SSL/TLS connection with %s port %hu",
- hostname, conn->remote_port);
+ if(connssl->backend->ctxt) {
+ infof(data, "schannel: shutting down SSL/TLS connection with %s port %d",
+ connssl->hostname, connssl->port);
}
- if(connssl->use && backend->cred && backend->ctxt) {
+ if(backend->cred && backend->ctxt) {
SecBufferDesc BuffDesc;
SecBuffer Buffer;
SECURITY_STATUS sspi_status;
@@ -2552,8 +2547,9 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn,
if((sspi_status == SEC_E_OK) || (sspi_status == SEC_I_CONTEXT_EXPIRED)) {
/* send close message which is in output buffer */
ssize_t written;
- result = Curl_write_plain(data, conn->sock[sockindex], outbuf.pvBuffer,
- outbuf.cbBuffer, &written);
+ result = Curl_write_plain(data, cf->conn->sock[cf->sockindex],
+ outbuf.pvBuffer, outbuf.cbBuffer,
+ &written);
s_pSecFn->FreeContextBuffer(outbuf.pvBuffer);
if((result != CURLE_OK) || (outbuf.cbBuffer != (size_t) written)) {
@@ -2596,14 +2592,9 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn,
return CURLE_OK;
}
-static void schannel_close(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+static void schannel_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
- if(conn->ssl[sockindex].use)
- /* Curl_ssl_shutdown resets the socket state and calls schannel_shutdown */
- Curl_ssl_shutdown(data, conn, sockindex);
- else
- schannel_shutdown(data, conn, sockindex);
+ schannel_shutdown(cf, data);
}
static int schannel_init(void)
@@ -2631,11 +2622,11 @@ static CURLcode schannel_random(struct Curl_easy *data UNUSED_PARAM,
return Curl_win32_random(entropy, length);
}
-static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
- struct connectdata *conn, int sockindex,
+static CURLcode pkp_pin_peer_pubkey(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
const char *pinnedpubkey)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
CERT_CONTEXT *pCertContextServer = NULL;
@@ -2790,7 +2781,7 @@ const struct Curl_ssl Curl_ssl_schannel = {
Curl_none_cert_status_request, /* cert_status_request */
schannel_connect, /* connect */
schannel_connect_nonblocking, /* connect_nonblocking */
- Curl_ssl_getsock, /* getsock */
+ Curl_ssl_get_select_socks, /* getsock */
schannel_get_internals, /* get_internals */
schannel_close, /* close_one */
Curl_none_close_all, /* close_all */
diff --git a/lib/vtls/schannel.h b/lib/vtls/schannel.h
index 42cecd9e5..6d4235a96 100644
--- a/lib/vtls/schannel.h
+++ b/lib/vtls/schannel.h
@@ -54,6 +54,7 @@
#include <schannel.h>
#include "curl_sspi.h"
+#include "cfilters.h"
#include "urldata.h"
/* <wincrypt.h> has been included via the above <schnlsp.h>.
@@ -77,8 +78,8 @@
extern const struct Curl_ssl Curl_ssl_schannel;
-CURLcode Curl_verify_certificate(struct Curl_easy *data,
- struct connectdata *conn, int sockindex);
+CURLcode Curl_verify_certificate(struct Curl_cfilter *cf,
+ struct Curl_easy *data);
/* structs to expose only in schannel.c and schannel_verify.c */
#ifdef EXPOSE_SCHANNEL_INTERNAL_STRUCTS
diff --git a/lib/vtls/schannel_verify.c b/lib/vtls/schannel_verify.c
index 6ee9a78c4..e4992162e 100644
--- a/lib/vtls/schannel_verify.c
+++ b/lib/vtls/schannel_verify.c
@@ -459,7 +459,7 @@ static DWORD cert_get_name_string(struct Curl_easy *data,
static CURLcode verify_host(struct Curl_easy *data,
CERT_CONTEXT *pCertContextServer,
- const char * const conn_hostname)
+ const char *conn_hostname)
{
CURLcode result = CURLE_PEER_FAILED_VERIFICATION;
TCHAR *cert_hostname_buff = NULL;
@@ -563,17 +563,18 @@ cleanup:
return result;
}
-CURLcode Curl_verify_certificate(struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+CURLcode Curl_verify_certificate(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
+ struct ssl_connect_data *connssl = cf->ctx;
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
SECURITY_STATUS sspi_status;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
CURLcode result = CURLE_OK;
CERT_CONTEXT *pCertContextServer = NULL;
const CERT_CHAIN_CONTEXT *pChainContext = NULL;
HCERTCHAINENGINE cert_chain_engine = NULL;
HCERTSTORE trust_store = NULL;
- const char * const conn_hostname = SSL_HOST_NAME();
DEBUGASSERT(BACKEND);
@@ -590,7 +591,7 @@ CURLcode Curl_verify_certificate(struct Curl_easy *data,
}
if(result == CURLE_OK &&
- (SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) &&
+ (conn_config->CAfile || conn_config->ca_info_blob) &&
BACKEND->use_manual_cred_validation) {
/*
* Create a chain engine that uses the certificates in the CA file as
@@ -617,7 +618,7 @@ CURLcode Curl_verify_certificate(struct Curl_easy *data,
result = CURLE_SSL_CACERT_BADFILE;
}
else {
- const struct curl_blob *ca_info_blob = SSL_CONN_CONFIG(ca_info_blob);
+ const struct curl_blob *ca_info_blob = conn_config->ca_info_blob;
if(ca_info_blob) {
result = add_certs_data_to_store(trust_store,
(const char *)ca_info_blob->data,
@@ -627,7 +628,7 @@ CURLcode Curl_verify_certificate(struct Curl_easy *data,
}
else {
result = add_certs_file_to_store(trust_store,
- SSL_CONN_CONFIG(CAfile),
+ conn_config->CAfile,
data);
}
}
@@ -670,7 +671,7 @@ CURLcode Curl_verify_certificate(struct Curl_easy *data,
NULL,
pCertContextServer->hCertStore,
&ChainPara,
- (SSL_SET_OPTION(no_revoke) ? 0 :
+ (ssl_config->no_revoke ? 0 :
CERT_CHAIN_REVOCATION_CHECK_CHAIN),
NULL,
&pChainContext)) {
@@ -719,8 +720,8 @@ CURLcode Curl_verify_certificate(struct Curl_easy *data,
}
if(result == CURLE_OK) {
- if(SSL_CONN_CONFIG(verifyhost)) {
- result = verify_host(data, pCertContextServer, conn_hostname);
+ if(conn_config->verifyhost) {
+ result = verify_host(data, pCertContextServer, connssl->hostname);
}
}
diff --git a/lib/vtls/sectransp.c b/lib/vtls/sectransp.c
index 7da1a396d..78076f623 100644
--- a/lib/vtls/sectransp.c
+++ b/lib/vtls/sectransp.c
@@ -1370,14 +1370,14 @@ static CURLcode sectransp_version_from_curl(SSLProtocol *darwinver,
}
#endif
-static CURLcode
-set_ssl_version_min_max(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+static CURLcode set_ssl_version_min_max(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
- long ssl_version = SSL_CONN_CONFIG(version);
- long ssl_version_max = SSL_CONN_CONFIG(version_max);
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ long ssl_version = conn_config->version;
+ long ssl_version_max = conn_config->version_max;
long max_supported_version_by_os;
DEBUGASSERT(backend);
@@ -1663,23 +1663,22 @@ static CURLcode sectransp_set_selected_ciphers(struct Curl_easy *data,
return CURLE_OK;
}
-static CURLcode sectransp_connect_step1(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex)
+static CURLcode sectransp_connect_step1(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- curl_socket_t sockfd = conn->sock[sockindex];
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ curl_socket_t sockfd = cf->conn->sock[cf->sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
- const struct curl_blob *ssl_cablob = SSL_CONN_CONFIG(ca_info_blob);
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
+ const struct curl_blob *ssl_cablob = conn_config->ca_info_blob;
const char * const ssl_cafile =
/* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */
- (ssl_cablob ? NULL : SSL_CONN_CONFIG(CAfile));
- const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
- char * const ssl_cert = SSL_SET_OPTION(primary.clientcert);
- const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob);
- bool isproxy = SSL_IS_PROXY();
- const char * const hostname = SSL_HOST_NAME();
- const long int port = SSL_HOST_PORT();
+ (ssl_cablob ? NULL : conn_config->CAfile);
+ const bool verifypeer = conn_config->verifypeer;
+ char * const ssl_cert = ssl_config->primary.clientcert;
+ const struct curl_blob *ssl_cert_blob = ssl_config->primary.cert_blob;
+ bool isproxy = Curl_ssl_cf_is_proxy(cf);
#ifdef ENABLE_IPV6
struct in6_addr addr;
#else
@@ -1731,7 +1730,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
/* check to see if we've been told to use an explicit SSL/TLS version */
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
if(SSLSetProtocolVersionMax) {
- switch(conn->ssl_config.version) {
+ switch(conn_config->version) {
case CURL_SSLVERSION_TLSv1:
(void)SSLSetProtocolVersionMin(backend->ssl_ctx, kTLSProtocol1);
#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
@@ -1752,7 +1751,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
case CURL_SSLVERSION_TLSv1_2:
case CURL_SSLVERSION_TLSv1_3:
{
- CURLcode result = set_ssl_version_min_max(data, conn, sockindex);
+ CURLcode result = set_ssl_version_min_max(cf, data);
if(result != CURLE_OK)
return result;
break;
@@ -1771,7 +1770,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
(void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
kSSLProtocolAll,
false);
- switch(conn->ssl_config.version) {
+ switch(conn_config->version) {
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
(void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
@@ -1789,7 +1788,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
case CURL_SSLVERSION_TLSv1_2:
case CURL_SSLVERSION_TLSv1_3:
{
- CURLcode result = set_ssl_version_min_max(data, conn, sockindex);
+ CURLcode result = set_ssl_version_min_max(cf, data);
if(result != CURLE_OK)
return result;
break;
@@ -1805,13 +1804,13 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
#endif /* CURL_SUPPORT_MAC_10_8 */
}
#else
- if(conn->ssl_config.version_max != CURL_SSLVERSION_MAX_NONE) {
+ if(conn_config->version_max != CURL_SSLVERSION_MAX_NONE) {
failf(data, "Your version of the OS does not support to set maximum"
" SSL/TLS version");
return CURLE_SSL_CONNECT_ERROR;
}
(void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, kSSLProtocolAll, false);
- switch(conn->ssl_config.version) {
+ switch(conn_config->version) {
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
case CURL_SSLVERSION_TLSv1_0:
@@ -1839,7 +1838,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
- if(conn->bits.tls_enable_alpn) {
+ if(cf->conn->bits.tls_enable_alpn) {
if(__builtin_available(macOS 10.13.4, iOS 11, tvOS 11, *)) {
CFMutableArrayRef alpnArr = CFArrayCreateMutable(NULL, 0,
&kCFTypeArrayCallBacks);
@@ -1847,7 +1846,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
#ifdef USE_HTTP2
if(data->state.httpwant >= CURL_HTTP_VERSION_2
#ifndef CURL_DISABLE_PROXY
- && (!isproxy || !conn->bits.tunnel_proxy)
+ && (!isproxy || !cf->conn->bits.tunnel_proxy)
#endif
) {
CFArrayAppendValue(alpnArr, CFSTR(ALPN_H2));
@@ -1870,7 +1869,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
}
#endif
- if(SSL_SET_OPTION(key)) {
+ if(ssl_config->key) {
infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
"Transport. The private key must be in the Keychain.");
}
@@ -1889,17 +1888,17 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
else
err = !noErr;
if((err != noErr) && (is_cert_file || is_cert_data)) {
- if(!SSL_SET_OPTION(cert_type))
+ if(!ssl_config->cert_type)
infof(data, "SSL: Certificate type not set, assuming "
"PKCS#12 format.");
- else if(!strcasecompare(SSL_SET_OPTION(cert_type), "P12")) {
+ else if(!strcasecompare(ssl_config->cert_type, "P12")) {
failf(data, "SSL: The Security framework only supports "
"loading identities that are in PKCS#12 format.");
return CURLE_SSL_CERTPROBLEM;
}
err = CopyIdentityFromPKCS12File(ssl_cert, ssl_cert_blob,
- SSL_SET_OPTION(key_passwd),
+ ssl_config->key_passwd,
&cert_and_key);
}
@@ -1992,7 +1991,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
#else
if(SSLSetSessionOption) {
#endif /* CURL_BUILD_MAC */
- bool break_on_auth = !conn->ssl_config.verifypeer ||
+ bool break_on_auth = !conn_config->verifypeer ||
ssl_cafile || ssl_cablob;
err = SSLSetSessionOption(backend->ssl_ctx,
kSSLSessionOptionBreakOnServerAuth,
@@ -2005,7 +2004,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
else {
#if CURL_SUPPORT_MAC_10_8
err = SSLSetEnableCertVerify(backend->ssl_ctx,
- conn->ssl_config.verifypeer?true:false);
+ conn_config->verifypeer?true:false);
if(err != noErr) {
failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
return CURLE_SSL_CONNECT_ERROR;
@@ -2014,7 +2013,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
}
#else
err = SSLSetEnableCertVerify(backend->ssl_ctx,
- conn->ssl_config.verifypeer?true:false);
+ conn_config->verifypeer?true:false);
if(err != noErr) {
failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
return CURLE_SSL_CONNECT_ERROR;
@@ -2035,9 +2034,9 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
/* Configure hostname check. SNI is used if available.
* Both hostname check and SNI require SSLSetPeerDomainName().
* Also: the verifyhost setting influences SNI usage */
- if(conn->ssl_config.verifyhost) {
+ if(conn_config->verifyhost) {
size_t snilen;
- char *snihost = Curl_ssl_snihost(data, hostname, &snilen);
+ char *snihost = Curl_ssl_snihost(data, connssl->hostname, &snilen);
if(!snihost) {
failf(data, "Failed to set SNI");
return CURLE_SSL_CONNECT_ERROR;
@@ -2050,9 +2049,9 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
return CURLE_SSL_CONNECT_ERROR;
}
- if((Curl_inet_pton(AF_INET, hostname, &addr))
+ if((Curl_inet_pton(AF_INET, connssl->hostname, &addr))
#ifdef ENABLE_IPV6
- || (Curl_inet_pton(AF_INET6, hostname, &addr))
+ || (Curl_inet_pton(AF_INET6, connssl->hostname, &addr))
#endif
) {
infof(data, "WARNING: using IP address, SNI is being disabled by "
@@ -2063,7 +2062,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
infof(data, "WARNING: disabling hostname validation also disables SNI.");
}
- ciphers = SSL_CONN_CONFIG(cipher_list);
+ ciphers = conn_config->cipher_list;
if(ciphers) {
err = sectransp_set_selected_ciphers(data, backend->ssl_ctx, ciphers);
}
@@ -2081,20 +2080,20 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
specifically doesn't want us doing that: */
if(SSLSetSessionOption) {
SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
- !SSL_SET_OPTION(enable_beast));
+ !ssl_config->enable_beast);
SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionFalseStart,
- data->set.ssl.falsestart); /* false start support */
+ ssl_config->falsestart); /* false start support */
}
#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
/* Check if there's a cached ID we can/should use here! */
- if(SSL_SET_OPTION(primary.sessionid)) {
+ if(ssl_config->primary.sessionid) {
char *ssl_sessionid;
size_t ssl_sessionid_len;
Curl_ssl_sessionid_lock(data);
- if(!Curl_ssl_getsessionid(data, conn, isproxy, (void **)&ssl_sessionid,
- &ssl_sessionid_len, sockindex)) {
+ if(!Curl_ssl_getsessionid(cf, data, (void **)&ssl_sessionid,
+ &ssl_sessionid_len)) {
/* we got a session id, use it! */
err = SSLSetPeerID(backend->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
Curl_ssl_sessionid_unlock(data);
@@ -2110,9 +2109,10 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
else {
CURLcode result;
ssl_sessionid =
- aprintf("%s:%d:%d:%s:%ld",
+ aprintf("%s:%d:%d:%s:%d",
ssl_cafile ? ssl_cafile : "(blob memory)",
- verifypeer, SSL_CONN_CONFIG(verifyhost), hostname, port);
+ verifypeer, conn_config->verifyhost, connssl->hostname,
+ connssl->port);
ssl_sessionid_len = strlen(ssl_sessionid);
err = SSLSetPeerID(backend->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
@@ -2122,8 +2122,8 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
return CURLE_SSL_CONNECT_ERROR;
}
- result = Curl_ssl_addsessionid(data, conn, isproxy, ssl_sessionid,
- ssl_sessionid_len, sockindex, NULL);
+ result = Curl_ssl_addsessionid(cf, data, ssl_sessionid,
+ ssl_sessionid_len, NULL);
Curl_ssl_sessionid_unlock(data);
if(result) {
failf(data, "failed to store ssl session");
@@ -2542,16 +2542,15 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
}
#endif /* SECTRANSP_PINNEDPUBKEY */
-static CURLcode
-sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+static CURLcode sectransp_connect_step2(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
OSStatus err;
SSLCipherSuite cipher;
SSLProtocol protocol = 0;
- const char * const hostname = SSL_HOST_NAME();
DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
|| ssl_connect_2_reading == connssl->connecting_state
@@ -2571,16 +2570,16 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn,
/* The below is errSSLServerAuthCompleted; it's not defined in
Leopard's headers */
case -9841:
- if((SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) &&
- SSL_CONN_CONFIG(verifypeer)) {
- CURLcode result = verify_cert(data, SSL_CONN_CONFIG(CAfile),
- SSL_CONN_CONFIG(ca_info_blob),
+ if((conn_config->CAfile || conn_config->ca_info_blob) &&
+ conn_config->verifypeer) {
+ CURLcode result = verify_cert(data, conn_config->CAfile,
+ conn_config->ca_info_blob,
backend->ssl_ctx);
if(result)
return result;
}
/* the documentation says we need to call SSLHandshake() again */
- return sectransp_connect_step2(data, conn, sockindex);
+ return sectransp_connect_step2(cf, data);
/* Problem with encrypt / decrypt */
case errSSLPeerDecodeError:
@@ -2682,7 +2681,7 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn,
host name: */
case errSSLHostNameMismatch:
failf(data, "SSL certificate peer verification failed, the "
- "certificate did not match \"%s\"\n", conn->host.dispname);
+ "certificate did not match \"%s\"\n", connssl->dispname);
return CURLE_PEER_FAILED_VERIFICATION;
/* Problem with SSL / TLS negotiation */
@@ -2774,7 +2773,7 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn,
default:
/* May also return codes listed in Security Framework Result Codes */
failf(data, "Unknown SSL protocol error in connection to %s:%d",
- hostname, err);
+ connssl->hostname, err);
break;
}
return CURLE_SSL_CONNECT_ERROR;
@@ -2833,7 +2832,7 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn,
}
#if(CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
- if(conn->bits.tls_enable_alpn) {
+ if(cf->conn->bits.tls_enable_alpn) {
if(__builtin_available(macOS 10.13.4, iOS 11, tvOS 11, *)) {
CFArrayRef alpnArr = NULL;
CFStringRef chosenProtocol = NULL;
@@ -2845,18 +2844,18 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn,
#ifdef USE_HTTP2
if(chosenProtocol &&
!CFStringCompare(chosenProtocol, CFSTR(ALPN_H2), 0)) {
- conn->alpn = CURL_HTTP_VERSION_2;
+ cf->conn->alpn = CURL_HTTP_VERSION_2;
}
else
#endif
if(chosenProtocol &&
!CFStringCompare(chosenProtocol, CFSTR(ALPN_HTTP_1_1), 0)) {
- conn->alpn = CURL_HTTP_VERSION_1_1;
+ cf->conn->alpn = CURL_HTTP_VERSION_1_1;
}
else
infof(data, VTLS_INFOF_NO_ALPN);
- Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ?
+ Curl_multiuse_state(data, cf->conn->alpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
/* chosenProtocol is a reference to the string within alpnArr
@@ -2892,11 +2891,12 @@ add_cert_to_certinfo(struct Curl_easy *data,
}
static CURLcode
-collect_server_cert_single(struct Curl_easy *data,
+collect_server_cert_single(struct Curl_cfilter *cf, struct Curl_easy *data,
SecCertificateRef server_cert,
CFIndex idx)
{
CURLcode result = CURLE_OK;
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
#ifndef CURL_DISABLE_VERBOSE_STRINGS
if(data->set.verbose) {
char *certp;
@@ -2907,25 +2907,24 @@ collect_server_cert_single(struct Curl_easy *data,
}
}
#endif
- if(data->set.ssl.certinfo)
+ if(ssl_config->certinfo)
result = add_cert_to_certinfo(data, server_cert, (int)idx);
return result;
}
/* This should be called during step3 of the connection at the earliest */
-static CURLcode
-collect_server_cert(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex)
+static CURLcode collect_server_cert(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
#ifndef CURL_DISABLE_VERBOSE_STRINGS
const bool show_verbose_server_cert = data->set.verbose;
#else
const bool show_verbose_server_cert = false;
#endif
- CURLcode result = data->set.ssl.certinfo ?
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
+ CURLcode result = ssl_config->certinfo ?
CURLE_PEER_FAILED_VERIFICATION : CURLE_OK;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
CFArrayRef server_certs = NULL;
SecCertificateRef server_cert;
@@ -2935,7 +2934,7 @@ collect_server_cert(struct Curl_easy *data,
DEBUGASSERT(backend);
- if(!show_verbose_server_cert && !data->set.ssl.certinfo)
+ if(!show_verbose_server_cert && !ssl_config->certinfo)
return CURLE_OK;
if(!backend->ssl_ctx)
@@ -2949,11 +2948,11 @@ collect_server_cert(struct Curl_easy *data,
a null trust, so be on guard for that: */
if(err == noErr && trust) {
count = SecTrustGetCertificateCount(trust);
- if(data->set.ssl.certinfo)
+ if(ssl_config->certinfo)
result = Curl_ssl_init_certinfo(data, (int)count);
for(i = 0L ; !result && (i < count) ; i++) {
server_cert = SecTrustGetCertificateAtIndex(trust, i);
- result = collect_server_cert_single(data, server_cert, i);
+ result = collect_server_cert_single(cf, data, server_cert, i);
}
CFRelease(trust);
}
@@ -2971,11 +2970,11 @@ collect_server_cert(struct Curl_easy *data,
a null trust, so be on guard for that: */
if(err == noErr && trust) {
count = SecTrustGetCertificateCount(trust);
- if(data->set.ssl.certinfo)
+ if(ssl_config->certinfo)
result = Curl_ssl_init_certinfo(data, (int)count);
for(i = 0L ; !result && (i < count) ; i++) {
server_cert = SecTrustGetCertificateAtIndex(trust, i);
- result = collect_server_cert_single(data, server_cert, i);
+ result = collect_server_cert_single(cf, data, server_cert, i);
}
CFRelease(trust);
}
@@ -2986,12 +2985,12 @@ collect_server_cert(struct Curl_easy *data,
/* Just in case SSLCopyPeerCertificates() returns null too... */
if(err == noErr && server_certs) {
count = CFArrayGetCount(server_certs);
- if(data->set.ssl.certinfo)
+ if(ssl_config->certinfo)
result = Curl_ssl_init_certinfo(data, (int)count);
for(i = 0L ; !result && (i < count) ; i++) {
server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
i);
- result = collect_server_cert_single(data, server_cert, i);
+ result = collect_server_cert_single(cf, data, server_cert, i);
}
CFRelease(server_certs);
}
@@ -3003,11 +3002,11 @@ collect_server_cert(struct Curl_easy *data,
err = SSLCopyPeerCertificates(backend->ssl_ctx, &server_certs);
if(err == noErr) {
count = CFArrayGetCount(server_certs);
- if(data->set.ssl.certinfo)
+ if(ssl_config->certinfo)
result = Curl_ssl_init_certinfo(data, (int)count);
for(i = 0L ; !result && (i < count) ; i++) {
server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i);
- result = collect_server_cert_single(data, server_cert, i);
+ result = collect_server_cert_single(cf, data, server_cert, i);
}
CFRelease(server_certs);
}
@@ -3015,16 +3014,15 @@ collect_server_cert(struct Curl_easy *data,
return result;
}
-static CURLcode
-sectransp_connect_step3(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+static CURLcode sectransp_connect_step3(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
/* There is no step 3!
* Well, okay, let's collect server certificates, and if verbose mode is on,
* let's print the details of the server certificates. */
- const CURLcode result = collect_server_cert(data, conn, sockindex);
+ const CURLcode result = collect_server_cert(cf, data);
if(result)
return result;
@@ -3032,19 +3030,14 @@ sectransp_connect_step3(struct Curl_easy *data, struct connectdata *conn,
return CURLE_OK;
}
-static Curl_recv sectransp_recv;
-static Curl_send sectransp_send;
-
static CURLcode
-sectransp_connect_common(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex,
+sectransp_connect_common(struct Curl_cfilter *cf, struct Curl_easy *data,
bool nonblocking,
bool *done)
{
CURLcode result;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- curl_socket_t sockfd = conn->sock[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
+ curl_socket_t sockfd = cf->conn->sock[cf->sockindex];
int what;
/* check if the connection has already been established */
@@ -3063,7 +3056,7 @@ sectransp_connect_common(struct Curl_easy *data,
return CURLE_OPERATION_TIMEDOUT;
}
- result = sectransp_connect_step1(data, conn, sockindex);
+ result = sectransp_connect_step1(cf, data);
if(result)
return result;
}
@@ -3117,7 +3110,7 @@ sectransp_connect_common(struct Curl_easy *data,
* before step2 has completed while ensuring that a client using select()
* or epoll() will always have a valid fdset to wait on.
*/
- result = sectransp_connect_step2(data, conn, sockindex);
+ result = sectransp_connect_step2(cf, data);
if(result || (nonblocking &&
(ssl_connect_2 == connssl->connecting_state ||
ssl_connect_2_reading == connssl->connecting_state ||
@@ -3128,7 +3121,7 @@ sectransp_connect_common(struct Curl_easy *data,
if(ssl_connect_3 == connssl->connecting_state) {
- result = sectransp_connect_step3(data, conn, sockindex);
+ result = sectransp_connect_step3(cf, data);
if(result)
return result;
}
@@ -3146,20 +3139,20 @@ sectransp_connect_common(struct Curl_easy *data,
return CURLE_OK;
}
-static CURLcode sectransp_connect_nonblocking(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex, bool *done)
+static CURLcode sectransp_connect_nonblocking(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool *done)
{
- return sectransp_connect_common(data, conn, sockindex, TRUE, done);
+ return sectransp_connect_common(cf, data, TRUE, done);
}
-static CURLcode sectransp_connect(struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+static CURLcode sectransp_connect(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
CURLcode result;
bool done = FALSE;
- result = sectransp_connect_common(data, conn, sockindex, FALSE, &done);
+ result = sectransp_connect_common(cf, data, FALSE, &done);
if(result)
return result;
@@ -3169,10 +3162,9 @@ static CURLcode sectransp_connect(struct Curl_easy *data,
return CURLE_OK;
}
-static void sectransp_close(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+static void sectransp_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
(void) data;
@@ -3196,10 +3188,10 @@ static void sectransp_close(struct Curl_easy *data, struct connectdata *conn,
backend->ssl_sockfd = 0;
}
-static int sectransp_shutdown(struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+static int sectransp_shutdown(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
ssize_t nread;
int what;
@@ -3217,11 +3209,11 @@ static int sectransp_shutdown(struct Curl_easy *data,
return 0;
#endif
- sectransp_close(data, conn, sockindex);
+ sectransp_close(cf, data);
rc = 0;
- what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT);
+ what = SOCKET_READABLE(cf->conn->sock[cf->sockindex], SSL_SHUTDOWN_TIMEOUT);
while(loop--) {
if(what < 0) {
@@ -3239,7 +3231,7 @@ static int sectransp_shutdown(struct Curl_easy *data,
/* Something to read, let's do it and hope that it is the close
notify alert from the server. No way to SSL_Read now, so use read(). */
- nread = read(conn->sock[sockindex], buf, sizeof(buf));
+ nread = read(cf->conn->sock[cf->sockindex], buf, sizeof(buf));
if(nread < 0) {
char buffer[STRERROR_LEN];
@@ -3251,7 +3243,7 @@ static int sectransp_shutdown(struct Curl_easy *data,
if(nread <= 0)
break;
- what = SOCKET_READABLE(conn->sock[sockindex], 0);
+ what = SOCKET_READABLE(cf->conn->sock[cf->sockindex], 0);
}
return rc;
@@ -3281,13 +3273,15 @@ static size_t sectransp_version(char *buffer, size_t size)
* 0 means the connection has been closed
* -1 means the connection status is unknown
*/
-static int sectransp_check_cxn(struct connectdata *conn)
+static int sectransp_check_cxn(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
OSStatus err;
SSLSessionState state;
+ (void)data;
DEBUGASSERT(backend);
if(backend->ssl_ctx) {
@@ -3299,14 +3293,15 @@ static int sectransp_check_cxn(struct connectdata *conn)
return 0;
}
-static bool sectransp_data_pending(const struct connectdata *conn,
- int connindex)
+static bool sectransp_data_pending(struct Curl_cfilter *cf,
+ const struct Curl_easy *data)
{
- const struct ssl_connect_data *connssl = &conn->ssl[connindex];
+ const struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
OSStatus err;
size_t buffer;
+ (void)data;
DEBUGASSERT(backend);
if(backend->ssl_ctx) { /* SSL is in use */
@@ -3358,14 +3353,13 @@ static bool sectransp_false_start(void)
return FALSE;
}
-static ssize_t sectransp_send(struct Curl_easy *data,
- int sockindex,
+static ssize_t sectransp_send(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
const void *mem,
size_t len,
CURLcode *curlcode)
{
- struct connectdata *conn = data->conn;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
size_t processed = 0UL;
OSStatus err;
@@ -3427,15 +3421,15 @@ static ssize_t sectransp_send(struct Curl_easy *data,
return (ssize_t)processed;
}
-static ssize_t sectransp_recv(struct Curl_easy *data,
- int num,
+static ssize_t sectransp_recv(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
char *buf,
size_t buffersize,
CURLcode *curlcode)
{
- struct connectdata *conn = data->conn;
- struct ssl_connect_data *connssl = &conn->ssl[num];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
size_t processed = 0UL;
OSStatus err;
@@ -3466,10 +3460,10 @@ static ssize_t sectransp_recv(struct Curl_easy *data,
/* The below is errSSLPeerAuthCompleted; it's not defined in
Leopard's headers */
case -9841:
- if((SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) &&
- SSL_CONN_CONFIG(verifypeer)) {
- CURLcode result = verify_cert(data, SSL_CONN_CONFIG(CAfile),
- SSL_CONN_CONFIG(ca_info_blob),
+ if((conn_config->CAfile || conn_config->ca_info_blob) &&
+ conn_config->verifypeer) {
+ CURLcode result = verify_cert(data, conn_config->CAfile,
+ conn_config->ca_info_blob,
backend->ssl_ctx);
if(result)
return result;
@@ -3517,7 +3511,7 @@ const struct Curl_ssl Curl_ssl_sectransp = {
Curl_none_cert_status_request, /* cert_status_request */
sectransp_connect, /* connect */
sectransp_connect_nonblocking, /* connect_nonblocking */
- Curl_ssl_getsock, /* getsock */
+ Curl_ssl_get_select_socks, /* getsock */
sectransp_get_internals, /* get_internals */
sectransp_close, /* close_one */
Curl_none_close_all, /* close_all */
diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c
index 67b378402..91fdd2f00 100644
--- a/lib/vtls/vtls.c
+++ b/lib/vtls/vtls.c
@@ -293,109 +293,60 @@ static bool ssl_prefs_check(struct Curl_easy *data)
return TRUE;
}
-#ifndef CURL_DISABLE_PROXY
-static CURLcode
-ssl_connect_init_proxy(struct connectdata *conn, int sockindex)
-{
- /* TODO: curl has, so far, a limit of 2 SSL instances per
- * connection per sockindex. One for SSL to the origin server
- * and one for SSL to a proxy server.
- * - conn->ssl[sockindex]
- * - conn->ssl_proxy[sockindex]
- * Any SSL activity always happens on conn->ssl[sockindex], even
- * if it is to a proxy server. When the handshake is done,
- * conn->bits.proxy_ssl_connected[sockindex] = TRUE
- * is set, though conn->ssl_proxy[sockindex] is still empty.
- *
- * A new activity, on seeing this, will COPY the contents
- * of conn->ssl[sockindex] to conn->ssl_proxy[sockindex]
- * and NUL conn->ssl[sockindex] for a fresh start.
- *
- * This is what this function does.
- */
- DEBUGASSERT(conn->bits.proxy_ssl_connected[sockindex]);
- if(ssl_connection_complete == conn->ssl[sockindex].state &&
- !conn->proxy_ssl[sockindex].use) {
- struct ssl_backend_data *pbdata;
-
- if(!(Curl_ssl->supports & SSLSUPP_HTTPS_PROXY))
- return CURLE_NOT_BUILT_IN;
-
- /* The pointers to the ssl backend data, which is opaque here, are swapped
- rather than move the contents. */
- pbdata = conn->proxy_ssl[sockindex].backend;
- conn->proxy_ssl[sockindex] = conn->ssl[sockindex];
+static struct ssl_connect_data *cf_ctx_new(struct Curl_easy *data)
+{
+ struct ssl_connect_data *ctx;
- DEBUGASSERT(pbdata != NULL);
+ ctx = calloc(1, sizeof(*ctx));
+ if(!ctx)
+ return NULL;
- memset(&conn->ssl[sockindex], 0, sizeof(conn->ssl[sockindex]));
- memset(pbdata, 0, Curl_ssl->sizeof_ssl_backend_data);
+ ctx->backend = calloc(1, Curl_ssl_get_backend_data_size(data));
+ if(!ctx->backend) {
+ free(ctx);
+ return NULL;
+ }
+ return ctx;
+}
- conn->ssl[sockindex].backend = pbdata;
+static void cf_ctx_free(struct ssl_connect_data *ctx)
+{
+ if(ctx) {
+ free(ctx->backend);
+ free(ctx);
}
- return CURLE_OK;
}
-#endif
-static CURLcode
-ssl_connect(struct Curl_easy *data, struct connectdata *conn, int sockindex)
+static CURLcode ssl_connect(struct Curl_cfilter *cf, struct Curl_easy *data)
{
+ struct ssl_connect_data *connssl = cf->ctx;
CURLcode result;
-#ifndef CURL_DISABLE_PROXY
- if(conn->bits.proxy_ssl_connected[sockindex]) {
- result = ssl_connect_init_proxy(conn, sockindex);
- if(result)
- return result;
- }
-#endif
-
if(!ssl_prefs_check(data))
return CURLE_SSL_CONNECT_ERROR;
/* mark this is being ssl-enabled from here on. */
- conn->ssl[sockindex].use = TRUE;
- conn->ssl[sockindex].state = ssl_connection_negotiating;
+ connssl->state = ssl_connection_negotiating;
- result = Curl_ssl->connect_blocking(data, conn, sockindex);
+ result = Curl_ssl->connect_blocking(cf, data);
if(!result) {
Curl_pgrsTime(data, TIMER_APPCONNECT); /* SSL is connected */
- DEBUGASSERT(conn->ssl[sockindex].state == ssl_connection_complete);
+ DEBUGASSERT(connssl->state == ssl_connection_complete);
}
- else
- conn->ssl[sockindex].use = FALSE;
return result;
}
static CURLcode
-ssl_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn,
- bool isproxy, int sockindex, bool *done)
+ssl_connect_nonblocking(struct Curl_cfilter *cf, struct Curl_easy *data,
+ bool *done)
{
- CURLcode result;
-
-#ifndef CURL_DISABLE_PROXY
- if(conn->bits.proxy_ssl_connected[sockindex]) {
- result = ssl_connect_init_proxy(conn, sockindex);
- if(result)
- return result;
- }
-#endif
if(!ssl_prefs_check(data))
return CURLE_SSL_CONNECT_ERROR;
/* mark this is being ssl requested from here on. */
- conn->ssl[sockindex].use = TRUE;
- result = Curl_ssl->connect_nonblocking(data, conn, sockindex, done);
- if(result)
- conn->ssl[sockindex].use = FALSE;
- else if(*done) {
- if(!isproxy)
- Curl_pgrsTime(data, TIMER_APPCONNECT); /* SSL is connected */
- DEBUGASSERT(conn->ssl[sockindex].state == ssl_connection_complete);
- }
- return result;
+ return Curl_ssl->connect_nonblocking(cf, data, done);
}
/*
@@ -420,42 +371,30 @@ void Curl_ssl_sessionid_unlock(struct Curl_easy *data)
* Check if there's a session ID for the given connection in the cache, and if
* there's one suitable, it is provided. Returns TRUE when no entry matched.
*/
-bool Curl_ssl_getsessionid(struct Curl_easy *data,
- struct connectdata *conn,
- const bool isProxy,
+bool Curl_ssl_getsessionid(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
void **ssl_sessionid,
- size_t *idsize, /* set 0 if unknown */
- int sockindex)
+ size_t *idsize) /* set 0 if unknown */
{
+ struct ssl_connect_data *connssl = cf->ctx;
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
struct Curl_ssl_session *check;
size_t i;
long *general_age;
bool no_match = TRUE;
-#ifndef CURL_DISABLE_PROXY
- struct ssl_primary_config * const ssl_config = isProxy ?
- &conn->proxy_ssl_config :
- &conn->ssl_config;
- const char * const name = isProxy ?
- conn->http_proxy.host.name : conn->host.name;
- int port = isProxy ? (int)conn->port : conn->remote_port;
-#else
- /* no proxy support */
- struct ssl_primary_config * const ssl_config = &conn->ssl_config;
- const char * const name = conn->host.name;
- int port = conn->remote_port;
-#endif
- (void)sockindex;
*ssl_sessionid = NULL;
-
+ if(!ssl_config)
+ return TRUE;
#ifdef CURL_DISABLE_PROXY
if(isProxy)
return TRUE;
#endif
- DEBUGASSERT(SSL_SET_OPTION(primary.sessionid));
+ DEBUGASSERT(ssl_config->primary.sessionid);
- if(!SSL_SET_OPTION(primary.sessionid) || !data->state.session)
+ if(!ssl_config->primary.sessionid || !data->state.session)
/* session ID re-use is disabled or the session cache has not been
setup */
return TRUE;
@@ -471,16 +410,16 @@ bool Curl_ssl_getsessionid(struct Curl_easy *data,
if(!check->sessionid)
/* not session ID means blank entry */
continue;
- if(strcasecompare(name, check->name) &&
- ((!conn->bits.conn_to_host && !check->conn_to_host) ||
- (conn->bits.conn_to_host && check->conn_to_host &&
- strcasecompare(conn->conn_to_host.name, check->conn_to_host))) &&
- ((!conn->bits.conn_to_port && check->conn_to_port == -1) ||
- (conn->bits.conn_to_port && check->conn_to_port != -1 &&
- conn->conn_to_port == check->conn_to_port)) &&
- (port == check->remote_port) &&
- strcasecompare(conn->handler->scheme, check->scheme) &&
- Curl_ssl_config_matches(ssl_config, &check->ssl_config)) {
+ if(strcasecompare(connssl->hostname, check->name) &&
+ ((!cf->conn->bits.conn_to_host && !check->conn_to_host) ||
+ (cf->conn->bits.conn_to_host && check->conn_to_host &&
+ strcasecompare(cf->conn->conn_to_host.name, check->conn_to_host))) &&
+ ((!cf->conn->bits.conn_to_port && check->conn_to_port == -1) ||
+ (cf->conn->bits.conn_to_port && check->conn_to_port != -1 &&
+ cf->conn->conn_to_port == check->conn_to_port)) &&
+ (connssl->port == check->remote_port) &&
+ strcasecompare(cf->conn->handler->scheme, check->scheme) &&
+ Curl_ssl_config_matches(conn_config, &check->ssl_config)) {
/* yes, we have a session ID! */
(*general_age)++; /* increase general age */
check->age = *general_age; /* set this as used in this age */
@@ -492,10 +431,10 @@ bool Curl_ssl_getsessionid(struct Curl_easy *data,
}
}
- DEBUGF(infof(data, "%s Session ID in cache for %s %s://%s:%d",
+ DEBUGF(infof(data, DMSG(data, "%s Session ID in cache for %s %s://%s:%d"),
no_match? "Didn't find": "Found",
- isProxy ? "proxy" : "host",
- conn->handler->scheme, name, port));
+ Curl_ssl_cf_is_proxy(cf) ? "proxy" : "host",
+ cf->conn->handler->scheme, connssl->hostname, connssl->port));
return no_match;
}
@@ -543,14 +482,15 @@ void Curl_ssl_delsessionid(struct Curl_easy *data, void *ssl_sessionid)
* layer. Curl_XXXX_session_free() will be called to free/kill the session ID
* later on.
*/
-CURLcode Curl_ssl_addsessionid(struct Curl_easy *data,
- struct connectdata *conn,
- const bool isProxy,
+CURLcode Curl_ssl_addsessionid(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
void *ssl_sessionid,
size_t idsize,
- int sockindex,
bool *added)
{
+ struct ssl_connect_data *connssl = cf->ctx;
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
size_t i;
struct Curl_ssl_session *store;
long oldest_age;
@@ -558,17 +498,6 @@ CURLcode Curl_ssl_addsessionid(struct Curl_easy *data,
char *clone_conn_to_host;
int conn_to_port;
long *general_age;
-#ifndef CURL_DISABLE_PROXY
- struct ssl_primary_config * const ssl_config = isProxy ?
- &conn->proxy_ssl_config :
- &conn->ssl_config;
- const char *hostname = isProxy ? conn->http_proxy.host.name :
- conn->host.name;
-#else
- struct ssl_primary_config * const ssl_config = &conn->ssl_config;
- const char *hostname = conn->host.name;
-#endif
- (void)sockindex;
if(added)
*added = FALSE;
@@ -578,14 +507,15 @@ CURLcode Curl_ssl_addsessionid(struct Curl_easy *data,
store = &data->state.session[0];
oldest_age = data->state.session[0].age; /* zero if unused */
- DEBUGASSERT(SSL_SET_OPTION(primary.sessionid));
+ (void)ssl_config;
+ DEBUGASSERT(ssl_config->primary.sessionid);
- clone_host = strdup(hostname);
+ clone_host = strdup(connssl->hostname);
if(!clone_host)
return CURLE_OUT_OF_MEMORY; /* bail out */
- if(conn->bits.conn_to_host) {
- clone_conn_to_host = strdup(conn->conn_to_host.name);
+ if(cf->conn->bits.conn_to_host) {
+ clone_conn_to_host = strdup(cf->conn->conn_to_host.name);
if(!clone_conn_to_host) {
free(clone_host);
return CURLE_OUT_OF_MEMORY; /* bail out */
@@ -594,8 +524,8 @@ CURLcode Curl_ssl_addsessionid(struct Curl_easy *data,
else
clone_conn_to_host = NULL;
- if(conn->bits.conn_to_port)
- conn_to_port = conn->conn_to_port;
+ if(cf->conn->bits.conn_to_port)
+ conn_to_port = cf->conn->conn_to_port;
else
conn_to_port = -1;
@@ -635,10 +565,10 @@ CURLcode Curl_ssl_addsessionid(struct Curl_easy *data,
store->conn_to_host = clone_conn_to_host; /* clone connect to host name */
store->conn_to_port = conn_to_port; /* connect to port number */
/* port number */
- store->remote_port = isProxy ? (int)conn->port : conn->remote_port;
- store->scheme = conn->handler->scheme;
+ store->remote_port = connssl->port;
+ store->scheme = cf->conn->handler->scheme;
- if(!Curl_clone_primary_ssl_config(ssl_config, &store->ssl_config)) {
+ if(!Curl_clone_primary_ssl_config(conn_config, &store->ssl_config)) {
Curl_free_primary_ssl_config(&store->ssl_config);
store->sessionid = NULL; /* let caller free sessionid */
free(clone_host);
@@ -649,9 +579,9 @@ CURLcode Curl_ssl_addsessionid(struct Curl_easy *data,
if(added)
*added = TRUE;
- DEBUGF(infof(data, "Added Session ID to cache for %s://%s:%d [%s]",
- store->scheme, store->name, store->remote_port,
- isProxy ? "PROXY" : "server"));
+ DEBUGF(infof(data, DMSG(data, "Added Session ID to cache for %s://%s:%d"
+ " [%s]"), store->scheme, store->name, store->remote_port,
+ Curl_ssl_cf_is_proxy(cf) ? "PROXY" : "server"));
return CURLE_OK;
}
@@ -677,36 +607,26 @@ void Curl_ssl_close_all(struct Curl_easy *data)
Curl_ssl->close_all(data);
}
-int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks)
+int Curl_ssl_get_select_socks(struct Curl_cfilter *cf, struct Curl_easy *data,
+ curl_socket_t *socks)
{
- struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
+ struct ssl_connect_data *connssl = cf->ctx;
+ (void)data;
if(connssl->connecting_state == ssl_connect_2_writing) {
/* write mode */
- socks[0] = conn->sock[FIRSTSOCKET];
+ socks[0] = cf->conn->sock[FIRSTSOCKET];
return GETSOCK_WRITESOCK(0);
}
if(connssl->connecting_state == ssl_connect_2_reading) {
/* read mode */
- socks[0] = conn->sock[FIRSTSOCKET];
+ socks[0] = cf->conn->sock[FIRSTSOCKET];
return GETSOCK_READSOCK(0);
}
return GETSOCK_BLANK;
}
-CURLcode Curl_ssl_shutdown(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
-{
- if(Curl_ssl->shut_down(data, conn, sockindex))
- return CURLE_SSL_SHUTDOWN_FAILED;
-
- conn->ssl[sockindex].use = FALSE; /* get back to ordinary socket usage */
- conn->ssl[sockindex].state = ssl_connection_none;
-
- return CURLE_OK;
-}
-
/* Selects an SSL crypto engine
*/
CURLcode Curl_ssl_set_engine(struct Curl_easy *data, const char *engine)
@@ -769,9 +689,10 @@ void Curl_ssl_version(char *buffer, size_t size)
* 0 means the connection has been closed
* -1 means the connection status is unknown
*/
-int Curl_ssl_check_cxn(struct connectdata *conn)
+int Curl_ssl_check_cxn(struct Curl_easy *data, struct connectdata *conn)
{
- return Curl_ssl->check_cxn(conn);
+ struct Curl_cfilter *cf = Curl_ssl_cf_get_ssl(conn->cfilter[FIRSTSOCKET]);
+ return cf? Curl_ssl->check_cxn(cf, data) : -1;
}
void Curl_ssl_free_certinfo(struct Curl_easy *data)
@@ -1145,19 +1066,18 @@ int Curl_none_init(void)
void Curl_none_cleanup(void)
{ }
-int Curl_none_shutdown(struct Curl_easy *data UNUSED_PARAM,
- struct connectdata *conn UNUSED_PARAM,
- int sockindex UNUSED_PARAM)
+int Curl_none_shutdown(struct Curl_cfilter *cf UNUSED_PARAM,
+ struct Curl_easy *data UNUSED_PARAM)
{
(void)data;
- (void)conn;
- (void)sockindex;
+ (void)cf;
return 0;
}
-int Curl_none_check_cxn(struct connectdata *conn UNUSED_PARAM)
+int Curl_none_check_cxn(struct Curl_cfilter *cf, struct Curl_easy *data)
{
- (void)conn;
+ (void)cf;
+ (void)data;
return -1;
}
@@ -1181,11 +1101,11 @@ void Curl_none_session_free(void *ptr UNUSED_PARAM)
(void)ptr;
}
-bool Curl_none_data_pending(const struct connectdata *conn UNUSED_PARAM,
- int connindex UNUSED_PARAM)
+bool Curl_none_data_pending(struct Curl_cfilter *cf UNUSED_PARAM,
+ const struct Curl_easy *data UNUSED_PARAM)
{
- (void)conn;
- (void)connindex;
+ (void)cf;
+ (void)data;
return 0;
}
@@ -1226,28 +1146,30 @@ static int multissl_init(void)
return Curl_ssl->init();
}
-static CURLcode multissl_connect(struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+static CURLcode multissl_connect(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
if(multissl_setup(NULL))
return CURLE_FAILED_INIT;
- return Curl_ssl->connect_blocking(data, conn, sockindex);
+ return Curl_ssl->connect_blocking(cf, data);
}
-static CURLcode multissl_connect_nonblocking(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex, bool *done)
+static CURLcode multissl_connect_nonblocking(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool *done)
{
if(multissl_setup(NULL))
return CURLE_FAILED_INIT;
- return Curl_ssl->connect_nonblocking(data, conn, sockindex, done);
+ return Curl_ssl->connect_nonblocking(cf, data, done);
}
-static int multissl_getsock(struct connectdata *conn, curl_socket_t *socks)
+static int multissl_get_select_socks(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ curl_socket_t *socks)
{
if(multissl_setup(NULL))
return 0;
- return Curl_ssl->getsock(conn, socks);
+ return Curl_ssl->get_select_socks(cf, data, socks);
}
static void *multissl_get_internals(struct ssl_connect_data *connssl,
@@ -1258,29 +1180,30 @@ static void *multissl_get_internals(struct ssl_connect_data *connssl,
return Curl_ssl->get_internals(connssl, info);
}
-static void multissl_close(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+static void multissl_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
if(multissl_setup(NULL))
return;
- Curl_ssl->close_one(data, conn, sockindex);
+ Curl_ssl->close(cf, data);
}
-static ssize_t multissl_recv_plain(struct Curl_easy *data, int sockindex,
+static ssize_t multissl_recv_plain(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
char *buf, size_t len, CURLcode *code)
{
if(multissl_setup(NULL))
return CURLE_FAILED_INIT;
- return Curl_ssl->recv_plain(data, sockindex, buf, len, code);
+ return Curl_ssl->recv_plain(cf, data, buf, len, code);
}
-static ssize_t multissl_send_plain(struct Curl_easy *data, int sockindex,
+static ssize_t multissl_send_plain(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
const void *mem, size_t len,
CURLcode *code)
{
if(multissl_setup(NULL))
return CURLE_FAILED_INIT;
- return Curl_ssl->send_plain(data, sockindex, mem, len, code);
+ return Curl_ssl->send_plain(cf, data, mem, len, code);
}
static const struct Curl_ssl Curl_ssl_multi = {
@@ -1298,7 +1221,7 @@ static const struct Curl_ssl Curl_ssl_multi = {
Curl_none_cert_status_request, /* cert_status_request */
multissl_connect, /* connect */
multissl_connect_nonblocking, /* connect_nonblocking */
- multissl_getsock, /* getsock */
+ multissl_get_select_socks, /* getsock */
multissl_get_internals, /* get_internals */
multissl_close, /* close_one */
Curl_none_close_all, /* close_all */
@@ -1505,19 +1428,47 @@ CURLsslset Curl_init_sslset_nolock(curl_sslbackend id, const char *name,
static void cf_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
+ struct ssl_connect_data *connssl = cf->ctx;
/* TODO: close_one closes BOTH conn->ssl AND conn->proxy_ssl for this
* sockindex (if in use). Gladly, it is safe to call more than once. */
- Curl_ssl->close_one(data, cf->conn, cf->sockindex);
- cf->conn->ssl[cf->sockindex].state = ssl_connection_none;
-#ifndef CURL_DISABLE_PROXY
- cf->conn->bits.proxy_ssl_connected[cf->sockindex] = FALSE;
-#endif
+ if(connssl) {
+ Curl_ssl->close(cf, data);
+ connssl->state = ssl_connection_none;
+ }
cf->connected = FALSE;
}
+static void reinit_hostname(struct Curl_cfilter *cf)
+{
+ struct ssl_connect_data *connssl = cf->ctx;
+
+ if(Curl_ssl_cf_is_proxy(cf)) {
+ /* TODO: there is not definition for a proxy setup on a secondary conn */
+ connssl->hostname = cf->conn->http_proxy.host.name;
+ connssl->dispname = cf->conn->http_proxy.host.dispname;
+ connssl->port = (int)cf->conn->http_proxy.port;
+ }
+ else {
+ /* TODO: secondaryhostname is set to the IP address we connect to
+ * in the FTP handler, it is assumed that host verification uses the
+ * hostname from FIRSTSOCKET */
+ if(cf->sockindex == SECONDARYSOCKET && 0) {
+ connssl->hostname = cf->conn->secondaryhostname;
+ connssl->dispname = connssl->hostname;
+ connssl->port = (int)cf->conn->secondary_port;
+ }
+ else {
+ connssl->hostname = cf->conn->host.name;
+ connssl->dispname = cf->conn->host.dispname;
+ connssl->port = (int)cf->conn->remote_port;
+ }
+ }
+}
+
static void ssl_cf_destroy(struct Curl_cfilter *cf, struct Curl_easy *data)
{
cf_close(cf, data);
+ cf_ctx_free(cf->ctx);
}
static CURLcode ssl_cf_setup(struct Curl_cfilter *cf,
@@ -1545,6 +1496,7 @@ static CURLcode ssl_cf_connect(struct Curl_cfilter *cf,
struct Curl_easy *data,
bool blocking, bool *done)
{
+ struct ssl_connect_data *connssl = cf->ctx;
CURLcode result;
if(cf->connected) {
@@ -1552,48 +1504,39 @@ static CURLcode ssl_cf_connect(struct Curl_cfilter *cf,
return CURLE_OK;
}
+ (void)connssl;
+ DEBUGASSERT(connssl);
+ /* TODO: right now we do not fully control when hostname is set, but
+ * copy it over again on each connect call. Esp. secondary chains seems
+ * to set it after the filters have been added */
+ reinit_hostname(cf);
+
result = cf->next->cft->connect(cf->next, data, blocking, done);
if(result || !*done)
return result;
*done = FALSE;
if(blocking) {
- result = ssl_connect(data, cf->conn, cf->sockindex);
+ result = ssl_connect(cf, data);
*done = (result == CURLE_OK);
}
else {
- result = ssl_connect_nonblocking(data, cf->conn, FALSE,
- cf->sockindex, done);
+ result = ssl_connect_nonblocking(cf, data, done);
}
- if (*done)
- cf->connected = TRUE;
- return result;
-}
-#ifndef CURL_DISABLE_PROXY
-static CURLcode ssl_proxy_cf_connect(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- bool blocking, bool *done)
-{
- CURLcode result;
-
- if(cf->connected) {
- *done = TRUE;
- return CURLE_OK;
- }
-
- result = ssl_cf_connect(cf, data, blocking, done);
if(!result && *done) {
- cf->conn->bits.proxy_ssl_connected[cf->sockindex] = TRUE;
+ cf->connected = TRUE;
+ if(cf->sockindex == FIRSTSOCKET && !Curl_ssl_cf_is_proxy(cf))
+ Curl_pgrsTime(data, TIMER_APPCONNECT); /* SSL is connected */
+ DEBUGASSERT(connssl->state == ssl_connection_complete);
}
return result;
}
-#endif
static bool ssl_cf_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data)
{
- if(Curl_ssl->data_pending(cf->conn, cf->sockindex))
+ if(cf->ctx && Curl_ssl->data_pending(cf, data))
return TRUE;
return cf->next->cft->has_data_pending(cf->next, data);
}
@@ -1605,9 +1548,9 @@ static ssize_t ssl_cf_send(struct Curl_cfilter *cf,
ssize_t nwritten;
*err = CURLE_OK;
- nwritten = Curl_ssl->send_plain(data, cf->sockindex, buf, len, err);
- DEBUGF(infof(data, "cf_ssl_send(handle=%p, len=%ld) -> %ld, code=%d",
- data, len, nwritten, *err));
+ nwritten = Curl_ssl->send_plain(cf, data, buf, len, err);
+ DEBUGF(infof(data, CFMSG(cf, "send(len=%ld) -> %ld, code=%d"),
+ len, nwritten, *err));
return nwritten;
}
@@ -1618,9 +1561,9 @@ static ssize_t ssl_cf_recv(struct Curl_cfilter *cf,
ssize_t nread;
*err = CURLE_OK;
- nread = Curl_ssl->recv_plain(data, cf->sockindex, buf, len, err);
- DEBUGF(infof(data, "cf_ssl_recv(handle=%p) -> %ld, code=%d",
- data, nread, *err));
+ nread = Curl_ssl->recv_plain(cf, data, buf, len, err);
+ DEBUGF(infof(data, CFMSG(cf, "recv -> %ld, code=%d"),
+ nread, *err));
return nread;
}
@@ -1634,22 +1577,22 @@ static int ssl_cf_get_select_socks(struct Curl_cfilter *cf,
* to READ or WRITE or needs nothing.
*/
(void)data;
- return Curl_ssl->getsock(cf->conn, socks);
+ return Curl_ssl->get_select_socks(cf, data, socks);
}
-static void ssl_cf_def_attach_data(struct Curl_cfilter *cf,
- struct Curl_easy *data)
+static void ssl_cf_attach_data(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- if(Curl_ssl->associate_connection) {
- Curl_ssl->associate_connection(data, cf->conn, cf->sockindex);
+ if(Curl_ssl->attach_data) {
+ Curl_ssl->attach_data(cf, data);
}
}
-static void ssl_cf_def_detach_data(struct Curl_cfilter *cf,
- struct Curl_easy *data)
+static void ssl_cf_detach_data(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- if(Curl_ssl->disassociate_connection) {
- Curl_ssl->disassociate_connection(data, cf->sockindex);
+ if(Curl_ssl->detach_data) {
+ Curl_ssl->detach_data(cf, data);
}
}
@@ -1657,60 +1600,89 @@ static const struct Curl_cftype cft_ssl = {
"SSL",
CF_TYPE_SSL,
ssl_cf_destroy,
- ssl_cf_def_attach_data,
- ssl_cf_def_detach_data,
ssl_cf_setup,
- ssl_cf_close,
ssl_cf_connect,
+ ssl_cf_close,
+ Curl_cf_def_get_host,
ssl_cf_get_select_socks,
ssl_cf_data_pending,
ssl_cf_send,
ssl_cf_recv,
+ ssl_cf_attach_data,
+ ssl_cf_detach_data,
};
-#ifndef CURL_DISABLE_PROXY
static const struct Curl_cftype cft_ssl_proxy = {
"SSL-PROXY",
CF_TYPE_SSL,
ssl_cf_destroy,
- ssl_cf_def_attach_data,
- ssl_cf_def_detach_data,
ssl_cf_setup,
+ ssl_cf_connect,
ssl_cf_close,
- ssl_proxy_cf_connect,
+ Curl_cf_def_get_host,
ssl_cf_get_select_socks,
ssl_cf_data_pending,
ssl_cf_send,
ssl_cf_recv,
+ ssl_cf_attach_data,
+ ssl_cf_detach_data,
};
-#endif
-CURLcode Curl_cfilter_ssl_add(struct Curl_easy *data,
- struct connectdata *conn,
+CURLcode Curl_ssl_cfilter_add(struct Curl_easy *data,
int sockindex)
{
struct Curl_cfilter *cf;
+ struct ssl_connect_data *ctx;
CURLcode result;
- result = Curl_cfilter_create(&cf, data, conn, sockindex,
- &cft_ssl, NULL);
- if(!result)
- Curl_cfilter_add(data, conn, sockindex, cf);
+ DEBUGASSERT(data->conn);
+ ctx = cf_ctx_new(data);
+ if(!ctx) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto out;
+ }
+
+ result = Curl_cf_create(&cf, &cft_ssl, ctx);
+ if(result)
+ goto out;
+
+ Curl_conn_cf_add(data, sockindex, cf);
+
+ reinit_hostname(cf);
+ result = CURLE_OK;
+
+out:
+ if(result)
+ cf_ctx_free(ctx);
return result;
}
#ifndef CURL_DISABLE_PROXY
-CURLcode Curl_cfilter_ssl_proxy_add(struct Curl_easy *data,
- struct connectdata *conn,
+CURLcode Curl_ssl_cfilter_proxy_add(struct Curl_easy *data,
int sockindex)
{
struct Curl_cfilter *cf;
+ struct ssl_connect_data *ctx;
CURLcode result;
- result = Curl_cfilter_create(&cf, data, conn, sockindex,
- &cft_ssl_proxy, NULL);
- if(!result)
- Curl_cfilter_add(data, conn, sockindex, cf);
+ ctx = cf_ctx_new(data);
+ if(!ctx) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto out;
+ }
+
+ result = Curl_cf_create(&cf, &cft_ssl_proxy, ctx);
+ if(result)
+ goto out;
+
+ Curl_conn_cf_add(data, sockindex, cf);
+
+ reinit_hostname(cf);
+ result = CURLE_OK;
+
+out:
+ if(result)
+ cf_ctx_free(ctx);
return result;
}
@@ -1731,53 +1703,124 @@ bool Curl_ssl_supports(struct Curl_easy *data, int option)
void *Curl_ssl_get_internals(struct Curl_easy *data, int sockindex,
CURLINFO info, int n)
{
- struct connectdata *conn = data->conn;
+ (void)n;
+ if(data->conn) {
+ struct Curl_cfilter *cf;
+ /* get first filter in chain, if any is present */
+ cf = Curl_ssl_cf_get_ssl(data->conn->cfilter[sockindex]);
+ if(cf)
+ return Curl_ssl->get_internals(cf->ctx, info);
+ }
+ return NULL;
+}
-#if 0
- struct Curl_cfilter *cf = conn? conn->cfilters[sockindex] : NULL;
+bool Curl_ssl_use(struct connectdata *conn, int sockindex)
+{
+ return Curl_ssl_cf_get_ssl(conn->cfilter[sockindex]) != NULL;
+}
+bool Curl_ssl_conn_is_ssl(struct Curl_easy *data,
+ int sockindex)
+{
+ struct Curl_cfilter *cf = data->conn? data->conn->cfilter[sockindex] : NULL;
+
+ /* TODO: this is an inomplete check. We might skip filters here that
+ * tunnel/transform and only use SSL for part of the connection.
+ */
+ (void)data;
for(; cf; cf = cf->next) {
- if(cf->cft == cft_ssl || cf->cft == cft_ssl_proxy) {
- if(n > 0) {
- --n;
- continue;
- }
- /* TODO: use cf->ctx instance once we have that */
- return Curl_ssl->get_internals(&data->conn->ssl[0], info);
+ if(cf->cft == &cft_ssl)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+CURLcode Curl_ssl_cfilter_remove(struct Curl_easy *data,
+ int sockindex)
+{
+ struct Curl_cfilter *cf = data->conn? data->conn->cfilter[sockindex] : NULL;
+ CURLcode result = CURLE_OK;
+
+ (void)data;
+ for(; cf; cf = cf->next) {
+ if(cf->cft == &cft_ssl) {
+ if(Curl_ssl->shut_down(cf, data))
+ result = CURLE_SSL_SHUTDOWN_FAILED;
+ Curl_conn_cf_discard(cf, data);
+ break;
}
}
-#else
- if(conn) {
- size_t i;
- (void)n;
- (void)sockindex;
- for(i = 0; i < (sizeof(conn->ssl) / sizeof(conn->ssl[0])); ++i) {
- if(conn->ssl[i].use) {
- return Curl_ssl->get_internals(&conn->ssl[i], info);
+ return result;
+}
+
+static struct Curl_cfilter *get_ssl_cf_engaged(struct connectdata *conn,
+ int sockindex)
+{
+ struct Curl_cfilter *cf, *lowest_ssl_cf = NULL;
+
+ for(cf = conn->cfilter[sockindex]; cf; cf = cf->next) {
+ if(cf->cft == &cft_ssl || cf->cft == &cft_ssl_proxy) {
+ lowest_ssl_cf = cf;
+ if(cf->connected || (cf->next && cf->next->connected)) {
+ /* connected or about to start */
+ return cf;
}
}
}
-#endif
- return NULL;
+ return lowest_ssl_cf;
}
-bool Curl_ssl_use(struct connectdata *conn, int sockindex)
+bool Curl_ssl_cf_is_proxy(struct Curl_cfilter *cf)
+{
+ return (cf->cft == &cft_ssl_proxy);
+}
+
+struct ssl_config_data *
+Curl_ssl_cf_get_config(struct Curl_cfilter *cf, struct Curl_easy *data)
{
- return conn->ssl[sockindex].use;
+ return Curl_ssl_cf_is_proxy(cf)? &data->set.proxy_ssl : &data->set.ssl;
}
-bool Curl_cfilter_ssl_added(struct Curl_easy *data,
+struct ssl_config_data *
+Curl_ssl_get_config(struct Curl_easy *data, int sockindex)
+{
+ struct Curl_cfilter *cf;
+
+ (void)data;
+ DEBUGASSERT(data->conn);
+ cf = get_ssl_cf_engaged(data->conn, sockindex);
+ return cf? Curl_ssl_cf_get_config(cf, data) : NULL;
+}
+
+struct ssl_primary_config *
+Curl_ssl_cf_get_primary_config(struct Curl_cfilter *cf)
+{
+ return Curl_ssl_cf_is_proxy(cf)?
+ &cf->conn->proxy_ssl_config : &cf->conn->ssl_config;
+}
+
+struct ssl_primary_config *
+Curl_ssl_get_primary_config(struct Curl_easy *data,
struct connectdata *conn,
int sockindex)
{
- struct Curl_cfilter *cf = conn? conn->cfilter[sockindex] : NULL;
+ struct Curl_cfilter *cf;
(void)data;
- for(; cf; cf = cf->next) {
- if(cf->cft == &cft_ssl)
- return TRUE;
+ DEBUGASSERT(conn);
+ cf = get_ssl_cf_engaged(conn, sockindex);
+ return cf? Curl_ssl_cf_get_primary_config(cf) : NULL;
+}
+
+struct Curl_cfilter *Curl_ssl_cf_get_ssl(struct Curl_cfilter *cf)
+{
+ struct Curl_cfilter *cfn;
+
+ for(cfn = cf->next; cfn; cfn = cfn->next) {
+ if(cfn->cft == &cft_ssl || cfn->cft == &cft_ssl_proxy)
+ return cfn;
}
- return FALSE;
+ return NULL;
}
#endif /* USE_SSL */
diff --git a/lib/vtls/vtls.h b/lib/vtls/vtls.h
index 8fd77b159..17c377095 100644
--- a/lib/vtls/vtls.h
+++ b/lib/vtls/vtls.h
@@ -26,6 +26,7 @@
#include "curl_setup.h"
struct connectdata;
+struct ssl_config_data;
struct ssl_connect_data;
struct ssl_primary_config;
struct Curl_ssl_session;
@@ -70,40 +71,6 @@ CURLsslset Curl_init_sslset_nolock(curl_sslbackend id, const char *name,
#define ALPN_H2_LENGTH 2
#define ALPN_H2 "h2"
-/* set of helper macros for the backends to access the correct fields. For the
- proxy or for the remote host - to properly support HTTPS proxy */
-#ifndef CURL_DISABLE_PROXY
-#define SSL_IS_PROXY() \
- (CURLPROXY_HTTPS == conn->http_proxy.proxytype && \
- ssl_connection_complete != \
- conn->proxy_ssl[conn->sock[SECONDARYSOCKET] == \
- CURL_SOCKET_BAD ? FIRSTSOCKET : SECONDARYSOCKET].state)
-#define SSL_SET_OPTION(var) \
- (SSL_IS_PROXY() ? data->set.proxy_ssl.var : data->set.ssl.var)
-#define SSL_SET_OPTION_LVALUE(var) \
- (*(SSL_IS_PROXY() ? &data->set.proxy_ssl.var : &data->set.ssl.var))
-#define SSL_CONN_CONFIG(var) \
- (SSL_IS_PROXY() ? conn->proxy_ssl_config.var : conn->ssl_config.var)
-#define SSL_HOST_NAME() \
- (SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name)
-#define SSL_HOST_DISPNAME() \
- (SSL_IS_PROXY() ? conn->http_proxy.host.dispname : conn->host.dispname)
-#define SSL_HOST_PORT() \
- (SSL_IS_PROXY() ? conn->port : conn->remote_port)
-#define SSL_PINNED_PUB_KEY() (SSL_IS_PROXY() \
- ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] \
- : data->set.str[STRING_SSL_PINNEDPUBLICKEY])
-#else
-#define SSL_IS_PROXY() FALSE
-#define SSL_SET_OPTION(var) data->set.ssl.var
-#define SSL_SET_OPTION_LVALUE(var) data->set.ssl.var
-#define SSL_CONN_CONFIG(var) conn->ssl_config.var
-#define SSL_HOST_NAME() conn->host.name
-#define SSL_HOST_DISPNAME() conn->host.dispname
-#define SSL_HOST_PORT() conn->remote_port
-#define SSL_PINNED_PUB_KEY() \
- data->set.str[STRING_SSL_PINNEDPUBLICKEY]
-#endif
char *Curl_ssl_snihost(struct Curl_easy *data, const char *host, size_t *olen);
bool Curl_ssl_config_matches(struct ssl_primary_config *data,
@@ -120,8 +87,6 @@ void Curl_ssl_cleanup(void);
/* tell the SSL stuff to close down all open information regarding
connections (and thus session ID caching etc) */
void Curl_ssl_close_all(struct Curl_easy *data);
-CURLcode Curl_ssl_shutdown(struct Curl_easy *data, struct connectdata *conn,
- int sockindex);
CURLcode Curl_ssl_set_engine(struct Curl_easy *data, const char *engine);
/* Sets engine as default for all SSL operations */
CURLcode Curl_ssl_set_engine_default(struct Curl_easy *data);
@@ -130,7 +95,7 @@ struct curl_slist *Curl_ssl_engines_list(struct Curl_easy *data);
/* init the SSL session ID cache */
CURLcode Curl_ssl_initsessions(struct Curl_easy *, size_t);
void Curl_ssl_version(char *buffer, size_t size);
-int Curl_ssl_check_cxn(struct connectdata *conn);
+int Curl_ssl_check_cxn(struct Curl_easy *data, struct connectdata *conn);
/* Certificate information list handling. */
@@ -156,30 +121,6 @@ void Curl_ssl_sessionid_lock(struct Curl_easy *data);
/* Unlock session cache mutex */
void Curl_ssl_sessionid_unlock(struct Curl_easy *data);
-/* extract a session ID
- * Sessionid mutex must be locked (see Curl_ssl_sessionid_lock).
- * Caller must make sure that the ownership of returned sessionid object
- * is properly taken (e.g. its refcount is incremented
- * under sessionid mutex).
- */
-bool Curl_ssl_getsessionid(struct Curl_easy *data,
- struct connectdata *conn,
- const bool isProxy,
- void **ssl_sessionid,
- size_t *idsize, /* set 0 if unknown */
- int sockindex);
-/* add a new session ID
- * Sessionid mutex must be locked (see Curl_ssl_sessionid_lock).
- * Caller must ensure that it has properly shared ownership of this sessionid
- * object with cache (e.g. incrementing refcount on success)
- */
-CURLcode Curl_ssl_addsessionid(struct Curl_easy *data,
- struct connectdata *conn,
- const bool isProxy,
- void *ssl_sessionid,
- size_t idsize,
- int sockindex,
- bool *added);
/* Kill a single session ID entry in the cache
* Sessionid mutex must be locked (see Curl_ssl_sessionid_lock).
* This will call engine-specific curlssl_session_free function, which must
@@ -211,17 +152,48 @@ void Curl_free_multi_ssl_backend_data(struct multi_ssl_backend_data *mbackend);
#define SSL_SHUTDOWN_TIMEOUT 10000 /* ms */
-CURLcode Curl_cfilter_ssl_add(struct Curl_easy *data,
- struct connectdata *conn,
+CURLcode Curl_ssl_cfilter_add(struct Curl_easy *data,
int sockindex);
+CURLcode Curl_ssl_cfilter_remove(struct Curl_easy *data,
+ int sockindex);
+
#ifndef CURL_DISABLE_PROXY
-CURLcode Curl_cfilter_ssl_proxy_add(struct Curl_easy *data,
- struct connectdata *conn,
+CURLcode Curl_ssl_cfilter_proxy_add(struct Curl_easy *data,
int sockindex);
#endif /* !CURL_DISABLE_PROXY */
-bool Curl_cfilter_ssl_added(struct Curl_easy *data,
+/**
+ * Return TRUE iff the filter chain `sockindex` at connection `conn`
+ * is using/prepared for SSL encryption. This tests the presence of the
+ * necessary filters and not their connectedness.
+ */
+bool Curl_ssl_conn_is_ssl(struct Curl_easy *data,
+ int sockindex);
+
+/**
+ * Get the SSL configuration that is used on the connection.
+ * This returns NULL if no SSL is configured.
+ * Otherwise it returns the config of the first (highest) one that is
+ * either connected, in handshake or about to start
+ * (e.g. all filters below it are connected). If SSL filters are present,
+ * but neither can start operating, return the config of the lowest one
+ * that will first come into effect when connecting.
+ */
+struct ssl_config_data *Curl_ssl_get_config(struct Curl_easy *data,
+ int sockindex);
+
+/**
+ * Get the primary SSL configuration from the connection.
+ * This returns NULL if no SSL is configured.
+ * Otherwise it returns the config of the first (highest) one that is
+ * either connected, in handshake or about to start
+ * (e.g. all filters below it are connected). If SSL filters are present,
+ * but neither can start operating, return the config of the lowest one
+ * that will first come into effect when connecting.
+ */
+struct ssl_primary_config *
+Curl_ssl_get_primary_config(struct Curl_easy *data,
struct connectdata *conn,
int sockindex);
@@ -252,12 +224,11 @@ bool Curl_ssl_use(struct connectdata *conn, int sockindex);
#define Curl_ssl_init() 1
#define Curl_ssl_cleanup() Curl_nop_stmt
#define Curl_ssl_close_all(x) Curl_nop_stmt
-#define Curl_ssl_shutdown(x,y,z) CURLE_NOT_BUILT_IN
#define Curl_ssl_set_engine(x,y) CURLE_NOT_BUILT_IN
#define Curl_ssl_set_engine_default(x) CURLE_NOT_BUILT_IN
#define Curl_ssl_engines_list(x) NULL
#define Curl_ssl_initsessions(x,y) CURLE_OK
-#define Curl_ssl_check_cxn(x) 0
+#define Curl_ssl_check_cxn(d,x) 0
#define Curl_ssl_free_certinfo(x) Curl_nop_stmt
#define Curl_ssl_kill_session(x) Curl_nop_stmt
#define Curl_ssl_random(x,y,z) ((void)x, CURLE_NOT_BUILT_IN)
@@ -267,9 +238,11 @@ bool Curl_ssl_use(struct connectdata *conn, int sockindex);
#define Curl_ssl_supports(a,b) FALSE
#define Curl_ssl_get_backend_data_size(a) 0
#define Curl_ssl_use(a,b) FALSE
-#define Curl_cfilter_ssl_added(a,b,c) FALSE
-#define Curl_cfilter_ssl_add(a,b,c) CURLE_NOT_BUILT_IN
-#define Curl_cfilter_ssl_proxy_add(a,b,c) CURLE_NOT_BUILT_IN
+#define Curl_ssl_conn_is_ssl(a,b) FALSE
+#define Curl_ssl_cfilter_add(a,b) CURLE_NOT_BUILT_IN
+#define Curl_ssl_cfilter_proxy_add(a,b) CURLE_NOT_BUILT_IN
+#define Curl_ssl_get_config(a,b) NULL
+#define Curl_ssl_cfilter_remove(a,b) CURLE_OK
#endif
#endif /* HEADER_CURL_VTLS_H */
diff --git a/lib/vtls/vtls_int.h b/lib/vtls/vtls_int.h
index cf912670b..90d737d7f 100644
--- a/lib/vtls/vtls_int.h
+++ b/lib/vtls/vtls_int.h
@@ -24,11 +24,25 @@
*
***************************************************************************/
#include "curl_setup.h"
+#include "cfilters.h"
#include "urldata.h"
+#ifdef USE_SSL
+
+/* Information in each SSL cfilter context: cf->ctx */
+struct ssl_connect_data {
+ ssl_connection_state state;
+ ssl_connect_state connecting_state;
+ const char *hostname;
+ const char *dispname;
+ int port;
+ struct ssl_backend_data *backend;
+};
+
+
/* Definitions for SSL Implementations */
- struct Curl_ssl {
+struct Curl_ssl {
/*
* This *must* be the first entry to allow returning the list of available
* backends in curl_global_sslset().
@@ -41,21 +55,21 @@
void (*cleanup)(void);
size_t (*version)(char *buffer, size_t size);
- int (*check_cxn)(struct connectdata *cxn);
- int (*shut_down)(struct Curl_easy *data, struct connectdata *conn,
- int sockindex);
- bool (*data_pending)(const struct connectdata *conn,
- int connindex);
+ int (*check_cxn)(struct Curl_cfilter *cf, struct Curl_easy *data);
+ int (*shut_down)(struct Curl_cfilter *cf,
+ struct Curl_easy *data);
+ bool (*data_pending)(struct Curl_cfilter *cf,
+ const struct Curl_easy *data);
/* return 0 if a find random is filled in */
CURLcode (*random)(struct Curl_easy *data, unsigned char *entropy,
size_t length);
bool (*cert_status_request)(void);
- CURLcode (*connect_blocking)(struct Curl_easy *data,
- struct connectdata *conn, int sockindex);
- CURLcode (*connect_nonblocking)(struct Curl_easy *data,
- struct connectdata *conn, int sockindex,
+ CURLcode (*connect_blocking)(struct Curl_cfilter *cf,
+ struct Curl_easy *data);
+ CURLcode (*connect_nonblocking)(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
bool *done);
/* If the SSL backend wants to read or write on this connection during a
@@ -63,11 +77,11 @@
a bitmap indicating read or write with GETSOCK_WRITESOCK(0) or
GETSOCK_READSOCK(0). Otherwise return GETSOCK_BLANK.
Mandatory. */
- int (*getsock)(struct connectdata *conn, curl_socket_t *socks);
+ int (*get_select_socks)(struct Curl_cfilter *cf, struct Curl_easy *data,
+ curl_socket_t *socks);
void *(*get_internals)(struct ssl_connect_data *connssl, CURLINFO info);
- void (*close_one)(struct Curl_easy *data, struct connectdata *conn,
- int sockindex);
+ void (*close)(struct Curl_cfilter *cf, struct Curl_easy *data);
void (*close_all)(struct Curl_easy *data);
void (*session_free)(void *ptr);
@@ -79,16 +93,14 @@
CURLcode (*sha256sum)(const unsigned char *input, size_t inputlen,
unsigned char *sha256sum, size_t sha256sumlen);
- bool (*associate_connection)(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex);
- void (*disassociate_connection)(struct Curl_easy *data, int sockindex);
+ bool (*attach_data)(struct Curl_cfilter *cf, struct Curl_easy *data);
+ void (*detach_data)(struct Curl_cfilter *cf, struct Curl_easy *data);
void (*free_multi_ssl_backend_data)(struct multi_ssl_backend_data *mbackend);
- ssize_t (*recv_plain)(struct Curl_easy *data, int sockindex, char *buf,
- size_t len, CURLcode *code);
- ssize_t (*send_plain)(struct Curl_easy *data, int sockindex,
+ ssize_t (*recv_plain)(struct Curl_cfilter *cf, struct Curl_easy *data,
+ char *buf, size_t len, CURLcode *code);
+ ssize_t (*send_plain)(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *mem, size_t len, CURLcode *code);
};
@@ -98,20 +110,64 @@ extern const struct Curl_ssl *Curl_ssl;
int Curl_none_init(void);
void Curl_none_cleanup(void);
-int Curl_none_shutdown(struct Curl_easy *data, struct connectdata *conn,
- int sockindex);
-int Curl_none_check_cxn(struct connectdata *conn);
+int Curl_none_shutdown(struct Curl_cfilter *cf, struct Curl_easy *data);
+int Curl_none_check_cxn(struct Curl_cfilter *cf, struct Curl_easy *data);
CURLcode Curl_none_random(struct Curl_easy *data, unsigned char *entropy,
size_t length);
void Curl_none_close_all(struct Curl_easy *data);
void Curl_none_session_free(void *ptr);
-bool Curl_none_data_pending(const struct connectdata *conn, int connindex);
+bool Curl_none_data_pending(struct Curl_cfilter *cf,
+ const struct Curl_easy *data);
bool Curl_none_cert_status_request(void);
CURLcode Curl_none_set_engine(struct Curl_easy *data, const char *engine);
CURLcode Curl_none_set_engine_default(struct Curl_easy *data);
struct curl_slist *Curl_none_engines_list(struct Curl_easy *data);
bool Curl_none_false_start(void);
-int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks);
+int Curl_ssl_get_select_socks(struct Curl_cfilter *cf, struct Curl_easy *data,
+ curl_socket_t *socks);
+
+/**
+ * Get the ssl_config_data in `data` that is relevant for cfilter `cf`.
+ */
+struct ssl_config_data *Curl_ssl_cf_get_config(struct Curl_cfilter *cf,
+ struct Curl_easy *data);
+
+/**
+ * Get the primary config relevant for the filter from its connection.
+ */
+struct ssl_primary_config *
+ Curl_ssl_cf_get_primary_config(struct Curl_cfilter *cf);
+
+/**
+ * Get the first SSL filter in the chain starting with `cf`, or NULL.
+ */
+struct Curl_cfilter *Curl_ssl_cf_get_ssl(struct Curl_cfilter *cf);
+
+/**
+ * Get the SSL filter below the given one or NULL if there is none.
+ */
+bool Curl_ssl_cf_is_proxy(struct Curl_cfilter *cf);
+
+/* extract a session ID
+ * Sessionid mutex must be locked (see Curl_ssl_sessionid_lock).
+ * Caller must make sure that the ownership of returned sessionid object
+ * is properly taken (e.g. its refcount is incremented
+ * under sessionid mutex).
+ */
+bool Curl_ssl_getsessionid(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ void **ssl_sessionid,
+ size_t *idsize); /* set 0 if unknown */
+/* add a new session ID
+ * Sessionid mutex must be locked (see Curl_ssl_sessionid_lock).
+ * Caller must ensure that it has properly shared ownership of this sessionid
+ * object with cache (e.g. incrementing refcount on success)
+ */
+CURLcode Curl_ssl_addsessionid(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ void *ssl_sessionid,
+ size_t idsize,
+ bool *added);
#include "openssl.h" /* OpenSSL versions */
#include "gtls.h" /* GnuTLS versions */
@@ -124,4 +180,6 @@ int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks);
#include "bearssl.h" /* BearSSL versions */
#include "rustls.h" /* rustls versions */
+#endif /* USE_SSL */
+
#endif /* HEADER_CURL_VTLS_INT_H */
diff --git a/lib/vtls/wolfssl.c b/lib/vtls/wolfssl.c
index 16a9a37f0..a622d63d8 100644
--- a/lib/vtls/wolfssl.c
+++ b/lib/vtls/wolfssl.c
@@ -90,9 +90,6 @@ struct ssl_backend_data {
SSL* handle;
};
-static Curl_recv wolfssl_recv;
-static Curl_send wolfssl_send;
-
#ifdef OPENSSL_EXTRA
/*
* Availability note:
@@ -247,14 +244,15 @@ static const struct group_name_map gnm[] = {
* layer and do all necessary magic.
*/
static CURLcode
-wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
{
char *ciphers, *curves;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ const struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
SSL_METHOD* req_method = NULL;
- curl_socket_t sockfd = conn->sock[sockindex];
+ curl_socket_t sockfd = cf->conn->sock[cf->sockindex];
#ifdef HAVE_LIBOQS
word16 oqsAlg = 0;
size_t idx = 0;
@@ -271,13 +269,13 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn,
if(connssl->state == ssl_connection_complete)
return CURLE_OK;
- if(SSL_CONN_CONFIG(version_max) != CURL_SSLVERSION_MAX_NONE) {
+ if(conn_config->version_max != CURL_SSLVERSION_MAX_NONE) {
failf(data, "wolfSSL does not support to set maximum SSL/TLS version");
return CURLE_SSL_CONNECT_ERROR;
}
/* check to see if we've been told to use an explicit SSL/TLS version */
- switch(SSL_CONN_CONFIG(version)) {
+ switch(conn_config->version) {
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
#if LIBWOLFSSL_VERSION_HEX >= 0x03003000 /* >= 3.3.0 */
@@ -340,7 +338,7 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn,
return CURLE_OUT_OF_MEMORY;
}
- switch(SSL_CONN_CONFIG(version)) {
+ switch(conn_config->version) {
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
#if LIBWOLFSSL_VERSION_HEX > 0x03004006 /* > 3.4.6 */
@@ -364,7 +362,7 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn,
break;
}
- ciphers = SSL_CONN_CONFIG(cipher_list);
+ ciphers = conn_config->cipher_list;
if(ciphers) {
if(!SSL_CTX_set_cipher_list(backend->ctx, ciphers)) {
failf(data, "failed setting cipher list: %s", ciphers);
@@ -373,7 +371,7 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn,
infof(data, "Cipher selection: %s", ciphers);
}
- curves = SSL_CONN_CONFIG(curves);
+ curves = conn_config->curves;
if(curves) {
#ifdef HAVE_LIBOQS
@@ -395,18 +393,18 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn,
}
#ifndef NO_FILESYSTEM
/* load trusted cacert */
- if(SSL_CONN_CONFIG(CAfile)) {
+ if(conn_config->CAfile) {
if(1 != SSL_CTX_load_verify_locations(backend->ctx,
- SSL_CONN_CONFIG(CAfile),
- SSL_CONN_CONFIG(CApath))) {
- if(SSL_CONN_CONFIG(verifypeer)) {
+ conn_config->CAfile,
+ conn_config->CApath)) {
+ if(conn_config->verifypeer) {
/* Fail if we insist on successfully verifying the server. */
failf(data, "error setting certificate verify locations:"
" CAfile: %s CApath: %s",
- SSL_CONN_CONFIG(CAfile)?
- SSL_CONN_CONFIG(CAfile): "none",
- SSL_CONN_CONFIG(CApath)?
- SSL_CONN_CONFIG(CApath) : "none");
+ conn_config->CAfile?
+ conn_config->CAfile: "none",
+ conn_config->CApath?
+ conn_config->CApath : "none");
return CURLE_SSL_CACERT_BADFILE;
}
else {
@@ -421,25 +419,25 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn,
infof(data, "successfully set certificate verify locations:");
}
infof(data, " CAfile: %s",
- SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile) : "none");
+ conn_config->CAfile ? conn_config->CAfile : "none");
infof(data, " CApath: %s",
- SSL_CONN_CONFIG(CApath) ? SSL_CONN_CONFIG(CApath) : "none");
+ conn_config->CApath ? conn_config->CApath : "none");
}
/* Load the client certificate, and private key */
- if(SSL_SET_OPTION(primary.clientcert) && SSL_SET_OPTION(key)) {
- int file_type = do_file_type(SSL_SET_OPTION(cert_type));
+ if(ssl_config->primary.clientcert && ssl_config->key) {
+ int file_type = do_file_type(ssl_config->cert_type);
if(SSL_CTX_use_certificate_file(backend->ctx,
- SSL_SET_OPTION(primary.clientcert),
+ ssl_config->primary.clientcert,
file_type) != 1) {
failf(data, "unable to use client certificate (no key or wrong pass"
" phrase?)");
return CURLE_SSL_CONNECT_ERROR;
}
- file_type = do_file_type(SSL_SET_OPTION(key_type));
- if(SSL_CTX_use_PrivateKey_file(backend->ctx, SSL_SET_OPTION(key),
+ file_type = do_file_type(ssl_config->key_type);
+ if(SSL_CTX_use_PrivateKey_file(backend->ctx, ssl_config->key,
file_type) != 1) {
failf(data, "unable to set private key");
return CURLE_SSL_CONNECT_ERROR;
@@ -452,8 +450,8 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn,
* anyway. In the latter case the result of the verification is checked with
* SSL_get_verify_result() below. */
SSL_CTX_set_verify(backend->ctx,
- SSL_CONN_CONFIG(verifypeer)?SSL_VERIFY_PEER:
- SSL_VERIFY_NONE,
+ conn_config->verifypeer?SSL_VERIFY_PEER:
+ SSL_VERIFY_NONE,
NULL);
#ifdef HAVE_SNI
@@ -462,16 +460,16 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn,
#ifdef ENABLE_IPV6
struct in6_addr addr6;
#endif
- const char * const hostname = SSL_HOST_NAME();
- size_t hostname_len = strlen(hostname);
+ size_t hostname_len = strlen(connssl->hostname);
+
if((hostname_len < USHRT_MAX) &&
- !Curl_inet_pton(AF_INET, hostname, &addr4)
+ !Curl_inet_pton(AF_INET, connssl->hostname, &addr4)
#ifdef ENABLE_IPV6
- && !Curl_inet_pton(AF_INET6, hostname, &addr6)
+ && !Curl_inet_pton(AF_INET6, connssl->hostname, &addr6)
#endif
) {
size_t snilen;
- char *snihost = Curl_ssl_snihost(data, hostname, &snilen);
+ char *snihost = Curl_ssl_snihost(data, connssl->hostname, &snilen);
if(!snihost ||
wolfSSL_CTX_UseSNI(backend->ctx, WOLFSSL_SNI_HOST_NAME, snihost,
(unsigned short)snilen) != 1) {
@@ -492,7 +490,7 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn,
}
}
#ifdef NO_FILESYSTEM
- else if(SSL_CONN_CONFIG(verifypeer)) {
+ else if(conn_config->verifypeer) {
failf(data, "SSL: Certificates can't be loaded because wolfSSL was built"
" with \"no filesystem\". Either disable peer verification"
" (insecure) or if you are building an application with libcurl you"
@@ -519,7 +517,7 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn,
#endif
#ifdef HAVE_ALPN
- if(conn->bits.tls_enable_alpn) {
+ if(cf->conn->bits.tls_enable_alpn) {
char protocols[128];
*protocols = '\0';
@@ -564,13 +562,11 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn,
#endif /* HAVE_SECURE_RENEGOTIATION */
/* Check if there's a cached ID we can/should use here! */
- if(SSL_SET_OPTION(primary.sessionid)) {
+ if(ssl_config->primary.sessionid) {
void *ssl_sessionid = NULL;
Curl_ssl_sessionid_lock(data);
- if(!Curl_ssl_getsessionid(data, conn,
- SSL_IS_PROXY() ? TRUE : FALSE,
- &ssl_sessionid, NULL, sockindex)) {
+ if(!Curl_ssl_getsessionid(cf, data, &ssl_sessionid, NULL)) {
/* we got a session id, use it! */
if(!SSL_set_session(backend->handle, ssl_sessionid)) {
Curl_ssl_delsessionid(data, ssl_sessionid);
@@ -594,22 +590,23 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn,
static CURLcode
-wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+wolfssl_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
{
int ret = -1;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
- const char * const dispname = SSL_HOST_DISPNAME();
- const char * const pinnedpubkey = SSL_PINNED_PUB_KEY();
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ const char * const pinnedpubkey = Curl_ssl_cf_is_proxy(cf)?
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]:
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY];
DEBUGASSERT(backend);
ERR_clear_error();
/* Enable RFC2818 checks */
- if(SSL_CONN_CONFIG(verifyhost)) {
- char *snihost = Curl_ssl_snihost(data, SSL_HOST_NAME(), NULL);
+ if(conn_config->verifyhost) {
+ char *snihost = Curl_ssl_snihost(data, connssl->hostname, NULL);
if(!snihost ||
(wolfSSL_check_domain_name(backend->handle, snihost) == SSL_FAILURE))
return CURLE_SSL_CONNECT_ERROR;
@@ -659,32 +656,32 @@ wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn,
else if(DOMAIN_NAME_MISMATCH == detail) {
#if 1
failf(data, " subject alt name(s) or common name do not match \"%s\"",
- dispname);
+ connssl->dispname);
return CURLE_PEER_FAILED_VERIFICATION;
#else
/* When the wolfssl_check_domain_name() is used and you desire to
- * continue on a DOMAIN_NAME_MISMATCH, i.e. 'conn->ssl_config.verifyhost
+ * continue on a DOMAIN_NAME_MISMATCH, i.e. 'ssl_config.verifyhost
* == 0', CyaSSL version 2.4.0 will fail with an INCOMPLETE_DATA
* error. The only way to do this is currently to switch the
* Wolfssl_check_domain_name() in and out based on the
- * 'conn->ssl_config.verifyhost' value. */
- if(SSL_CONN_CONFIG(verifyhost)) {
+ * 'ssl_config.verifyhost' value. */
+ if(conn_config->verifyhost) {
failf(data,
" subject alt name(s) or common name do not match \"%s\"\n",
- dispname);
+ connssl->dispname);
return CURLE_PEER_FAILED_VERIFICATION;
}
else {
infof(data,
" subject alt name(s) and/or common name do not match \"%s\"",
- dispname);
+ connssl->dispname);
return CURLE_OK;
}
#endif
}
#if LIBWOLFSSL_VERSION_HEX >= 0x02007000 /* 2.7.0 */
else if(ASN_NO_SIGNER_E == detail) {
- if(SSL_CONN_CONFIG(verifypeer)) {
+ if(conn_config->verifypeer) {
failf(data, " CA signer not available for verification");
return CURLE_SSL_CACERT_BADFILE;
}
@@ -749,7 +746,7 @@ wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn,
}
#ifdef HAVE_ALPN
- if(conn->bits.tls_enable_alpn) {
+ if(cf->conn->bits.tls_enable_alpn) {
int rc;
char *protocol = NULL;
unsigned short protocol_len = 0;
@@ -761,17 +758,17 @@ wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn,
if(protocol_len == ALPN_HTTP_1_1_LENGTH &&
!memcmp(protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH))
- conn->alpn = CURL_HTTP_VERSION_1_1;
+ cf->conn->alpn = CURL_HTTP_VERSION_1_1;
#ifdef USE_HTTP2
else if(data->state.httpwant >= CURL_HTTP_VERSION_2 &&
protocol_len == ALPN_H2_LENGTH &&
!memcmp(protocol, ALPN_H2, ALPN_H2_LENGTH))
- conn->alpn = CURL_HTTP_VERSION_2;
+ cf->conn->alpn = CURL_HTTP_VERSION_2;
#endif
else
infof(data, "ALPN, unrecognized protocol %.*s", protocol_len,
protocol);
- Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ?
+ Curl_multiuse_state(data, cf->conn->alpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
else if(rc == SSL_ALPN_NOT_FOUND)
@@ -797,28 +794,26 @@ wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn,
static CURLcode
-wolfssl_connect_step3(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+wolfssl_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data)
{
CURLcode result = CURLE_OK;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
+ const struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
DEBUGASSERT(backend);
- if(SSL_SET_OPTION(primary.sessionid)) {
+ if(ssl_config->primary.sessionid) {
bool incache;
bool added = FALSE;
void *old_ssl_sessionid = NULL;
/* SSL_get1_session allocates memory that has to be freed. */
SSL_SESSION *our_ssl_sessionid = SSL_get1_session(backend->handle);
- bool isproxy = SSL_IS_PROXY() ? TRUE : FALSE;
if(our_ssl_sessionid) {
Curl_ssl_sessionid_lock(data);
- incache = !(Curl_ssl_getsessionid(data, conn, isproxy,
- &old_ssl_sessionid, NULL, sockindex));
+ incache = !(Curl_ssl_getsessionid(cf, data, &old_ssl_sessionid, NULL));
if(incache) {
if(old_ssl_sessionid != our_ssl_sessionid) {
infof(data, "old SSL session ID is stale, removing");
@@ -828,8 +823,7 @@ wolfssl_connect_step3(struct Curl_easy *data, struct connectdata *conn,
}
if(!incache) {
- result = Curl_ssl_addsessionid(data, conn, isproxy, our_ssl_sessionid,
- 0, sockindex, NULL);
+ result = Curl_ssl_addsessionid(cf, data, our_ssl_sessionid, 0, NULL);
if(result) {
Curl_ssl_sessionid_unlock(data);
SSL_SESSION_free(our_ssl_sessionid);
@@ -855,14 +849,13 @@ wolfssl_connect_step3(struct Curl_easy *data, struct connectdata *conn,
}
-static ssize_t wolfssl_send(struct Curl_easy *data,
- int sockindex,
+static ssize_t wolfssl_send(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
const void *mem,
size_t len,
CURLcode *curlcode)
{
- struct connectdata *conn = data->conn;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
char error_buffer[WOLFSSL_MAX_ERROR_SZ];
int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
@@ -894,10 +887,9 @@ static ssize_t wolfssl_send(struct Curl_easy *data,
return rc;
}
-static void wolfssl_close(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+static void wolfssl_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
(void) data;
@@ -919,14 +911,13 @@ static void wolfssl_close(struct Curl_easy *data, struct connectdata *conn,
}
}
-static ssize_t wolfssl_recv(struct Curl_easy *data,
- int num,
+static ssize_t wolfssl_recv(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
char *buf,
size_t buffersize,
CURLcode *curlcode)
{
- struct connectdata *conn = data->conn;
- struct ssl_connect_data *connssl = &conn->ssl[num];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
char error_buffer[WOLFSSL_MAX_ERROR_SZ];
int buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
@@ -997,14 +988,15 @@ static void wolfssl_cleanup(void)
}
-static bool wolfssl_data_pending(const struct connectdata *conn,
- int connindex)
+static bool wolfssl_data_pending(struct Curl_cfilter *cf,
+ const struct Curl_easy *data)
{
- const struct ssl_connect_data *connssl = &conn->ssl[connindex];
- struct ssl_backend_data *backend = connssl->backend;
- DEBUGASSERT(backend);
- if(backend->handle) /* SSL is in use */
- return (0 != SSL_pending(backend->handle)) ? TRUE : FALSE;
+ struct ssl_connect_data *ctx = cf->ctx;
+
+ (void)data;
+ DEBUGASSERT(ctx && ctx->backend);
+ if(ctx->backend->handle) /* SSL is in use */
+ return (0 != SSL_pending(ctx->backend->handle)) ? TRUE : FALSE;
else
return FALSE;
}
@@ -1014,36 +1006,33 @@ static bool wolfssl_data_pending(const struct connectdata *conn,
* This function is called to shut down the SSL layer but keep the
* socket open (CCC - Clear Command Channel)
*/
-static int wolfssl_shutdown(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+static int wolfssl_shutdown(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
+ struct ssl_connect_data *ctx = cf->ctx;
int retval = 0;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- struct ssl_backend_data *backend = connssl->backend;
- (void) data;
-
- DEBUGASSERT(backend);
+ (void)data;
+ DEBUGASSERT(ctx && ctx->backend);
- if(backend->handle) {
+ if(ctx->backend->handle) {
ERR_clear_error();
- SSL_free(backend->handle);
- backend->handle = NULL;
+ SSL_free(ctx->backend->handle);
+ ctx->backend->handle = NULL;
}
return retval;
}
static CURLcode
-wolfssl_connect_common(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex,
- bool nonblocking,
- bool *done)
+wolfssl_connect_common(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool nonblocking,
+ bool *done)
{
CURLcode result;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- curl_socket_t sockfd = conn->sock[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
+ curl_socket_t sockfd = cf->conn->sock[cf->sockindex];
int what;
/* check if the connection has already been established */
@@ -1062,7 +1051,7 @@ wolfssl_connect_common(struct Curl_easy *data,
return CURLE_OPERATION_TIMEDOUT;
}
- result = wolfssl_connect_step1(data, conn, sockindex);
+ result = wolfssl_connect_step1(cf, data);
if(result)
return result;
}
@@ -1117,7 +1106,7 @@ wolfssl_connect_common(struct Curl_easy *data,
* ensuring that a client using select() or epoll() will always
* have a valid fdset to wait on.
*/
- result = wolfssl_connect_step2(data, conn, sockindex);
+ result = wolfssl_connect_step2(cf, data);
if(result || (nonblocking &&
(ssl_connect_2 == connssl->connecting_state ||
ssl_connect_2_reading == connssl->connecting_state ||
@@ -1126,7 +1115,7 @@ wolfssl_connect_common(struct Curl_easy *data,
} /* repeat step2 until all transactions are done. */
if(ssl_connect_3 == connssl->connecting_state) {
- result = wolfssl_connect_step3(data, conn, sockindex);
+ result = wolfssl_connect_step3(cf, data);
if(result)
return result;
}
@@ -1145,21 +1134,21 @@ wolfssl_connect_common(struct Curl_easy *data,
}
-static CURLcode wolfssl_connect_nonblocking(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex, bool *done)
+static CURLcode wolfssl_connect_nonblocking(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool *done)
{
- return wolfssl_connect_common(data, conn, sockindex, TRUE, done);
+ return wolfssl_connect_common(cf, data, TRUE, done);
}
-static CURLcode wolfssl_connect(struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+static CURLcode wolfssl_connect(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
CURLcode result;
bool done = FALSE;
- result = wolfssl_connect_common(data, conn, sockindex, FALSE, &done);
+ result = wolfssl_connect_common(cf, data, FALSE, &done);
if(result)
return result;
@@ -1226,7 +1215,7 @@ const struct Curl_ssl Curl_ssl_wolfssl = {
Curl_none_cert_status_request, /* cert_status_request */
wolfssl_connect, /* connect */
wolfssl_connect_nonblocking, /* connect_nonblocking */
- Curl_ssl_getsock, /* getsock */
+ Curl_ssl_get_select_socks, /* getsock */
wolfssl_get_internals, /* get_internals */
wolfssl_close, /* close_one */
Curl_none_close_all, /* close_all */
diff --git a/lib/vtls/x509asn1.c b/lib/vtls/x509asn1.c
index 0cfcbe87d..a3e4d7ec3 100644
--- a/lib/vtls/x509asn1.c
+++ b/lib/vtls/x509asn1.c
@@ -1276,9 +1276,12 @@ static const char *checkOID(const char *beg, const char *end,
return matched? ccp: NULL;
}
-CURLcode Curl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
+CURLcode Curl_verifyhost(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
const char *beg, const char *end)
{
+ struct ssl_connect_data *connssl = cf->ctx;
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
struct Curl_X509certificate cert;
struct Curl_asn1Element dn;
struct Curl_asn1Element elem;
@@ -1290,9 +1293,8 @@ CURLcode Curl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
int matched = -1;
size_t addrlen = (size_t) -1;
ssize_t len;
- const char * const hostname = SSL_HOST_NAME();
- const char * const dispname = SSL_HOST_DISPNAME();
- size_t hostlen = strlen(hostname);
+ size_t hostlen;
+
#ifdef ENABLE_IPV6
struct in6_addr addr;
#else
@@ -1302,19 +1304,21 @@ CURLcode Curl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
/* Verify that connection server matches info in X509 certificate at
`beg'..`end'. */
- if(!SSL_CONN_CONFIG(verifyhost))
+ if(!conn_config->verifyhost)
return CURLE_OK;
if(Curl_parseX509(&cert, beg, end))
return CURLE_PEER_FAILED_VERIFICATION;
+ hostlen = strlen(connssl->hostname);
+
/* Get the server IP address. */
#ifdef ENABLE_IPV6
- if(conn->bits.ipv6_ip && Curl_inet_pton(AF_INET6, hostname, &addr))
+ if(conn->bits.ipv6_ip && Curl_inet_pton(AF_INET6, connssl->hostname, &addr))
addrlen = sizeof(struct in6_addr);
else
#endif
- if(Curl_inet_pton(AF_INET, hostname, &addr))
+ if(Curl_inet_pton(AF_INET, connssl->hostname, &addr))
addrlen = sizeof(struct in_addr);
/* Process extensions. */
@@ -1348,8 +1352,8 @@ CURLcode Curl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
len = utf8asn1str(&dnsname, CURL_ASN1_IA5_STRING,
name.beg, name.end);
if(len > 0 && (size_t)len == strlen(dnsname))
- matched = Curl_cert_hostcheck(dnsname,
- (size_t)len, hostname, hostlen);
+ matched = Curl_cert_hostcheck(dnsname, (size_t)len,
+ connssl->hostname, hostlen);
else
matched = 0;
free(dnsname);
@@ -1367,12 +1371,12 @@ CURLcode Curl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
switch(matched) {
case 1:
/* an alternative name matched the server hostname */
- infof(data, " subjectAltName: %s matched", dispname);
+ infof(data, " subjectAltName: %s matched", connssl->dispname);
return CURLE_OK;
case 0:
/* an alternative name field existed, but didn't match and then
we MUST fail */
- infof(data, " subjectAltName does not match %s", dispname);
+ infof(data, " subjectAltName does not match %s", connssl->dispname);
return CURLE_PEER_FAILED_VERIFICATION;
}
@@ -1409,14 +1413,14 @@ CURLcode Curl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
if(strlen(dnsname) != (size_t) len) /* Nul byte in string ? */
failf(data, "SSL: illegal cert name field");
else if(Curl_cert_hostcheck((const char *) dnsname,
- len, hostname, hostlen)) {
+ len, connssl->hostname, hostlen)) {
infof(data, " common name: %s (matched)", dnsname);
free(dnsname);
return CURLE_OK;
}
else
failf(data, "SSL: certificate subject name '%s' does not match "
- "target host name '%s'", dnsname, dispname);
+ "target host name '%s'", dnsname, connssl->dispname);
free(dnsname);
}
diff --git a/lib/vtls/x509asn1.h b/lib/vtls/x509asn1.h
index a18fa1153..eb8e9597c 100644
--- a/lib/vtls/x509asn1.h
+++ b/lib/vtls/x509asn1.h
@@ -30,6 +30,7 @@
#if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \
defined(USE_WOLFSSL) || defined(USE_SCHANNEL) || defined(USE_SECTRANSP)
+#include "cfilters.h"
#include "urldata.h"
/*
@@ -73,7 +74,7 @@ int Curl_parseX509(struct Curl_X509certificate *cert,
const char *beg, const char *end);
CURLcode Curl_extract_certinfo(struct Curl_easy *data, int certnum,
const char *beg, const char *end);
-CURLcode Curl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
+CURLcode Curl_verifyhost(struct Curl_cfilter *cf, struct Curl_easy *data,
const char *beg, const char *end);
#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL
* or USE_SECTRANSP */