summaryrefslogtreecommitdiff
path: root/cups/http.c
diff options
context:
space:
mode:
authorMichael R Sweet <michaelrsweet@gmail.com>2017-11-06 16:19:27 -0500
committerMichael R Sweet <michaelrsweet@gmail.com>2017-11-06 16:28:31 -0500
commit7ec11630684301572cb7d19a95c244c104961a2a (patch)
tree75940c5fb6da6293797bae904c7865433ead08e7 /cups/http.c
parent054eee9cd0555f836ef9ad87f21d6e6ace1d47f1 (diff)
downloadcups-7ec11630684301572cb7d19a95c244c104961a2a.tar.gz
Support the latest HTTP Digest authentication specification (Issue #4862)
Also deprecates all httpMD5* functions. - cgi-bin/var.c: Use cupsHashData to compute SID hash. - cups/auth.c: Rewrite WWW-Authenticate parser to support multiple auth schemes and the new RFC 7616 version of HTTP Digest. - cups/cups.h: Add cupsHashString function to get a hex version of a hash. - cups/hash.c: Add MD5 support. - cups/http.c: Track WWW-Authenticate in a long string, concatenate new set values. - cups/http.h: Deprecate httpMD5* and recommend cupsDoAuth and cupsHash*. - cups/http-private.h: Pull MD5 stuff, nonce_count is unsigned, track WWW-Authenticate header as a potentially long string. - cups/http-support.c: Use cupsHashData to compute UUID hash. - cups/md5.c: Comment everything out if we have an OS-supplied MD5 hash function. - cups/md5passwd.c: Use cupsHash* functions. - cups/tls-*.c: Use cupsHash* functions. - cups/versioning.h: Add CUPS_API_2_3 definition. - scheduler/client.c: Update WWW-Authenticate header to include AuthRef, Local, and PeerCred schemes with parameters as needed.
Diffstat (limited to 'cups/http.c')
-rw-r--r--cups/http.c61
1 files changed, 50 insertions, 11 deletions
diff --git a/cups/http.c b/cups/http.c
index 61b88c9db..4dd47865a 100644
--- a/cups/http.c
+++ b/cups/http.c
@@ -325,6 +325,12 @@ httpClearFields(http_t *http) /* I - HTTP connection */
http->server = NULL;
}
+ if (http->www_authenticate)
+ {
+ free(http->www_authenticate);
+ http->www_authenticate = NULL;
+ }
+
http->expect = (http_status_t)0;
}
}
@@ -973,12 +979,27 @@ httpGetField(http_t *http, /* I - HTTP connection */
if (http->field_authorization)
{
/*
- * Special case for WWW-Authenticate: as its contents can be
+ * Special case for Authorization: as its contents can be
* longer than HTTP_MAX_VALUE...
*/
return (http->field_authorization);
}
+ else
+ return (http->fields[field]);
+
+ case HTTP_FIELD_WWW_AUTHENTICATE :
+ if (http->www_authenticate)
+ {
+ /*
+ * Special case for WWW-Authenticate: as its contents can be
+ * longer than HTTP_MAX_VALUE...
+ */
+
+ return (http->www_authenticate);
+ }
+ else
+ return (http->fields[field]);
default :
return (http->fields[field]);
@@ -2683,17 +2704,35 @@ httpSetField(http_t *http, /* I - HTTP connection */
break;
case HTTP_FIELD_WWW_AUTHENTICATE :
- /* CUPS STR #4503 - don't override WWW-Authenticate for unknown auth schemes */
- if (http->fields[HTTP_FIELD_WWW_AUTHENTICATE][0] &&
- _cups_strncasecmp(value, "Basic ", 6) &&
- _cups_strncasecmp(value, "Digest ", 7) &&
- _cups_strncasecmp(value, "Negotiate ", 10))
- {
- DEBUG_printf(("1httpSetField: Ignoring unknown auth scheme in \"%s\".", value));
- return;
- }
+ if (!http->www_authenticate)
+ {
+ /*
+ * First WWW-Authenticate seen, just copy it over...
+ */
- /* Fall through to copy */
+ http->www_authenticate = strdup(value);
+ strlcpy(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], value, HTTP_MAX_VALUE);
+ }
+ else
+ {
+ /*
+ * Nth WWW-Authenticate seen, append to existing string...
+ */
+
+ size_t len = strlen(http->www_authenticate) + 2 + strlen(value) + 1;
+ char *temp = realloc(http->www_authenticate, len);
+
+ if (!temp)
+ return;
+
+ http->www_authenticate = temp;
+ strlcat(http->www_authenticate, ", ", len);
+ strlcat(http->www_authenticate, value, len);
+
+ /* Probably more efficient than two more strlcat's */
+ strlcpy(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], http->www_authenticate, HTTP_MAX_VALUE);
+ }
+ break;
default :
strlcpy(http->fields[field], value, HTTP_MAX_VALUE);