]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Non-Kerberized IPP printing to Windows was broken (Issue #5515)
authorMichael R Sweet <michael.r.sweet@gmail.com>
Fri, 15 Feb 2019 22:07:10 +0000 (17:07 -0500)
committerMichael R Sweet <michael.r.sweet@gmail.com>
Fri, 15 Feb 2019 22:07:10 +0000 (17:07 -0500)
CHANGES.md
cups/auth.c

index fefebe0d88a55f12773fc8484cffc38cec2425db..9d0aa5aeb0e01fe6a5620dc2b40f15dd0ccff06c 100644 (file)
@@ -1,4 +1,4 @@
-CHANGES - 2.2.11 - 2019-02-05
+CHANGES - 2.2.11 - 2019-02-15
 =============================
 
 
@@ -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)
 
index e4328e025bad91e72c3c338d67631becb81733b2..a91b0dbe4a8345ba62901692866e56eabc729eb9 100644 (file)
@@ -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>
@@ -178,6 +181,8 @@ cupsDoAuthentication(
     * Check the scheme name...
     */
 
+    DEBUG_printf(("2cupsDoAuthentication: Trying scheme \"%s\"...", scheme));
+
 #ifdef HAVE_GSSAPI
     if (!_cups_strcasecmp(scheme, "Negotiate"))
     {
@@ -185,18 +190,36 @@ cupsDoAuthentication(
       * 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...
@@ -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);
       }
@@ -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;
@@ -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);
@@ -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") */
@@ -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());
@@ -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...
@@ -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)
@@ -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 */