]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - cups/http-support.c
More Digest changes.
[thirdparty/cups.git] / cups / http-support.c
index cd423aefd9fcbc95ecf4ce63788e30271a53c8ec..3834dbef8470bab2d04716fa7a2ef245c223f4a4 100644 (file)
@@ -661,139 +661,6 @@ httpDecode64_2(char       *out,           /* I  - String to write to */
 }
 
 
-/*
- * '_httpSetDigestAuthString()' - Calculate a Digest authentication response
- *                                using the appropriate RFC 2068/2617/7616
- *                                algorithm.
- */
-
-int                                    /* O - 1 on success, 0 on failure */
-_httpSetDigestAuthString(
-    http_t     *http,                  /* I - HTTP connection */
-    const char *method,                        /* I - HTTP method */
-    const char *resource)              /* I - HTTP resource path */
-{
-  char         kd[65],                 /* Final MD5/SHA-256 digest */
-               ha1[65],                /* Hash of username:realm:password */
-               ha2[65],                /* Hash of method:request-uri */
-               username[HTTP_MAX_VALUE],
-                                       /* username:password */
-               *password,              /* Pointer to password */
-               temp[1024],             /* Temporary string */
-               digest[1024];           /* Digest auth data */
-  unsigned char        hash[32];               /* Hash buffer */
-  size_t       hashsize;               /* Size of hash */
-
-
-  DEBUG_printf(("2_httpSetDigestAuthString(http=%p, method=\"%s\", resource=\"%s\")", http, method, resource));
-
-  strlcpy(username, http->userpass, sizeof(username));
-  if ((password = strchr(username, ':')) != NULL)
-    *password++ = '\0';
-  else
-    return (0);
-
-  if (http->algorithm[0])
-  {
-   /*
-    * Follow RFC 2617/7616...
-    */
-
-    int                i;                      /* Looping var */
-    char       cnonce[65];             /* cnonce value */
-    const char *hashalg;               /* Hashing algorithm */
-
-    for (i = 0; i < 64; i ++)
-      cnonce[i] = "0123456789ABCDEF"[CUPS_RAND() & 15];
-    cnonce[64] = '\0';
-
-    if (!_cups_strcasecmp(http->algorithm, "MD5"))
-    {
-     /*
-      * RFC 2617 Digest with MD5
-      */
-
-      hashalg = "md5";
-    }
-    else if (!_cups_strcasecmp(http->algorithm, "SHA-256"))
-    {
-     /*
-      * RFC 7616 Digest with SHA-256
-      */
-
-      hashalg = "sha2-256";
-    }
-    else
-    {
-     /*
-      * Some other algorithm we don't support, skip this one...
-      */
-
-      return (0);
-    }
-
-   /*
-    * Calculate digest value...
-    */
-
-    /* H(A1) = H(username:realm:password) */
-    snprintf(temp, sizeof(temp), "%s:%s:%s", username, http->realm, password);
-    hashsize = (size_t)cupsHashData(hashalg, (unsigned char *)temp, strlen(temp), hash, sizeof(hash));
-    cupsHashString(hash, hashsize, ha1, sizeof(ha1));
-
-    /* H(A2) = H(method:uri) */
-    snprintf(temp, sizeof(temp), "%s:%s", method, resource);
-    hashsize = (size_t)cupsHashData(hashalg, (unsigned char *)temp, strlen(temp), hash, sizeof(hash));
-    cupsHashString(hash, hashsize, ha2, sizeof(ha2));
-
-    /* KD = H(H(A1):nonce:nc:cnonce:qop:H(A2)) */
-    snprintf(temp, sizeof(temp), "%s:%s:%08x:%s:%s:%s", ha1, http->nonce, http->nonce_count, cnonce, "auth", ha2);
-    hashsize = (size_t)cupsHashData(hashalg, (unsigned char *)temp, strlen(temp), hash, sizeof(hash));
-    cupsHashString(hash, hashsize, kd, sizeof(kd));
-
-   /*
-    * Pass the RFC 2617/7616 WWW-Authenticate header...
-    */
-
-    if (http->opaque[0])
-      snprintf(digest, sizeof(digest), "username=\"%s\", realm=\"%s\", nonce=\"%s\", algorithm=%s, qop=auth, opaque=\"%s\", cnonce=\"%s\", nc=%08x, uri=\"%s\", response=\"%s\"", cupsUser(), http->realm, http->nonce, http->algorithm, http->opaque, cnonce, http->nonce_count, resource, kd);
-    else
-      snprintf(digest, sizeof(digest), "username=\"%s\", realm=\"%s\", nonce=\"%s\", algorithm=%s, qop=auth, cnonce=\"%s\", nc=%08x, uri=\"%s\", response=\"%s\"", username, http->realm, http->nonce, http->algorithm, cnonce, http->nonce_count, resource, kd);
-  }
-  else
-  {
-   /*
-    * Use old RFC 2069 Digest method...
-    */
-
-    /* H(A1) = H(username:realm:password) */
-    snprintf(temp, sizeof(temp), "%s:%s:%s", username, http->realm, password);
-    hashsize = (size_t)cupsHashData("md5", (unsigned char *)temp, strlen(temp), hash, sizeof(hash));
-    cupsHashString(hash, hashsize, ha1, sizeof(ha1));
-
-    /* H(A2) = H(method:uri) */
-    snprintf(temp, sizeof(temp), "%s:%s", method, resource);
-    hashsize = (size_t)cupsHashData("md5", (unsigned char *)temp, strlen(temp), hash, sizeof(hash));
-    cupsHashString(hash, hashsize, ha2, sizeof(ha2));
-
-    /* KD = H(H(A1):nonce:H(A2)) */
-    snprintf(temp, sizeof(temp), "%s:%s:%s", ha1, http->nonce, ha2);
-    hashsize = (size_t)cupsHashData("md5", (unsigned char *)temp, strlen(temp), hash, sizeof(hash));
-    cupsHashString(hash, hashsize, kd, sizeof(kd));
-
-   /*
-    * Pass the old RFC 2069 WWW-Authenticate header...
-    */
-
-    snprintf(digest, sizeof(digest), "username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\"", username, http->realm, http->nonce, resource, kd);
-  }
-
-  httpSetAuthString(http, "Digest", digest);
-
-  return (1);
-}
-
-
 /*
  * 'httpEncode64()' - Base64-encode a string.
  *
@@ -1430,6 +1297,152 @@ httpSeparateURI(
 }
 
 
+/*
+ * '_httpSetDigestAuthString()' - Calculate a Digest authentication response
+ *                                using the appropriate RFC 2068/2617/7616
+ *                                algorithm.
+ */
+
+int                                    /* O - 1 on success, 0 on failure */
+_httpSetDigestAuthString(
+    http_t     *http,                  /* I - HTTP connection */
+    const char *nonce,                 /* I - Nonce value */
+    const char *method,                        /* I - HTTP method */
+    const char *resource)              /* I - HTTP resource path */
+{
+  char         kd[65],                 /* Final MD5/SHA-256 digest */
+               ha1[65],                /* Hash of username:realm:password */
+               ha2[65],                /* Hash of method:request-uri */
+               username[HTTP_MAX_VALUE],
+                                       /* username:password */
+               *password,              /* Pointer to password */
+               temp[1024],             /* Temporary string */
+               digest[1024];           /* Digest auth data */
+  unsigned char        hash[32];               /* Hash buffer */
+  size_t       hashsize;               /* Size of hash */
+
+
+  DEBUG_printf(("2_httpSetDigestAuthString(http=%p, nonce=\"%s\", method=\"%s\", resource=\"%s\")", http, nonce, method, resource));
+
+  if (nonce && *nonce && strcmp(nonce, http->nonce))
+  {
+    strlcpy(http->nonce, nonce, sizeof(http->nonce));
+
+    if (nonce == http->nextnonce)
+      http->nextnonce[0] = '\0';
+
+    http->nonce_count = 1;
+  }
+  else
+    http->nonce_count ++;
+
+  strlcpy(username, http->userpass, sizeof(username));
+  if ((password = strchr(username, ':')) != NULL)
+    *password++ = '\0';
+  else
+    return (0);
+
+  if (http->algorithm[0])
+  {
+   /*
+    * Follow RFC 2617/7616...
+    */
+
+    int                i;                      /* Looping var */
+    char       cnonce[65];             /* cnonce value */
+    const char *hashalg;               /* Hashing algorithm */
+
+    for (i = 0; i < 64; i ++)
+      cnonce[i] = "0123456789ABCDEF"[CUPS_RAND() & 15];
+    cnonce[64] = '\0';
+
+    if (!_cups_strcasecmp(http->algorithm, "MD5"))
+    {
+     /*
+      * RFC 2617 Digest with MD5
+      */
+
+      hashalg = "md5";
+    }
+    else if (!_cups_strcasecmp(http->algorithm, "SHA-256"))
+    {
+     /*
+      * RFC 7616 Digest with SHA-256
+      */
+
+      hashalg = "sha2-256";
+    }
+    else
+    {
+     /*
+      * Some other algorithm we don't support, skip this one...
+      */
+
+      return (0);
+    }
+
+   /*
+    * Calculate digest value...
+    */
+
+    /* H(A1) = H(username:realm:password) */
+    snprintf(temp, sizeof(temp), "%s:%s:%s", username, http->realm, password);
+    hashsize = (size_t)cupsHashData(hashalg, (unsigned char *)temp, strlen(temp), hash, sizeof(hash));
+    cupsHashString(hash, hashsize, ha1, sizeof(ha1));
+
+    /* H(A2) = H(method:uri) */
+    snprintf(temp, sizeof(temp), "%s:%s", method, resource);
+    hashsize = (size_t)cupsHashData(hashalg, (unsigned char *)temp, strlen(temp), hash, sizeof(hash));
+    cupsHashString(hash, hashsize, ha2, sizeof(ha2));
+
+    /* KD = H(H(A1):nonce:nc:cnonce:qop:H(A2)) */
+    snprintf(temp, sizeof(temp), "%s:%s:%08x:%s:%s:%s", ha1, http->nonce, http->nonce_count, cnonce, "auth", ha2);
+    hashsize = (size_t)cupsHashData(hashalg, (unsigned char *)temp, strlen(temp), hash, sizeof(hash));
+    cupsHashString(hash, hashsize, kd, sizeof(kd));
+
+   /*
+    * Pass the RFC 2617/7616 WWW-Authenticate header...
+    */
+
+    if (http->opaque[0])
+      snprintf(digest, sizeof(digest), "username=\"%s\", realm=\"%s\", nonce=\"%s\", algorithm=%s, qop=auth, opaque=\"%s\", cnonce=\"%s\", nc=%08x, uri=\"%s\", response=\"%s\"", cupsUser(), http->realm, http->nonce, http->algorithm, http->opaque, cnonce, http->nonce_count, resource, kd);
+    else
+      snprintf(digest, sizeof(digest), "username=\"%s\", realm=\"%s\", nonce=\"%s\", algorithm=%s, qop=auth, cnonce=\"%s\", nc=%08x, uri=\"%s\", response=\"%s\"", username, http->realm, http->nonce, http->algorithm, cnonce, http->nonce_count, resource, kd);
+  }
+  else
+  {
+   /*
+    * Use old RFC 2069 Digest method...
+    */
+
+    /* H(A1) = H(username:realm:password) */
+    snprintf(temp, sizeof(temp), "%s:%s:%s", username, http->realm, password);
+    hashsize = (size_t)cupsHashData("md5", (unsigned char *)temp, strlen(temp), hash, sizeof(hash));
+    cupsHashString(hash, hashsize, ha1, sizeof(ha1));
+
+    /* H(A2) = H(method:uri) */
+    snprintf(temp, sizeof(temp), "%s:%s", method, resource);
+    hashsize = (size_t)cupsHashData("md5", (unsigned char *)temp, strlen(temp), hash, sizeof(hash));
+    cupsHashString(hash, hashsize, ha2, sizeof(ha2));
+
+    /* KD = H(H(A1):nonce:H(A2)) */
+    snprintf(temp, sizeof(temp), "%s:%s:%s", ha1, http->nonce, ha2);
+    hashsize = (size_t)cupsHashData("md5", (unsigned char *)temp, strlen(temp), hash, sizeof(hash));
+    cupsHashString(hash, hashsize, kd, sizeof(kd));
+
+   /*
+    * Pass the old RFC 2069 WWW-Authenticate header...
+    */
+
+    snprintf(digest, sizeof(digest), "username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\"", username, http->realm, http->nonce, resource, kd);
+  }
+
+  httpSetAuthString(http, "Digest", digest);
+
+  return (1);
+}
+
+
 /*
  * 'httpStateString()' - Return the string describing a HTTP state value.
  *