Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix negotiate authentication between CGIs and scheduler #19

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 17 additions & 11 deletions cups/auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ static void cups_gss_printf(OM_uint32 major_status, OM_uint32 minor_status,
# define cups_gss_printf(major, minor, message)
# endif /* DEBUG */
#endif /* HAVE_GSSAPI */
static int cups_is_local_connection(http_t *http);
static int cups_local_auth(http_t *http);


Expand Down Expand Up @@ -174,10 +175,10 @@ cupsDoAuthentication(
DEBUG_printf(("2cupsDoAuthentication: Trying scheme \"%s\"...", scheme));

#ifdef HAVE_GSSAPI
if (!_cups_strcasecmp(scheme, "Negotiate"))
if (!_cups_strcasecmp(scheme, "Negotiate") && !cups_is_local_connection(http))
{
/*
* Kerberos authentication...
* Kerberos authentication to remote server...
*/

int gss_status; /* Auth status */
Expand All @@ -201,7 +202,9 @@ cupsDoAuthentication(
}
else
#endif /* HAVE_GSSAPI */
if (_cups_strcasecmp(scheme, "Basic") && _cups_strcasecmp(scheme, "Digest"))
if (_cups_strcasecmp(scheme, "Basic") &&
_cups_strcasecmp(scheme, "Digest") &&
_cups_strcasecmp(scheme, "Negotiate"))
{
/*
* Other schemes not yet supported...
Expand All @@ -215,7 +218,7 @@ cupsDoAuthentication(
* See if we should retry the current username:password...
*/

if ((http->digest_tries > 1 || !http->userpass[0]) && (!_cups_strcasecmp(scheme, "Basic") || (!_cups_strcasecmp(scheme, "Digest"))))
if (http->digest_tries > 1 || !http->userpass[0])
{
/*
* Nope - get a new password from the user...
Expand Down Expand Up @@ -295,7 +298,7 @@ cupsDoAuthentication(
}
}

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

Expand Down Expand Up @@ -916,6 +919,14 @@ cups_gss_printf(OM_uint32 major_status,/* I - Major status code */
# endif /* DEBUG */
#endif /* HAVE_GSSAPI */

static int /* O - 0 if not a local connection */
/* 1 if local connection */
cups_is_local_connection(http_t *http) /* I - HTTP connection to server */
{
if (!httpAddrLocalhost(http->hostaddr) && _cups_strcasecmp(http->hostname, "localhost") != 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can probably just be:

return (httpAddLocalhost(http->hostaddr) || !_cups_strcasecmp(http->hostname, "localhost"));

return 0;
return 1;
}

/*
* 'cups_local_auth()' - Get the local authorization certificate if
Expand Down Expand Up @@ -958,7 +969,7 @@ cups_local_auth(http_t *http) /* I - HTTP connection to server */
* See if we are accessing localhost...
*/

if (!httpAddrLocalhost(http->hostaddr) && _cups_strcasecmp(http->hostname, "localhost") != 0)
if (!cups_is_local_connection(http))
{
DEBUG_puts("8cups_local_auth: Not a local connection!");
return (1);
Expand Down Expand Up @@ -1032,11 +1043,6 @@ cups_local_auth(http_t *http) /* I - HTTP connection to server */
}
# endif /* HAVE_AUTHORIZATION_H */

# ifdef HAVE_GSSAPI
if (cups_auth_find(www_auth, "Negotiate"))
return (1);
# endif /* HAVE_GSSAPI */

# if defined(SO_PEERCRED) && defined(AF_LOCAL)
/*
* See if we can authenticate using the peer credentials provided over a
Expand Down
9 changes: 2 additions & 7 deletions scheduler/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -2109,18 +2109,13 @@ cupsdSendHeader(
}
else if (auth_type == CUPSD_AUTH_NEGOTIATE)
{
#if defined(SO_PEERCRED) && defined(AF_LOCAL)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will break macOS clients. We never send Kerberos credentials over a domain socket for a native (IPP) client since we use the login UID to do authorization. Need to think about how this can be managed... :/

Copy link
Contributor Author

@scabrero scabrero Nov 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't aware how these changes can affect macOS.

The 'PeerCred' mech will still be in WWW-Authenticate string together with 'Negotiate' and 'Local', added just below:

https://github.com/scabrero/cups/blob/web-interface-negotiate-fix/scheduler/client.c#L2135

Then the cups_local_auth will work also for macOS because of this check:

 if (http->hostaddr->addr.sa_family == AF_LOCAL &&
      !getenv("GATEWAY_INTERFACE") &&	/* Not via CGI programs... */
      cups_auth_find(www_auth, "PeerCred"))
  {

if (httpAddrFamily(httpGetAddress(con->http)) == AF_LOCAL)
strlcpy(auth_str, "PeerCred", sizeof(auth_str));
else
#endif /* SO_PEERCRED && AF_LOCAL */
strlcpy(auth_str, "Negotiate", sizeof(auth_str));
}

if (con->best && auth_type != CUPSD_AUTH_NEGOTIATE && !con->is_browser && !_cups_strcasecmp(httpGetHostname(con->http, NULL, 0), "localhost"))
if (con->best && !con->is_browser && !_cups_strcasecmp(httpGetHostname(con->http, NULL, 0), "localhost"))
{
/*
* Add a "trc" (try root certification) parameter for local non-Kerberos
* Add a "trc" (try root certification) parameter for local
* requests when the request requires system group membership - then the
* client knows the root certificate can/should be used.
*
Expand Down