aboutsummaryrefslogtreecommitdiff
path: root/src/tool_getparam.c
diff options
context:
space:
mode:
authorJared Jennings <jjenning@fastmail.fm>2013-04-05 16:01:31 +0200
committerKamil Dudka <kdudka@redhat.com>2013-05-06 14:32:26 +0200
commit865d4138a08daff460f116c2494adb9c889f5304 (patch)
tree86e0841f7a385d001a18023ac04766fb7900a995 /src/tool_getparam.c
parent35874298e420aa53fde28982d86d5051aa92279a (diff)
curl -E: allow to escape ':' in cert nickname
Diffstat (limited to 'src/tool_getparam.c')
-rw-r--r--src/tool_getparam.c123
1 files changed, 100 insertions, 23 deletions
diff --git a/src/tool_getparam.c b/src/tool_getparam.c
index b44b9c020..55750c911 100644
--- a/src/tool_getparam.c
+++ b/src/tool_getparam.c
@@ -286,6 +286,99 @@ static const struct feat feats[] = {
{"TLS-SRP", CURL_VERSION_TLSAUTH_SRP}
};
+/* https://sourceforge.net/p/curl/bugs/1196/ */
+static void parse_cert_parameter(const char *cert_parameter,
+ char **certname,
+ char **passphrase)
+{
+ size_t param_length = strlen(cert_parameter);
+ size_t parsed_chars = 0;
+ size_t span;
+ const char *param_place = NULL;
+ char *certname_place = NULL;
+ /* most trivial assumption: cert_parameter is empty */
+ if(param_length == 0) {
+ *certname = NULL;
+ *passphrase = NULL;
+ return;
+ }
+ /* next less trivial: cert_parameter contains no colon nor backslash; this
+ * means no passphrase was given and no characters escaped */
+ if(!strpbrk(cert_parameter, ":\\")) {
+ *certname = strdup(cert_parameter);
+ *passphrase = NULL;
+ return;
+ }
+ /* deal with escaped chars; find unescaped colon if it exists */
+ *certname = (char *) malloc(param_length + 1);
+ *passphrase = NULL;
+ param_place = cert_parameter;
+ certname_place = *certname;
+ param_place = cert_parameter;
+ while(*param_place) {
+ span = strcspn(param_place, ":\\");
+ strncpy(certname_place, param_place, span);
+ param_place += span;
+ certname_place += span;
+ *certname_place = '\0';
+ /* we just ate all the non-special chars. now we're on either a special
+ * char or the end of the string. */
+ switch(*param_place) {
+ case '\0':
+ break;
+ case '\\':
+ param_place++;
+ switch(*param_place) {
+ case '\0':
+ *certname_place++ = '\\';
+ break;
+ case '\\':
+ *certname_place++ = '\\';
+ param_place++;
+ break;
+ case ':':
+ *certname_place++ = ':';
+ param_place++;
+ break;
+ default:
+ *certname_place++ = '\\';
+ *certname_place++ = *param_place;
+ param_place++;
+ break;
+ }
+ break;
+ case ':':
+ /* Since we live in a world of weirdness and confusion, the win32
+ dudes can use : when using drive letters and thus c:\file:password
+ needs to work. In order not to break compatibility, we still use : as
+ separator, but we try to detect when it is used for a file name! On
+ windows. */
+#ifdef WIN32
+ if(param_place &&
+ (param_place == &cert_parameter[1]) &&
+ (cert_parameter[2] == '\\' || cert_parameter[2] == '/') &&
+ (ISALPHA(cert_parameter[0])) ) {
+ /* colon in the second column, followed by a backslash, and the
+ first character is an alphabetic letter:
+
+ this is a drive letter colon */
+ *certname_place++ = ':';
+ param_place++;
+ break;
+ }
+#endif
+ /* escaped colons and Windows drive letter colons were handled
+ * above; if we're still here, this is a separating colon */
+ param_place++;
+ if(strlen(param_place) > 0) {
+ *passphrase = strdup(param_place);
+ }
+ return;
+ break;
+ }
+ }
+}
+
ParameterError getparameter(char *flag, /* f or -long-flag */
char *nextarg, /* NULL if unset */
bool *usedarg, /* set to TRUE if the arg
@@ -1207,30 +1300,14 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
break;
default: /* certificate file */
{
- char *ptr = strchr(nextarg, ':');
- /* Since we live in a world of weirdness and confusion, the win32
- dudes can use : when using drive letters and thus
- c:\file:password needs to work. In order not to break
- compatibility, we still use : as separator, but we try to detect
- when it is used for a file name! On windows. */
-#ifdef WIN32
- if(ptr &&
- (ptr == &nextarg[1]) &&
- (nextarg[2] == '\\' || nextarg[2] == '/') &&
- (ISALPHA(nextarg[0])) )
- /* colon in the second column, followed by a backslash, and the
- first character is an alphabetic letter:
-
- this is a drive letter colon */
- ptr = strchr(&nextarg[3], ':'); /* find the next one instead */
-#endif
- if(ptr) {
- /* we have a password too */
- *ptr = '\0';
- ptr++;
- GetStr(&config->key_passwd, ptr);
+ char *certname, *passphrase;
+ parse_cert_parameter(nextarg, &certname, &passphrase);
+ if(certname) {
+ GetStr(&config->cert, certname);
+ }
+ if(passphrase) {
+ GetStr(&config->key_passwd, passphrase);
}
- GetStr(&config->cert, nextarg);
cleanarg(nextarg);
}
}