cURL / Mailing Lists / curl-library / Single Mail

curl-library

[PATCH 1/8] curl -E: allow to escape ':' in cert nickname

From: Kamil Dudka <kdudka_at_redhat.com>
Date: Fri, 3 May 2013 23:32:47 +0200

From: Jared Jennings <jjenning_at_fastmail.fm>

---
 RELEASE-NOTES       |    3 +-
 src/tool_getparam.c |  123 +++++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 102 insertions(+), 24 deletions(-)
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index 53b41c8..0321416 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -21,6 +21,7 @@ This release includes the following changes:
  o usercertinmem.c: add example showing user cert in memory
  o url: Added smtp and pop3 hostnames to the protocol detection list
  o imap/pop3/smtp: Added support for enabling the SASL initial response [8]
+ o curl -E: allow to use ':' in certificate nicknames [9]
  o 
 
 This release includes the following bugfixes:
@@ -64,4 +65,4 @@ References to bug reports and discussions on issues:
  [6] = https://bugzilla.redhat.com/906031
  [7] = http://curl.haxx.se/bug/view.cgi?id=1218
  [8] = http://curl.haxx.se/mail/lib-2012-03/0114.html
- [9]
+ [9] = http://curl.haxx.se/bug/view.cgi?id=1196
diff --git a/src/tool_getparam.c b/src/tool_getparam.c
index b44b9c0..55750c9 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);
       }
       }
-- 
1.7.1
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette:  http://curl.haxx.se/mail/etiquette.html
Received on 2013-05-03