From 55700cb01f4a01b8187f387e1655371e6fe0703a Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 20 Feb 2008 08:28:02 +0000 Subject: - We no longer support setting the CURLOPT_URL option from inside a callback such as the CURLOPT_SSL_CTX_FUNCTION one treat that as if it was a Location: following. The patch that introduced this feature was done for 7.11.0, but this code and functionality has been broken since about 7.15.4 (March 2006) with the introduction of non-blocking OpenSSL "connects". It was a hack to begin with and since it doesn't work and hasn't worked correctly for a long time and nobody has even noticed, I consider it a very suitable subject for plain removal. And so it was done. --- CHANGES | 11 ++ RELEASE-NOTES | 5 +- lib/gtls.c | 4 +- lib/multi.c | 45 +----- lib/transfer.c | 52 +++---- lib/url.c | 2 - lib/urldata.h | 4 - tests/data/Makefile.am | 2 +- tests/data/test509 | 64 --------- tests/libtest/Makefile.am | 4 +- tests/libtest/lib509.c | 351 ---------------------------------------------- 11 files changed, 43 insertions(+), 501 deletions(-) delete mode 100644 tests/data/test509 delete mode 100644 tests/libtest/lib509.c diff --git a/CHANGES b/CHANGES index 3b4499a3b..4dd0b7dde 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,17 @@ Changelog +Daniel S (20 Feb 2008) +- We no longer support setting the CURLOPT_URL option from inside a callback + such as the CURLOPT_SSL_CTX_FUNCTION one treat that as if it was a Location: + following. The patch that introduced this feature was done for 7.11.0, but + this code and functionality has been broken since about 7.15.4 (March 2006) + with the introduction of non-blocking OpenSSL "connects". + + It was a hack to begin with and since it doesn't work and hasn't worked + correctly for a long time and nobody has even noticed, I consider it a very + suitable subject for plain removal. And so it was done. + Daniel Fandrich (19 Feb 2007) - Added test309 to test HTTP redirect to HTTPS URL diff --git a/RELEASE-NOTES b/RELEASE-NOTES index f17eb784d..9279ea1fc 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -13,6 +13,8 @@ This release includes the following changes: o added support for HttpOnly cookies o 'make ca-bundle' downloads and generates an updated ca bundle file o we no longer distribute or install a ca cert bundle + o SSLv2 is now disabled by default for SSL operations + o the test509-style setting URL in callback is officially no longer supported This release includes the following bugfixes: @@ -42,6 +44,7 @@ This release would not have looked like this without help, code, reports and advice from friends like these: Michal Marek, Dmitry Kurochkin, Niklas Angebrand, Günter Knauf, Yang Tse, - Dan Fandrich, Mike Hommey, Pooyan McSporran, Jerome Muffat-Meridol + Dan Fandrich, Mike Hommey, Pooyan McSporran, Jerome Muffat-Meridol, + Kaspar Brand Thanks! (and sorry if I forgot to mention someone) diff --git a/lib/gtls.c b/lib/gtls.c index e980a5bdc..2364c2778 100644 --- a/lib/gtls.c +++ b/lib/gtls.c @@ -230,7 +230,9 @@ Curl_gtls_connect(struct connectdata *conn, void *ssl_sessionid; size_t ssl_idsize; - if(!gtls_inited) _Curl_gtls_init(); + if(!gtls_inited) + _Curl_gtls_init(); + /* GnuTLS only supports TLSv1 (and SSLv3?) */ if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) { failf(data, "GnuTLS does not support SSLv2"); diff --git a/lib/multi.c b/lib/multi.c index ab0db3236..a29b6a0ae 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -860,12 +860,14 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, CURLMcode result = CURLM_OK; struct SingleRequest *k; + if(!GOOD_EASY_HANDLE(easy->easy_handle)) + return CURLM_BAD_EASY_HANDLE; + do { + /* this is a do-while loop just to allow a break to skip to the end + of it */ bool disconnect_conn = FALSE; - if(!GOOD_EASY_HANDLE(easy->easy_handle)) - return CURLM_BAD_EASY_HANDLE; - /* Handle the case when the pipe breaks, i.e., the connection we're using gets cleaned up and we're left with nothing. */ if(easy->easy_handle->state.pipe_broke) { @@ -885,40 +887,9 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } if(easy->state > CURLM_STATE_CONNECT && - easy->state < CURLM_STATE_COMPLETED) { + easy->state < CURLM_STATE_COMPLETED) /* Make sure we set the connection's current owner */ easy->easy_conn->data = easy->easy_handle; - } - - if(CURLM_STATE_WAITCONNECT <= easy->state && - easy->state <= CURLM_STATE_DO && - easy->easy_handle->change.url_changed) { - char *gotourl; - Curl_posttransfer(easy->easy_handle); - - easy->result = Curl_done(&easy->easy_conn, CURLE_OK, FALSE); - /* We make sure that the pipe broken flag is reset - because in this case, it isn't an actual break */ - easy->easy_handle->state.pipe_broke = FALSE; - if(CURLE_OK == easy->result) { - gotourl = strdup(easy->easy_handle->change.url); - if(gotourl) { - easy->easy_handle->change.url_changed = FALSE; - easy->result = Curl_follow(easy->easy_handle, gotourl, FALSE); - if(CURLE_OK == easy->result) - multistate(easy, CURLM_STATE_CONNECT); - else - free(gotourl); - } - else { - easy->result = CURLE_OUT_OF_MEMORY; - multistate(easy, CURLM_STATE_COMPLETED); - break; - } - } - } - - easy->easy_handle->change.url_changed = FALSE; switch(easy->state) { case CURLM_STATE_INIT: @@ -1403,9 +1374,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, multistate(easy, CURLM_STATE_COMPLETED); } } - - } while(easy->easy_handle->change.url_changed); - + } while(0); if((CURLM_STATE_COMPLETED == easy->state) && !easy->msg) { if(easy->easy_handle->dns.hostcachetype == HCACHE_MULTI) { /* clear out the usage of the shared DNS cache */ diff --git a/lib/transfer.c b/lib/transfer.c index 49397e8c9..86dcfe24f 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -2260,44 +2260,24 @@ connect_host(struct SessionHandle *data, struct connectdata **conn) { CURLcode res = CURLE_OK; - int urlchanged = FALSE; - do { - bool async; - bool protocol_done=TRUE; /* will be TRUE always since this is only used + bool async; + bool protocol_done=TRUE; /* will be TRUE always since this is only used within the easy interface */ - Curl_pgrsTime(data, TIMER_STARTSINGLE); - data->change.url_changed = FALSE; - res = Curl_connect(data, conn, &async, &protocol_done); - - if((CURLE_OK == res) && async) { - /* Now, if async is TRUE here, we need to wait for the name - to resolve */ - res = Curl_wait_for_resolv(*conn, NULL); - if(CURLE_OK == res) - /* Resolved, continue with the connection */ - res = Curl_async_resolved(*conn, &protocol_done); - else - /* if we can't resolve, we kill this "connection" now */ - (void)Curl_disconnect(*conn); - } - if(res) - break; - - /* If a callback (or something) has altered the URL we should use within - the Curl_connect(), we detect it here and act as if we are redirected - to the new URL */ - urlchanged = data->change.url_changed; - if((CURLE_OK == res) && urlchanged) { - res = Curl_done(conn, res, FALSE); - if(CURLE_OK == res) { - char *gotourl = strdup(data->change.url); - res = Curl_follow(data, gotourl, FALSE); - if(res) - free(gotourl); - } - } - } while(urlchanged && res == CURLE_OK); + Curl_pgrsTime(data, TIMER_STARTSINGLE); + res = Curl_connect(data, conn, &async, &protocol_done); + + if((CURLE_OK == res) && async) { + /* Now, if async is TRUE here, we need to wait for the name + to resolve */ + res = Curl_wait_for_resolv(*conn, NULL); + if(CURLE_OK == res) + /* Resolved, continue with the connection */ + res = Curl_async_resolved(*conn, &protocol_done); + else + /* if we can't resolve, we kill this "connection" now */ + (void)Curl_disconnect(*conn); + } return res; } diff --git a/lib/url.c b/lib/url.c index 7b06604d8..71a533d25 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1481,8 +1481,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, result = setstropt(&data->set.str[STRING_SET_URL], va_arg(param, char *)); data->change.url = data->set.str[STRING_SET_URL]; - if(data->change.url) - data->change.url_changed = TRUE; break; case CURLOPT_PORT: /* diff --git a/lib/urldata.h b/lib/urldata.h index 505da5500..2eeb08c20 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -1250,10 +1250,6 @@ struct UrlState { struct DynamicStatic { char *url; /* work URL, copied from UserDefined */ bool url_alloc; /* URL string is malloc()'ed */ - bool url_changed; /* set on CURL_OPT_URL, used to detect if the URL was - changed after the connect phase, as we allow callback - to change it and if so, we reconnect to use the new - URL instead */ char *referer; /* referer string */ bool referer_alloc; /* referer sting is malloc()ed */ struct curl_slist *cookielist; /* list of cookie files set by diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 1cc19f12a..e4e14b514 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -19,7 +19,7 @@ EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46 \ test505 test74 test75 test76 test77 test78 test147 test148 test506 test79 \ test80 test81 test82 test83 test84 test85 test86 test87 test507 test149 \ test88 test89 test90 test508 test91 test92 test203 test93 test94 test95 \ - test509 test510 test97 test98 test99 test150 test151 test152 test153 \ + test510 test97 test98 test99 test150 test151 test152 test153 \ test154 test155 test156 test157 test158 test159 test511 test160 test161 \ test162 test163 test164 test512 test165 test166 test167 test168 test169 \ test170 test171 test172 test204 test205 test173 test174 test175 test176 \ diff --git a/tests/data/test509 b/tests/data/test509 deleted file mode 100644 index d29a4ba78..000000000 --- a/tests/data/test509 +++ /dev/null @@ -1,64 +0,0 @@ - - - -HTTPS -HTTP GET - - - -# -# Server-side - - -HTTP/1.1 200 OK -Date: Thu, 09 Nov 2010 14:49:00 GMT -Content-length:6 - -Hello - - -Hello - - - -# -# Client-side - - -https - - -SSL -OpenSSL - - -lib509 - - - -simple HTTPS GET and URL redirect in certificate - - -https://%HOSTIP:%HTTPSPORT/dvcs %HTTPSPORT - - - -# -# Verify data after the test has been "shot" - - -^User-Agent:.* - - -GET /509 HTTP/1.1 -Host: %HOSTIP:%HTTPSPORT -Accept: */* - - -# valgrind detects numerous problems in OpenSSL for this test case, disable -# the valgrind logfile scan - -disable - - - diff --git a/tests/libtest/Makefile.am b/tests/libtest/Makefile.am index 65c987d1e..8a9e3a42e 100644 --- a/tests/libtest/Makefile.am +++ b/tests/libtest/Makefile.am @@ -45,7 +45,7 @@ SUPPORTFILES = first.c test.h # These are all libcurl test programs noinst_PROGRAMS = lib500 lib501 lib502 lib503 lib504 lib505 lib506 \ - lib507 lib508 lib509 lib510 lib511 lib512 lib513 lib514 lib515 lib516 \ + lib507 lib508 lib510 lib511 lib512 lib513 lib514 lib515 lib516 \ lib517 lib518 lib519 lib520 lib521 lib523 lib524 lib525 lib526 lib527 \ lib529 lib530 lib532 lib533 lib536 lib537 lib540 lib541 lib542 lib543 \ lib544 lib545 lib547 lib548 lib549 lib552 lib553 @@ -73,8 +73,6 @@ lib507_SOURCES = lib507.c $(SUPPORTFILES) $(TESTUTIL) lib508_SOURCES = lib508.c $(SUPPORTFILES) -lib509_SOURCES = lib509.c $(SUPPORTFILES) $(TESTUTIL) - lib510_SOURCES = lib510.c $(SUPPORTFILES) lib511_SOURCES = lib511.c $(SUPPORTFILES) diff --git a/tests/libtest/lib509.c b/tests/libtest/lib509.c deleted file mode 100644 index 6e5e67139..000000000 --- a/tests/libtest/lib509.c +++ /dev/null @@ -1,351 +0,0 @@ -/***************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * $Id$ - */ - -#include "test.h" - -#ifdef USE_SSLEAY - -#include - -#include -#include - -#ifndef YASSL_VERSION - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "testutil.h" - -#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000 -#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000 - -int portnum; /* the HTTPS port number we use */ - -typedef struct sslctxparm_st { - CURL* curl; - int accesstype; - unsigned char * accessinfoURL; -} sslctxparm; - - -static unsigned char *i2s_ASN1_IA5STRING( ASN1_IA5STRING *ia5) -{ - unsigned char *tmp; - if(!ia5 || !ia5->length) - return NULL; - tmp = OPENSSL_malloc(ia5->length + 1); - memcpy(tmp, ia5->data, ia5->length); - tmp[ia5->length] = 0; - return tmp; -} - -/* A conveniance routine to get an access URI. */ - -static unsigned char *my_get_ext(X509 * cert, const int type, - int extensiontype) -{ - int i; - STACK_OF(ACCESS_DESCRIPTION) * accessinfo ; - accessinfo = X509_get_ext_d2i(cert, extensiontype, NULL, NULL) ; - - if (!sk_ACCESS_DESCRIPTION_num(accessinfo)) - return NULL; - - for (i = 0; i < sk_ACCESS_DESCRIPTION_num(accessinfo); i++) { - ACCESS_DESCRIPTION * ad = sk_ACCESS_DESCRIPTION_value(accessinfo, i); - if (OBJ_obj2nid(ad->method) == type) { - if (ad->location->type == GEN_URI) { - return i2s_ASN1_IA5STRING(ad->location->d.ia5); - } - return NULL; - } - } - return NULL; -} - -void * globalparm = NULL; - -char newurl[512]; - -static int ssl_app_verify_callback(X509_STORE_CTX *ctx, void *arg) -{ - sslctxparm * p = (sslctxparm *) arg; - int ok, err; - - fprintf(stderr,"ssl_app_verify_callback sslctxparm=%p ctx=%p\n", - (void *)p, (void*)ctx); - -#if OPENSSL_VERSION_NUMBER<0x00907000L -/* not necessary in openssl 0.9.7 or later */ - - fprintf(stderr,"This version %s of openssl does not support a parm (%p)" - ", getting a global static %p \n", - OPENSSL_VERSION_TEXT, (void *)p, (void *)globalparm); - - p = globalparm; -#endif - -/* The following error should not occur. We test this to avoid segfault. */ - if (!p || !ctx) { - fprintf(stderr,"Internal error in ssl_app_verify_callback " - "sslctxparm=%p ctx=%p\n",(void *)p,(void*)ctx); - return 0; - } - - ok= X509_verify_cert(ctx); - err=X509_STORE_CTX_get_error(ctx); - -/* The following seems to be a problem in 0.9.7/8 openssl versions */ - -#if 1 - if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT || - err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) { - fprintf(stderr,"X509_verify_cert: repairing self signed\n") ; - X509_STORE_CTX_set_error(ctx,X509_V_OK); - ok = 1; - } -#endif - - if (ok && ctx->cert) { - unsigned char * accessinfoURL ; - - accessinfoURL = my_get_ext(ctx->cert,p->accesstype ,NID_info_access); - if (accessinfoURL) { - - if (strcmp((char *)p->accessinfoURL, (char *)accessinfoURL)) { - fprintf(stderr, "Setting URL <%s>, was <%s>\n", - (char *)accessinfoURL, (char *)p->accessinfoURL); - OPENSSL_free(p->accessinfoURL); - p->accessinfoURL = accessinfoURL; - - /* We need to be able to deal with a custom port number, but the - URL in the cert uses a static one. We thus need to create a new - URL that uses the currently requested port number which may not - be the one this URL uses! */ - sprintf(newurl, "https://127.0.0.1:%d/509", portnum); - fprintf(stderr, "But *really* Setting URL <%s>\n", newurl); - - curl_easy_setopt(p->curl, CURLOPT_URL, newurl); - } - else - OPENSSL_free(accessinfoURL); - } - } - return(ok); -} - - -static CURLcode sslctxfun(CURL * curl, void * sslctx, void * parm) -{ - sslctxparm * p = (sslctxparm *) parm; - - SSL_CTX * ctx = (SSL_CTX *) sslctx ; - fprintf(stderr,"sslctxfun start curl=%p ctx=%p parm=%p\n", - (void *)curl,(void *)ctx,(void *)p); - - SSL_CTX_set_quiet_shutdown(ctx,1); - SSL_CTX_set_cipher_list(ctx,"RC4-MD5"); - SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); - -/* one might assume that the cert validaton would not fail when setting this, - but it still does, see the error handling in the call back */ - - SSL_CTX_set_verify_depth(ctx,0); - SSL_CTX_set_verify(ctx,SSL_VERIFY_NONE,ZERO_NULL); - -#if OPENSSL_VERSION_NUMBER<0x00907000L -/* in newer openssl versions we can set a parameter for the call back. */ - fprintf(stderr,"This version %s of openssl does not support a parm," - " setting global one\n", OPENSSL_VERSION_TEXT); - /* this is only done to support 0.9.6 version */ - globalparm = parm; - -/* in 0.9.6 the parm is not taken */ -#endif - SSL_CTX_set_cert_verify_callback(ctx, ssl_app_verify_callback, parm); - fprintf(stderr,"sslctxfun end\n"); - - return CURLE_OK ; -} - -int test(char *URL) -{ - CURLM* multi; - sslctxparm p; - CURLMcode res; - int running; - char done = FALSE; - int i = 0; - CURLMsg *msg; - - struct timeval ml_start; - struct timeval mp_start; - char ml_timedout = FALSE; - char mp_timedout = FALSE; - - if(libtest_arg2) { - portnum = atoi(libtest_arg2); - } - - if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { - fprintf(stderr, "curl_global_init() failed\n"); - return TEST_ERR_MAJOR_BAD; - } - - if ((p.curl = curl_easy_init()) == NULL) { - fprintf(stderr, "curl_easy_init() failed\n"); - curl_global_cleanup(); - return TEST_ERR_MAJOR_BAD; - } - - p.accessinfoURL = (unsigned char *) strdup(URL); - p.accesstype = OBJ_obj2nid(OBJ_txt2obj("AD_DVCS",0)) ; - - curl_easy_setopt(p.curl, CURLOPT_URL, p.accessinfoURL); - - curl_easy_setopt(p.curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun) ; - curl_easy_setopt(p.curl, CURLOPT_SSL_CTX_DATA, &p); - - curl_easy_setopt(p.curl, CURLOPT_SSL_VERIFYPEER, FALSE); - curl_easy_setopt(p.curl, CURLOPT_SSL_VERIFYHOST, 1); - - curl_easy_setopt(p.curl, CURLOPT_VERBOSE, 1); - - if ((multi = curl_multi_init()) == NULL) { - fprintf(stderr, "curl_multi_init() failed\n"); - curl_easy_cleanup(p.curl); - curl_global_cleanup(); - return TEST_ERR_MAJOR_BAD; - } - - if ((res = curl_multi_add_handle(multi, p.curl)) != CURLM_OK) { - fprintf(stderr, "curl_multi_add_handle() failed, " - "with code %d\n", res); - curl_multi_cleanup(multi); - curl_easy_cleanup(p.curl); - curl_global_cleanup(); - return TEST_ERR_MAJOR_BAD; - } - - fprintf(stderr, "Going to perform %s\n", (char *)p.accessinfoURL); - - ml_timedout = FALSE; - ml_start = tutil_tvnow(); - - while (!done) { - fd_set rd, wr, exc; - int max_fd; - struct timeval interval; - - interval.tv_sec = 1; - interval.tv_usec = 0; - - if (tutil_tvdiff(tutil_tvnow(), ml_start) > - MAIN_LOOP_HANG_TIMEOUT) { - ml_timedout = TRUE; - break; - } - mp_timedout = FALSE; - mp_start = tutil_tvnow(); - - while (res == CURLM_CALL_MULTI_PERFORM) { - res = curl_multi_perform(multi, &running); - if (tutil_tvdiff(tutil_tvnow(), mp_start) > - MULTI_PERFORM_HANG_TIMEOUT) { - mp_timedout = TRUE; - break; - } - fprintf(stderr, "running=%d res=%d\n",running,res); - if (running <= 0) { - done = TRUE; - break; - } - } - if (mp_timedout || done) - break; - - if (res != CURLM_OK) { - fprintf(stderr, "not okay???\n"); - i = 80; - break; - } - - FD_ZERO(&rd); - FD_ZERO(&wr); - FD_ZERO(&exc); - max_fd = 0; - - if (curl_multi_fdset(multi, &rd, &wr, &exc, &max_fd) != CURLM_OK) { - fprintf(stderr, "unexpected failured of fdset.\n"); - i = 89; - break; - } - - if (select_test(max_fd+1, &rd, &wr, &exc, &interval) == -1) { - fprintf(stderr, "bad select??\n"); - i =95; - break; - } - - res = CURLM_CALL_MULTI_PERFORM; - } - - if (ml_timedout || mp_timedout) { - if (ml_timedout) fprintf(stderr, "ml_timedout\n"); - if (mp_timedout) fprintf(stderr, "mp_timedout\n"); - fprintf(stderr, "ABORTING TEST, since it seems " - "that it would have run forever.\n"); - i = TEST_ERR_RUNS_FOREVER; - } - else { - msg = curl_multi_info_read(multi, &running); - /* this should now contain a result code from the easy handle, get it */ - if(msg) - i = msg->data.result; - fprintf(stderr, "all done\n"); - } - - curl_multi_remove_handle(multi, p.curl); - curl_easy_cleanup(p.curl); - curl_multi_cleanup(multi); - - curl_global_cleanup(); - free(p.accessinfoURL); - - return i; -} -#endif /* YASSL_VERSION */ -#endif /* USE_SSLEAY */ - -#if !defined(USE_SSLEAY) || defined(YASSL_VERSION) - -int test(char *URL) -{ - (void)URL; - - if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { - fprintf(stderr, "curl_global_init() failed\n"); - return TEST_ERR_MAJOR_BAD; - } - fprintf(stderr, "libcurl lacks openssl support needed for test 509\n"); - curl_global_cleanup(); - return TEST_ERR_MAJOR_BAD; -} - -#endif /* USE_SSLEAY */ -- cgit v1.2.3