From 2d7a803d4dbd947c4d015e3cca8ec354876effd1 Mon Sep 17 00:00:00 2001 From: Hugh Waite Date: Tue, 19 Jan 2016 18:45:49 +0000 Subject: [PATCH 1/5] curl: Add client key/certificate to curl_connect - Use the client key, certificate and cacert modparams when provided - Use the verifyserver modparam (default enabled) - Implement per-connection verifyserver parameter - Add ciphersuites modparam to override libcurl defaults --- modules/curl/curl.c | 2 + modules/curl/curl.h | 6 +- modules/curl/curlcon.c | 24 ++++++- modules/curl/doc/curl_admin.xml | 26 ++++++++ modules/curl/functions.c | 113 +++++++++++++++++++++++++------- 5 files changed, 145 insertions(+), 26 deletions(-) diff --git a/modules/curl/curl.c b/modules/curl/curl.c index 510de293a56..005d8cac59e 100644 --- a/modules/curl/curl.c +++ b/modules/curl/curl.c @@ -76,6 +76,7 @@ unsigned int default_connection_timeout = 4; char *default_tls_cacert = NULL; /*!< File name: Default CA cert to use for curl TLS connection */ char *default_tls_clientcert = NULL; /*!< File name: Default client certificate to use for curl TLS connection */ char *default_tls_clientkey = NULL; /*!< File name: Key in PEM format that belongs to client cert */ +char *default_cipher_suite_list = NULL; /*!< List of allowed cipher suites */ unsigned int default_tls_verifyserver = 1; /*!< 0 = Do not verify TLS server cert. 1 = Verify TLS cert (default) */ char *default_http_proxy = NULL; /*!< Default HTTP proxy to use */ unsigned int default_http_proxy_port = 0; /*!< Default HTTP proxy port to use */ @@ -139,6 +140,7 @@ static param_export_t params[] = { {"tlscacert", PARAM_STRING, &default_tls_cacert }, {"tlsclientcert", PARAM_STRING, &default_tls_clientcert }, {"tlsclientkey", PARAM_STRING, &default_tls_clientkey }, + {"tlscipherlist", PARAM_STRING, &default_cipher_suite_list }, {"tlsverifyserver", PARAM_INT, &default_tls_verifyserver }, {"httpproxyport", PARAM_INT, &default_http_proxy_port }, {"httpproxy", PARAM_STRING, &default_http_proxy}, diff --git a/modules/curl/curl.h b/modules/curl/curl.h index dcab50a9699..38de6d1f8b6 100644 --- a/modules/curl/curl.h +++ b/modules/curl/curl.h @@ -39,6 +39,7 @@ extern unsigned int default_connection_timeout; extern char *default_tls_cacert; /*!< File name: Default CA cert to use for curl TLS connection */ extern char *default_tls_clientcert; /*!< File name: Default client certificate to use for curl TLS connection */ extern char *default_tls_clientkey; /*!< File name: Key in PEM format that belongs to client cert */ +extern char *default_cipher_suite_list; /*!< List of allowed cipher suites */ extern unsigned int default_tls_verifyserver; /*!< 0 = Do not verify TLS server cert. 1 = Verify TLS cert (default) */ extern char *default_http_proxy; /*!< Default HTTP proxy to use */ extern unsigned int default_http_proxy_port; /*!< Default HTTP proxy port to use */ @@ -69,10 +70,11 @@ typedef struct _curl_con str username; /*!< The username to use for auth */ str password; /*!< The password to use for auth */ str failover; /*!< Another connection to use if this one fails */ + str useragent; /*!< Useragent to use for this connection */ str cacert; /*!< File name of CA cert to use */ str clientcert; /*!< File name of CA client cert */ - str useragent; /*!< Useragent to use for this connection */ - int tls_verifyserver; /*!< TRUE if server cert needs to be verified */ + str clientkey; /*!< File name of CA client key */ + int verify_server; /*!< TRUE if server cert to be verified */ int http_follow_redirect; /*!< TRUE if we should follow HTTP 302 redirects */ unsigned int port; /*!< The port to connect to */ int timeout; /*!< Timeout for this connection */ diff --git a/modules/curl/curlcon.c b/modules/curl/curlcon.c index cbc6a376423..0a26fb26649 100644 --- a/modules/curl/curlcon.c +++ b/modules/curl/curlcon.c @@ -96,6 +96,7 @@ curl_con_t* curl_get_connection(str *name) * useragent * failover * maxdatasize + * verifyserver * */ int curl_parse_param(char *val) @@ -108,10 +109,14 @@ int curl_parse_param(char *val) str params = STR_NULL; str failover = STR_NULL; + str client_cert = { default_tls_clientcert, default_tls_clientcert ? strlen(default_tls_clientcert) : 0 }; + str client_key = { default_tls_clientkey, default_tls_clientkey ? strlen(default_tls_clientkey) : 0 }; + unsigned int maxdatasize = default_maxdatasize; unsigned int timeout = default_connection_timeout; str useragent = { default_useragent, strlen(default_useragent) }; unsigned int http_follow_redirect = default_http_follow_redirect; + unsigned int verifyserver = default_tls_verifyserver; str in; char *p; @@ -300,6 +305,17 @@ int curl_parse_param(char *val) maxdatasize = default_maxdatasize; } LM_DBG("curl [%.*s] - timeout [%d]\n", pit->name.len, pit->name.s, maxdatasize); + } else if(pit->name.len==12 && strncmp(pit->name.s, "verifyserver", 7)==0) { + if(str2int(&tok, &verifyserver)!=0) { + /* Bad integer */ + LM_DBG("curl connection [%.*s]: verifyserver bad value. Using default\n", name.len, name.s); + verifyserver = default_tls_verifyserver; + } + if (verifyserver != 0 && verifyserver != 1) { + LM_DBG("curl connection [%.*s]: verifyserver bad value. Using default\n", name.len, name.s); + verifyserver = default_tls_verifyserver; + } + LM_DBG("curl [%.*s] - verifyserver [%d]\n", pit->name.len, pit->name.s, verifyserver); } else { LM_ERR("curl Unknown parameter [%.*s] \n", pit->name.len, pit->name.s); } @@ -310,7 +326,10 @@ int curl_parse_param(char *val) LM_DBG("cname: [%.*s] url: [%.*s] username [%.*s] password [%.*s] failover [%.*s] timeout [%d] useragent [%.*s] maxdatasize [%d]\n", name.len, name.s, url.len, url.s, username.len, username.s, - password.len, password.s, failover.len, failover.s, timeout, useragent.len, useragent.s, maxdatasize); + password.len, password.s, failover.len, failover.s, timeout, + useragent.len, useragent.s, maxdatasize); + LM_DBG("cname: [%.*s] client_cert [%.*s] client_key [%.*s] verifyserver [%d]\n", + name.len, name.s, client_cert.len, client_cert.s, client_key.len, client_key.s, verifyserver); if(conparams != NULL) { free_params(conparams); @@ -326,6 +345,9 @@ int curl_parse_param(char *val) cc->failover = failover; cc->useragent = useragent; cc->url = url; + cc->clientcert = client_cert; + cc->clientkey = client_key; + cc->verify_server = verifyserver; cc->timeout = timeout; cc->maxdatasize = maxdatasize; cc->http_follow_redirect = http_follow_redirect; diff --git a/modules/curl/doc/curl_admin.xml b/modules/curl/doc/curl_admin.xml index 54e3e595ceb..152db481c58 100644 --- a/modules/curl/doc/curl_admin.xml +++ b/modules/curl/doc/curl_admin.xml @@ -219,6 +219,28 @@ modparam("curl", "tlsclientkey", "/var/certs/sollentuna.example.com.key") ... modparam("curl", "tlscacert", "/var/certs/ca/edvina-sip-ca.pem") +... + + + +
+ <varname>tlscipherlist</varname> (string) + + List of allowed cipher suites. + See http://curl.haxx.se/libcurl/c/CURLOPT_SSL_CIPHER_LIST.html for details + of the cipher list curl option. + + + + Default value is empty string, i.e. + the default list of ciphers in libcurl will be used. + + + + Set <varname>tlscipherlist</varname> parameter + +... +modparam("curl", "tlscipherlist", "ecdhe_ecdsa_aes_128_gcm_sha_256,rsa_aes_128_gcm_sha_256") ... @@ -286,6 +308,10 @@ modparam("curl", "tlsverifyserver", 1) useragent Useragent used for HTTP requests. Overrides useragent modparam. + + verifyserver Enables or disables server certificate verification. + Overrides tlsverifyserver modparam. + diff --git a/modules/curl/functions.c b/modules/curl/functions.c index 8d77b92beb5..d4701f89171 100644 --- a/modules/curl/functions.c +++ b/modules/curl/functions.c @@ -45,10 +45,25 @@ #include "curl.h" #include "curlcon.h" + +typedef struct { + char *username; + char *secret; + char *contenttype; + char *post; + char *clientcert; + char *clientkey; + char *cacert; + char *ciphersuites; + unsigned int verify_server; + unsigned int timeout; + unsigned int http_follow_redirect; + unsigned int oneline; + unsigned int maxdatasize; +} curl_query_t; + /* Forward declaration */ -static int curL_query_url(struct sip_msg* _m, const char* _url, str* _dst, const char *username, - const char *secret, const char *contenttype, const char* _post, const unsigned int timeout, - unsigned int http_follow_redirect, unsigned int oneline, unsigned int maxdatasize); +static int curL_query_url(struct sip_msg* _m, const char* _url, str* _dst, const curl_query_t * const query_params); /* * curl write function that saves received data as zero terminated @@ -86,7 +101,7 @@ size_t write_function( void *ptr, size_t size, size_t nmemb, void *stream_ptr) /*! Send query to server, optionally post data. */ -static int curL_query_url(struct sip_msg* _m, const char* _url, str* _dst, const char *_username, const char *_secret, const char *contenttype, const char* _post, unsigned int timeout, unsigned int http_follow_redirect, unsigned int oneline, unsigned int maxdatasize) +static int curL_query_url(struct sip_msg* _m, const char* _url, str* _dst, const curl_query_t * const params) { CURL *curl; CURLcode res; @@ -99,7 +114,7 @@ static int curL_query_url(struct sip_msg* _m, const char* _url, str* _dst, const struct curl_slist *headerlist = NULL; memset(&stream, 0, sizeof(curl_res_stream_t)); - stream.max_size = (size_t) maxdatasize; + stream.max_size = (size_t) params->maxdatasize; curl = curl_easy_init(); if (curl == NULL) { @@ -110,11 +125,11 @@ static int curL_query_url(struct sip_msg* _m, const char* _url, str* _dst, const LM_DBG("****** ##### CURL URL [%s] \n", _url); res = curl_easy_setopt(curl, CURLOPT_URL, _url); - if (_post) { + if (params->post) { char ctype[256]; ctype[0] = '\0'; - snprintf(ctype, sizeof(ctype), "Content-Type: %s", contenttype); + snprintf(ctype, sizeof(ctype), "Content-Type: %s", params->contenttype); /* Now specify we want to POST data */ res |= curl_easy_setopt(curl, CURLOPT_POST, 1L); @@ -124,28 +139,49 @@ static int curL_query_url(struct sip_msg* _m, const char* _url, str* _dst, const /* Tell CURL we want to upload using POST */ - res |= curl_easy_setopt(curl, CURLOPT_POSTFIELDS, _post); + res |= curl_easy_setopt(curl, CURLOPT_POSTFIELDS, params->post); } - if (maxdatasize) { + if (params->maxdatasize) { /* Maximum data size to download - we always download full response, but cut it off before moving to pvar */ - LM_DBG("****** ##### CURL Max datasize %u\n", maxdatasize); + LM_DBG("****** ##### CURL Max datasize %u\n", params->maxdatasize); } - if (_username) { - res |= curl_easy_setopt(curl, CURLOPT_USERNAME, _username); + if (params->username) { + res |= curl_easy_setopt(curl, CURLOPT_USERNAME, params->username); res |= curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (CURLAUTH_DIGEST|CURLAUTH_BASIC)); } - if (_secret) { - res |= curl_easy_setopt(curl, CURLOPT_PASSWORD, _secret); + if (params->secret) { + res |= curl_easy_setopt(curl, CURLOPT_PASSWORD, params->secret); + } + + /* Client certificate */ + if (params->clientcert != NULL && params->clientkey != NULL) { + LM_ERR("Setting curl cert %s key %s \n", params->clientcert, params->clientkey); + res |= curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM"); + res |= curl_easy_setopt(curl, CURLOPT_SSLCERT, params->clientcert); + + res |= curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM"); + res |= curl_easy_setopt(curl, CURLOPT_SSLKEY, params->clientkey); + } + + if (params->cacert != NULL) { + LM_ERR("Setting ca cert %s\n", params->cacert); + res |= curl_easy_setopt(curl, CURLOPT_CAINFO, params->cacert); } + if (params->ciphersuites != NULL) { + LM_ERR("Setting ciphersuites %s\n", params->ciphersuites); + res |= curl_easy_setopt(curl, CURLOPT_SSL_CIPHER_LIST, params->ciphersuites); + } + + res |= curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, (long) params->verify_server); res |= curl_easy_setopt(curl, CURLOPT_NOSIGNAL, (long) 1); - res |= curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long) timeout); - res |= curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, (long) http_follow_redirect); + res |= curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long) params->timeout); + res |= curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, (long) params->http_follow_redirect); res |= curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_function); @@ -201,16 +237,16 @@ static int curL_query_url(struct sip_msg* _m, const char* _url, str* _dst, const if (download_size > 0) { - if (oneline) { + if (params->oneline) { /* search for line feed */ at = memchr(stream.buf, (char)10, download_size); datasize = (double) (at - stream.buf); LM_DBG(" -- curl download size cut to first line: %d \n", (int) datasize); } if (at == NULL) { - if (maxdatasize && ((unsigned int) download_size) > maxdatasize) { + if (params->maxdatasize && ((unsigned int) download_size) > params->maxdatasize) { /* Limit at maximum data size */ - datasize = (double) maxdatasize; + datasize = (double) params->maxdatasize; LM_DBG(" -- curl download size cut to maxdatasize : %d \n", (int) datasize); } else { /* Limit at actual downloaded data size */ @@ -253,6 +289,7 @@ int curl_con_query_url(struct sip_msg* _m, const str *connection, const str* url char *username_str = NULL; char *password_str = NULL; char *postdata = NULL; + curl_query_t query_params; unsigned int maxdatasize = default_maxdatasize; int res; @@ -319,8 +356,22 @@ int curl_con_query_url(struct sip_msg* _m, const str *connection, const str* url LM_DBG("***** #### ***** CURL POST data: %s Content-type %s\n", postdata, contenttype); } - res = curL_query_url(_m, urlbuf, result, username_str, password_str, (contenttype ? contenttype : "text/plain"), postdata, - conn->timeout, conn->http_follow_redirect, 0, (unsigned int) maxdatasize ); + memset(&query_params, 0, sizeof(curl_query_t)); + query_params.username = username_str; + query_params.secret = password_str; + query_params.contenttype = contenttype ? (char*)contenttype : "text/plain"; + query_params.post = postdata; + query_params.clientcert = conn->clientcert.s; + query_params.clientkey = conn->clientkey.s; + query_params.cacert = default_tls_cacert; + query_params.ciphersuites = default_cipher_suite_list; + query_params.verify_server = conn->verify_server; + query_params.timeout = conn->timeout; + query_params.http_follow_redirect = conn->http_follow_redirect; + query_params.oneline = 0; + query_params.maxdatasize = maxdatasize; + + res = curL_query_url(_m, urlbuf, result, &query_params); LM_DBG("***** #### ***** CURL DONE : %s \n", urlbuf); error: @@ -348,8 +399,24 @@ int curl_con_query_url(struct sip_msg* _m, const str *connection, const str* url int http_query(struct sip_msg* _m, char* _url, str* _dst, char* _post) { int res; - - res = curL_query_url(_m, _url, _dst, NULL, NULL, "text/plain", _post, default_connection_timeout, default_http_follow_redirect, 1, 0); + curl_query_t query_params; + + memset(&query_params, 0, sizeof(curl_query_t)); + query_params.username = NULL; + query_params.secret = NULL; + query_params.contenttype = "text/plain"; + query_params.post = _post; + query_params.clientcert = NULL; + query_params.clientkey = NULL; + query_params.cacert = NULL; + query_params.ciphersuites = NULL; + query_params.verify_server = default_tls_verifyserver; + query_params.timeout = default_connection_timeout; + query_params.http_follow_redirect = default_http_follow_redirect; + query_params.oneline = 1; + query_params.maxdatasize = 0; + + res = curL_query_url(_m, _url, _dst, &query_params); return res; } From 64764ff9ce7d117a95d7a0d1d1edf232965d8def Mon Sep 17 00:00:00 2001 From: Hugh Waite Date: Wed, 20 Jan 2016 17:36:04 +0000 Subject: [PATCH 2/5] curl: Add curl verifyhost option - Renamed verifyserver to verifypeer to match libcurl - Added default verifyhost modparam - Added per-connection verifyhost override --- modules/curl/curl.c | 13 +++------ modules/curl/curl.h | 6 +++-- modules/curl/curlcon.c | 41 +++++++++++++++++++--------- modules/curl/doc/curl_admin.xml | 47 ++++++++++++++++++++++++++++----- modules/curl/functions.c | 12 ++++++--- 5 files changed, 84 insertions(+), 35 deletions(-) diff --git a/modules/curl/curl.c b/modules/curl/curl.c index 005d8cac59e..2b152d6a5f5 100644 --- a/modules/curl/curl.c +++ b/modules/curl/curl.c @@ -77,7 +77,8 @@ char *default_tls_cacert = NULL; /*!< File name: Default CA cert to use for cu char *default_tls_clientcert = NULL; /*!< File name: Default client certificate to use for curl TLS connection */ char *default_tls_clientkey = NULL; /*!< File name: Key in PEM format that belongs to client cert */ char *default_cipher_suite_list = NULL; /*!< List of allowed cipher suites */ -unsigned int default_tls_verifyserver = 1; /*!< 0 = Do not verify TLS server cert. 1 = Verify TLS cert (default) */ +unsigned int default_tls_verify_peer = 1; /*!< 0 = Do not verify TLS server cert. 1 = Verify TLS cert (default) */ +unsigned int default_tls_verify_host = 2; /*!< 0 = Do not verify TLS server CN/SAN 2 = Verify TLS server CN/SAN (default) */ char *default_http_proxy = NULL; /*!< Default HTTP proxy to use */ unsigned int default_http_proxy_port = 0; /*!< Default HTTP proxy port to use */ unsigned int default_http_follow_redirect = 0; /*!< Follow HTTP redirects CURLOPT_FOLLOWLOCATION */ @@ -141,7 +142,8 @@ static param_export_t params[] = { {"tlsclientcert", PARAM_STRING, &default_tls_clientcert }, {"tlsclientkey", PARAM_STRING, &default_tls_clientkey }, {"tlscipherlist", PARAM_STRING, &default_cipher_suite_list }, - {"tlsverifyserver", PARAM_INT, &default_tls_verifyserver }, + {"tlsverifypeer", PARAM_INT, &default_tls_verify_peer }, + {"tlsverifyhost", PARAM_INT, &default_tls_verify_host }, {"httpproxyport", PARAM_INT, &default_http_proxy_port }, {"httpproxy", PARAM_STRING, &default_http_proxy}, {"httpredirect", PARAM_INT, &default_http_follow_redirect }, @@ -150,13 +152,6 @@ static param_export_t params[] = { {0, 0, 0} }; -// str default_tls_clientcert; /*!< File name: Default client certificate to use for curl TLS connection */ -// str default_tls_clientkey; /*!< File name: Key in PEM format that belongs to client cert */ -// int default_tls_verifyserver = 1; /*!< 0 = Do not verify TLS server cert. 1 = Verify TLS cert (default) */ -// str default_http_proxy; /*!< Default HTTP proxy to use */ -// int default_http_proxy_port; /*!< Default HTTP proxy port to use */ -// int default_http_follow_redirect = 0; /*!< Follow HTTP redirects CURLOPT_FOLLOWLOCATION */ -// str default_useragent; /*!< Default CURL useragent. Default "Kamailio Curl " */ /*! * \brief Exported Pseudo variables diff --git a/modules/curl/curl.h b/modules/curl/curl.h index 38de6d1f8b6..ab563e2204c 100644 --- a/modules/curl/curl.h +++ b/modules/curl/curl.h @@ -40,7 +40,8 @@ extern char *default_tls_cacert; /*!< File name: Default CA cert to use for cu extern char *default_tls_clientcert; /*!< File name: Default client certificate to use for curl TLS connection */ extern char *default_tls_clientkey; /*!< File name: Key in PEM format that belongs to client cert */ extern char *default_cipher_suite_list; /*!< List of allowed cipher suites */ -extern unsigned int default_tls_verifyserver; /*!< 0 = Do not verify TLS server cert. 1 = Verify TLS cert (default) */ +extern unsigned int default_tls_verify_peer; /*!< 0 = Do not verify TLS server cert. 1 = Verify TLS cert (default) */ +extern unsigned int default_tls_verify_host; /*!< 0 = Do not verify TLS server CN/SAN. 2 = Verify TLS server CN/SAN (default) */ extern char *default_http_proxy; /*!< Default HTTP proxy to use */ extern unsigned int default_http_proxy_port; /*!< Default HTTP proxy port to use */ extern unsigned int default_http_follow_redirect; /*!< Follow HTTP redirects CURLOPT_FOLLOWLOCATION */ @@ -74,7 +75,8 @@ typedef struct _curl_con str cacert; /*!< File name of CA cert to use */ str clientcert; /*!< File name of CA client cert */ str clientkey; /*!< File name of CA client key */ - int verify_server; /*!< TRUE if server cert to be verified */ + int verify_peer; /*!< TRUE if server cert to be verified */ + int verify_host; /*!< TRUE if server CN/SAN to be verified */ int http_follow_redirect; /*!< TRUE if we should follow HTTP 302 redirects */ unsigned int port; /*!< The port to connect to */ int timeout; /*!< Timeout for this connection */ diff --git a/modules/curl/curlcon.c b/modules/curl/curlcon.c index 0a26fb26649..f0a4a53ce6d 100644 --- a/modules/curl/curlcon.c +++ b/modules/curl/curlcon.c @@ -96,7 +96,8 @@ curl_con_t* curl_get_connection(str *name) * useragent * failover * maxdatasize - * verifyserver + * verifypeer + * verifyhost * */ int curl_parse_param(char *val) @@ -116,7 +117,8 @@ int curl_parse_param(char *val) unsigned int timeout = default_connection_timeout; str useragent = { default_useragent, strlen(default_useragent) }; unsigned int http_follow_redirect = default_http_follow_redirect; - unsigned int verifyserver = default_tls_verifyserver; + unsigned int verify_peer = default_tls_verify_peer; + unsigned int verify_host = default_tls_verify_host; str in; char *p; @@ -305,17 +307,28 @@ int curl_parse_param(char *val) maxdatasize = default_maxdatasize; } LM_DBG("curl [%.*s] - timeout [%d]\n", pit->name.len, pit->name.s, maxdatasize); - } else if(pit->name.len==12 && strncmp(pit->name.s, "verifyserver", 7)==0) { - if(str2int(&tok, &verifyserver)!=0) { + } else if(pit->name.len==12 && strncmp(pit->name.s, "verifypeer", 7)==0) { + if(str2int(&tok, &verify_peer)!=0) { /* Bad integer */ - LM_DBG("curl connection [%.*s]: verifyserver bad value. Using default\n", name.len, name.s); - verifyserver = default_tls_verifyserver; + LM_DBG("curl connection [%.*s]: verifypeer bad value. Using default\n", name.len, name.s); + verify_peer = default_tls_verify_peer; } - if (verifyserver != 0 && verifyserver != 1) { - LM_DBG("curl connection [%.*s]: verifyserver bad value. Using default\n", name.len, name.s); - verifyserver = default_tls_verifyserver; + if (verify_peer != 0 && verify_peer != 1) { + LM_DBG("curl connection [%.*s]: verifypeer bad value. Using default\n", name.len, name.s); + verify_peer = default_tls_verify_peer; } - LM_DBG("curl [%.*s] - verifyserver [%d]\n", pit->name.len, pit->name.s, verifyserver); + LM_DBG("curl [%.*s] - verifypeer [%d]\n", pit->name.len, pit->name.s, verify_peer); + } else if(pit->name.len==12 && strncmp(pit->name.s, "verifyhost", 7)==0) { + if(str2int(&tok, &verify_host)!=0) { + /* Bad integer */ + LM_DBG("curl connection [%.*s]: verifyhost bad value. Using default\n", name.len, name.s); + verify_host = default_tls_verify_host; + } + if (verify_host != 0 && verify_host != 1) { + LM_DBG("curl connection [%.*s]: verifyhost bad value. Using default\n", name.len, name.s); + verify_host = default_tls_verify_host; + } + LM_DBG("curl [%.*s] - verifyhost [%d]\n", pit->name.len, pit->name.s, verify_host); } else { LM_ERR("curl Unknown parameter [%.*s] \n", pit->name.len, pit->name.s); } @@ -328,8 +341,9 @@ int curl_parse_param(char *val) name.len, name.s, url.len, url.s, username.len, username.s, password.len, password.s, failover.len, failover.s, timeout, useragent.len, useragent.s, maxdatasize); - LM_DBG("cname: [%.*s] client_cert [%.*s] client_key [%.*s] verifyserver [%d]\n", - name.len, name.s, client_cert.len, client_cert.s, client_key.len, client_key.s, verifyserver); + LM_DBG("cname: [%.*s] client_cert [%.*s] client_key [%.*s] verify_peer [%d] verify_host [%d]\n", + name.len, name.s, client_cert.len, client_cert.s, client_key.len, client_key.s, + verify_peer, verify_host); if(conparams != NULL) { free_params(conparams); @@ -347,7 +361,8 @@ int curl_parse_param(char *val) cc->url = url; cc->clientcert = client_cert; cc->clientkey = client_key; - cc->verify_server = verifyserver; + cc->verify_peer = verify_peer; + cc->verify_host = verify_host; cc->timeout = timeout; cc->maxdatasize = maxdatasize; cc->http_follow_redirect = http_follow_redirect; diff --git a/modules/curl/doc/curl_admin.xml b/modules/curl/doc/curl_admin.xml index 152db481c58..cced9875132 100644 --- a/modules/curl/doc/curl_admin.xml +++ b/modules/curl/doc/curl_admin.xml @@ -245,8 +245,8 @@ modparam("curl", "tlscipherlist", "ecdhe_ecdsa_aes_128_gcm_sha_256,rsa_aes_128_g
-
- <varname>tlsverifyserver</varname> (int) +
+ <varname>tlsverifypeer</varname> (int) If set to 0, TLS verification of the server certificate is disabled. This means that the connection will get @@ -255,17 +255,45 @@ modparam("curl", "tlscipherlist", "ecdhe_ecdsa_aes_128_gcm_sha_256,rsa_aes_128_g that is meant to receive data. - IF set to 1, default setting, and one or more CA certificates + If set to 1, default setting, and one or more CA certificates is configured, the server TLS certificate will be validated. If validation fails, the connection fails. + See the curl documenation for more details. + http://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYPEER.html - Set <varname>tlsverifyserver</varname> parameter + Set <varname>tlsverifypeer</varname> parameter ... -modparam("curl", "tlsverifyserver", 1) +modparam("curl", "tlsverifypeer", 1) +... + + +
+
+ <varname>tlsverifyhost</varname> (int) + + If set to 0, domain verification of the server certificate + is disabled. This means that the connection will get + encrypted but there is no check that data will be sent to the + host that is meant to receive it. Disable with caution. + + + If set to 2, default setting, the hostname in the URL will + be verified against the Common Name or Subject Alt Name + in the certificate. If validation fails, the connection fails. + + + See the curl documentation for more details. + http://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYHOST.html + + + Set <varname>tlsverifyhost</varname> parameter + +... +modparam("curl", "tlsverifyhost", 2) ... @@ -309,8 +337,13 @@ modparam("curl", "tlsverifyserver", 1) useragent modparam. - verifyserver Enables or disables server certificate verification. - Overrides tlsverifyserver modparam. + verifypeer Set to 1 to enable or 0 to disable server + certificate verification. + Overrides tlsverifypeer modparam. + + verifyhost Set to 2 to enable or 0 to disable server + hostname verification. + Overrides tlsverifyhost modparam. diff --git a/modules/curl/functions.c b/modules/curl/functions.c index d4701f89171..eb909635453 100644 --- a/modules/curl/functions.c +++ b/modules/curl/functions.c @@ -55,7 +55,8 @@ typedef struct { char *clientkey; char *cacert; char *ciphersuites; - unsigned int verify_server; + unsigned int verify_peer; + unsigned int verify_host; unsigned int timeout; unsigned int http_follow_redirect; unsigned int oneline; @@ -177,7 +178,8 @@ static int curL_query_url(struct sip_msg* _m, const char* _url, str* _dst, const res |= curl_easy_setopt(curl, CURLOPT_SSL_CIPHER_LIST, params->ciphersuites); } - res |= curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, (long) params->verify_server); + res |= curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, (long) params->verify_peer); + res |= curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, (long) params->verify_host); res |= curl_easy_setopt(curl, CURLOPT_NOSIGNAL, (long) 1); res |= curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long) params->timeout); @@ -365,7 +367,8 @@ int curl_con_query_url(struct sip_msg* _m, const str *connection, const str* url query_params.clientkey = conn->clientkey.s; query_params.cacert = default_tls_cacert; query_params.ciphersuites = default_cipher_suite_list; - query_params.verify_server = conn->verify_server; + query_params.verify_peer = conn->verify_peer; + query_params.verify_host = conn->verify_host; query_params.timeout = conn->timeout; query_params.http_follow_redirect = conn->http_follow_redirect; query_params.oneline = 0; @@ -410,7 +413,8 @@ int http_query(struct sip_msg* _m, char* _url, str* _dst, char* _post) query_params.clientkey = NULL; query_params.cacert = NULL; query_params.ciphersuites = NULL; - query_params.verify_server = default_tls_verifyserver; + query_params.verify_peer = default_tls_verify_peer; + query_params.verify_host = default_tls_verify_host; query_params.timeout = default_connection_timeout; query_params.http_follow_redirect = default_http_follow_redirect; query_params.oneline = 1; From eb067dd33603099eb1fc92438834c302e3a00195 Mon Sep 17 00:00:00 2001 From: Hugh Waite Date: Thu, 21 Jan 2016 14:51:04 +0000 Subject: [PATCH 3/5] curl: Implement additional TLS parameters - Add per-connection useragent param - Add sslversion modparam - Add per-connection sslversion param - Add per-connection client cert/key/ciphers - Ensure all strings are null-terminated for libcurl --- modules/curl/curl.c | 17 ++++++---- modules/curl/curl.h | 27 +++++++++------- modules/curl/curlcon.c | 67 ++++++++++++++++++++++++++++------------ modules/curl/functions.c | 36 +++++++-------------- 4 files changed, 85 insertions(+), 62 deletions(-) diff --git a/modules/curl/curl.c b/modules/curl/curl.c index 2b152d6a5f5..79da671d480 100644 --- a/modules/curl/curl.c +++ b/modules/curl/curl.c @@ -74,15 +74,16 @@ MODULE_VERSION /* Module parameter variables */ unsigned int default_connection_timeout = 4; char *default_tls_cacert = NULL; /*!< File name: Default CA cert to use for curl TLS connection */ -char *default_tls_clientcert = NULL; /*!< File name: Default client certificate to use for curl TLS connection */ -char *default_tls_clientkey = NULL; /*!< File name: Key in PEM format that belongs to client cert */ -char *default_cipher_suite_list = NULL; /*!< List of allowed cipher suites */ +str default_tls_clientcert = STR_NULL; /*!< File name: Default client certificate to use for curl TLS connection */ +str default_tls_clientkey = STR_NULL; /*!< File name: Key in PEM format that belongs to client cert */ +str default_cipher_suite_list = STR_NULL; /*!< List of allowed cipher suites */ +unsigned int default_tls_version = 0; /*!< 0 = Use libcurl default */ unsigned int default_tls_verify_peer = 1; /*!< 0 = Do not verify TLS server cert. 1 = Verify TLS cert (default) */ unsigned int default_tls_verify_host = 2; /*!< 0 = Do not verify TLS server CN/SAN 2 = Verify TLS server CN/SAN (default) */ char *default_http_proxy = NULL; /*!< Default HTTP proxy to use */ unsigned int default_http_proxy_port = 0; /*!< Default HTTP proxy port to use */ unsigned int default_http_follow_redirect = 0; /*!< Follow HTTP redirects CURLOPT_FOLLOWLOCATION */ -char *default_useragent = CURL_USER_AGENT; /*!< Default CURL useragent. Default "Kamailio Curl " */ +str default_useragent = { CURL_USER_AGENT, CURL_USER_AGENT_LEN }; /*!< Default CURL useragent. Default "Kamailio Curl " */ unsigned int default_maxdatasize = 0; /*!< Default download size. 0=disabled */ static curl_version_info_data *curl_info; @@ -142,6 +143,7 @@ static param_export_t params[] = { {"tlsclientcert", PARAM_STRING, &default_tls_clientcert }, {"tlsclientkey", PARAM_STRING, &default_tls_clientkey }, {"tlscipherlist", PARAM_STRING, &default_cipher_suite_list }, + {"tlsversion", PARAM_INT, &default_tls_version }, {"tlsverifypeer", PARAM_INT, &default_tls_verify_peer }, {"tlsverifyhost", PARAM_INT, &default_tls_verify_host }, {"httpproxyport", PARAM_INT, &default_http_proxy_port }, @@ -246,10 +248,13 @@ static int mod_init(void) LM_DBG("**** init curl module done. Curl version: %s SSL %s\n", curl_info->version, curl_info->ssl_version); LM_DBG("**** init curl: Number of connection objects: %d \n", curl_connection_count()); - LM_DBG("**** init curl: User Agent: %s \n", default_useragent); + LM_DBG("**** init curl: User Agent: %.*s \n", default_useragent.len, default_useragent.s); LM_DBG("**** init curl: HTTPredirect: %d \n", default_http_follow_redirect); - LM_DBG("**** init curl: Client Cert: %s Key %s\n", default_tls_clientcert, default_tls_clientkey); + LM_DBG("**** init curl: Client Cert: %.*s Key %.*s\n", default_tls_clientcert.len, default_tls_clientcert.s, default_tls_clientkey.len, default_tls_clientkey.s); LM_DBG("**** init curl: CA Cert: %s \n", default_tls_cacert); + LM_DBG("**** init curl: Cipher Suites: %.*s \n", default_cipher_suite_list.len, default_cipher_suite_list.s); + LM_DBG("**** init curl: SSL Version: %d \n", default_tls_version); + LM_DBG("**** init curl: verifypeer: %d verifyhost: %d\n", default_tls_verify_peer, default_tls_verify_host); LM_DBG("**** init curl: HTTP Proxy: %s Port %d\n", default_http_proxy, default_http_proxy_port); LM_DBG("Extra: Curl supports %s %s %s \n", diff --git a/modules/curl/curl.h b/modules/curl/curl.h index ab563e2204c..f167e63a3de 100644 --- a/modules/curl/curl.h +++ b/modules/curl/curl.h @@ -37,15 +37,16 @@ extern unsigned int default_connection_timeout; extern char *default_tls_cacert; /*!< File name: Default CA cert to use for curl TLS connection */ -extern char *default_tls_clientcert; /*!< File name: Default client certificate to use for curl TLS connection */ -extern char *default_tls_clientkey; /*!< File name: Key in PEM format that belongs to client cert */ -extern char *default_cipher_suite_list; /*!< List of allowed cipher suites */ +extern str default_tls_clientcert; /*!< File name: Default client certificate to use for curl TLS connection */ +extern str default_tls_clientkey; /*!< File name: Key in PEM format that belongs to client cert */ +extern str default_cipher_suite_list; /*!< List of allowed cipher suites */ +extern unsigned int default_tls_version; /*!< 0 = Use libcurl default */ extern unsigned int default_tls_verify_peer; /*!< 0 = Do not verify TLS server cert. 1 = Verify TLS cert (default) */ extern unsigned int default_tls_verify_host; /*!< 0 = Do not verify TLS server CN/SAN. 2 = Verify TLS server CN/SAN (default) */ extern char *default_http_proxy; /*!< Default HTTP proxy to use */ extern unsigned int default_http_proxy_port; /*!< Default HTTP proxy port to use */ extern unsigned int default_http_follow_redirect; /*!< Follow HTTP redirects CURLOPT_FOLLOWLOCATION */ -extern char *default_useragent; /*!< Default CURL useragent. Default "Kamailio Curl " */ +extern str default_useragent; /*!< Default CURL useragent. Default "Kamailio Curl " */ extern unsigned int default_maxdatasize; /*!< Default Maximum download size */ extern counter_handle_t connections; /* Number of connection definitions */ @@ -68,15 +69,17 @@ typedef struct _curl_con unsigned int conid; /*!< Connection ID */ str url; /*!< The URL without schema (host + base URL)*/ str schema; /*!< The URL schema */ - str username; /*!< The username to use for auth */ - str password; /*!< The password to use for auth */ + char *username; /*!< The username to use for auth */ + char *password; /*!< The password to use for auth */ str failover; /*!< Another connection to use if this one fails */ - str useragent; /*!< Useragent to use for this connection */ - str cacert; /*!< File name of CA cert to use */ - str clientcert; /*!< File name of CA client cert */ - str clientkey; /*!< File name of CA client key */ - int verify_peer; /*!< TRUE if server cert to be verified */ - int verify_host; /*!< TRUE if server CN/SAN to be verified */ + char *useragent; /*!< Useragent to use for this connection */ + char *cacert; /*!< File name of CA cert to use */ + char *clientcert; /*!< File name of CA client cert */ + char *clientkey; /*!< File name of CA client key */ + char *ciphersuites; /*!< List of allowed cipher suites */ + unsigned int sslversion; /*!< SSL/TLS version to use */ + unsigned int verify_peer; /*!< TRUE if server cert to be verified */ + unsigned int verify_host; /*!< TRUE if server CN/SAN to be verified */ int http_follow_redirect; /*!< TRUE if we should follow HTTP 302 redirects */ unsigned int port; /*!< The port to connect to */ int timeout; /*!< Timeout for this connection */ diff --git a/modules/curl/curlcon.c b/modules/curl/curlcon.c index f0a4a53ce6d..85a0142e241 100644 --- a/modules/curl/curlcon.c +++ b/modules/curl/curlcon.c @@ -26,6 +26,8 @@ * \ingroup curl */ +#include + #include "../../hashes.h" #include "../../dprint.h" #include "../../parser/parse_param.h" @@ -110,15 +112,17 @@ int curl_parse_param(char *val) str params = STR_NULL; str failover = STR_NULL; - str client_cert = { default_tls_clientcert, default_tls_clientcert ? strlen(default_tls_clientcert) : 0 }; - str client_key = { default_tls_clientkey, default_tls_clientkey ? strlen(default_tls_clientkey) : 0 }; + str client_cert = default_tls_clientcert; + str client_key = default_tls_clientkey; + str ciphersuites = default_cipher_suite_list; + str useragent = default_useragent; unsigned int maxdatasize = default_maxdatasize; unsigned int timeout = default_connection_timeout; - str useragent = { default_useragent, strlen(default_useragent) }; unsigned int http_follow_redirect = default_http_follow_redirect; unsigned int verify_peer = default_tls_verify_peer; unsigned int verify_host = default_tls_verify_host; + unsigned int sslversion = default_tls_version; str in; char *p; @@ -126,8 +130,6 @@ int curl_parse_param(char *val) param_t *conparams = NULL; curl_con_t *cc; - username.len = 0; - password.len = 0; LM_INFO("curl modparam parsing starting\n"); LM_DBG("modparam curlcon: %s\n", val); @@ -307,7 +309,7 @@ int curl_parse_param(char *val) maxdatasize = default_maxdatasize; } LM_DBG("curl [%.*s] - timeout [%d]\n", pit->name.len, pit->name.s, maxdatasize); - } else if(pit->name.len==12 && strncmp(pit->name.s, "verifypeer", 7)==0) { + } else if(pit->name.len==10 && strncmp(pit->name.s, "verifypeer", 10)==0) { if(str2int(&tok, &verify_peer)!=0) { /* Bad integer */ LM_DBG("curl connection [%.*s]: verifypeer bad value. Using default\n", name.len, name.s); @@ -318,7 +320,7 @@ int curl_parse_param(char *val) verify_peer = default_tls_verify_peer; } LM_DBG("curl [%.*s] - verifypeer [%d]\n", pit->name.len, pit->name.s, verify_peer); - } else if(pit->name.len==12 && strncmp(pit->name.s, "verifyhost", 7)==0) { + } else if(pit->name.len==10 && strncmp(pit->name.s, "verifyhost", 10)==0) { if(str2int(&tok, &verify_host)!=0) { /* Bad integer */ LM_DBG("curl connection [%.*s]: verifyhost bad value. Using default\n", name.len, name.s); @@ -329,6 +331,29 @@ int curl_parse_param(char *val) verify_host = default_tls_verify_host; } LM_DBG("curl [%.*s] - verifyhost [%d]\n", pit->name.len, pit->name.s, verify_host); + } else if(pit->name.len==10 && strncmp(pit->name.s, "sslversion", 10)==0) { + if(str2int(&tok, &sslversion)!=0) { + /* Bad integer */ + LM_DBG("curl connection [%.*s]: sslversion bad value. Using default\n", name.len, name.s); + sslversion = default_tls_version; + } + if (sslversion >= CURL_SSLVERSION_LAST) { + LM_DBG("curl connection [%.*s]: sslversion bad value. Using default\n", name.len, name.s); + sslversion = default_tls_version; + } + LM_DBG("curl [%.*s] - sslversion [%d]\n", pit->name.len, pit->name.s, sslversion); + } else if(pit->name.len==10 && strncmp(pit->name.s, "clientcert", 10)==0) { + client_cert = tok; + LM_DBG("curl [%.*s] - clientcert [%.*s]\n", pit->name.len, pit->name.s, + client_cert.len, client_cert.s); + } else if(pit->name.len==9 && strncmp(pit->name.s, "clientkey", 9)==0) { + client_key = tok; + LM_DBG("curl [%.*s] - clientkey [%.*s]\n", pit->name.len, pit->name.s, + client_key.len, client_key.s); + } else if(pit->name.len==12 && strncmp(pit->name.s, "ciphersuites", 12)==0) { + ciphersuites = tok; + LM_DBG("curl [%.*s] - ciphersuites [%.*s]\n", pit->name.len, pit->name.s, + ciphersuites.len, ciphersuites.s); } else { LM_ERR("curl Unknown parameter [%.*s] \n", pit->name.len, pit->name.s); } @@ -337,14 +362,6 @@ int curl_parse_param(char *val) /* The URL ends either with nothing or parameters. Parameters start with ; */ - LM_DBG("cname: [%.*s] url: [%.*s] username [%.*s] password [%.*s] failover [%.*s] timeout [%d] useragent [%.*s] maxdatasize [%d]\n", - name.len, name.s, url.len, url.s, username.len, username.s, - password.len, password.s, failover.len, failover.s, timeout, - useragent.len, useragent.s, maxdatasize); - LM_DBG("cname: [%.*s] client_cert [%.*s] client_key [%.*s] verify_peer [%d] verify_host [%d]\n", - name.len, name.s, client_cert.len, client_cert.s, client_key.len, client_key.s, - verify_peer, verify_host); - if(conparams != NULL) { free_params(conparams); } @@ -353,19 +370,29 @@ int curl_parse_param(char *val) if (cc == NULL) { return -1; } - cc->username = username; - cc->password = password; + + cc->username = username.s ? as_asciiz(&username) : NULL; + cc->password = password.s ? as_asciiz(&password) : NULL; cc->schema = schema; cc->failover = failover; - cc->useragent = useragent; + cc->useragent = as_asciiz(&useragent); cc->url = url; - cc->clientcert = client_cert; - cc->clientkey = client_key; + cc->clientcert = client_cert.s ? as_asciiz(&client_cert) : NULL; + cc->clientkey = client_key.s ? as_asciiz(&client_key) : NULL; + cc->ciphersuites = ciphersuites.s ? as_asciiz(&ciphersuites) : NULL; + cc->sslversion = sslversion; cc->verify_peer = verify_peer; cc->verify_host = verify_host; cc->timeout = timeout; cc->maxdatasize = maxdatasize; cc->http_follow_redirect = http_follow_redirect; + + LM_DBG("cname: [%.*s] url: [%.*s] username [%s] password [%s] failover [%.*s] timeout [%d] useragent [%s] maxdatasize [%d]\n", + name.len, name.s, cc->url.len, cc->url.s, cc->username ? cc->username : "", cc->password ? cc->password : "", + cc->failover.len, cc->failover.s, cc->timeout, cc->useragent, cc->maxdatasize); + LM_DBG("cname: [%.*s] client_cert [%s] client_key [%s] ciphersuites [%s] sslversion [%d] verify_peer [%d] verify_host [%d]\n", + name.len, name.s, cc->clientcert, cc->clientkey, cc->ciphersuites, cc->sslversion, cc->verify_peer, cc->verify_host); + return 0; error: diff --git a/modules/curl/functions.c b/modules/curl/functions.c index eb909635453..1b530d63a1e 100644 --- a/modules/curl/functions.c +++ b/modules/curl/functions.c @@ -55,6 +55,7 @@ typedef struct { char *clientkey; char *cacert; char *ciphersuites; + unsigned int sslversion; unsigned int verify_peer; unsigned int verify_host; unsigned int timeout; @@ -160,7 +161,6 @@ static int curL_query_url(struct sip_msg* _m, const char* _url, str* _dst, const /* Client certificate */ if (params->clientcert != NULL && params->clientkey != NULL) { - LM_ERR("Setting curl cert %s key %s \n", params->clientcert, params->clientkey); res |= curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM"); res |= curl_easy_setopt(curl, CURLOPT_SSLCERT, params->clientcert); @@ -169,12 +169,14 @@ static int curL_query_url(struct sip_msg* _m, const char* _url, str* _dst, const } if (params->cacert != NULL) { - LM_ERR("Setting ca cert %s\n", params->cacert); res |= curl_easy_setopt(curl, CURLOPT_CAINFO, params->cacert); } + if (params->sslversion != CURL_SSLVERSION_DEFAULT) { + res |= curl_easy_setopt(curl, CURLOPT_SSLVERSION, (long) params->sslversion); + } + if (params->ciphersuites != NULL) { - LM_ERR("Setting ciphersuites %s\n", params->ciphersuites); res |= curl_easy_setopt(curl, CURLOPT_SSL_CIPHER_LIST, params->ciphersuites); } @@ -288,8 +290,6 @@ int curl_con_query_url(struct sip_msg* _m, const str *connection, const str* url { curl_con_t *conn = NULL; char *urlbuf = NULL; - char *username_str = NULL; - char *password_str = NULL; char *postdata = NULL; curl_query_t query_params; @@ -308,14 +308,6 @@ int curl_con_query_url(struct sip_msg* _m, const str *connection, const str* url return -1; } LM_DBG("******** CURL Connection found %.*s\n", connection->len, connection->s); - if (conn->username.s != NULL && conn->username.len > 0) - { - username_str = as_asciiz(&conn->username); - } - if (conn->password.s != NULL && conn->password.len > 0) - { - password_str = as_asciiz(&conn->password); - } maxdatasize = conn->maxdatasize; @@ -359,14 +351,15 @@ int curl_con_query_url(struct sip_msg* _m, const str *connection, const str* url } memset(&query_params, 0, sizeof(curl_query_t)); - query_params.username = username_str; - query_params.secret = password_str; + query_params.username = conn->username; + query_params.secret = conn->password; query_params.contenttype = contenttype ? (char*)contenttype : "text/plain"; query_params.post = postdata; - query_params.clientcert = conn->clientcert.s; - query_params.clientkey = conn->clientkey.s; + query_params.clientcert = conn->clientcert; + query_params.clientkey = conn->clientkey; query_params.cacert = default_tls_cacert; - query_params.ciphersuites = default_cipher_suite_list; + query_params.ciphersuites = conn->ciphersuites; + query_params.sslversion = conn->sslversion; query_params.verify_peer = conn->verify_peer; query_params.verify_host = conn->verify_host; query_params.timeout = conn->timeout; @@ -381,12 +374,6 @@ int curl_con_query_url(struct sip_msg* _m, const str *connection, const str* url if (urlbuf != NULL) { pkg_free(urlbuf); } - if (username_str != NULL) { - pkg_free(username_str); - } - if (password_str != NULL) { - pkg_free(password_str); - } if (postdata != NULL) { pkg_free(postdata); } @@ -413,6 +400,7 @@ int http_query(struct sip_msg* _m, char* _url, str* _dst, char* _post) query_params.clientkey = NULL; query_params.cacert = NULL; query_params.ciphersuites = NULL; + query_params.sslversion = default_tls_version; query_params.verify_peer = default_tls_verify_peer; query_params.verify_host = default_tls_verify_host; query_params.timeout = default_connection_timeout; From d9b5cdab809ac32b63589f270561cda17abaadb2 Mon Sep 17 00:00:00 2001 From: Hugh Waite Date: Tue, 26 Jan 2016 12:45:33 +0000 Subject: [PATCH 4/5] curl: Use correct modparam type for string params --- modules/curl/curl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/curl/curl.c b/modules/curl/curl.c index 79da671d480..0895039f36b 100644 --- a/modules/curl/curl.c +++ b/modules/curl/curl.c @@ -140,16 +140,16 @@ static param_export_t params[] = { {"connection_timeout", PARAM_INT, &default_connection_timeout}, {"curlcon", PARAM_STRING|USE_FUNC_PARAM, (void*)curl_con_param}, {"tlscacert", PARAM_STRING, &default_tls_cacert }, - {"tlsclientcert", PARAM_STRING, &default_tls_clientcert }, - {"tlsclientkey", PARAM_STRING, &default_tls_clientkey }, - {"tlscipherlist", PARAM_STRING, &default_cipher_suite_list }, + {"tlsclientcert", PARAM_STR, &default_tls_clientcert }, + {"tlsclientkey", PARAM_STR, &default_tls_clientkey }, + {"tlscipherlist", PARAM_STR, &default_cipher_suite_list }, {"tlsversion", PARAM_INT, &default_tls_version }, {"tlsverifypeer", PARAM_INT, &default_tls_verify_peer }, {"tlsverifyhost", PARAM_INT, &default_tls_verify_host }, {"httpproxyport", PARAM_INT, &default_http_proxy_port }, {"httpproxy", PARAM_STRING, &default_http_proxy}, {"httpredirect", PARAM_INT, &default_http_follow_redirect }, - {"useragent", PARAM_STRING, &default_useragent }, + {"useragent", PARAM_STR, &default_useragent }, {"maxdatasize", PARAM_INT, &default_maxdatasize }, {0, 0, 0} }; From 2f0205093803cbd3761e6ae0384b548c19b4e3e4 Mon Sep 17 00:00:00 2001 From: Hugh Waite Date: Tue, 2 Feb 2016 10:15:22 +0000 Subject: [PATCH 5/5] curl: Ensure all values of verify_host are valid - verify_host=1 is deprecated, automatically use 2 --- modules/curl/curlcon.c | 4 ---- modules/curl/functions.c | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/modules/curl/curlcon.c b/modules/curl/curlcon.c index 85a0142e241..5c947f51aca 100644 --- a/modules/curl/curlcon.c +++ b/modules/curl/curlcon.c @@ -326,10 +326,6 @@ int curl_parse_param(char *val) LM_DBG("curl connection [%.*s]: verifyhost bad value. Using default\n", name.len, name.s); verify_host = default_tls_verify_host; } - if (verify_host != 0 && verify_host != 1) { - LM_DBG("curl connection [%.*s]: verifyhost bad value. Using default\n", name.len, name.s); - verify_host = default_tls_verify_host; - } LM_DBG("curl [%.*s] - verifyhost [%d]\n", pit->name.len, pit->name.s, verify_host); } else if(pit->name.len==10 && strncmp(pit->name.s, "sslversion", 10)==0) { if(str2int(&tok, &sslversion)!=0) { diff --git a/modules/curl/functions.c b/modules/curl/functions.c index 1b530d63a1e..754bbb36d49 100644 --- a/modules/curl/functions.c +++ b/modules/curl/functions.c @@ -181,7 +181,7 @@ static int curL_query_url(struct sip_msg* _m, const char* _url, str* _dst, const } res |= curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, (long) params->verify_peer); - res |= curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, (long) params->verify_host); + res |= curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, (long) params->verify_host?2:0); res |= curl_easy_setopt(curl, CURLOPT_NOSIGNAL, (long) 1); res |= curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long) params->timeout);