diff options
Diffstat (limited to 'cups/getputfile.c')
-rw-r--r-- | cups/getputfile.c | 70 |
1 files changed, 65 insertions, 5 deletions
diff --git a/cups/getputfile.c b/cups/getputfile.c index ae33bc59..7749ae0a 100644 --- a/cups/getputfile.c +++ b/cups/getputfile.c @@ -1,7 +1,7 @@ /* * Get/put file functions for CUPS. * - * Copyright 2007-2014 by Apple Inc. + * Copyright 2007-2018 by Apple Inc. * Copyright 1997-2006 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -20,11 +20,11 @@ #include "cups-private.h" #include <fcntl.h> #include <sys/stat.h> -#if defined(WIN32) || defined(__EMX__) +#if defined(_WIN32) || defined(__EMX__) # include <io.h> #else # include <unistd.h> -#endif /* WIN32 || __EMX__ */ +#endif /* _WIN32 || __EMX__ */ /* @@ -45,6 +45,8 @@ cupsGetFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA http_status_t status; /* HTTP status from server */ char if_modified_since[HTTP_MAX_VALUE]; /* If-Modified-Since header */ + int new_auth = 0; /* Using new auth information? */ + int digest; /* Are we using Digest authentication? */ /* @@ -85,9 +87,33 @@ cupsGetFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA } httpClearFields(http); - httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring); httpSetField(http, HTTP_FIELD_IF_MODIFIED_SINCE, if_modified_since); + digest = http->authstring && !strncmp(http->authstring, "Digest ", 7); + + if (digest && !new_auth) + { + /* + * Update the Digest authentication string... + */ + + _httpSetDigestAuthString(http, http->nextnonce, "GET", resource); + } + +#ifdef HAVE_GSSAPI + if (http->authstring && !strncmp(http->authstring, "Negotiate", 9) && !new_auth) + { + /* + * Do not use cached Kerberos credentials since they will look like a + * "replay" attack... + */ + + _cupsSetNegotiateAuthString(http, "GET", resource); + } +#endif /* HAVE_GSSAPI */ + + httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring); + if (httpGet(http, resource)) { if (httpReconnect2(http, 30000, NULL)) @@ -102,6 +128,8 @@ cupsGetFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA } } + new_auth = 0; + while ((status = httpUpdate(http)) == HTTP_STATUS_CONTINUE); if (status == HTTP_STATUS_UNAUTHORIZED) @@ -116,6 +144,8 @@ cupsGetFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA * See if we can do authentication... */ + new_auth = 1; + if (cupsDoAuthentication(http, "GET", resource)) { status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; @@ -267,6 +297,8 @@ cupsPutFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA int retries; /* Number of retries */ char buffer[8192]; /* Buffer for file */ http_status_t status; /* HTTP status from server */ + int new_auth = 0; /* Using new auth information? */ + int digest; /* Are we using Digest authentication? */ /* @@ -309,10 +341,34 @@ cupsPutFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA http->authstring)); httpClearFields(http); - httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring); httpSetField(http, HTTP_FIELD_TRANSFER_ENCODING, "chunked"); httpSetExpect(http, HTTP_STATUS_CONTINUE); + digest = http->authstring && !strncmp(http->authstring, "Digest ", 7); + + if (digest && !new_auth) + { + /* + * Update the Digest authentication string... + */ + + _httpSetDigestAuthString(http, http->nextnonce, "PUT", resource); + } + +#ifdef HAVE_GSSAPI + if (http->authstring && !strncmp(http->authstring, "Negotiate", 9) && !new_auth) + { + /* + * Do not use cached Kerberos credentials since they will look like a + * "replay" attack... + */ + + _cupsSetNegotiateAuthString(http, "PUT", resource); + } +#endif /* HAVE_GSSAPI */ + + httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring); + if (httpPut(http, resource)) { if (httpReconnect2(http, 30000, NULL)) @@ -383,6 +439,8 @@ cupsPutFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA DEBUG_printf(("2cupsPutFd: status=%d", status)); + new_auth = 0; + if (status == HTTP_STATUS_UNAUTHORIZED) { /* @@ -395,6 +453,8 @@ cupsPutFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFA * See if we can do authentication... */ + new_auth = 1; + if (cupsDoAuthentication(http, "PUT", resource)) { status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; |