#ifndef UNITTESTS
static
#endif
-void parse_cert_parameter(const char *cert_parameter,
- char **certname,
- char **passphrase)
+ParameterError parse_cert_parameter(const char *cert_parameter,
+ char **certname,
+ char **passphrase)
{
size_t param_length = strlen(cert_parameter);
size_t span;
const char *param_place = NULL;
char *certname_place = NULL;
+ ParameterError err = PARAM_OK;
*certname = NULL;
*passphrase = NULL;
/* most trivial assumption: cert_parameter is empty */
if(param_length == 0)
- return;
+ return PARAM_BLANK_STRING;
/* next less trivial: cert_parameter starts 'pkcs11:' and thus
* looks like a RFC7512 PKCS#11 URI which can be used as-is.
if(curl_strnequal(cert_parameter, "pkcs11:", 7) ||
!strpbrk(cert_parameter, ":\\")) {
*certname = strdup(cert_parameter);
- return;
+ if(!*certname)
+ return PARAM_NO_MEM;
+ return PARAM_OK;
}
/* deal with escaped chars; find unescaped colon if it exists */
certname_place = malloc(param_length + 1);
- if(!certname_place)
- return;
+ if(!certname_place) {
+ err = PARAM_NO_MEM;
+ goto done;
+ }
*certname = certname_place;
param_place = cert_parameter;
param_place++;
if(*param_place) {
*passphrase = strdup(param_place);
+ if(!*passphrase)
+ err = PARAM_NO_MEM;
}
goto done;
}
}
done:
- *certname_place = '\0';
+ if(err) {
+ tool_safefree(*certname);
+ }
+ else
+ *certname_place = '\0';
+ return err;
}
/* Replace (in-place) '%20' by '+' according to RFC1866 */
return new_index; /* new size */
}
-static void
+static ParameterError
GetFileAndPassword(const char *nextarg, char **file, char **password)
{
char *certname, *passphrase;
+ ParameterError err;
/* nextarg is never NULL here */
- parse_cert_parameter(nextarg, &certname, &passphrase);
- free(*file);
- *file = certname;
- if(passphrase) {
- free(*password);
- *password = passphrase;
+ err = parse_cert_parameter(nextarg, &certname, &passphrase);
+ if(!err) {
+ free(*file);
+ *file = certname;
+ if(passphrase) {
+ free(*password);
+ *password = passphrase;
+ }
}
+ return err;
}
/* Get a size parameter for '--limit-rate' or '--max-filesize'.
return PARAM_OK;
}
+static ParameterError existingfile(char **store,
+ const struct LongShort *a,
+ const char *filename)
+{
+ struct_stat info;
+ if(curlx_stat(filename, &info)) {
+ errorf("The file '%s' provided to --%s does not exist",
+ filename, a->lname);
+ return PARAM_BAD_USE;
+ }
+ return getstr(store, filename, DENY_BLANK);
+}
+
/* opt_file handles file options */
static ParameterError opt_file(struct OperationConfig *config,
const struct LongShort *a,
err = getstr(&config->unix_socket_path, nextarg, DENY_BLANK);
break;
case C_CACERT: /* --cacert */
- err = getstr(&config->cacert, nextarg, DENY_BLANK);
+ err = existingfile(&config->cacert, a, nextarg);
break;
case C_CAPATH: /* --capath */
err = getstr(&config->capath, nextarg, DENY_BLANK);
break;
case C_CERT: /* --cert */
- GetFileAndPassword(nextarg, &config->cert, &config->key_passwd);
+ err = GetFileAndPassword(nextarg, &config->cert, &config->key_passwd);
break;
case C_CONFIG: /* --config */
if(--max_recursive < 0) {
}
break;
case C_CRLFILE: /* --crlfile */
- err = getstr(&config->crlfile, nextarg, DENY_BLANK);
+ err = existingfile(&config->crlfile, a, nextarg);
break;
case C_DUMP_HEADER: /* --dump-header */
err = getstr(&config->headerfile, nextarg, DENY_BLANK);
err = getstr(&config->key, nextarg, DENY_BLANK);
break;
case C_KNOWNHOSTS: /* --knownhosts */
- err = getstr(&config->knownhosts, nextarg, DENY_BLANK);
+ err = existingfile(&config->knownhosts, a, nextarg);
break;
case C_NETRC_FILE: /* --netrc-file */
- err = getstr(&config->netrc_file, nextarg, DENY_BLANK);
+ err = existingfile(&config->netrc_file, a, nextarg);
break;
case C_OUTPUT: /* --output */
err = parse_output(config, nextarg);
break;
case C_PROXY_CACERT: /* --proxy-cacert */
- err = getstr(&config->proxy_cacert, nextarg, DENY_BLANK);
+ err = existingfile(&config->proxy_cacert, a, nextarg);
break;
case C_PROXY_CAPATH: /* --proxy-capath */
err = getstr(&config->proxy_capath, nextarg, DENY_BLANK);
break;
case C_PROXY_CERT: /* --proxy-cert */
- GetFileAndPassword(nextarg, &config->proxy_cert,
- &config->proxy_key_passwd);
+ err = GetFileAndPassword(nextarg, &config->proxy_cert,
+ &config->proxy_key_passwd);
break;
case C_PROXY_CRLFILE: /* --proxy-crlfile */
- err = getstr(&config->proxy_crlfile, nextarg, DENY_BLANK);
+ err = existingfile(&config->proxy_crlfile, a, nextarg);
break;
case C_PROXY_KEY: /* --proxy-key */
err = getstr(&config->proxy_key, nextarg, ALLOW_BLANK);
{
UNITTEST_BEGIN_SIMPLE
- static const char *values[] = {
+ struct cert {
+ const char *param;
+ const char *cert;
+ const char *passwd;
+ };
+
+ static const struct cert values[] = {
/* -E parameter */ /* exp. cert name */ /* exp. passphrase */
- "foo:bar:baz", "foo", "bar:baz",
- "foo\\:bar:baz", "foo:bar", "baz",
- "foo\\\\:bar:baz", "foo\\", "bar:baz",
- "foo:bar\\:baz", "foo", "bar\\:baz",
- "foo:bar\\\\:baz", "foo", "bar\\\\:baz",
- "foo\\bar\\baz", "foo\\bar\\baz", NULL,
- "foo\\\\bar\\\\baz", "foo\\bar\\baz", NULL,
- "foo\\", "foo\\", NULL,
- "foo\\\\", "foo\\", NULL,
- "foo:bar\\", "foo", "bar\\",
- "foo:bar\\\\", "foo", "bar\\\\",
- "foo:bar:", "foo", "bar:",
- "foo\\::bar\\:", "foo:", "bar\\:",
- "pkcs11:foobar", "pkcs11:foobar", NULL,
- "PKCS11:foobar", "PKCS11:foobar", NULL,
- "PkCs11:foobar", "PkCs11:foobar", NULL,
+ {"foo:bar:baz", "foo", "bar:baz"},
+ {"foo\\:bar:baz", "foo:bar", "baz"},
+ {"foo\\\\:bar:baz", "foo\\", "bar:baz"},
+ {"foo:bar\\:baz", "foo", "bar\\:baz"},
+ {"foo:bar\\\\:baz", "foo", "bar\\\\:baz"},
+ {"foo\\bar\\baz", "foo\\bar\\baz", NULL},
+ {"foo\\\\bar\\\\baz", "foo\\bar\\baz", NULL},
+ {"foo\\", "foo\\", NULL},
+ {"foo\\\\", "foo\\", NULL},
+ {"foo:bar\\", "foo", "bar\\"},
+ {"foo:bar\\\\", "foo", "bar\\\\"},
+ {"foo:bar:", "foo", "bar:"},
+ {"foo\\::bar\\:", "foo:", "bar\\:"},
+ {"pkcs11:foobar", "pkcs11:foobar", NULL},
+ {"PKCS11:foobar", "PKCS11:foobar", NULL},
+ {"PkCs11:foobar", "PkCs11:foobar", NULL},
#ifdef _WIN32
- "c:\\foo:bar:baz", "c:\\foo", "bar:baz",
- "c:\\foo\\:bar:baz", "c:\\foo:bar", "baz",
- "c:\\foo\\\\:bar:baz", "c:\\foo\\", "bar:baz",
- "c:\\foo:bar\\:baz", "c:\\foo", "bar\\:baz",
- "c:\\foo:bar\\\\:baz", "c:\\foo", "bar\\\\:baz",
- "c:\\foo\\bar\\baz", "c:\\foo\\bar\\baz", NULL,
- "c:\\foo\\\\bar\\\\baz", "c:\\foo\\bar\\baz", NULL,
- "c:\\foo\\", "c:\\foo\\", NULL,
- "c:\\foo\\\\", "c:\\foo\\", NULL,
- "c:\\foo:bar\\", "c:\\foo", "bar\\",
- "c:\\foo:bar\\\\", "c:\\foo", "bar\\\\",
- "c:\\foo:bar:", "c:\\foo", "bar:",
- "c:\\foo\\::bar\\:", "c:\\foo:", "bar\\:",
+ {"c:\\foo:bar:baz", "c:\\foo", "bar:baz"},
+ {"c:\\foo\\:bar:baz", "c:\\foo:bar", "baz"},
+ {"c:\\foo\\\\:bar:baz", "c:\\foo\\", "bar:baz"},
+ {"c:\\foo:bar\\:baz", "c:\\foo", "bar\\:baz"},
+ {"c:\\foo:bar\\\\:baz", "c:\\foo", "bar\\\\:baz"},
+ {"c:\\foo\\bar\\baz", "c:\\foo\\bar\\baz", NULL},
+ {"c:\\foo\\\\bar\\\\baz", "c:\\foo\\bar\\baz", NULL},
+ {"c:\\foo\\", "c:\\foo\\", NULL},
+ {"c:\\foo\\\\", "c:\\foo\\", NULL},
+ {"c:\\foo:bar\\", "c:\\foo", "bar\\"},
+ {"c:\\foo:bar\\\\", "c:\\foo", "bar\\\\"},
+ {"c:\\foo:bar:", "c:\\foo", "bar:"},
+ {"c:\\foo\\::bar\\:", "c:\\foo:", "bar\\:"},
#endif
- NULL, NULL, NULL,
+ {NULL, NULL, NULL}
};
- const char **p;
+ const struct cert *p;
char *certname, *passphrase;
- for(p = values; *p; p += 3) {
- parse_cert_parameter(p[0], &certname, &passphrase);
- if(p[1]) {
+ ParameterError err;
+ for(p = &values[0]; p->param; p++) {
+ err = parse_cert_parameter(p->param, &certname, &passphrase);
+ if(!err) {
if(certname) {
- if(strcmp(p[1], certname)) {
+ if(strcmp(p->cert, certname)) {
curl_mprintf("expected certname '%s' but got '%s' "
- "for -E param '%s'\n", p[1], certname, p[0]);
+ "for -E param '%s'\n", p->cert, certname, p->param);
fail("assertion failure");
}
}
else {
curl_mprintf("expected certname '%s' but got NULL "
- "for -E param '%s'\n", p[1], p[0]);
+ "for -E param '%s'\n", p->cert, p->param);
fail("assertion failure");
}
}
else {
if(certname) {
curl_mprintf("expected certname NULL but got '%s' "
- "for -E param '%s'\n", certname, p[0]);
+ "for -E param '%s'\n", certname, p->param);
fail("assertion failure");
}
}
- if(p[2]) {
+ if(p->passwd) {
if(passphrase) {
- if(strcmp(p[2], passphrase)) {
+ if(strcmp(p->passwd, passphrase)) {
curl_mprintf("expected passphrase '%s' but got '%s'"
- "for -E param '%s'\n", p[2], passphrase, p[0]);
+ "for -E param '%s'\n", p->passwd, passphrase, p->param);
fail("assertion failure");
}
}
else {
curl_mprintf("expected passphrase '%s' but got NULL "
- "for -E param '%s'\n", p[2], p[0]);
+ "for -E param '%s'\n", p->passwd, p->param);
fail("assertion failure");
}
}
else {
if(passphrase) {
curl_mprintf("expected passphrase NULL but got '%s' "
- "for -E param '%s'\n", passphrase, p[0]);
+ "for -E param '%s'\n", passphrase, p->param);
fail("assertion failure");
}
}