diff options
-rw-r--r-- | include/curl/curl.h | 5 | ||||
-rw-r--r-- | lib/ftp.c | 3 | ||||
-rw-r--r-- | lib/url.c | 22 | ||||
-rw-r--r-- | lib/urldata.h | 7 | ||||
-rw-r--r-- | src/main.c | 35 |
5 files changed, 62 insertions, 10 deletions
diff --git a/include/curl/curl.h b/include/curl/curl.h index c0299c6f3..46a52b1c5 100644 --- a/include/curl/curl.h +++ b/include/curl/curl.h @@ -197,6 +197,8 @@ typedef enum { CURLE_SEND_ERROR, /* 55 - failed sending network data */ CURLE_RECV_ERROR, /* 56 - failure in receiving network data */ CURLE_SHARE_IN_USE, /* 57 - share is in use */ + CURLE_SSL_INSECURE, /* 58 - connect attempt without certificate + but SSL_INSECURE not explicitly allowed */ CURL_LAST /* never use! */ } CURLcode; @@ -571,6 +573,9 @@ typedef enum { /* Provide a CURLShare for mutexing non-ts data */ CINIT(SHARE, OBJECTPOINT, 100), + /* Explicitly allow insecure SSL connects */ + CINIT(SSL_INSECURE, LONG, 101), + CURLOPT_LASTENTRY /* the last unused */ } CURLoption; @@ -711,8 +711,7 @@ CURLcode ftp_cwd(struct connectdata *conn, char *path) CURLcode result; FTPSENDF(conn, "CWD %s", path); - nread = Curl_GetFTPResponse( - conn->data->state.buffer, conn, &ftpcode); + nread = Curl_GetFTPResponse(conn->data->state.buffer, conn, &ftpcode); if (nread < 0) return CURLE_OPERATION_TIMEOUTED; @@ -1004,10 +1004,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) break; case CURLOPT_CAPATH: /* - * Set CA path info for SSL connection. Specify directory name of the CA certificates - * which have been prepared using openssl c_rehash utility. + * Set CA path info for SSL connection. Specify directory name of the CA + * certificates which have been prepared using openssl c_rehash utility. */ - data->set.ssl.CApath = va_arg(param, char *); /*This does not work on windows.*/ + /* This does not work on windows. */ + data->set.ssl.CApath = va_arg(param, char *); break; case CURLOPT_TELNETOPTIONS: /* @@ -1048,6 +1049,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) } break; + case CURLOPT_SSL_INSECURE: + data->set.ssl.allow_insecure = va_arg(param, long)?TRUE:FALSE; + break; + default: /* unknown tag and its companion, just ignore: */ return CURLE_FAILED_INIT; /* correct this */ @@ -2035,6 +2040,17 @@ static CURLcode CreateConnection(struct SessionHandle *data, return CURLE_UNSUPPORTED_PROTOCOL; } + if(conn->protocol & PROT_SSL) { + /* If SSL is requested, require security level info */ + + if(!data->set.ssl.allow_insecure && + !(data->set.ssl.CAfile || data->set.ssl.CApath)) { + failf(data, "Insecure SSL connect attempted without explicit permission granted"); + return CURLE_SSL_INSECURE; + } + } + + /************************************************************* * Figure out the remote port number * diff --git a/lib/urldata.h b/lib/urldata.h index 0d4a11a8b..ce15dbf9f 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -136,14 +136,17 @@ struct ssl_config_data { long version; /* what version the client wants to use */ long certverifyresult; /* result from the certificate verification */ long verifypeer; /* set TRUE if this is desired */ - long verifyhost; /* 0: no verif, 1: check that CN exists, 2: CN must match hostname */ + long verifyhost; /* 0: no verify + 1: check that CN exists + 2: CN must match hostname */ char *CApath; /* DOES NOT WORK ON WINDOWS */ char *CAfile; /* cerficate to verify peer against */ char *random_file; /* path to file containing "random" data */ char *egdsocket; /* path to file containing the EGD daemon socket */ char *cipher_list; /* list of ciphers to use */ + bool allow_insecure; /* allow connects without any CA certificate */ - long numsessions; /* SSL session id cache size */ + long numsessions; /* SSL session id cache size */ }; /**************************************************************************** diff --git a/src/main.c b/src/main.c index 36d28ca7c..24eb8fb92 100644 --- a/src/main.c +++ b/src/main.c @@ -365,6 +365,7 @@ static void help(void) puts(" -j/--junk-session-cookies Ignore session cookies read from file (H)\n" " --interface <interface> Specify the interface to be used\n" " --krb4 <level> Enable krb4 with specified security level (F)\n" + " -k/--insecure Allow curl to connect to SSL sites without certs (H)\n" " -K/--config Specify which config file to read\n" " -l/--list-only List only names of an FTP directory (F)\n" " --limit-rate <rate> Limit how fast transfers to allow"); @@ -480,6 +481,7 @@ struct Configurable { bool nobuffer; bool globoff; bool use_httpget; + bool insecure_ok; /* set TRUE to allow insecure SSL connects */ char *writeout; /* %-styled format string to output */ bool writeenv; /* write results to environment, if available */ @@ -1030,6 +1032,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */ {"i", "include", FALSE}, {"I", "head", FALSE}, {"j", "junk-session-cookies", FALSE}, + {"k", "insecure", FALSE}, {"K", "config", TRUE}, {"l", "list-only", FALSE}, {"L", "location", FALSE}, @@ -1468,7 +1471,10 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */ return PARAM_BAD_USE; } break; - case 'K': + case 'k': /* allow insecure SSL connects */ + config->insecure_ok ^= TRUE; + break; + case 'K': /* parse config file */ res = parseconfig(nextarg, config); config->configread = TRUE; if(res) @@ -2791,6 +2797,9 @@ operate(struct Configurable *config, int argc, char *argv[]) config->conf |= CONF_VERBOSE; /* force verbose */ } curl_easy_setopt(curl, CURLOPT_VERBOSE, config->conf&CONF_VERBOSE); + + /* new in curl 7.10 */ + curl_easy_setopt(curl, CURLOPT_SSL_INSECURE, config->insecure_ok); res = curl_easy_perform(curl); @@ -2814,8 +2823,28 @@ operate(struct Configurable *config, int argc, char *argv[]) vms_show = VMSSTS_HIDE; } #else - if((res!=CURLE_OK) && config->showerror) - fprintf(config->errors, "curl: (%d) %s\n", res, errorbuffer); + if((res!=CURLE_OK) && config->showerror) { + switch(res) { + case CURLE_SSL_INSECURE: + /* Since this breaks how curl used to work, we need a slightly more + verbose and descriptive error here to educate people what is + happening and what to do to make it work. At least for a + while. */ + fprintf(config->errors, "curl: (%d) %s\n%s", res, + errorbuffer, + " Since SSL doesn't offer any true security if you don't use a CA\n" + " certificate to verify the peer certificate with, you must either\n" + " provide one to make sure that the server really is the server you\n" + " think it is, or you must explicitly tell curl that insecure SSL\n" + " connects are fine.\n" + " Allow insecure SSL operations with -k/--insecure\n" + ); + break; + default: + fprintf(config->errors, "curl: (%d) %s\n", res, errorbuffer); + break; + } + } #endif if (outfile && !strequal(outfile, "-") && outs.stream) |