Skip to content

Commit

Permalink
Non-Kerberized IPP printing to Windows was broken (Issue #5515)
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelrsweet committed Feb 15, 2019
1 parent 019198b commit bafbb26
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 19 deletions.
3 changes: 2 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
CHANGES - 2.2.11 - 2019-02-05
CHANGES - 2.2.11 - 2019-02-15
=============================


Expand All @@ -20,6 +20,7 @@ Changes in CUPS v2.2.11
(Issue #5506)
- The `ippValidateAttribute` function did not catch all instances of invalid
UTF-8 strings (Issue #5509)
- Non-Kerberized printing to Windows via IPP was broken (Issue #5515)
- Fixed a potential crash bug in cups-driverd (rdar://46625579)
- Fixed a performance regression with large PPDs (rdar://47040759)

Expand Down
72 changes: 54 additions & 18 deletions cups/auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ static const char *cups_auth_param(const char *scheme, const char *name, char *v
static const char *cups_auth_scheme(const char *www_authenticate, char *scheme, size_t schemesize);

#ifdef HAVE_GSSAPI
# define CUPS_GSS_OK 0 /* Successfully set credentials */
# define CUPS_GSS_NONE -1 /* No credentials */
# define CUPS_GSS_FAIL -2 /* Failed credentials/authentication */
# ifdef HAVE_GSS_ACQUIRE_CRED_EX_F
# ifdef HAVE_GSS_GSSAPI_SPI_H
# include <GSS/gssapi_spi.h>
Expand Down Expand Up @@ -178,25 +181,45 @@ cupsDoAuthentication(
* Check the scheme name...
*/

DEBUG_printf(("2cupsDoAuthentication: Trying scheme \"%s\"...", scheme));

#ifdef HAVE_GSSAPI
if (!_cups_strcasecmp(scheme, "Negotiate"))
{
/*
* Kerberos authentication...
*/

if (_cupsSetNegotiateAuthString(http, method, resource))
int gss_status; /* Auth status */

if ((gss_status = _cupsSetNegotiateAuthString(http, method, resource)) == CUPS_GSS_FAIL)
{
DEBUG_puts("1cupsDoAuthentication: Negotiate failed.");
http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED;
return (-1);
}

break;
else if (gss_status == CUPS_GSS_NONE)
{
DEBUG_puts("2cupsDoAuthentication: No credentials for Negotiate.");
continue;
}
else
{
DEBUG_puts("2cupsDoAuthentication: Using Negotiate.");
break;
}
}
else
#endif /* HAVE_GSSAPI */
if (_cups_strcasecmp(scheme, "Basic") && _cups_strcasecmp(scheme, "Digest"))
continue; /* Not supported (yet) */
{
/*
* Other schemes not yet supported...
*/

DEBUG_printf(("2cupsDoAuthentication: Scheme \"%s\" not yet supported.", scheme));
continue;
}

/*
* See if we should retry the current username:password...
Expand Down Expand Up @@ -226,6 +249,7 @@ cupsDoAuthentication(

if ((password = cupsGetPassword2(prompt, http, method, resource)) == NULL)
{
DEBUG_puts("1cupsDoAuthentication: User canceled password request.");
http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED;
return (-1);
}
Expand Down Expand Up @@ -255,6 +279,7 @@ cupsDoAuthentication(

char encode[256]; /* Base64 buffer */

DEBUG_puts("2cupsDoAuthentication: Using Basic.");
httpEncode64_2(encode, sizeof(encode), http->userpass, (int)strlen(http->userpass));
httpSetAuthString(http, "Basic", encode);
break;
Expand All @@ -273,19 +298,22 @@ cupsDoAuthentication(
cups_auth_param(schemedata, "realm", http->realm, sizeof(http->realm));

if (_httpSetDigestAuthString(http, nonce, method, resource))
{
DEBUG_puts("2cupsDoAuthentication: Using Basic.");
break;
}
}
}

if (http->authstring)
{
DEBUG_printf(("1cupsDoAuthentication: authstring=\"%s\"", http->authstring));
DEBUG_printf(("1cupsDoAuthentication: authstring=\"%s\".", http->authstring));

return (0);
}
else
{
DEBUG_printf(("1cupsDoAuthentication: Unknown auth type: \"%s\"", www_auth));
DEBUG_puts("1cupsDoAuthentication: No supported schemes.");
http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED;

return (-1);
Expand All @@ -298,7 +326,7 @@ cupsDoAuthentication(
* '_cupsSetNegotiateAuthString()' - Set the Kerberos authentication string.
*/

int /* O - 0 on success, -1 on error */
int /* O - 0 on success, negative on error */
_cupsSetNegotiateAuthString(
http_t *http, /* I - Connection to server */
const char *method, /* I - Request method ("GET", "POST", "PUT") */
Expand All @@ -323,10 +351,16 @@ _cupsSetNegotiateAuthString(
{
DEBUG_puts("1_cupsSetNegotiateAuthString: Weak-linked GSSAPI/Kerberos "
"framework is not present");
return (-1);
return (CUPS_GSS_NONE);
}
# endif /* __APPLE__ */

if (!strcmp(http->hostname, "localhost") || http->hostname[0] == '/' || isdigit(http->hostname[0] & 255) || !strchr(http->hostname, '.'))
{
DEBUG_printf(("1_cupsSetNegotiateAuthString: Kerberos not available for host \"%s\".", http->hostname));
return (CUPS_GSS_NONE);
}

if (http->gssname == GSS_C_NO_NAME)
{
http->gssname = cups_gss_getname(http, _cupsGSSServiceName());
Expand Down Expand Up @@ -371,7 +405,7 @@ _cupsSetNegotiateAuthString(
cupsUser(), http->gsshost);

if ((password = cupsGetPassword2(prompt, http, method, resource)) == NULL)
return (-1);
return (CUPS_GSS_FAIL);

/*
* Try to acquire credentials...
Expand Down Expand Up @@ -425,18 +459,20 @@ _cupsSetNegotiateAuthString(
}
# endif /* HAVE_GSS_ACQUIRED_CRED_EX_F */

if (GSS_ERROR(major_status))
if (major_status == GSS_S_NO_CRED)
{
cups_gss_printf(major_status, minor_status,
"_cupsSetNegotiateAuthString: Unable to initialize "
"security context");
return (-1);
cups_gss_printf(major_status, minor_status, "_cupsSetNegotiateAuthString: No credentials");
return (CUPS_GSS_NONE);
}
else if (GSS_ERROR(major_status))
{
cups_gss_printf(major_status, minor_status, "_cupsSetNegotiateAuthString: Unable to initialize security context");
return (CUPS_GSS_FAIL);
}

# ifdef DEBUG
else if (major_status == GSS_S_CONTINUE_NEEDED)
cups_gss_printf(major_status, minor_status,
"_cupsSetNegotiateAuthString: Continuation needed!");
cups_gss_printf(major_status, minor_status, "_cupsSetNegotiateAuthString: Continuation needed");
# endif /* DEBUG */

if (output_token.length > 0 && output_token.length <= 65536)
Expand Down Expand Up @@ -470,10 +506,10 @@ _cupsSetNegotiateAuthString(
"large - %d bytes!", (int)output_token.length));
gss_release_buffer(&minor_status, &output_token);

return (-1);
return (CUPS_GSS_FAIL);
}

return (0);
return (CUPS_GSS_OK);
}
#endif /* HAVE_GSSAPI */

Expand Down

0 comments on commit bafbb26

Please sign in to comment.