diff --git a/SOURCES/0051-curl-7.29.0-42a4cd4c.patch b/SOURCES/0051-curl-7.29.0-42a4cd4c.patch new file mode 100644 index 0000000..b3ed7d0 --- /dev/null +++ b/SOURCES/0051-curl-7.29.0-42a4cd4c.patch @@ -0,0 +1,102 @@ +From 93c0d8e98f3859c91fbfa2a6998235ee899e878e Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Thu, 20 Jul 2017 08:05:59 +0200 +Subject: [PATCH 1/2] nss: unify the coding style of nss_send() and nss_recv() + +No changes in behavior intended by this commit. + +Upstream-commit: c89eb6d0f87a3620074bc04a6af255e5dc3a523e +Signed-off-by: Kamil Dudka +--- + lib/nss.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/lib/nss.c b/lib/nss.c +index 9e0e373..ce1e25a 100644 +--- a/lib/nss.c ++++ b/lib/nss.c +@@ -1689,9 +1689,10 @@ static ssize_t nss_send(struct connectdata *conn, /* connection data */ + size_t len, /* amount to write */ + CURLcode *curlcode) + { +- int rc; ++ struct ssl_connect_data *connssl = &conn->ssl[sockindex]; ++ ssize_t rc; + +- rc = PR_Send(conn->ssl[sockindex].handle, mem, (int)len, 0, -1); ++ rc = PR_Send(connssl->handle, mem, (int)len, 0, -1); + + if(rc < 0) { + PRInt32 err = PR_GetError(); +@@ -1714,15 +1715,16 @@ static ssize_t nss_send(struct connectdata *conn, /* connection data */ + return rc; /* number of bytes */ + } + +-static ssize_t nss_recv(struct connectdata * conn, /* connection data */ +- int num, /* socketindex */ ++static ssize_t nss_recv(struct connectdata *conn, /* connection data */ ++ int sockindex, /* socketindex */ + char *buf, /* store read data here */ + size_t buffersize, /* max amount to read */ + CURLcode *curlcode) + { ++ struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + ssize_t nread; + +- nread = PR_Recv(conn->ssl[num].handle, buf, (int)buffersize, 0, -1); ++ nread = PR_Recv(connssl->handle, buf, (int)buffersize, 0, -1); + if(nread < 0) { + /* failed SSL read */ + PRInt32 err = PR_GetError(); +-- +2.13.5 + + +From 032731492497a1cde17752f8c178719bd32a7722 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Wed, 19 Jul 2017 18:02:26 +0200 +Subject: [PATCH 2/2] nss: fix a possible use-after-free in SelectClientCert() + +... causing a SIGSEGV in showit() in case the handle used to initiate +the connection has already been freed. + +This commit fixes a bug introduced in curl-7_19_5-204-g5f0cae803. + +Reported-by: Rob Sanders +Bug: https://bugzilla.redhat.com/1436158 + +Upstream-commit: 42a4cd4c78b3feb5ca07286479129116e125a730 +Signed-off-by: Kamil Dudka +--- + lib/nss.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/lib/nss.c b/lib/nss.c +index ce1e25a..b73a1e8 100644 +--- a/lib/nss.c ++++ b/lib/nss.c +@@ -1692,6 +1692,10 @@ static ssize_t nss_send(struct connectdata *conn, /* connection data */ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + ssize_t rc; + ++ /* The SelectClientCert() hook uses this for infof() and failf() but the ++ handle stored in nss_setup_connect() could have already been freed. */ ++ connssl->data = conn->data; ++ + rc = PR_Send(connssl->handle, mem, (int)len, 0, -1); + + if(rc < 0) { +@@ -1724,6 +1728,10 @@ static ssize_t nss_recv(struct connectdata *conn, /* connection data */ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + ssize_t nread; + ++ /* The SelectClientCert() hook uses this for infof() and failf() but the ++ handle stored in nss_setup_connect() could have already been freed. */ ++ connssl->data = conn->data; ++ + nread = PR_Recv(connssl->handle, buf, (int)buffersize, 0, -1); + if(nread < 0) { + /* failed SSL read */ +-- +2.13.5 + diff --git a/SOURCES/0052-curl-7.29.0-c8ea86f3.patch b/SOURCES/0052-curl-7.29.0-c8ea86f3.patch new file mode 100644 index 0000000..6d040d2 --- /dev/null +++ b/SOURCES/0052-curl-7.29.0-c8ea86f3.patch @@ -0,0 +1,42 @@ +From 67fdfef9a786fdd08da5456fca6fb30ff0d27be0 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Mon, 24 Apr 2017 15:01:04 +0200 +Subject: [PATCH] nss: do not leak PKCS #11 slot while loading a key + +It could prevent nss-pem from being unloaded later on. + +Bug: https://bugzilla.redhat.com/1444860 + +Upstream-commit: c8ea86f377a2f341db635ec96f99314023b5a8f3 +Signed-off-by: Kamil Dudka +--- + lib/nss.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/lib/nss.c b/lib/nss.c +index b73a1e8..86775b4 100644 +--- a/lib/nss.c ++++ b/lib/nss.c +@@ -551,7 +551,7 @@ fail: + static CURLcode nss_load_key(struct connectdata *conn, int sockindex, + char *key_file) + { +- PK11SlotInfo *slot; ++ PK11SlotInfo *slot, *tmp; + SECStatus status; + CURLcode rv; + struct ssl_connect_data *ssl = conn->ssl; +@@ -568,7 +568,9 @@ static CURLcode nss_load_key(struct connectdata *conn, int sockindex, + return CURLE_SSL_CERTPROBLEM; + + /* This will force the token to be seen as re-inserted */ +- SECMOD_WaitForAnyTokenEvent(mod, 0, 0); ++ tmp = SECMOD_WaitForAnyTokenEvent(mod, 0, 0); ++ if(tmp) ++ PK11_FreeSlot(tmp); + PK11_IsPresent(slot); + + status = PK11_Authenticate(slot, PR_TRUE, +-- +2.13.5 + diff --git a/SOURCES/0053-curl-7.29.0-52cd5ac2.patch b/SOURCES/0053-curl-7.29.0-52cd5ac2.patch new file mode 100644 index 0000000..1b71e6d --- /dev/null +++ b/SOURCES/0053-curl-7.29.0-52cd5ac2.patch @@ -0,0 +1,506 @@ +From 664776a2f8b4574ab8c80e7bc6986ef62ef24b77 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Thu, 3 Jul 2014 23:53:44 +0200 +Subject: [PATCH 1/5] nss: let nss_{cache,load}_crl return CURLcode + +Upstream-commit: 2968f957aa025003d15a4fa42c3138e99c6d2e3f +Signed-off-by: Kamil Dudka +--- + lib/nss.c | 21 ++++++++++----------- + 1 file changed, 10 insertions(+), 11 deletions(-) + +diff --git a/lib/nss.c b/lib/nss.c +index 86775b4..a82fc64 100644 +--- a/lib/nss.c ++++ b/lib/nss.c +@@ -471,7 +471,7 @@ static SECStatus nss_cache_crl(SECItem *crlDER) + /* CRL already cached */ + SEC_DestroyCrl(crl); + SECITEM_FreeItem(crlDER, PR_FALSE); +- return SECSuccess; ++ return CURLE_SSL_CRL_BADFILE; + } + + /* acquire lock before call of CERT_CacheCRL() */ +@@ -480,16 +480,16 @@ static SECStatus nss_cache_crl(SECItem *crlDER) + /* unable to cache CRL */ + PR_Unlock(nss_crllock); + SECITEM_FreeItem(crlDER, PR_FALSE); +- return SECFailure; ++ return CURLE_SSL_CRL_BADFILE; + } + + /* we need to clear session cache, so that the CRL could take effect */ + SSL_ClearSessionCache(); + PR_Unlock(nss_crllock); +- return SECSuccess; ++ return CURLE_OK; + } + +-static SECStatus nss_load_crl(const char* crlfilename) ++static CURLcode nss_load_crl(const char* crlfilename) + { + PRFileDesc *infile; + PRFileInfo info; +@@ -499,7 +499,7 @@ static SECStatus nss_load_crl(const char* crlfilename) + + infile = PR_Open(crlfilename, PR_RDONLY, 0); + if(!infile) +- return SECFailure; ++ return CURLE_SSL_CRL_BADFILE; + + if(PR_SUCCESS != PR_GetOpenFileInfo(infile, &info)) + goto fail; +@@ -545,7 +545,7 @@ static SECStatus nss_load_crl(const char* crlfilename) + fail: + PR_Close(infile); + SECITEM_FreeItem(&filedata, PR_FALSE); +- return SECFailure; ++ return CURLE_SSL_CRL_BADFILE; + } + + static CURLcode nss_load_key(struct connectdata *conn, int sockindex, +@@ -1463,13 +1463,12 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex) + } + + if(data->set.ssl.CRLfile) { +- if(SECSuccess != nss_load_crl(data->set.ssl.CRLfile)) { +- curlerr = CURLE_SSL_CRL_BADFILE; ++ const CURLcode rv = nss_load_crl(data->set.ssl.CRLfile); ++ if(CURLE_OK != rv) { ++ curlerr = rv; + goto error; + } +- infof(data, +- " CRLfile: %s\n", +- data->set.ssl.CRLfile ? data->set.ssl.CRLfile : "none"); ++ infof(data, " CRLfile: %s\n", data->set.ssl.CRLfile); + } + + if(data->set.str[STRING_CERT]) { +-- +2.13.5 + + +From 9efc8373f8190581b5463ebcb38f52ddaa89db51 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Fri, 4 Jul 2014 00:36:21 +0200 +Subject: [PATCH 2/5] nss: make crl_der allocated on heap + +... and spell it as crl_der instead of crlDER + +Upstream-commit: caa4db8a51e2b02e43ee85e63bc3fec232986699 +Signed-off-by: Kamil Dudka +--- + lib/nss.c | 23 ++++++++++++++--------- + 1 file changed, 14 insertions(+), 9 deletions(-) + +diff --git a/lib/nss.c b/lib/nss.c +index a82fc64..4e210bb 100644 +--- a/lib/nss.c ++++ b/lib/nss.c +@@ -463,23 +463,23 @@ static CURLcode nss_load_cert(struct ssl_connect_data *ssl, + } + + /* add given CRL to cache if it is not already there */ +-static SECStatus nss_cache_crl(SECItem *crlDER) ++static CURLcode nss_cache_crl(SECItem *crl_der) + { + CERTCertDBHandle *db = CERT_GetDefaultCertDB(); +- CERTSignedCrl *crl = SEC_FindCrlByDERCert(db, crlDER, 0); ++ CERTSignedCrl *crl = SEC_FindCrlByDERCert(db, crl_der, 0); + if(crl) { + /* CRL already cached */ + SEC_DestroyCrl(crl); +- SECITEM_FreeItem(crlDER, PR_FALSE); ++ SECITEM_FreeItem(crl_der, PR_TRUE); + return CURLE_SSL_CRL_BADFILE; + } + + /* acquire lock before call of CERT_CacheCRL() */ + PR_Lock(nss_crllock); +- if(SECSuccess != CERT_CacheCRL(db, crlDER)) { ++ if(SECSuccess != CERT_CacheCRL(db, crl_der)) { + /* unable to cache CRL */ + PR_Unlock(nss_crllock); +- SECITEM_FreeItem(crlDER, PR_FALSE); ++ SECITEM_FreeItem(crl_der, PR_TRUE); + return CURLE_SSL_CRL_BADFILE; + } + +@@ -494,7 +494,7 @@ static CURLcode nss_load_crl(const char* crlfilename) + PRFileDesc *infile; + PRFileInfo info; + SECItem filedata = { 0, NULL, 0 }; +- SECItem crlDER = { 0, NULL, 0 }; ++ SECItem *crl_der = NULL; + char *body; + + infile = PR_Open(crlfilename, PR_RDONLY, 0); +@@ -510,6 +510,10 @@ static CURLcode nss_load_crl(const char* crlfilename) + if(info.size != PR_Read(infile, filedata.data, info.size)) + goto fail; + ++ crl_der = SECITEM_AllocItem(NULL, NULL, 0U); ++ if(!crl_der) ++ goto fail; ++ + /* place a trailing zero right after the visible data */ + body = (char*)filedata.data; + body[--filedata.len] = '\0'; +@@ -530,20 +534,21 @@ static CURLcode nss_load_crl(const char* crlfilename) + + /* retrieve DER from ASCII */ + *trailer = '\0'; +- if(ATOB_ConvertAsciiToItem(&crlDER, begin)) ++ if(ATOB_ConvertAsciiToItem(crl_der, begin)) + goto fail; + + SECITEM_FreeItem(&filedata, PR_FALSE); + } + else + /* assume DER */ +- crlDER = filedata; ++ *crl_der = filedata; + + PR_Close(infile); +- return nss_cache_crl(&crlDER); ++ return nss_cache_crl(crl_der); + + fail: + PR_Close(infile); ++ SECITEM_FreeItem(crl_der, PR_TRUE); + SECITEM_FreeItem(&filedata, PR_FALSE); + return CURLE_SSL_CRL_BADFILE; + } +-- +2.13.5 + + +From f2c35b7b7f50b691d3019783ce19cc6a8dd5b484 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Fri, 4 Jul 2014 00:39:23 +0200 +Subject: [PATCH 3/5] nss: fix a memory leak when CURLOPT_CRLFILE is used + +Upstream-commit: 52cd5ac21cdfdc0a6c016de97fe70d3a50baa526 +Signed-off-by: Kamil Dudka +--- + lib/nss.c | 38 +++++++++++++++++++++++++++++++++----- + lib/urldata.h | 1 + + 2 files changed, 34 insertions(+), 5 deletions(-) + +diff --git a/lib/nss.c b/lib/nss.c +index 4e210bb..c3247c8 100644 +--- a/lib/nss.c ++++ b/lib/nss.c +@@ -425,6 +425,14 @@ static void nss_destroy_object(void *user, void *ptr) + PK11_DestroyGenericObject(obj); + } + ++/* same as nss_destroy_object() but for CRL items */ ++static void nss_destroy_crl_item(void *user, void *ptr) ++{ ++ SECItem *crl_der = (SECItem *)ptr; ++ (void) user; ++ SECITEM_FreeItem(crl_der, PR_TRUE); ++} ++ + static CURLcode nss_load_cert(struct ssl_connect_data *ssl, + const char *filename, PRBool cacert) + { +@@ -463,7 +471,7 @@ static CURLcode nss_load_cert(struct ssl_connect_data *ssl, + } + + /* add given CRL to cache if it is not already there */ +-static CURLcode nss_cache_crl(SECItem *crl_der) ++static CURLcode nss_cache_crl(struct ssl_connect_data *ssl, SECItem *crl_der) + { + CERTCertDBHandle *db = CERT_GetDefaultCertDB(); + CERTSignedCrl *crl = SEC_FindCrlByDERCert(db, crl_der, 0); +@@ -474,12 +482,17 @@ static CURLcode nss_cache_crl(SECItem *crl_der) + return CURLE_SSL_CRL_BADFILE; + } + ++ /* store the CRL item so that we can free it in Curl_nss_close() */ ++ if(!Curl_llist_insert_next(ssl->crl_list, ssl->crl_list->tail, crl_der)) { ++ SECITEM_FreeItem(crl_der, PR_FALSE); ++ return CURLE_OUT_OF_MEMORY; ++ } ++ + /* acquire lock before call of CERT_CacheCRL() */ + PR_Lock(nss_crllock); + if(SECSuccess != CERT_CacheCRL(db, crl_der)) { + /* unable to cache CRL */ + PR_Unlock(nss_crllock); +- SECITEM_FreeItem(crl_der, PR_TRUE); + return CURLE_SSL_CRL_BADFILE; + } + +@@ -489,7 +502,8 @@ static CURLcode nss_cache_crl(SECItem *crl_der) + return CURLE_OK; + } + +-static CURLcode nss_load_crl(const char* crlfilename) ++static CURLcode nss_load_crl(struct ssl_connect_data *connssl, ++ const char* crlfilename) + { + PRFileDesc *infile; + PRFileInfo info; +@@ -544,7 +558,7 @@ static CURLcode nss_load_crl(const char* crlfilename) + *crl_der = filedata; + + PR_Close(infile); +- return nss_cache_crl(crl_der); ++ return nss_cache_crl(connssl, crl_der); + + fail: + PR_Close(infile); +@@ -1147,6 +1161,10 @@ void Curl_nss_close(struct connectdata *conn, int sockindex) + connssl->obj_list = NULL; + connssl->obj_clicert = NULL; + ++ /* destroy all CRL items */ ++ Curl_llist_destroy(connssl->crl_list, NULL); ++ connssl->crl_list = NULL; ++ + PR_Close(connssl->handle); + connssl->handle = NULL; + } +@@ -1325,6 +1343,8 @@ static CURLcode nss_fail_connect(struct ssl_connect_data *connssl, + /* cleanup on connection failure */ + Curl_llist_destroy(connssl->obj_list, NULL); + connssl->obj_list = NULL; ++ Curl_llist_destroy(connssl->crl_list, NULL); ++ connssl->crl_list = NULL; + return curlerr; + } + +@@ -1367,6 +1387,14 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex) + if(!connssl->obj_list) + return CURLE_OUT_OF_MEMORY; + ++ /* list of all CRL items we need to destroy in Curl_nss_close() */ ++ connssl->crl_list = Curl_llist_alloc(nss_destroy_crl_item); ++ if(!connssl->crl_list) { ++ Curl_llist_destroy(connssl->obj_list, NULL); ++ connssl->obj_list = NULL; ++ return CURLE_OUT_OF_MEMORY; ++ } ++ + /* FIXME. NSS doesn't support multiple databases open at the same time. */ + PR_Lock(nss_initlock); + curlerr = nss_init(conn->data); +@@ -1468,7 +1496,7 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex) + } + + if(data->set.ssl.CRLfile) { +- const CURLcode rv = nss_load_crl(data->set.ssl.CRLfile); ++ const CURLcode rv = nss_load_crl(connssl, data->set.ssl.CRLfile); + if(CURLE_OK != rv) { + curlerr = rv; + goto error; +diff --git a/lib/urldata.h b/lib/urldata.h +index f4c6222..3624af1 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -301,6 +301,7 @@ struct ssl_connect_data { + PRFileDesc *handle; + char *client_nickname; + struct SessionHandle *data; ++ struct curl_llist *crl_list; + struct curl_llist *obj_list; + PK11GenericObject *obj_clicert; + ssl_connect_state connecting_state; +-- +2.13.5 + + +From 6f93eefb3361e430274eb9e76ff84380289c6164 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Fri, 4 Jul 2014 12:41:53 +0200 +Subject: [PATCH 4/5] nss: make the list of CRL items global + +Otherwise NSS could use an already freed item for another connection. + +Upstream-commit: ca2aa61b66d684a1076d43025048f1a43d5755b6 +Signed-off-by: Kamil Dudka +--- + lib/nss.c | 46 ++++++++++++++++++++++------------------------ + lib/urldata.h | 1 - + 2 files changed, 22 insertions(+), 25 deletions(-) + +diff --git a/lib/nss.c b/lib/nss.c +index c3247c8..acbd09a 100644 +--- a/lib/nss.c ++++ b/lib/nss.c +@@ -77,6 +77,7 @@ PRFileDesc *PR_ImportTCPSocket(PRInt32 osfd); + static PRLock *nss_initlock = NULL; + static PRLock *nss_crllock = NULL; + static PRLock *nss_findslot_lock = NULL; ++struct curl_llist *nss_crl_list = NULL; + NSSInitContext * nss_context = NULL; + + volatile int initialized = 0; +@@ -471,7 +472,7 @@ static CURLcode nss_load_cert(struct ssl_connect_data *ssl, + } + + /* add given CRL to cache if it is not already there */ +-static CURLcode nss_cache_crl(struct ssl_connect_data *ssl, SECItem *crl_der) ++static CURLcode nss_cache_crl(SECItem *crl_der) + { + CERTCertDBHandle *db = CERT_GetDefaultCertDB(); + CERTSignedCrl *crl = SEC_FindCrlByDERCert(db, crl_der, 0); +@@ -482,14 +483,16 @@ static CURLcode nss_cache_crl(struct ssl_connect_data *ssl, SECItem *crl_der) + return CURLE_SSL_CRL_BADFILE; + } + +- /* store the CRL item so that we can free it in Curl_nss_close() */ +- if(!Curl_llist_insert_next(ssl->crl_list, ssl->crl_list->tail, crl_der)) { +- SECITEM_FreeItem(crl_der, PR_FALSE); ++ /* acquire lock before call of CERT_CacheCRL() and accessing nss_crl_list */ ++ PR_Lock(nss_crllock); ++ ++ /* store the CRL item so that we can free it in Curl_nss_cleanup() */ ++ if(!Curl_llist_insert_next(nss_crl_list, nss_crl_list->tail, crl_der)) { ++ SECITEM_FreeItem(crl_der, PR_TRUE); ++ PR_Unlock(nss_crllock); + return CURLE_OUT_OF_MEMORY; + } + +- /* acquire lock before call of CERT_CacheCRL() */ +- PR_Lock(nss_crllock); + if(SECSuccess != CERT_CacheCRL(db, crl_der)) { + /* unable to cache CRL */ + PR_Unlock(nss_crllock); +@@ -502,8 +505,7 @@ static CURLcode nss_cache_crl(struct ssl_connect_data *ssl, SECItem *crl_der) + return CURLE_OK; + } + +-static CURLcode nss_load_crl(struct ssl_connect_data *connssl, +- const char* crlfilename) ++static CURLcode nss_load_crl(const char* crlfilename) + { + PRFileDesc *infile; + PRFileInfo info; +@@ -558,7 +560,7 @@ static CURLcode nss_load_crl(struct ssl_connect_data *connssl, + *crl_der = filedata; + + PR_Close(infile); +- return nss_cache_crl(connssl, crl_der); ++ return nss_cache_crl(crl_der); + + fail: + PR_Close(infile); +@@ -996,6 +998,11 @@ static CURLcode nss_init(struct SessionHandle *data) + if(initialized) + return CURLE_OK; + ++ /* list of all CRL items we need to destroy in Curl_nss_cleanup() */ ++ nss_crl_list = Curl_llist_alloc(nss_destroy_crl_item); ++ if(!nss_crl_list) ++ return CURLE_OUT_OF_MEMORY; ++ + /* First we check if $SSL_DIR points to a valid dir */ + cert_dir = getenv("SSL_DIR"); + if(cert_dir) { +@@ -1096,6 +1103,11 @@ void Curl_nss_cleanup(void) + NSS_ShutdownContext(nss_context); + nss_context = NULL; + } ++ ++ /* destroy all CRL items */ ++ Curl_llist_destroy(nss_crl_list, NULL); ++ nss_crl_list = NULL; ++ + PR_Unlock(nss_initlock); + + PR_DestroyLock(nss_initlock); +@@ -1161,10 +1173,6 @@ void Curl_nss_close(struct connectdata *conn, int sockindex) + connssl->obj_list = NULL; + connssl->obj_clicert = NULL; + +- /* destroy all CRL items */ +- Curl_llist_destroy(connssl->crl_list, NULL); +- connssl->crl_list = NULL; +- + PR_Close(connssl->handle); + connssl->handle = NULL; + } +@@ -1343,8 +1351,6 @@ static CURLcode nss_fail_connect(struct ssl_connect_data *connssl, + /* cleanup on connection failure */ + Curl_llist_destroy(connssl->obj_list, NULL); + connssl->obj_list = NULL; +- Curl_llist_destroy(connssl->crl_list, NULL); +- connssl->crl_list = NULL; + return curlerr; + } + +@@ -1387,14 +1393,6 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex) + if(!connssl->obj_list) + return CURLE_OUT_OF_MEMORY; + +- /* list of all CRL items we need to destroy in Curl_nss_close() */ +- connssl->crl_list = Curl_llist_alloc(nss_destroy_crl_item); +- if(!connssl->crl_list) { +- Curl_llist_destroy(connssl->obj_list, NULL); +- connssl->obj_list = NULL; +- return CURLE_OUT_OF_MEMORY; +- } +- + /* FIXME. NSS doesn't support multiple databases open at the same time. */ + PR_Lock(nss_initlock); + curlerr = nss_init(conn->data); +@@ -1496,7 +1494,7 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex) + } + + if(data->set.ssl.CRLfile) { +- const CURLcode rv = nss_load_crl(connssl, data->set.ssl.CRLfile); ++ const CURLcode rv = nss_load_crl(data->set.ssl.CRLfile); + if(CURLE_OK != rv) { + curlerr = rv; + goto error; +diff --git a/lib/urldata.h b/lib/urldata.h +index 3624af1..f4c6222 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -301,7 +301,6 @@ struct ssl_connect_data { + PRFileDesc *handle; + char *client_nickname; + struct SessionHandle *data; +- struct curl_llist *crl_list; + struct curl_llist *obj_list; + PK11GenericObject *obj_clicert; + ssl_connect_state connecting_state; +-- +2.13.5 + + +From de0742d4141ede4d1849ff1ebffd820faea53ad7 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Wed, 8 Oct 2014 17:13:59 +0200 +Subject: [PATCH 5/5] nss: do not fail if a CRL is already cached + +This fixes a copy-paste mistake from commit 2968f957. + +Upstream-commit: 9e37a7f9a5cd141c717aa0262e8dee7713c25200 +Signed-off-by: Kamil Dudka +--- + lib/nss.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/nss.c b/lib/nss.c +index acbd09a..1b8abd3 100644 +--- a/lib/nss.c ++++ b/lib/nss.c +@@ -480,7 +480,7 @@ static CURLcode nss_cache_crl(SECItem *crl_der) + /* CRL already cached */ + SEC_DestroyCrl(crl); + SECITEM_FreeItem(crl_der, PR_TRUE); +- return CURLE_SSL_CRL_BADFILE; ++ return CURLE_OK; + } + + /* acquire lock before call of CERT_CacheCRL() and accessing nss_crl_list */ +-- +2.13.5 + diff --git a/SOURCES/0054-curl-7.29.0-ce2c3ebd.patch b/SOURCES/0054-curl-7.29.0-ce2c3ebd.patch new file mode 100644 index 0000000..b6dffe6 --- /dev/null +++ b/SOURCES/0054-curl-7.29.0-ce2c3ebd.patch @@ -0,0 +1,509 @@ +From 5285b2518773185c049b0c2af980654a0b1c6871 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Wed, 8 Mar 2017 12:21:09 +0100 +Subject: [PATCH 1/4] socks: use proxy_user instead of proxy_name + +... to make it obvious what the data is used for + +Upstream-commit: 641072b919b1a52c58664cd18619f8dd1c4c0cee +Signed-off-by: Kamil Dudka +--- + lib/socks.c | 30 +++++++++++++++--------------- + 1 file changed, 15 insertions(+), 15 deletions(-) + +diff --git a/lib/socks.c b/lib/socks.c +index 0cf397c..9aac9ca 100644 +--- a/lib/socks.c ++++ b/lib/socks.c +@@ -106,7 +106,7 @@ int Curl_blockread_all(struct connectdata *conn, /* connection data */ + * Set protocol4a=true for "SOCKS 4A (Simple Extension to SOCKS 4 Protocol)" + * Nonsupport "Identification Protocol (RFC1413)" + */ +-CURLcode Curl_SOCKS4(const char *proxy_name, ++CURLcode Curl_SOCKS4(const char *proxy_user, + const char *hostname, + int remote_port, + int sockindex, +@@ -200,8 +200,8 @@ CURLcode Curl_SOCKS4(const char *proxy_name, + * This is currently not supporting "Identification Protocol (RFC1413)". + */ + socksreq[8] = 0; /* ensure empty userid is NUL-terminated */ +- if(proxy_name) +- strlcat((char*)socksreq + 8, proxy_name, sizeof(socksreq) - 8); ++ if(proxy_user) ++ strlcat((char*)socksreq + 8, proxy_user, sizeof(socksreq) - 8); + + /* + * Make connection +@@ -337,7 +337,7 @@ CURLcode Curl_SOCKS4(const char *proxy_name, + * This function logs in to a SOCKS5 proxy and sends the specifics to the final + * destination server. + */ +-CURLcode Curl_SOCKS5(const char *proxy_name, ++CURLcode Curl_SOCKS5(const char *proxy_user, + const char *proxy_password, + const char *hostname, + int remote_port, +@@ -410,12 +410,12 @@ CURLcode Curl_SOCKS5(const char *proxy_name, + + socksreq[0] = 5; /* version */ + #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) +- socksreq[1] = (char)(proxy_name ? 3 : 2); /* number of methods (below) */ ++ socksreq[1] = (char)(proxy_user ? 3 : 2); /* number of methods (below) */ + socksreq[2] = 0; /* no authentication */ + socksreq[3] = 1; /* gssapi */ + socksreq[4] = 2; /* username/password */ + #else +- socksreq[1] = (char)(proxy_name ? 2 : 1); /* number of methods (below) */ ++ socksreq[1] = (char)(proxy_user ? 2 : 1); /* number of methods (below) */ + socksreq[2] = 0; /* no authentication */ + socksreq[3] = 2; /* username/password */ + #endif +@@ -474,13 +474,13 @@ CURLcode Curl_SOCKS5(const char *proxy_name, + #endif + else if(socksreq[1] == 2) { + /* Needs user name and password */ +- size_t proxy_name_len, proxy_password_len; +- if(proxy_name && proxy_password) { +- proxy_name_len = strlen(proxy_name); ++ size_t proxy_user_len, proxy_password_len; ++ if(proxy_user && proxy_password) { ++ proxy_user_len = strlen(proxy_user); + proxy_password_len = strlen(proxy_password); + } + else { +- proxy_name_len = 0; ++ proxy_user_len = 0; + proxy_password_len = 0; + } + +@@ -493,10 +493,10 @@ CURLcode Curl_SOCKS5(const char *proxy_name, + */ + len = 0; + socksreq[len++] = 1; /* username/pw subnegotiation version */ +- socksreq[len++] = (unsigned char) proxy_name_len; +- if(proxy_name && proxy_name_len) +- memcpy(socksreq + len, proxy_name, proxy_name_len); +- len += proxy_name_len; ++ socksreq[len++] = (unsigned char) proxy_user_len; ++ if(proxy_user && proxy_user_len) ++ memcpy(socksreq + len, proxy_user, proxy_user_len); ++ len += proxy_user_len; + socksreq[len++] = (unsigned char) proxy_password_len; + if(proxy_password && proxy_password_len) + memcpy(socksreq + len, proxy_password, proxy_password_len); +@@ -535,7 +535,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name, + } + else if(socksreq[1] == 255) { + #endif +- if(!proxy_name || !*proxy_name) { ++ if(!proxy_user || !*proxy_user) { + failf(data, + "No authentication method was acceptable. (It is quite likely" + " that the SOCKS5 server wanted a username/password, since none" +-- +2.13.5 + + +From 3676c3fab628e848270e2169398f912a1449c31b Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Wed, 8 Mar 2017 12:16:01 +0100 +Subject: [PATCH 2/4] socks: deduplicate the code for auth request + +Upstream-commit: cd1c9f08078d4a8566ed10f6df9ae9a729f3290b +Signed-off-by: Kamil Dudka +--- + lib/socks.c | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +diff --git a/lib/socks.c b/lib/socks.c +index 9aac9ca..398e0ac 100644 +--- a/lib/socks.c ++++ b/lib/socks.c +@@ -362,6 +362,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user, + */ + + unsigned char socksreq[600]; /* room for large user/pw (255 max each) */ ++ int idx; + ssize_t actualread; + ssize_t written; + int result; +@@ -408,17 +409,17 @@ CURLcode Curl_SOCKS5(const char *proxy_user, + return CURLE_COULDNT_CONNECT; + } + +- socksreq[0] = 5; /* version */ ++ idx = 0; ++ socksreq[idx++] = 5; /* version */ ++ idx++; /* reserve for the number of authentication methods */ ++ socksreq[idx++] = 0; /* no authentication */ + #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) +- socksreq[1] = (char)(proxy_user ? 3 : 2); /* number of methods (below) */ +- socksreq[2] = 0; /* no authentication */ +- socksreq[3] = 1; /* gssapi */ +- socksreq[4] = 2; /* username/password */ +-#else +- socksreq[1] = (char)(proxy_user ? 2 : 1); /* number of methods (below) */ +- socksreq[2] = 0; /* no authentication */ +- socksreq[3] = 2; /* username/password */ ++ socksreq[idx++] = 1; /* GSS-API */ + #endif ++ if(proxy_user) ++ socksreq[idx++] = 2; /* username/password */ ++ /* write the number of authentication methods */ ++ socksreq[1] = (unsigned char) (idx - 2); + + curlx_nonblock(sock, FALSE); + +-- +2.13.5 + + +From a76468431c030fc832aed7a5fa5b4b3f9acfe2ae Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Thu, 27 Apr 2017 15:18:49 +0200 +Subject: [PATCH 3/4] CURLOPT_SOCKS5_AUTH: allowed methods for SOCKS5 proxy + auth + +If libcurl was built with GSS-API support, it unconditionally advertised +GSS-API authentication while connecting to a SOCKS5 proxy. This caused +problems in environments with improperly configured Kerberos: a stock +libcurl failed to connect, despite libcurl built without GSS-API +connected fine using username and password. + +This commit introduces the CURLOPT_SOCKS5_AUTH option to control the +allowed methods for SOCKS5 authentication at run time. + +Note that a new option was preferred over reusing CURLOPT_PROXYAUTH +for compatibility reasons because the set of authentication methods +allowed by default was different for HTTP and SOCKS5 proxies. + +Bug: https://curl.haxx.se/mail/lib-2017-01/0005.html +Closes https://github.com/curl/curl/pull/1454 + +Upstream-commit: 8924f58c370afa756fc4fd13916dfdea91d21b21 +Signed-off-by: Kamil Dudka +--- + docs/libcurl/curl_easy_setopt.3 | 8 ++++++++ + docs/libcurl/symbols-in-versions | 2 ++ + include/curl/curl.h | 6 ++++++ + lib/socks.c | 27 ++++++++++++++++++--------- + lib/url.c | 8 ++++++++ + lib/urldata.h | 1 + + 6 files changed, 43 insertions(+), 9 deletions(-) + +diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3 +index 0a9375e..4ce8207 100644 +--- a/docs/libcurl/curl_easy_setopt.3 ++++ b/docs/libcurl/curl_easy_setopt.3 +@@ -862,6 +862,14 @@ Set the parameter to 1 to make the library tunnel all operations through a + given HTTP proxy. There is a big difference between using a proxy and to + tunnel through it. If you don't know what this means, you probably don't want + this tunneling option. ++.IP CURLOPT_SOCKS5_AUTH ++Pass a long as parameter, which is set to a bitmask, to tell libcurl which ++authentication method(s) are allowed for SOCKS5 proxy authentication. The only ++supported flags are \fICURLAUTH_BASIC\fP, which allows username/password ++authentication, \fICURLAUTH_GSSAPI\fP, which allows GSS-API authentication, and ++\fICURLAUTH_NONE\fP, which allows no authentication. Set the actual user name ++and password with the \fICURLOPT_PROXYUSERPWD(3)\fP option. Defaults to ++\fICURLAUTH_BASIC|CURLAUTH_GSSAPI\fP. (Added in 7.55.0) + .IP CURLOPT_SOCKS5_GSSAPI_SERVICE + Pass a char * as parameter to a string holding the name of the service. The + default service name for a SOCKS5 server is rcmd/server-fqdn. This option +diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions +index 0f7469d..b0b6232 100644 +--- a/docs/libcurl/symbols-in-versions ++++ b/docs/libcurl/symbols-in-versions +@@ -17,6 +17,7 @@ CURLAUTH_ANYSAFE 7.10.6 + CURLAUTH_BASIC 7.10.6 + CURLAUTH_DIGEST 7.10.6 + CURLAUTH_DIGEST_IE 7.19.3 ++CURLAUTH_GSSAPI 7.55.0 + CURLAUTH_GSSNEGOTIATE 7.10.6 + CURLAUTH_NONE 7.10.6 + CURLAUTH_NTLM 7.10.6 +@@ -454,6 +455,7 @@ CURLOPT_SERVER_RESPONSE_TIMEOUT 7.20.0 + CURLOPT_SHARE 7.10 + CURLOPT_SOCKOPTDATA 7.16.0 + CURLOPT_SOCKOPTFUNCTION 7.16.0 ++CURLOPT_SOCKS5_AUTH 7.55.0 + CURLOPT_SOCKS5_GSSAPI_NEC 7.19.4 + CURLOPT_SOCKS5_GSSAPI_SERVICE 7.19.4 + CURLOPT_SOURCE_HOST 7.12.1 - 7.15.5 +diff --git a/include/curl/curl.h b/include/curl/curl.h +index 14f6fd7..0375a64 100644 +--- a/include/curl/curl.h ++++ b/include/curl/curl.h +@@ -626,6 +626,9 @@ typedef enum { + #define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE) + #define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE)) + ++/* Used for CURLOPT_SOCKS5_AUTH to stay terminologically correct */ ++#define CURLAUTH_GSSAPI CURLAUTH_GSSNEGOTIATE ++ + #define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */ + #define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */ + #define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */ +@@ -1539,6 +1542,9 @@ typedef enum { + /* Path to UNIX domain socket */ + CINIT(UNIX_SOCKET_PATH, OBJECTPOINT, 231), + ++ /* bitmask of allowed auth methods for connections to SOCKS5 proxies */ ++ CINIT(SOCKS5_AUTH, LONG, 267), ++ + CURLOPT_LASTENTRY /* the last unused */ + } CURLoption; + +diff --git a/lib/socks.c b/lib/socks.c +index 398e0ac..5900063 100644 +--- a/lib/socks.c ++++ b/lib/socks.c +@@ -373,6 +373,8 @@ CURLcode Curl_SOCKS5(const char *proxy_user, + bool socks5_resolve_local = (conn->proxytype == CURLPROXY_SOCKS5)?TRUE:FALSE; + const size_t hostname_len = strlen(hostname); + ssize_t len = 0; ++ const unsigned long auth = data->set.socks5auth; ++ bool allow_gssapi = FALSE; + + /* RFC1928 chapter 5 specifies max 255 chars for domain name in packet */ + if(!socks5_resolve_local && hostname_len > 255) { +@@ -409,13 +411,24 @@ CURLcode Curl_SOCKS5(const char *proxy_user, + return CURLE_COULDNT_CONNECT; + } + ++ if(auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI)) ++ infof(conn->data, ++ "warning: unsupported value passed to CURLOPT_SOCKS5_AUTH: %lu\n", ++ auth); ++ if(!(auth & CURLAUTH_BASIC)) ++ /* disable username/password auth */ ++ proxy_user = NULL; ++#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) ++ if(auth & CURLAUTH_GSSAPI) ++ allow_gssapi = TRUE; ++#endif ++ + idx = 0; + socksreq[idx++] = 5; /* version */ + idx++; /* reserve for the number of authentication methods */ + socksreq[idx++] = 0; /* no authentication */ +-#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) +- socksreq[idx++] = 1; /* GSS-API */ +-#endif ++ if(allow_gssapi) ++ socksreq[idx++] = 1; /* GSS-API */ + if(proxy_user) + socksreq[idx++] = 2; /* username/password */ + /* write the number of authentication methods */ +@@ -465,7 +478,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user, + ; + } + #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) +- else if(socksreq[1] == 1) { ++ else if(allow_gssapi && (socksreq[1] == 1)) { + code = Curl_SOCKS5_gssapi_negotiate(sockindex, conn); + if(code != CURLE_OK) { + failf(data, "Unable to negotiate SOCKS5 gssapi context."); +@@ -526,16 +539,12 @@ CURLcode Curl_SOCKS5(const char *proxy_user, + } + else { + /* error */ +-#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) +- if(socksreq[1] == 255) { +-#else +- if(socksreq[1] == 1) { ++ if(!allow_gssapi && (socksreq[1] == 1)) { + failf(data, + "SOCKS5 GSSAPI per-message authentication is not supported."); + return CURLE_COULDNT_CONNECT; + } + else if(socksreq[1] == 255) { +-#endif + if(!proxy_user || !*proxy_user) { + failf(data, + "No authentication method was acceptable. (It is quite likely" +diff --git a/lib/url.c b/lib/url.c +index 19a40c7..d632813 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -516,6 +516,9 @@ CURLcode Curl_init_userdefined(struct UserDefined *set) + set->httpauth = CURLAUTH_BASIC; /* defaults to basic */ + set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */ + ++ /* SOCKS5 proxy auth defaults to username/password + GSS-API */ ++ set->socks5auth = CURLAUTH_BASIC | CURLAUTH_GSSAPI; ++ + /* make libcurl quiet by default: */ + set->hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */ + +@@ -1380,6 +1383,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, + break; + #endif /* CURL_DISABLE_PROXY */ + ++ case CURLOPT_SOCKS5_AUTH: ++ data->set.socks5auth = va_arg(param, unsigned long); ++ if(data->set.socks5auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI)) ++ result = CURLE_NOT_BUILT_IN; ++ break; + #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) + case CURLOPT_SOCKS5_GSSAPI_SERVICE: + /* +diff --git a/lib/urldata.h b/lib/urldata.h +index f4c6222..3e6ace5 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -1406,6 +1406,7 @@ struct UserDefined { + long use_port; /* which port to use (when not using default) */ + unsigned long httpauth; /* kind of HTTP authentication to use (bitmask) */ + unsigned long proxyauth; /* kind of proxy authentication to use (bitmask) */ ++ unsigned long socks5auth;/* kind of SOCKS5 authentication to use (bitmask) */ + long followlocation; /* as in HTTP Location: */ + long maxredirs; /* maximum no. of http(s) redirects to follow, set to -1 + for infinity */ +-- +2.13.5 + + +From 08f6dc218afe2d7e74f87996965f0770a566f185 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Fri, 19 May 2017 18:11:47 +0200 +Subject: [PATCH 4/4] curl --socks5-{basic,gssapi}: control socks5 auth + +Closes https://github.com/curl/curl/pull/1454 + +Upstream-commit: ce2c3ebda20919fe636e675f219ae387e386f508 +Signed-off-by: Kamil Dudka +--- + docs/curl.1 | 10 ++++++++++ + src/tool_cfgable.h | 1 + + src/tool_getparam.c | 16 ++++++++++++++++ + src/tool_help.c | 2 ++ + src/tool_operate.c | 5 +++++ + src/tool_setopt.c | 1 + + src/tool_setopt.h | 1 + + 7 files changed, 36 insertions(+) + +diff --git a/docs/curl.1 b/docs/curl.1 +index c9bb336..7906f1f 100644 +--- a/docs/curl.1 ++++ b/docs/curl.1 +@@ -1343,6 +1343,16 @@ Since 7.21.7, this option is superfluous since you can specify a socks4a proxy + with \fI-x, --proxy\fP using a socks4a:// protocol prefix. + + If this option is used several times, the last one will be used. ++.IP "--socks5-basic" ++Tells curl to use username/password authentication when connecting to a SOCKS5 ++proxy. The username/password authentication is enabled by default. Use ++\fI--socks5-gssapi\fP to force GSS-API authentication to SOCKS5 proxies. ++(Added in 7.55.0) ++.IP "--socks5-gssapi" ++Tells curl to use GSS-API authentication when connecting to a SOCKS5 proxy. ++The GSS-API authentication is enabled by default (if curl is compiled with ++GSS-API support). Use \fI--socks5-basic\fP to force username/password ++authentication to SOCKS5 proxies. (Added in 7.55.0) + .IP "--socks5-hostname " + Use the specified SOCKS5 proxy (and let the proxy resolve the host name). If + the port number is not specified, it is assumed at port 1080. (Added in +diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h +index a9b033b..68d0297 100644 +--- a/src/tool_cfgable.h ++++ b/src/tool_cfgable.h +@@ -172,6 +172,7 @@ struct Configurable { + * default rcmd */ + int socks5_gssapi_nec ; /* The NEC reference server does not protect + * the encryption type exchange */ ++ unsigned long socks5_auth;/* auth bitmask for socks5 proxies */ + + bool tcp_nodelay; + long req_retry; /* number of retries */ +diff --git a/src/tool_getparam.c b/src/tool_getparam.c +index 33db742..32fc68b 100644 +--- a/src/tool_getparam.c ++++ b/src/tool_getparam.c +@@ -210,6 +210,8 @@ static const struct LongShort aliases[]= { + {"El", "tlspassword", TRUE}, + {"Em", "tlsauthtype", TRUE}, + {"En", "ssl-allow-beast", FALSE}, ++ {"EA", "socks5-basic", FALSE}, ++ {"EB", "socks5-gssapi", FALSE}, + {"f", "fail", FALSE}, + {"F", "form", TRUE}, + {"Fs", "form-string", TRUE}, +@@ -1324,6 +1326,20 @@ ParameterError getparameter(char *flag, /* f or -long-flag */ + if(curlinfo->features & CURL_VERSION_SSL) + config->ssl_allow_beast = toggle; + break; ++ case 'A': ++ /* --socks5-basic */ ++ if(toggle) ++ config->socks5_auth |= CURLAUTH_BASIC; ++ else ++ config->socks5_auth &= ~CURLAUTH_BASIC; ++ break; ++ case 'B': ++ /* --socks5-gssapi */ ++ if(toggle) ++ config->socks5_auth |= CURLAUTH_GSSAPI; ++ else ++ config->socks5_auth &= ~CURLAUTH_GSSAPI; ++ break; + default: /* certificate file */ + { + char *certname, *passphrase; +diff --git a/src/tool_help.c b/src/tool_help.c +index 3a64e35..c2883eb 100644 +--- a/src/tool_help.c ++++ b/src/tool_help.c +@@ -179,6 +179,8 @@ static const char *const helptext[] = { + " --socks4 HOST[:PORT] SOCKS4 proxy on given host + port", + " --socks4a HOST[:PORT] SOCKS4a proxy on given host + port", + " --socks5 HOST[:PORT] SOCKS5 proxy on given host + port", ++ " --socks5-basic Enable username/password auth for SOCKS5 proxies", ++ " --socks5-gssapi Enable GSS-API auth for SOCKS5 proxies", + " --socks5-hostname HOST[:PORT] " + "SOCKS5 proxy, pass host name to proxy", + #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) +diff --git a/src/tool_operate.c b/src/tool_operate.c +index 41b0e6b..185f9c6 100644 +--- a/src/tool_operate.c ++++ b/src/tool_operate.c +@@ -1208,6 +1208,11 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) + if(config->socks5_gssapi_nec) + my_setopt_str(curl, CURLOPT_SOCKS5_GSSAPI_NEC, + config->socks5_gssapi_nec); ++ ++ /* new in curl 7.55.0 */ ++ if(config->socks5_auth) ++ my_setopt_bitmask(curl, CURLOPT_SOCKS5_AUTH, ++ (long)config->socks5_auth); + } + #endif + /* curl 7.13.0 */ +diff --git a/src/tool_setopt.c b/src/tool_setopt.c +index 9860117..5ae32cd 100644 +--- a/src/tool_setopt.c ++++ b/src/tool_setopt.c +@@ -130,6 +130,7 @@ const NameValue setopt_nv_CURLPROTO[] = { + static const NameValue setopt_nv_CURLNONZERODEFAULTS[] = { + NV1(CURLOPT_SSL_VERIFYPEER, 1), + NV1(CURLOPT_SSL_VERIFYHOST, 1), ++ NV1(CURLOPT_SOCKS5_AUTH, 1), + NVEND + }; + +diff --git a/src/tool_setopt.h b/src/tool_setopt.h +index d107756..60e614c 100644 +--- a/src/tool_setopt.h ++++ b/src/tool_setopt.h +@@ -64,6 +64,7 @@ extern const NameValueUnsigned setopt_nv_CURLAUTH[]; + #define setopt_nv_CURLOPT_REDIR_PROTOCOLS setopt_nv_CURLPROTO + #define setopt_nv_CURLOPT_PROXYTYPE setopt_nv_CURLPROXY + #define setopt_nv_CURLOPT_PROXYAUTH setopt_nv_CURLAUTH ++#define setopt_nv_CURLOPT_SOCKS5_AUTH setopt_nv_CURLAUTH + + /* Intercept setopt calls for --libcurl */ + +-- +2.13.5 + diff --git a/SOURCES/0056-curl-7.29.0-0afbcfd8.patch b/SOURCES/0056-curl-7.29.0-0afbcfd8.patch new file mode 100644 index 0000000..ae66f6c --- /dev/null +++ b/SOURCES/0056-curl-7.29.0-0afbcfd8.patch @@ -0,0 +1,167 @@ +From bf614e0e8a231b820160ebca2bc13afeee44c683 Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Fri, 27 Jan 2017 00:42:28 +0200 +Subject: [PATCH 1/3] authneg: clear auth.multi flag at http_done + +This flag is meant for the current request based on authentication +state, once the request is done we can clear the flag. + +Also change auth.multi to auth.multipass for better readability. + +Fixes https://github.com/curl/curl/issues/1095 +Closes https://github.com/curl/curl/pull/1326 + +Signed-off-by: Isaac Boukris +Reported-by: Michael Kaufmann + +Upstream-commit: 5278462c32a70cd972a8cc824a38f164151d6c6d +Signed-off-by: Kamil Dudka +--- + lib/http.c | 11 ++++++++--- + lib/urldata.h | 4 ++-- + 2 files changed, 10 insertions(+), 5 deletions(-) + +diff --git a/lib/http.c b/lib/http.c +index db37cf9..9419bff 100644 +--- a/lib/http.c ++++ b/lib/http.c +@@ -585,10 +585,10 @@ output_auth_headers(struct connectdata *conn, + proxy?"Proxy":"Server", auth, + proxy?(conn->proxyuser?conn->proxyuser:""): + (conn->user?conn->user:"")); +- authstatus->multi = (!authstatus->done) ? TRUE : FALSE; ++ authstatus->multipass = (!authstatus->done) ? TRUE : FALSE; + } + else +- authstatus->multi = FALSE; ++ authstatus->multipass = FALSE; + + return CURLE_OK; + } +@@ -1402,6 +1402,11 @@ CURLcode Curl_http_done(struct connectdata *conn, + struct SessionHandle *data = conn->data; + struct HTTP *http =data->state.proto.http; + ++ /* Clear multipass flag. If authentication isn't done yet, then it will get ++ * a chance to be set back to true when we output the next auth header */ ++ data->state.authhost.multipass = FALSE; ++ data->state.authproxy.multipass = FALSE; ++ + Curl_unencode_cleanup(conn); + + #ifdef USE_HTTP_NEGOTIATE +@@ -1738,7 +1743,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) + if(result) + return result; + +- if((data->state.authhost.multi || data->state.authproxy.multi) && ++ if((data->state.authhost.multipass || data->state.authproxy.multipass) && + (httpreq != HTTPREQ_GET) && + (httpreq != HTTPREQ_HEAD)) { + /* Auth is required and we are not authenticated yet. Make a PUT or POST +diff --git a/lib/urldata.h b/lib/urldata.h +index 3e6ace5..7e0c30d 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -1143,8 +1143,8 @@ struct auth { + this resource */ + bool done; /* TRUE when the auth phase is done and ready to do the *actual* + request */ +- bool multi; /* TRUE if this is not yet authenticated but within the auth +- multipass negotiation */ ++ bool multipass; /* TRUE if this is not yet authenticated but within the ++ auth multipass negotiation */ + bool iestyle; /* TRUE if digest should be done IE-style or FALSE if it should + be RFC compliant */ + }; +-- +2.13.6 + + +From 8fe4533bc8de3664f8b664fa5ab78739b5ea3d87 Mon Sep 17 00:00:00 2001 +From: Michael Kaufmann +Date: Sat, 11 Mar 2017 18:22:30 +0100 +Subject: [PATCH 2/3] curl_easy_reset: Also reset the authentication state + +Follow-up to 5278462 +See https://github.com/curl/curl/issues/1095 + +Upstream-commit: 0afbcfd800c45e766e225e4ce273b128ee6a8c25 +Signed-off-by: Kamil Dudka +--- + lib/easy.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/lib/easy.c b/lib/easy.c +index 13801b2..0e9ba18 100644 +--- a/lib/easy.c ++++ b/lib/easy.c +@@ -670,6 +670,10 @@ void curl_easy_reset(CURL *curl) + + data->progress.flags |= PGRS_HIDE; + data->state.current_speed = -1; /* init to negative == impossible */ ++ ++ /* zero out authentication data: */ ++ memset(&data->state.authhost, 0, sizeof(struct auth)); ++ memset(&data->state.authproxy, 0, sizeof(struct auth)); + } + + /* +-- +2.13.6 + + +From db75a5b82f0b4b24a838fb91e9d3352d4c4c05f2 Mon Sep 17 00:00:00 2001 +From: Michael Kaufmann +Date: Sat, 11 Mar 2017 20:06:56 +0100 +Subject: [PATCH 3/3] tests: fix the authretry tests + +Do not call curl_easy_reset() between the requests, because the +auth state must be preserved for these tests. + +Follow-up to 0afbcfd + +Upstream-commit: 8d105209933e27293cfc4f224614cea57ddd8372 +Signed-off-by: Kamil Dudka +--- + tests/libtest/libauthretry.c | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/tests/libtest/libauthretry.c b/tests/libtest/libauthretry.c +index 9576132..6342252 100644 +--- a/tests/libtest/libauthretry.c ++++ b/tests/libtest/libauthretry.c +@@ -111,12 +111,10 @@ int test(char *url) + res = send_wrong_password(curl, url, 100, main_auth_scheme); + if (res != CURLE_OK) + goto test_cleanup; +- curl_easy_reset(curl); + + res = send_right_password(curl, url, 200, fallback_auth_scheme); + if (res != CURLE_OK) + goto test_cleanup; +- curl_easy_reset(curl); + + curl_easy_cleanup(curl); + +@@ -131,17 +129,14 @@ int test(char *url) + res = send_wrong_password(curl, url, 300, main_auth_scheme); + if (res != CURLE_OK) + goto test_cleanup; +- curl_easy_reset(curl); + + res = send_wrong_password(curl, url, 400, fallback_auth_scheme); + if (res != CURLE_OK) + goto test_cleanup; +- curl_easy_reset(curl); + + res = send_right_password(curl, url, 500, fallback_auth_scheme); + if (res != CURLE_OK) + goto test_cleanup; +- curl_easy_reset(curl); + + test_cleanup: + +-- +2.13.6 + diff --git a/SOURCES/0109-curl-7.29.0-crl-valgrind.patch b/SOURCES/0109-curl-7.29.0-crl-valgrind.patch deleted file mode 100644 index 7e02ce4..0000000 --- a/SOURCES/0109-curl-7.29.0-crl-valgrind.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 1442501b9eee46a959f3480600e2a63c831e9d9e Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Wed, 1 Mar 2017 15:11:34 +0100 -Subject: [PATCH] test313: suppress a bug newly detected by valgrind (#1427883) - ---- - tests/data/test313 | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/tests/data/test313 b/tests/data/test313 -index c54495a..aada83c 100644 ---- a/tests/data/test313 -+++ b/tests/data/test313 -@@ -35,5 +35,8 @@ perl -e "print 'Test requires default test server host' if ( '%HOSTIP' ne '127.0 - - 60 - -+ -+disable -+ - - --- -2.9.3 - diff --git a/SPECS/curl.spec b/SPECS/curl.spec index 1cd4453..8aa74bc 100644 --- a/SPECS/curl.spec +++ b/SPECS/curl.spec @@ -1,7 +1,7 @@ Summary: A utility for getting files from remote servers (FTP, HTTP, and others) Name: curl Version: 7.29.0 -Release: 42%{?dist}.1 +Release: 46%{?dist} License: MIT Group: Applications/Internet Source: http://curl.haxx.se/download/%{name}-%{version}.tar.lzma @@ -157,9 +157,24 @@ Patch49: 0049-curl-7.29.0-8fa54098.patch # work around race condition in PK11_FindSlotByName() in NSS (#1404815) Patch50: 0050-curl-7.29.0-3a5d5de9.patch +# nss: fix a possible use-after-free in SelectClientCert() (#1473158) +Patch51: 0051-curl-7.29.0-42a4cd4c.patch + +# nss: do not leak PKCS #11 slot while loading a key (#1444860) +Patch52: 0052-curl-7.29.0-c8ea86f3.patch + +# nss: fix a memory leak when CURLOPT_CRLFILE is used (#1427883) +Patch53: 0053-curl-7.29.0-52cd5ac2.patch + +# curl --socks5-{basic,gssapi}: control socks5 auth (#1409208) +Patch54: 0054-curl-7.29.0-ce2c3ebd.patch + # fix buffer overflow while processing IMAP FETCH response (CVE-2017-1000257) Patch55: 0055-curl-7.29.0-CVE-2017-1000257.patch +# reset authentication state when HTTP transfer is done (#1511523) +Patch56: 0056-curl-7.29.0-0afbcfd8.patch + # patch making libcurl multilib ready Patch101: 0101-curl-7.29.0-multilib.patch @@ -185,9 +200,6 @@ Patch107: 0107-curl-7.21.4-libidn-valgrind.patch # a simple iconv can't fix them Patch108: 0108-curl-7.29.0-utf8.patch -# test313: suppress a bug newly detected by valgrind (#1427883) -Patch109: 0109-curl-7.29.0-crl-valgrind.patch - Provides: webclient URL: http://curl.haxx.se/ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(id -nu) @@ -328,7 +340,6 @@ documentation of the library, too. %patch106 -p1 %patch107 -p1 %patch108 -p1 -%patch109 -p1 # upstream patches %patch41 -p1 @@ -341,9 +352,12 @@ documentation of the library, too. %patch48 -p1 %patch49 -p1 %patch50 -p1 - -# 7.4.z +%patch51 -p1 +%patch52 -p1 +%patch53 -p1 +%patch54 -p1 %patch55 -p1 +%patch56 -p1 # regenerate Makefile.in files aclocal -I m4 @@ -459,9 +473,21 @@ rm -rf $RPM_BUILD_ROOT %{_datadir}/aclocal/libcurl.m4 %changelog -* Mon Oct 23 2017 Kamil Dudka - 7.29.0-42.el7_4.1 +* Mon Dec 11 2017 Kamil Dudka - 7.29.0-46 +- reset authentication state when HTTP transfer is done (#1511523) + +* Mon Oct 23 2017 Kamil Dudka - 7.29.0-45 - fix buffer overflow while processing IMAP FETCH response (CVE-2017-1000257) +* Thu Sep 14 2017 Kamil Dudka 7.29.0-44 +- drop 0109-curl-7.29.0-crl-valgrind.patch no longer needed (#1427883) + +* Wed Sep 13 2017 Kamil Dudka 7.29.0-43 +- curl --socks5-{basic,gssapi}: control socks5 auth (#1409208) +- nss: fix a memory leak when CURLOPT_CRLFILE is used (#1427883) +- nss: do not leak PKCS #11 slot while loading a key (#1444860) +- nss: fix a possible use-after-free in SelectClientCert() (#1473158) + * Wed Mar 29 2017 Kamil Dudka 7.29.0-42 - fix use of uninitialized variable detected by Covscan