From cb4e2be7c6d42ca0780f8e0a747cecf9ba45f151 Mon Sep 17 00:00:00 2001 From: Alex Rousskov Date: Wed, 16 Nov 2016 10:49:15 -0700 Subject: proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks. --- src/tool_cfgable.c | 12 +++++ src/tool_cfgable.h | 18 +++++++ src/tool_getparam.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++++---- src/tool_help.c | 26 ++++++++++ src/tool_operate.c | 49 ++++++++++++++++++- src/tool_setopt.c | 11 +++++ src/tool_setopt.h | 3 ++ src/tool_writeout.c | 8 +++ 8 files changed, 253 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/tool_cfgable.c b/src/tool_cfgable.c index 567123b82..5d38fb338 100644 --- a/src/tool_cfgable.c +++ b/src/tool_cfgable.c @@ -68,6 +68,9 @@ static void free_config_fields(struct OperationConfig *config) Curl_safefree(config->tls_username); Curl_safefree(config->tls_password); Curl_safefree(config->tls_authtype); + Curl_safefree(config->proxy_tls_username); + Curl_safefree(config->proxy_tls_password); + Curl_safefree(config->proxy_tls_authtype); Curl_safefree(config->proxyuserpwd); Curl_safefree(config->proxy); @@ -99,15 +102,24 @@ static void free_config_fields(struct OperationConfig *config) config->url_out = NULL; Curl_safefree(config->cipher_list); + Curl_safefree(config->proxy_cipher_list); Curl_safefree(config->cert); + Curl_safefree(config->proxy_cert); Curl_safefree(config->cert_type); + Curl_safefree(config->proxy_cert_type); Curl_safefree(config->cacert); + Curl_safefree(config->proxy_cacert); Curl_safefree(config->capath); + Curl_safefree(config->proxy_capath); Curl_safefree(config->crlfile); Curl_safefree(config->pinnedpubkey); + Curl_safefree(config->proxy_crlfile); Curl_safefree(config->key); + Curl_safefree(config->proxy_key); Curl_safefree(config->key_type); + Curl_safefree(config->proxy_key_type); Curl_safefree(config->key_passwd); + Curl_safefree(config->proxy_key_passwd); Curl_safefree(config->pubkey); Curl_safefree(config->hostpubmd5); Curl_safefree(config->engine); diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h index e72fab11b..6589d8824 100644 --- a/src/tool_cfgable.h +++ b/src/tool_cfgable.h @@ -78,6 +78,9 @@ struct OperationConfig { char *tls_username; char *tls_password; char *tls_authtype; + char *proxy_tls_username; + char *proxy_tls_password; + char *proxy_tls_authtype; char *proxyuserpwd; char *proxy; int proxyver; /* set to CURLPROXY_HTTP* define */ @@ -106,15 +109,24 @@ struct OperationConfig { struct getout *url_get; /* point to the node to fill in URL */ struct getout *url_out; /* point to the node to fill in outfile */ char *cipher_list; + char *proxy_cipher_list; char *cert; + char *proxy_cert; char *cert_type; + char *proxy_cert_type; char *cacert; + char *proxy_cacert; char *capath; + char *proxy_capath; char *crlfile; + char *proxy_crlfile; char *pinnedpubkey; char *key; + char *proxy_key; char *key_type; + char *proxy_key_type; char *key_passwd; + char *proxy_key_passwd; char *pubkey; char *hostpubmd5; char *engine; @@ -127,6 +139,8 @@ struct OperationConfig { bool globoff; bool use_httpget; bool insecure_ok; /* set TRUE to allow insecure SSL connects */ + bool proxy_insecure_ok; /* set TRUE to allow insecure SSL connects + for proxy */ bool verifystatus; bool create_dirs; bool ftp_create_dirs; @@ -142,6 +156,7 @@ struct OperationConfig { struct curl_slist *postquote; struct curl_slist *prequote; long ssl_version; + long proxy_ssl_version; long ip_version; curl_TimeCond timecond; time_t condtime; @@ -202,7 +217,10 @@ struct OperationConfig { bool xattr; /* store metadata in extended attributes */ long gssapi_delegation; bool ssl_allow_beast; /* allow this SSL vulnerability */ + bool proxy_ssl_allow_beast; /* allow this SSL vulnerability for proxy*/ + bool ssl_no_revoke; /* disable SSL certificate revocation checks */ + /*bool proxy_ssl_no_revoke; */ bool use_metalink; /* process given URLs as metalink XML file */ metalinkfile *metalinkfile_list; /* point to the first node */ diff --git a/src/tool_getparam.c b/src/tool_getparam.c index 1f89fbc00..3d254e1b5 100644 --- a/src/tool_getparam.c +++ b/src/tool_getparam.c @@ -230,6 +230,24 @@ static const struct LongShort aliases[]= { {"Er", "false-start", FALSE}, {"Es", "ssl-no-revoke", FALSE}, {"Et", "tcp-fastopen", FALSE}, + {"Eu", "proxy-tlsuser", TRUE}, + {"Ev", "proxy-tlspassword", TRUE}, + {"Ew", "proxy-tlsauthtype", TRUE}, + {"Ex", "proxy-cert", TRUE}, + {"Ey", "proxy-cert-type", TRUE}, + {"Ez", "proxy-key", TRUE}, + {"E0", "proxy-key-type", TRUE}, + {"E1", "proxy-pass", TRUE}, + {"E2", "proxy-ciphers", TRUE}, + {"E3", "proxy-crlfile", TRUE}, + {"E4", "proxy-ssl-allow-beast", FALSE}, + {"E5", "login-options", TRUE}, + {"E6", "proxy-cacert", TRUE}, + {"E7", "proxy-capath", TRUE}, + {"E8", "proxy-insecure", FALSE}, + {"E9", "proxy-tlsv1", FALSE}, + {"EA", "proxy-sslv2", FALSE}, + {"EB", "proxy-sslv3", FALSE}, {"f", "fail", FALSE}, {"fa", "fail-early", FALSE}, {"F", "form", TRUE}, @@ -384,6 +402,20 @@ done: *certname_place = '\0'; } +static void +GetFileAndPassword(char *nextarg, char **file, char **password) +{ + char *certname, *passphrase; + parse_cert_parameter(nextarg, &certname, &passphrase); + Curl_safefree(*file); + *file = certname; + if(passphrase) { + Curl_safefree(*password); + *password = passphrase; + } + cleanarg(nextarg); +} + ParameterError getparameter(char *flag, /* f or -long-flag */ char *nextarg, /* NULL if unset */ bool *usedarg, /* set to TRUE if the arg @@ -1334,6 +1366,9 @@ ParameterError getparameter(char *flag, /* f or -long-flag */ break; case 'E': switch(subletter) { + case '\0': /* certificate file */ + GetFileAndPassword(nextarg, &config->cert, &config->key_passwd); + break; case 'a': /* CA info PEM file */ /* CA info PEM file */ GetStr(&config->cacert, nextarg); @@ -1424,18 +1459,101 @@ ParameterError getparameter(char *flag, /* f or -long-flag */ config->tcp_fastopen = TRUE; break; - default: /* certificate file */ - { - char *certname, *passphrase; - parse_cert_parameter(nextarg, &certname, &passphrase); - Curl_safefree(config->cert); - config->cert = certname; - if(passphrase) { - Curl_safefree(config->key_passwd); - config->key_passwd = passphrase; + case 'u': /* TLS username for proxy */ + if(curlinfo->features & CURL_VERSION_TLSAUTH_SRP) + GetStr(&config->proxy_tls_username, nextarg); + else + return PARAM_LIBCURL_DOESNT_SUPPORT; + break; + + case 'v': /* TLS password for proxy */ + if(curlinfo->features & CURL_VERSION_TLSAUTH_SRP) + GetStr(&config->proxy_tls_password, nextarg); + else + return PARAM_LIBCURL_DOESNT_SUPPORT; + break; + + case 'w': /* TLS authentication type for proxy */ + if(curlinfo->features & CURL_VERSION_TLSAUTH_SRP) { + GetStr(&config->proxy_tls_authtype, nextarg); + if(!curl_strequal(config->proxy_tls_authtype, "SRP")) + return PARAM_LIBCURL_DOESNT_SUPPORT; /* only support TLS-SRP */ } + else + return PARAM_LIBCURL_DOESNT_SUPPORT; + break; + + case 'x': /* certificate file for proxy */ + GetFileAndPassword(nextarg, &config->proxy_cert, + &config->proxy_key_passwd); + break; + + case 'y': /* cert file type for proxy */ + GetStr(&config->proxy_cert_type, nextarg); + break; + + case 'z': /* private key file for proxy */ + GetStr(&config->proxy_key, nextarg); + break; + + case '0': /* private key file type for proxy */ + GetStr(&config->proxy_key_type, nextarg); + break; + + case '1': /* private key passphrase for proxy */ + GetStr(&config->proxy_key_passwd, nextarg); cleanarg(nextarg); - } + break; + + case '2': /* ciphers for proxy */ + GetStr(&config->proxy_cipher_list, nextarg); + break; + + case '3': /* CRL info PEM file for proxy */ + /* CRL file */ + GetStr(&config->proxy_crlfile, nextarg); + break; + + case '4': /* no empty SSL fragments for proxy */ + if(curlinfo->features & CURL_VERSION_SSL) + config->proxy_ssl_allow_beast = toggle; + break; + + case '5': /* --login-options */ + GetStr(&config->login_options, nextarg); + break; + + case '6': /* CA info PEM file for proxy */ + /* CA info PEM file */ + GetStr(&config->proxy_cacert, nextarg); + break; + + case '7': /* CA info PEM file for proxy */ + /* CA cert directory */ + GetStr(&config->proxy_capath, nextarg); + break; + + case '8': /* allow insecure SSL connects for proxy */ + config->proxy_insecure_ok = toggle; + break; + + case '9': + /* TLS version 1 for proxy */ + config->proxy_ssl_version = CURL_SSLVERSION_TLSv1; + break; + + case 'A': + /* SSL version 2 for proxy */ + config->proxy_ssl_version = CURL_SSLVERSION_SSLv2; + break; + + case 'B': + /* SSL version 3 for proxy */ + config->proxy_ssl_version = CURL_SSLVERSION_SSLv3; + break; + + default: /* unknown flag */ + return PARAM_OPTION_UNKNOWN; } break; case 'f': diff --git a/src/tool_help.c b/src/tool_help.c index 02794ebc1..b55410f68 100644 --- a/src/tool_help.c +++ b/src/tool_help.c @@ -176,10 +176,36 @@ static const char *const helptext[] = { " --proxy-anyauth Pick \"any\" proxy authentication method (H)", " --proxy-basic Use Basic authentication on the proxy (H)", " --proxy-digest Use Digest authentication on the proxy (H)", + " --proxy-cacert FILE " + "CA certificate to verify peer against for proxy (SSL)", + " --proxy-capath DIR " + "CA directory to verify peer against for proxy (SSL)", + " --proxy-cert CERT[:PASSWD] " + "Client certificate file and password for proxy (SSL)", + " --proxy-cert-type TYPE " + "Certificate file type (DER/PEM/ENG) for proxy (SSL)", + " --proxy-ciphers LIST SSL ciphers to use for proxy (SSL)", + " --proxy-crlfile FILE " + "Get a CRL list in PEM format from the given file for proxy", + " --proxy-insecure " + "Allow connections to SSL sites without certs for proxy (H)", + " --proxy-key KEY Private key file name for proxy (SSL)", + " --proxy-key-type TYPE " + "Private key file type for proxy (DER/PEM/ENG) (SSL)", " --proxy-negotiate " "Use HTTP Negotiate (SPNEGO) authentication on the proxy (H)", " --proxy-ntlm Use NTLM authentication on the proxy (H)", " --proxy-header LINE Pass custom header LINE to proxy (H)", + " --proxy-pass PASS Pass phrase for the private key for proxy (SSL)", + " --proxy-ssl-allow-beast " + "Allow security flaw to improve interop for proxy (SSL)", + " --proxy-sslv2 Use SSLv2 for proxy (SSL)", + " --proxy-sslv3 Use SSLv3 for proxy (SSL)", + " --proxy-tlsv1 Use TLSv1 for proxy (SSL)", + " --proxy-tlsuser USER TLS username for proxy", + " --proxy-tlspassword STRING TLS password for proxy", + " --proxy-tlsauthtype STRING " + "TLS authentication type for proxy (default SRP)", " --proxy-service-name NAME SPNEGO proxy service name", " --service-name NAME SPNEGO service name", " -U, --proxy-user USER[:PASSWORD] Proxy user and password", diff --git a/src/tool_operate.c b/src/tool_operate.c index c44f2141c..b115ad94e 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -869,8 +869,9 @@ static CURLcode operate_do(struct GlobalConfig *global, /* new in libcurl 7.10 */ if(config->socksproxy) { - my_setopt_str(curl, CURLOPT_PROXY, config->socksproxy); - my_setopt_enum(curl, CURLOPT_PROXYTYPE, (long)config->socksver); + my_setopt_str(curl, CURLOPT_SOCKS_PROXY, config->socksproxy); + my_setopt_enum(curl, CURLOPT_SOCKS_PROXYTYPE, + (long)config->socksver); } /* new in libcurl 7.10.6 */ @@ -1000,6 +1001,7 @@ static CURLcode operate_do(struct GlobalConfig *global, my_setopt(curl, CURLOPT_RESUME_FROM_LARGE, CURL_OFF_T_C(0)); my_setopt_str(curl, CURLOPT_KEYPASSWD, config->key_passwd); + my_setopt_str(curl, CURLOPT_PROXY_KEYPASSWD, config->proxy_key_passwd); if(built_in_protos & (CURLPROTO_SCP|CURLPROTO_SFTP)) { @@ -1017,6 +1019,8 @@ static CURLcode operate_do(struct GlobalConfig *global, if(config->cacert) my_setopt_str(curl, CURLOPT_CAINFO, config->cacert); + if(config->proxy_cacert) + my_setopt_str(curl, CURLOPT_PROXY_CAINFO, config->proxy_cacert); if(config->capath) { result = res_setopt_str(curl, CURLOPT_CAPATH, config->capath); if(result == CURLE_NOT_BUILT_IN) { @@ -1027,17 +1031,32 @@ static CURLcode operate_do(struct GlobalConfig *global, else if(result) goto show_error; } + if(config->proxy_capath) + my_setopt_str(curl, CURLOPT_PROXY_CAPATH, config->proxy_capath); + else if(config->capath) /* CURLOPT_PROXY_CAPATH default is capath */ + my_setopt_str(curl, CURLOPT_PROXY_CAPATH, config->capath); + if(config->crlfile) my_setopt_str(curl, CURLOPT_CRLFILE, config->crlfile); + if(config->proxy_crlfile) + my_setopt_str(curl, CURLOPT_PROXY_CRLFILE, config->proxy_crlfile); + else if(config->crlfile) /* CURLOPT_PROXY_CRLFILE default is crlfile */ + my_setopt_str(curl, CURLOPT_PROXY_CRLFILE, config->crlfile); if(config->pinnedpubkey) my_setopt_str(curl, CURLOPT_PINNEDPUBLICKEY, config->pinnedpubkey); if(curlinfo->features & CURL_VERSION_SSL) { my_setopt_str(curl, CURLOPT_SSLCERT, config->cert); + my_setopt_str(curl, CURLOPT_PROXY_SSLCERT, config->proxy_cert); my_setopt_str(curl, CURLOPT_SSLCERTTYPE, config->cert_type); + my_setopt_str(curl, CURLOPT_PROXY_SSLCERTTYPE, + config->proxy_cert_type); my_setopt_str(curl, CURLOPT_SSLKEY, config->key); + my_setopt_str(curl, CURLOPT_PROXY_SSLKEY, config->proxy_key); my_setopt_str(curl, CURLOPT_SSLKEYTYPE, config->key_type); + my_setopt_str(curl, CURLOPT_PROXY_SSLKEYTYPE, + config->proxy_key_type); if(config->insecure_ok) { my_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); @@ -1048,6 +1067,13 @@ static CURLcode operate_do(struct GlobalConfig *global, /* libcurl default is strict verifyhost -> 2L */ /* my_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L); */ } + if(config->proxy_insecure_ok) { + my_setopt(curl, CURLOPT_PROXY_SSL_VERIFYPEER, 0L); + my_setopt(curl, CURLOPT_PROXY_SSL_VERIFYHOST, 0L); + } + else { + my_setopt(curl, CURLOPT_PROXY_SSL_VERIFYPEER, 1L); + } if(config->verifystatus) my_setopt(curl, CURLOPT_SSL_VERIFYSTATUS, 1L); @@ -1056,6 +1082,8 @@ static CURLcode operate_do(struct GlobalConfig *global, my_setopt(curl, CURLOPT_SSL_FALSESTART, 1L); my_setopt_enum(curl, CURLOPT_SSLVERSION, config->ssl_version); + my_setopt_enum(curl, CURLOPT_PROXY_SSLVERSION, + config->proxy_ssl_version); } if(config->path_as_is) my_setopt(curl, CURLOPT_PATH_AS_IS, 1L); @@ -1157,6 +1185,10 @@ static CURLcode operate_do(struct GlobalConfig *global, if(config->cipher_list) my_setopt_str(curl, CURLOPT_SSL_CIPHER_LIST, config->cipher_list); + if(config->proxy_cipher_list) + my_setopt_str(curl, CURLOPT_PROXY_SSL_CIPHER_LIST, + config->proxy_cipher_list); + /* new in libcurl 7.9.2: */ if(config->disable_epsv) /* disable it */ @@ -1325,6 +1357,15 @@ static CURLcode operate_do(struct GlobalConfig *global, if(config->tls_authtype) my_setopt_str(curl, CURLOPT_TLSAUTH_TYPE, config->tls_authtype); + if(config->proxy_tls_username) + my_setopt_str(curl, CURLOPT_PROXY_TLSAUTH_USERNAME, + config->proxy_tls_username); + if(config->proxy_tls_password) + my_setopt_str(curl, CURLOPT_PROXY_TLSAUTH_PASSWORD, + config->proxy_tls_password); + if(config->proxy_tls_authtype) + my_setopt_str(curl, CURLOPT_PROXY_TLSAUTH_TYPE, + config->proxy_tls_authtype); } /* new in 7.22.0 */ @@ -1340,6 +1381,10 @@ static CURLcode operate_do(struct GlobalConfig *global, my_setopt_bitmask(curl, CURLOPT_SSL_OPTIONS, mask); } + if(config->proxy_ssl_allow_beast) + my_setopt(curl, CURLOPT_PROXY_SSL_OPTIONS, + (long)CURLSSLOPT_ALLOW_BEAST); + if(config->mail_auth) my_setopt_str(curl, CURLOPT_MAIL_AUTH, config->mail_auth); diff --git a/src/tool_setopt.c b/src/tool_setopt.c index f3de09dee..ad3d30739 100644 --- a/src/tool_setopt.c +++ b/src/tool_setopt.c @@ -45,6 +45,15 @@ const NameValue setopt_nv_CURLPROXY[] = { NV(CURLPROXY_HTTP), NV(CURLPROXY_HTTP_1_0), + NV(CURLPROXY_HTTPS), + NV(CURLPROXY_SOCKS4), + NV(CURLPROXY_SOCKS5), + NV(CURLPROXY_SOCKS4A), + NV(CURLPROXY_SOCKS5_HOSTNAME), + NVEND, +}; + +const NameValue setopt_nv_CURL_SOCKS_PROXY[] = { NV(CURLPROXY_SOCKS4), NV(CURLPROXY_SOCKS5), NV(CURLPROXY_SOCKS4A), @@ -159,6 +168,8 @@ static const NameValue setopt_nv_CURLNONZERODEFAULTS[] = { NV1(CURLOPT_SSL_ENABLE_NPN, 1), NV1(CURLOPT_SSL_ENABLE_ALPN, 1), NV1(CURLOPT_TCP_NODELAY, 1), + NV1(CURLOPT_PROXY_SSL_VERIFYPEER, 1), + NV1(CURLOPT_PROXY_SSL_VERIFYHOST, 1), NVEND }; diff --git a/src/tool_setopt.h b/src/tool_setopt.h index 7cd38751c..fecf24fa3 100644 --- a/src/tool_setopt.h +++ b/src/tool_setopt.h @@ -47,6 +47,7 @@ typedef struct { } NameValueUnsigned; extern const NameValue setopt_nv_CURLPROXY[]; +extern const NameValue setopt_nv_CURL_SOCKS_PROXY[]; extern const NameValue setopt_nv_CURL_HTTP_VERSION[]; extern const NameValue setopt_nv_CURL_SSLVERSION[]; extern const NameValue setopt_nv_CURL_TIMECOND[]; @@ -61,6 +62,7 @@ extern const NameValueUnsigned setopt_nv_CURLAUTH[]; #define setopt_nv_CURLOPT_HTTP_VERSION setopt_nv_CURL_HTTP_VERSION #define setopt_nv_CURLOPT_HTTPAUTH setopt_nv_CURLAUTH #define setopt_nv_CURLOPT_SSLVERSION setopt_nv_CURL_SSLVERSION +#define setopt_nv_CURLOPT_PROXY_SSLVERSION setopt_nv_CURL_SSLVERSION #define setopt_nv_CURLOPT_TIMECONDITION setopt_nv_CURL_TIMECOND #define setopt_nv_CURLOPT_FTP_SSL_CCC setopt_nv_CURLFTPSSL_CCC #define setopt_nv_CURLOPT_USE_SSL setopt_nv_CURLUSESSL @@ -69,6 +71,7 @@ extern const NameValueUnsigned setopt_nv_CURLAUTH[]; #define setopt_nv_CURLOPT_PROTOCOLS setopt_nv_CURLPROTO #define setopt_nv_CURLOPT_REDIR_PROTOCOLS setopt_nv_CURLPROTO #define setopt_nv_CURLOPT_PROXYTYPE setopt_nv_CURLPROXY +#define setopt_nv_CURLOPT_SOCKS_PROXYTYPE setopt_nv_CURL_SOCKS_PROXY #define setopt_nv_CURLOPT_PROXYAUTH setopt_nv_CURLAUTH /* Intercept setopt calls for --libcurl */ diff --git a/src/tool_writeout.c b/src/tool_writeout.c index 60221d09b..dfe86471e 100644 --- a/src/tool_writeout.c +++ b/src/tool_writeout.c @@ -52,6 +52,7 @@ typedef enum { VAR_FTP_ENTRY_PATH, VAR_REDIRECT_URL, VAR_SSL_VERIFY_RESULT, + VAR_PROXY_SSL_VERIFY_RESULT, VAR_EFFECTIVE_FILENAME, VAR_PRIMARY_IP, VAR_PRIMARY_PORT, @@ -91,6 +92,7 @@ static const struct variable replacements[]={ {"ftp_entry_path", VAR_FTP_ENTRY_PATH}, {"redirect_url", VAR_REDIRECT_URL}, {"ssl_verify_result", VAR_SSL_VERIFY_RESULT}, + {"proxy_ssl_verify_result", VAR_PROXY_SSL_VERIFY_RESULT}, {"filename_effective", VAR_EFFECTIVE_FILENAME}, {"remote_ip", VAR_PRIMARY_IP}, {"remote_port", VAR_PRIMARY_PORT}, @@ -252,6 +254,12 @@ void ourWriteOut(CURL *curl, struct OutStruct *outs, const char *writeinfo) &longinfo)) fprintf(stream, "%ld", longinfo); break; + case VAR_PROXY_SSL_VERIFY_RESULT: + if(CURLE_OK == + curl_easy_getinfo(curl, CURLINFO_PROXY_SSL_VERIFYRESULT, + &longinfo)) + fprintf(stream, "%ld", longinfo); + break; case VAR_EFFECTIVE_FILENAME: if(outs->filename) fprintf(stream, "%s", outs->filename); -- cgit v1.2.3