diff --git a/lib/setopt.c b/lib/setopt.c index e3220cd893..d588ae45e7 100644 --- a/lib/setopt.c +++ b/lib/setopt.c @@ -1584,10 +1584,6 @@ static CURLcode setopt_pointers(struct Curl_easy *data, CURLoption option, if(data->share->hsts == data->hsts) data->hsts = NULL; #endif -#ifdef USE_SSL - if(data->share->ssl_scache == data->state.ssl_scache) - data->state.ssl_scache = data->multi ? data->multi->ssl_scache : NULL; -#endif #ifdef USE_LIBPSL if(data->psl == &data->share->psl) data->psl = data->multi ? &data->multi->psl : NULL; @@ -1628,10 +1624,6 @@ static CURLcode setopt_pointers(struct Curl_easy *data, CURLoption option, data->hsts = data->share->hsts; } #endif -#ifdef USE_SSL - if(data->share->ssl_scache) - data->state.ssl_scache = data->share->ssl_scache; -#endif #ifdef USE_LIBPSL if(data->share->specifier & (1 << CURL_LOCK_DATA_PSL)) data->psl = &data->share->psl; diff --git a/lib/transfer.c b/lib/transfer.c index c4b23a8f0c..742828a763 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -567,12 +567,6 @@ CURLcode Curl_pretransfer(struct Curl_easy *data) #endif data->state.httpreq = data->set.method; -#ifdef USE_SSL - if(!data->state.ssl_scache) - /* There was no ssl session cache set via a share, use the multi one */ - data->state.ssl_scache = data->multi->ssl_scache; -#endif - data->state.requests = 0; data->state.followlocation = 0; /* reset the location-follow counter */ data->state.this_is_a_follow = FALSE; /* reset this */ diff --git a/lib/urldata.h b/lib/urldata.h index 33fa0d1354..b9b6b21291 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -1199,7 +1199,6 @@ struct UrlState { curl_prot_t first_remote_protocol; int retrycount; /* number of retries on a new connection */ - struct Curl_ssl_scache *ssl_scache; /* TLS session pool */ int os_errno; /* filled in with errno whenever an error occurs */ long followlocation; /* redirect counter */ int requests; /* request counter: redirects + authentication retakes */ diff --git a/lib/vtls/vtls_scache.c b/lib/vtls/vtls_scache.c index 32b16f6247..365e945920 100644 --- a/lib/vtls/vtls_scache.c +++ b/lib/vtls/vtls_scache.c @@ -77,17 +77,7 @@ struct Curl_ssl_scache_peer { #define CURL_SCACHE_MAGIC 0x000e1551 -#ifdef DEBUGBUILD -/* On a debug build, we want to fail hard on scaches that - * are not NULL, but no longer have the MAGIC touch. This gives - * us early warning on things only discovered by valgrind otherwise. */ -#define GOOD_SCACHE(x) \ - (((x) && (x)->magic == CURL_SCACHE_MAGIC)? TRUE: \ - (DEBUGASSERT(!(x)), FALSE)) -#else -#define GOOD_SCACHE(x) \ - ((x) && (x)->magic == CURL_SCACHE_MAGIC) -#endif +#define GOOD_SCACHE(x) ((x) && (x)->magic == CURL_SCACHE_MAGIC) struct Curl_ssl_scache { unsigned int magic; @@ -97,6 +87,23 @@ struct Curl_ssl_scache { long age; }; +static struct Curl_ssl_scache *cf_ssl_scache_get(struct Curl_easy *data) +{ + struct Curl_ssl_scache *scache = NULL; + /* If a share is present, its ssl_scache has preference over the multi */ + if(data->share && data->share->ssl_scache) + scache = data->share->ssl_scache; + else if(data->multi && data->multi->ssl_scache) + scache = data->multi->ssl_scache; + if(scache && !GOOD_SCACHE(scache)) { + failf(data, "transfer would use an invalid scache at %p, denied", + (void *)scache); + DEBUGASSERT(0); + return NULL; + } + return scache; +} + static void cf_ssl_scache_clear_session(struct Curl_ssl_session *s) { if(s->sdata) { @@ -606,7 +613,6 @@ cf_ssl_find_peer_by_key(struct Curl_easy *data, *ppeer = NULL; if(!GOOD_SCACHE(scache)) { - failf(data, "cf_ssl_find_peer_by_key with BAD sache magic!"); return CURLE_BAD_FUNCTION_ARGUMENT; } @@ -772,11 +778,6 @@ static CURLcode cf_scache_add_session(struct Curl_cfilter *cf, Curl_ssl_session_destroy(s); return CURLE_OK; } - if(!GOOD_SCACHE(scache)) { - Curl_ssl_session_destroy(s); - failf(data, "cf_scache_add_session with BAD scache magic!"); - return CURLE_BAD_FUNCTION_ARGUMENT; - } if(s->valid_until <= 0) s->valid_until = now + scache->default_lifetime_secs; @@ -822,7 +823,7 @@ CURLcode Curl_ssl_scache_put(struct Curl_cfilter *cf, const char *ssl_peer_key, struct Curl_ssl_session *s) { - struct Curl_ssl_scache *scache = data->state.ssl_scache; + struct Curl_ssl_scache *scache = cf_ssl_scache_get(data); struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); CURLcode result; DEBUGASSERT(ssl_config); @@ -833,7 +834,6 @@ CURLcode Curl_ssl_scache_put(struct Curl_cfilter *cf, } if(!GOOD_SCACHE(scache)) { Curl_ssl_session_destroy(s); - failf(data, "Curl_ssl_scache_put with BAD scache magic!"); return CURLE_BAD_FUNCTION_ARGUMENT; } @@ -861,7 +861,7 @@ CURLcode Curl_ssl_scache_take(struct Curl_cfilter *cf, const char *ssl_peer_key, struct Curl_ssl_session **ps) { - struct Curl_ssl_scache *scache = data->state.ssl_scache; + struct Curl_ssl_scache *scache = cf_ssl_scache_get(data); struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); struct Curl_ssl_scache_peer *peer = NULL; struct Curl_llist_node *n; @@ -871,10 +871,6 @@ CURLcode Curl_ssl_scache_take(struct Curl_cfilter *cf, *ps = NULL; if(!scache) return CURLE_OK; - if(!GOOD_SCACHE(scache)) { - failf(data, "Curl_ssl_scache_take with BAD scache magic!"); - return CURLE_BAD_FUNCTION_ARGUMENT; - } Curl_ssl_scache_lock(data); result = cf_ssl_find_peer_by_key(data, scache, ssl_peer_key, conn_config, @@ -909,7 +905,7 @@ CURLcode Curl_ssl_scache_add_obj(struct Curl_cfilter *cf, void *sobj, Curl_ssl_scache_obj_dtor *sobj_free) { - struct Curl_ssl_scache *scache = data->state.ssl_scache; + struct Curl_ssl_scache *scache = cf_ssl_scache_get(data); struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); struct Curl_ssl_scache_peer *peer = NULL; CURLcode result; @@ -917,8 +913,7 @@ CURLcode Curl_ssl_scache_add_obj(struct Curl_cfilter *cf, DEBUGASSERT(sobj); DEBUGASSERT(sobj_free); - if(!GOOD_SCACHE(scache)) { - failf(data, "Curl_ssl_scache_add_obj with BAD scache magic!"); + if(!scache) { result = CURLE_BAD_FUNCTION_ARGUMENT; goto out; } @@ -943,7 +938,7 @@ bool Curl_ssl_scache_get_obj(struct Curl_cfilter *cf, const char *ssl_peer_key, void **sobj) { - struct Curl_ssl_scache *scache = data->state.ssl_scache; + struct Curl_ssl_scache *scache = cf_ssl_scache_get(data); struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); struct Curl_ssl_scache_peer *peer = NULL; CURLcode result; @@ -951,10 +946,6 @@ bool Curl_ssl_scache_get_obj(struct Curl_cfilter *cf, *sobj = NULL; if(!scache) return FALSE; - if(!GOOD_SCACHE(scache)) { - failf(data, "Curl_ssl_scache_get_obj with BAD scache magic!"); - return FALSE; - } result = cf_ssl_find_peer_by_key(data, scache, ssl_peer_key, conn_config, &peer); @@ -973,13 +964,13 @@ void Curl_ssl_scache_remove_all(struct Curl_cfilter *cf, struct Curl_easy *data, const char *ssl_peer_key) { - struct Curl_ssl_scache *scache = data->state.ssl_scache; + struct Curl_ssl_scache *scache = cf_ssl_scache_get(data); struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); struct Curl_ssl_scache_peer *peer = NULL; CURLcode result; (void)cf; - if(!scache || !GOOD_SCACHE(scache)) + if(!scache) return; Curl_ssl_scache_lock(data); @@ -1073,14 +1064,13 @@ CURLcode Curl_ssl_session_import(struct Curl_easy *data, const unsigned char *shmac, size_t shmac_len, const unsigned char *sdata, size_t sdata_len) { - struct Curl_ssl_scache *scache = data->state.ssl_scache; + struct Curl_ssl_scache *scache = cf_ssl_scache_get(data); struct Curl_ssl_scache_peer *peer = NULL; struct Curl_ssl_session *s = NULL; bool locked = FALSE; CURLcode r; - if(!scache || !GOOD_SCACHE(scache)) { - failf(data, "Curl_ssl_session_import with BAD scache magic!"); + if(!scache) { r = CURLE_BAD_FUNCTION_ARGUMENT; goto out; } @@ -1145,7 +1135,7 @@ CURLcode Curl_ssl_session_export(struct Curl_easy *data, curl_ssls_export_cb *export_fn, void *userptr) { - struct Curl_ssl_scache *scache = data->state.ssl_scache; + struct Curl_ssl_scache *scache = cf_ssl_scache_get(data); struct Curl_ssl_scache_peer *peer; struct dynbuf sbuf, hbuf; struct Curl_llist_node *n; @@ -1157,10 +1147,6 @@ CURLcode Curl_ssl_session_export(struct Curl_easy *data, return CURLE_BAD_FUNCTION_ARGUMENT; if(!scache) return CURLE_OK; - if(!GOOD_SCACHE(scache)) { - failf(data, "Curl_ssl_session_export with BAD scache magic!"); - return CURLE_BAD_FUNCTION_ARGUMENT; - } Curl_ssl_scache_lock(data); diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 65f7712f23..01fbe9b23e 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -272,6 +272,6 @@ test3032 \ \ test3100 test3101 test3102 test3103 test3104 test3105 \ test3200 \ -test3201 test3202 test3203 test3204 test3205 test3207 +test3201 test3202 test3203 test3204 test3205 test3207 test3208 EXTRA_DIST = $(TESTCASES) DISABLED diff --git a/tests/data/test3208 b/tests/data/test3208 new file mode 100644 index 0000000000..cc646e8661 --- /dev/null +++ b/tests/data/test3208 @@ -0,0 +1,60 @@ + + + +HTTP +HTTP GET +libtest + + +# +# Server-side + + +HTTP/1.1 200 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT +ETag: "21025-dc7-39462498" +Accept-Ranges: bytes +Content-Length: 6 +Connection: close +Content-Type: text/html +Funny-head: yesyes + +-foo- + + + +# Client-side + + +https + +# tool is what to use instead of 'curl' + +lib%TESTNUMBER + + + +curl_easy_perform then curl_multi_perform the same handle + + +https://%HOSTIP:%HTTPSPORT/%TESTNUMBER + + + +# +# Verify data after the test has been "shot" + + +GET /%TESTNUMBER HTTP/1.1 +Host: %HOSTIP:%HTTPSPORT +Accept: */* + +GET /%TESTNUMBER HTTP/1.1 +Host: %HOSTIP:%HTTPSPORT +Accept: */* + + + + diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc index 01f94018b5..cf4d6e7122 100644 --- a/tests/libtest/Makefile.inc +++ b/tests/libtest/Makefile.inc @@ -76,7 +76,7 @@ LIBTESTPROGS = libauthretry libntlmconnect libprereq \ lib2402 lib2404 lib2405 \ lib2502 \ lib3010 lib3025 lib3026 lib3027 \ - lib3100 lib3101 lib3102 lib3103 lib3104 lib3105 lib3207 + lib3100 lib3101 lib3102 lib3103 lib3104 lib3105 lib3207 lib3208 libntlmconnect_SOURCES = libntlmconnect.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) libntlmconnect_LDADD = $(TESTUTIL_LIBS) @@ -736,3 +736,6 @@ lib3105_SOURCES = lib3105.c $(SUPPORTFILES) lib3207_SOURCES = lib3207.c $(SUPPORTFILES) $(TESTUTIL) $(THREADS) $(WARNLESS) $(MULTIBYTE) lib3207_LDADD = $(TESTUTIL_LIBS) + +lib3208_SOURCES = lib3208.c $(SUPPORTFILES) $(TESTUTIL) +lib3208_LDADD = $(TESTUTIL_LIBS) diff --git a/tests/libtest/lib3208.c b/tests/libtest/lib3208.c new file mode 100644 index 0000000000..8a451823d6 --- /dev/null +++ b/tests/libtest/lib3208.c @@ -0,0 +1,100 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * SPDX-License-Identifier: curl + * + ***************************************************************************/ +#include "test.h" + +#include "testutil.h" +#include "warnless.h" +#include "memdebug.h" + +#define TEST_HANG_TIMEOUT 60 * 1000 + +CURLcode test(char *URL) +{ + CURL *curl = NULL; + CURLM *multi = NULL; + int still_running; + CURLcode i = TEST_ERR_FAILURE; + CURLcode res = CURLE_OK; + CURLMsg *msg; + + start_test_timing(); + + global_init(CURL_GLOBAL_ALL); + + multi_init(multi); + + easy_init(curl); + + easy_setopt(curl, CURLOPT_URL, URL); + easy_setopt(curl, CURLOPT_HEADER, 1L); + /* no peer verify */ + easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + + /* first, make an easy perform with the handle */ + curl_easy_perform(curl); + + /* then proceed and use it for a multi perform */ + multi_add_handle(multi, curl); + + multi_perform(multi, &still_running); + + abort_on_test_timeout(); + + while(still_running) { + CURLMcode mres; + int num; + mres = curl_multi_wait(multi, NULL, 0, TEST_HANG_TIMEOUT, &num); + if(mres != CURLM_OK) { + printf("curl_multi_wait() returned %d\n", mres); + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + + abort_on_test_timeout(); + + multi_perform(multi, &still_running); + + abort_on_test_timeout(); + } + + msg = curl_multi_info_read(multi, &still_running); + if(msg) + /* this should now contain a result code from the easy handle, + get it */ + i = msg->data.result; + +test_cleanup: + + /* undocumented cleanup sequence - type UA */ + + curl_multi_cleanup(multi); + curl_easy_cleanup(curl); + curl_global_cleanup(); + + if(res) + i = res; + + return i; /* return the final return code */ +}