summaryrefslogtreecommitdiff
path: root/cups/http-support.c
diff options
context:
space:
mode:
authorMichael R Sweet <michael.r.sweet@gmail.com>2018-09-14 14:58:35 -0400
committerMichael R Sweet <michael.r.sweet@gmail.com>2018-09-14 14:58:35 -0400
commit5737d5eba4ed4b376555b8c8de0c58ed8f598bb7 (patch)
tree8515edabd91421c1d2ff6548d9e788f4d2679007 /cups/http-support.c
parent16f67389a8533e9572149189a1340b737fe98a20 (diff)
downloadcups-5737d5eba4ed4b376555b8c8de0c58ed8f598bb7.tar.gz
More Digest changes.
Diffstat (limited to 'cups/http-support.c')
-rw-r--r--cups/http-support.c279
1 files changed, 146 insertions, 133 deletions
diff --git a/cups/http-support.c b/cups/http-support.c
index cd423aefd..3834dbef8 100644
--- a/cups/http-support.c
+++ b/cups/http-support.c
@@ -662,139 +662,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.
*
* This function is deprecated. Use the httpEncode64_2() function instead
@@ -1431,6 +1298,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.
*
* @since CUPS 2.0/OS 10.10@