]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Parser starting to take shape
authorHenrik Nordstrom <henrik@henriknordstrom.net>
Tue, 2 Mar 2010 14:08:22 +0000 (15:08 +0100)
committerHenrik Nordstrom <henrik@henriknordstrom.net>
Tue, 2 Mar 2010 14:08:22 +0000 (15:08 +0100)
src/HttpHeaderTools.cc
src/auth/digest/auth_digest.cc

index 3a2b7d3ad02956acf4ee51395f199e9c896be4e4..875a98d62f02f711b40da2e907ad662d6b7dfe39 100644 (file)
@@ -335,25 +335,29 @@ httpHeaderParseQuotedString(const char *start, String *val)
 {
     const char *end, *pos;
     val->clean();
-    assert (*start == '"');
+    if (*start != '"') {
+       debugs(66, 2, "failed to parse a quoted-string header field near '" << start << "'");
+       return 0;
+    }
     pos = start + 1;
 
-    while (1) {
-        if (!(end = index (pos,'"'))) {
-            debugs(66, 2, "failed to parse a quoted-string header field near '" << start << "'");
-            return 0;
-        }
-
-        /* check for quoted-chars */
-        if (*(end - 1) != '\\') {
-            /* done */
-            val->append(start + 1, end-start-1);
-            return 1;
-        }
-
-        /* try for the end again */
-        pos = end + 1;
+    while (*pos != '"') {
+       if (*pos == '\\') {
+           pos++;
+       }
+       if (!*pos) {
+           debugs(66, 2, "failed to parse a quoted-string header field near '" << start << "'");
+           val->clean();
+           return 0;
+       }
+       end = pos + strcspn(pos, "\"\\");
+       val->append(pos, end-pos);
+       pos = end;
     }
+    /* Make sure it's defined even if empty "" */
+    if (!val->defined())
+       val->limitInit("", 0);
+    return 1;
 }
 
 /**
index f6b338e25e9347d15186b67e47b50b964aae3c2f..46c61f191da22e44bf9d912a5f992af63478806d 100644 (file)
@@ -67,7 +67,7 @@ static MemAllocator *digest_nonce_pool = NULL;
 
 CBDATA_TYPE(DigestAuthenticateStateData);
 
-enum {
+enum http_digest_attr_type {
     DIGEST_USERNAME=1,
     DIGEST_REALM,
     DIGEST_QOP,
@@ -1103,7 +1103,7 @@ AuthDigestConfig::decode(char const *proxy_auth)
     const char *pos = NULL;
     char *username = NULL;
     digest_nonce_h *nonce;
-    int ilen;
+    size_t ilen;
 
     debugs(29, 9, "authenticateDigestDecodeAuth: beginning");
 
@@ -1121,124 +1121,84 @@ AuthDigestConfig::decode(char const *proxy_auth)
     String temp(proxy_auth);
 
     while (strListGetItem(&temp, ',', &item, &ilen, &pos)) {
-        if ((p = strchr(item, '=')) && (p - item < ilen))
-            ilen = p++ - item;
-
-        if (!strncmp(item, "username", ilen)) {
-            /* white space */
-
-            while (xisspace(*p))
-                p++;
-
-            /* quote mark */
-            p++;
-
+       String value();
+       size_t nlen;
+       /* isolate directive name */
+       if ((p = (const char *)memchr(item, '=', ilen)) && (p - item < ilen)) {
+            nlen = p++ - item;
+           if (!httpHeaderParseQuotedString(p, &value))
+               value.initLimit(p, ilen - (p - item));
+       } else
+           nlen = ilen;
+
+       if (!value.defined()) {
+           debugs(29, 9, "authDigestDecodeAuth: Failed to parse attribute '" << temp << "' in '" << proxy_auth << "'");
+           continue;
+       }
+
+       /* find type */
+       http_digest_attr_type type = (http_digest_attr_type)httpHeaderIdByName(item, nlen, DigestFieldsInfo, DIGEST_ENUM_END);
+
+       switch (type) {
+       case DIGEST_USERNAME:
             safe_free(username);
-            username = xstrndup(p, strchr(p, '"') + 1 - p);
-
+            username = xstrndup(value.rawBuf(), value.size() + 1);
             debugs(29, 9, "authDigestDecodeAuth: Found Username '" << username << "'");
-        } else if (!strncmp(item, "realm", ilen)) {
-            /* white space */
-
-            while (xisspace(*p))
-                p++;
-
-            /* quote mark */
-            p++;
+           break;
 
+       case DIGEST_REALM:
             safe_free(digest_request->realm);
-            digest_request->realm = xstrndup(p, strchr(p, '"') + 1 - p);
-
+            digest_request->realm = xstrndup(value.rawBuf(), value.size() + 1);
             debugs(29, 9, "authDigestDecodeAuth: Found realm '" << digest_request->realm << "'");
-        } else if (!strncmp(item, "qop", ilen)) {
-            /* white space */
-
-            while (xisspace(*p))
-                p++;
-
-            if (*p == '\"')
-                /* quote mark */
-                p++;
+           break;
 
+       case DIGEST_QOP:
             safe_free(digest_request->qop);
-            digest_request->qop = xstrndup(p, strcspn(p, "\" \t\r\n()<>@,;:\\/[]?={}") + 1);
-
+            digest_request->qop = xstrndup(value.rawBuf(), value.size() + 1);
             debugs(29, 9, "authDigestDecodeAuth: Found qop '" << digest_request->qop << "'");
-        } else if (!strncmp(item, "algorithm", ilen)) {
-            /* white space */
-
-            while (xisspace(*p))
-                p++;
-
-            if (*p == '\"')
-                /* quote mark */
-                p++;
+           break;
 
+       case DIGEST_ALGORITHM:
             safe_free(digest_request->algorithm);
-            digest_request->algorithm = xstrndup(p, strcspn(p, "\" \t\r\n()<>@,;:\\/[]?={}") + 1);
-
+            digest_request->algorithm = xstrndup(value.rawBuf(), value.size() + 1);
             debugs(29, 9, "authDigestDecodeAuth: Found algorithm '" << digest_request->algorithm << "'");
-        } else if (!strncmp(item, "uri", ilen)) {
-            /* white space */
-
-            while (xisspace(*p))
-                p++;
-
-            /* quote mark */
-            p++;
+           break;
 
+       case DIGEST_URI:
             safe_free(digest_request->uri);
-            digest_request->uri = xstrndup(p, strchr(p, '"') + 1 - p);
-
+            digest_request->uri = xstrndup(value.rawBuf(), value.size() + 1);
             debugs(29, 9, "authDigestDecodeAuth: Found uri '" << digest_request->uri << "'");
-        } else if (!strncmp(item, "nonce", ilen)) {
-            /* white space */
-
-            while (xisspace(*p))
-                p++;
-
-            /* quote mark */
-            p++;
+           break;
 
+       case DIGEST_NONCE:
             safe_free(digest_request->nonceb64);
-            digest_request->nonceb64 = xstrndup(p, strchr(p, '"') + 1 - p);
-
+            digest_request->nonceb64 = xstrndup(value.rawBuf(), value.size() + 1);
             debugs(29, 9, "authDigestDecodeAuth: Found nonce '" << digest_request->nonceb64 << "'");
-        } else if (!strncmp(item, "nc", ilen)) {
-            /* white space */
-
-            while (xisspace(*p))
-                p++;
-
-            xstrncpy(digest_request->nc, p, 9);
+           break;
 
+       case DIGEST_NC:
+           if (value.size() != 8) {
+               debugs(29, 9, "authDigestDecodeAuth: Invalid nc '" << value << "' in '" << temp << "'");
+           }
+            xstrncpy(digest_request->nc, value.rawBuf(), value.size() + 1);
             debugs(29, 9, "authDigestDecodeAuth: Found noncecount '" << digest_request->nc << "'");
-        } else if (!strncmp(item, "cnonce", ilen)) {
-            /* white space */
-
-            while (xisspace(*p))
-                p++;
-
-            /* quote mark */
-            p++;
+           break;
 
+       case DIGEST_CNONCE:
             safe_free(digest_request->cnonce);
-            digest_request->cnonce = xstrndup(p, strchr(p, '"') + 1 - p);
-
+            digest_request->cnonce = xstrndup(value.rawBuf(), value.size() + 1);
             debugs(29, 9, "authDigestDecodeAuth: Found cnonce '" << digest_request->cnonce << "'");
-        } else if (!strncmp(item, "response", ilen)) {
-            /* white space */
-
-            while (xisspace(*p))
-                p++;
-
-            /* quote mark */
-            p++;
+           break;
 
+       case DIGEST_RESPONSE:
             safe_free(digest_request->response);
-            digest_request->response = xstrndup(p, strchr(p, '"') + 1 - p);
-
+            digest_request->response = xstrndup(value.rawBuf(), value.size() + 1);
             debugs(29, 9, "authDigestDecodeAuth: Found response '" << digest_request->response << "'");
+           break;
+
+       default:
+            debugs(29, 2, "authDigestDecodeAuth: Unknown attribute '" << item << "' in '" << temp << "'");
+
         }
     }