Blame SOURCES/cups-fips-compliance.patch

e33d6f
diff --git a/cups/cups.h b/cups/cups.h
e33d6f
index 8f5c818..9d8c3a3 100644
e33d6f
--- a/cups/cups.h
e33d6f
+++ b/cups/cups.h
e33d6f
@@ -606,6 +606,9 @@ extern ssize_t		cupsHashData(const char *algorithm, const void *data, size_t dat
e33d6f
 extern int		cupsAddIntegerOption(const char *name, int value, int num_options, cups_option_t **options) _CUPS_API_2_2_4;
e33d6f
 extern int		cupsGetIntegerOption(const char *name, int num_options, cups_option_t *options) _CUPS_API_2_2_4;
e33d6f
 
e33d6f
+/* New in CUPS 2.3 */
e33d6f
+extern const char	*cupsHashString(const unsigned char *hash, size_t hashsize, char *buffer, size_t bufsize);
e33d6f
+
e33d6f
 #  ifdef __cplusplus
e33d6f
 }
e33d6f
 #  endif /* __cplusplus */
e33d6f
diff --git a/cups/hash.c b/cups/hash.c
e33d6f
index ede5461..8ebe20b 100644
e33d6f
--- a/cups/hash.c
e33d6f
+++ b/cups/hash.c
e33d6f
@@ -21,6 +21,8 @@
e33d6f
 #  include <CommonCrypto/CommonDigest.h>
e33d6f
 #elif defined(HAVE_GNUTLS)
e33d6f
 #  include <gnutls/crypto.h>
e33d6f
+#else
e33d6f
+#  include "md5-private.h"
e33d6f
 #endif /* __APPLE__ */
e33d6f
 
e33d6f
 
e33d6f
@@ -171,7 +173,9 @@ cupsHashData(const char    *algorithm,	/* I - Algorithm name */
e33d6f
   unsigned char	temp[64];		/* Temporary hash buffer */
e33d6f
   size_t	tempsize = 0;		/* Truncate to this size? */
e33d6f
 
e33d6f
-  if (!strcmp(algorithm, "sha"))
e33d6f
+  if (!strcmp(algorithm, "md5"))
e33d6f
+    alg = GNUTLS_DIG_MD5;
e33d6f
+  else if (!strcmp(algorithm, "sha"))
e33d6f
     alg = GNUTLS_DIG_SHA1;
e33d6f
   else if (!strcmp(algorithm, "sha2-224"))
e33d6f
     alg = GNUTLS_DIG_SHA224;
e33d6f
@@ -219,10 +223,20 @@ cupsHashData(const char    *algorithm,	/* I - Algorithm name */
e33d6f
 
e33d6f
 #else
e33d6f
  /*
e33d6f
-  * No hash support without CommonCrypto or GNU TLS...
e33d6f
+  * No hash support beyond MD5 without CommonCrypto or GNU TLS...
e33d6f
   */
e33d6f
 
e33d6f
-  if (hashsize < 64)
e33d6f
+  if (!strcmp(algorithm, "md5"))
e33d6f
+  {
e33d6f
+    _cups_md5_state_t	state;		/* MD5 state info */
e33d6f
+
e33d6f
+    _cupsMD5Init(&state);
e33d6f
+    _cupsMD5Append(&state, data, datalen);
e33d6f
+    _cupsMD5Finish(&state, hash);
e33d6f
+
e33d6f
+    return (16);
e33d6f
+  }
e33d6f
+  else if (hashsize < 64)
e33d6f
     goto too_small;
e33d6f
 #endif /* __APPLE__ */
e33d6f
 
e33d6f
@@ -243,3 +257,51 @@ cupsHashData(const char    *algorithm,	/* I - Algorithm name */
e33d6f
   _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Hash buffer too small."), 1);
e33d6f
   return (-1);
e33d6f
 }
e33d6f
+
e33d6f
+
e33d6f
+/*
e33d6f
+ * 'cupsHashString()' - Format a hash value as a hexadecimal string.
e33d6f
+ *
e33d6f
+ * The passed buffer must be at least 2 * hashsize + 1 characters in length.
e33d6f
+ */
e33d6f
+
e33d6f
+const char *				/* O - Formatted string */
e33d6f
+cupsHashString(
e33d6f
+    const unsigned char *hash,		/* I - Hash */
e33d6f
+    size_t              hashsize,	/* I - Size of hash */
e33d6f
+    char                *buffer,	/* I - String buffer */
e33d6f
+    size_t		bufsize)	/* I - Size of string buffer */
e33d6f
+{
e33d6f
+  char		*bufptr = buffer;	/* Pointer into buffer */
e33d6f
+  static const char *hex = "0123456789abcdef";
e33d6f
+					/* Hex characters (lowercase!) */
e33d6f
+
e33d6f
+
e33d6f
+ /*
e33d6f
+  * Range check input...
e33d6f
+  */
e33d6f
+
e33d6f
+  if (!hash || hashsize < 1 || !buffer || bufsize < (2 * hashsize + 1))
e33d6f
+  {
e33d6f
+    if (buffer)
e33d6f
+      *buffer = '\0';
e33d6f
+    return (NULL);
e33d6f
+  }
e33d6f
+
e33d6f
+ /*
e33d6f
+  * Loop until we've converted the whole hash...
e33d6f
+  */
e33d6f
+
e33d6f
+  while (hashsize > 0)
e33d6f
+  {
e33d6f
+    *bufptr++ = hex[*hash >> 4];
e33d6f
+    *bufptr++ = hex[*hash & 15];
e33d6f
+
e33d6f
+    hash ++;
e33d6f
+    hashsize --;
e33d6f
+  }
e33d6f
+
e33d6f
+  *bufptr = '\0';
e33d6f
+
e33d6f
+  return (buffer);
e33d6f
+}
e33d6f
diff --git a/cups/md5passwd.c b/cups/md5passwd.c
e33d6f
index a9817aa..c9ffe04 100644
e33d6f
--- a/cups/md5passwd.c
e33d6f
+++ b/cups/md5passwd.c
e33d6f
@@ -17,6 +17,7 @@
e33d6f
  * Include necessary headers...
e33d6f
  */
e33d6f
 
e33d6f
+#include <cups/cups.h>
e33d6f
 #include "http-private.h"
e33d6f
 #include "string-private.h"
e33d6f
 
e33d6f
@@ -31,7 +32,6 @@ httpMD5(const char *username,		/* I - User name */
e33d6f
         const char *passwd,		/* I - Password string */
e33d6f
 	char       md5[33])		/* O - MD5 string */
e33d6f
 {
e33d6f
-  _cups_md5_state_t	state;		/* MD5 state info */
e33d6f
   unsigned char		sum[16];	/* Sum data */
e33d6f
   char			line[256];	/* Line to sum */
e33d6f
 
e33d6f
@@ -41,15 +41,13 @@ httpMD5(const char *username,		/* I - User name */
e33d6f
   */
e33d6f
 
e33d6f
   snprintf(line, sizeof(line), "%s:%s:%s", username, realm, passwd);
e33d6f
-  _cupsMD5Init(&state);
e33d6f
-  _cupsMD5Append(&state, (unsigned char *)line, (int)strlen(line));
e33d6f
-  _cupsMD5Finish(&state, sum);
e33d6f
+  cupsHashData("md5", (unsigned char *)line, strlen(line), sum, sizeof(sum));
e33d6f
 
e33d6f
  /*
e33d6f
   * Return the sum...
e33d6f
   */
e33d6f
 
e33d6f
-  return (httpMD5String(sum, md5));
e33d6f
+  return ((char *)cupsHashString(sum, sizeof(sum), md5, 33));
e33d6f
 }
e33d6f
 
e33d6f
 
e33d6f
@@ -65,7 +63,6 @@ httpMD5Final(const char *nonce,		/* I - Server nonce value */
e33d6f
 	     const char *resource,	/* I - Resource path */
e33d6f
              char       md5[33])	/* IO - MD5 sum */
e33d6f
 {
e33d6f
-  _cups_md5_state_t	state;		/* MD5 state info */
e33d6f
   unsigned char		sum[16];	/* Sum data */
e33d6f
   char			line[1024];	/* Line of data */
e33d6f
   char			a2[33];		/* Hash of method and resource */
e33d6f
@@ -76,9 +73,7 @@ httpMD5Final(const char *nonce,		/* I - Server nonce value */
e33d6f
   */
e33d6f
 
e33d6f
   snprintf(line, sizeof(line), "%s:%s", method, resource);
e33d6f
-  _cupsMD5Init(&state);
e33d6f
-  _cupsMD5Append(&state, (unsigned char *)line, (int)strlen(line));
e33d6f
-  _cupsMD5Finish(&state, sum);
e33d6f
+  cupsHashData("md5", (unsigned char *)line, strlen(line), sum, sizeof(sum));
e33d6f
   httpMD5String(sum, a2);
e33d6f
 
e33d6f
  /*
e33d6f
@@ -88,12 +83,9 @@ httpMD5Final(const char *nonce,		/* I - Server nonce value */
e33d6f
   */
e33d6f
 
e33d6f
   snprintf(line, sizeof(line), "%s:%s:%s", md5, nonce, a2);
e33d6f
+  cupsHashData("md5", (unsigned char *)line, strlen(line), sum, sizeof(sum));
e33d6f
 
e33d6f
-  _cupsMD5Init(&state);
e33d6f
-  _cupsMD5Append(&state, (unsigned char *)line, (int)strlen(line));
e33d6f
-  _cupsMD5Finish(&state, sum);
e33d6f
-
e33d6f
-  return (httpMD5String(sum, md5));
e33d6f
+  return ((char *)cupsHashString(sum, sizeof(sum), md5, 33));
e33d6f
 }
e33d6f
 
e33d6f
 
e33d6f
@@ -106,23 +98,5 @@ httpMD5String(const unsigned char *sum,	/* I - MD5 sum data */
e33d6f
               char                md5[33])
e33d6f
 					/* O - MD5 sum in hex */
e33d6f
 {
e33d6f
-  int		i;			/* Looping var */
e33d6f
-  char		*md5ptr;		/* Pointer into MD5 string */
e33d6f
-  static const char hex[] = "0123456789abcdef";
e33d6f
-					/* Hex digits */
e33d6f
-
e33d6f
-
e33d6f
- /*
e33d6f
-  * Convert the MD5 sum to hexadecimal...
e33d6f
-  */
e33d6f
-
e33d6f
-  for (i = 16, md5ptr = md5; i > 0; i --, sum ++)
e33d6f
-  {
e33d6f
-    *md5ptr++ = hex[*sum >> 4];
e33d6f
-    *md5ptr++ = hex[*sum & 15];
e33d6f
-  }
e33d6f
-
e33d6f
-  *md5ptr = '\0';
e33d6f
-
e33d6f
-  return (md5);
e33d6f
+  return ((char *)cupsHashString(sum, 16, md5, 33));
e33d6f
 }
e33d6f
diff --git a/scheduler/auth.c b/scheduler/auth.c
e33d6f
index 71df9dc..e7d0006 100644
e33d6f
--- a/scheduler/auth.c
e33d6f
+++ b/scheduler/auth.c
e33d6f
@@ -72,9 +72,6 @@ static int		check_authref(cupsd_client_t *con, const char *right);
e33d6f
 static int		compare_locations(cupsd_location_t *a,
e33d6f
 			                  cupsd_location_t *b);
e33d6f
 static cupsd_authmask_t	*copy_authmask(cupsd_authmask_t *am, void *data);
e33d6f
-#if !HAVE_LIBPAM
e33d6f
-static char		*cups_crypt(const char *pw, const char *salt);
e33d6f
-#endif /* !HAVE_LIBPAM */
e33d6f
 static void		free_authmask(cupsd_authmask_t *am, void *data);
e33d6f
 #if HAVE_LIBPAM
e33d6f
 static int		pam_func(int, const struct pam_message **,
e33d6f
@@ -695,14 +692,14 @@ cupsdAuthorize(cupsd_client_t *con)	/* I - Client connection */
e33d6f
 	    * client...
e33d6f
 	    */
e33d6f
 
e33d6f
-	    pass = cups_crypt(password, pw->pw_passwd);
e33d6f
+	    pass = crypt(password, pw->pw_passwd);
e33d6f
 
e33d6f
 	    if (!pass || strcmp(pw->pw_passwd, pass))
e33d6f
 	    {
e33d6f
 #  ifdef HAVE_SHADOW_H
e33d6f
 	      if (spw)
e33d6f
 	      {
e33d6f
-		pass = cups_crypt(password, spw->sp_pwdp);
e33d6f
+		pass = crypt(password, spw->sp_pwdp);
e33d6f
 
e33d6f
 		if (pass == NULL || strcmp(spw->sp_pwdp, pass))
e33d6f
 		{
e33d6f
@@ -1988,129 +1985,6 @@ copy_authmask(cupsd_authmask_t *mask,	/* I - Existing auth mask */
e33d6f
 }
e33d6f
 
e33d6f
 
e33d6f
-#if !HAVE_LIBPAM
e33d6f
-/*
e33d6f
- * 'cups_crypt()' - Encrypt the password using the DES or MD5 algorithms,
e33d6f
- *                  as needed.
e33d6f
- */
e33d6f
-
e33d6f
-static char *				/* O - Encrypted password */
e33d6f
-cups_crypt(const char *pw,		/* I - Password string */
e33d6f
-           const char *salt)		/* I - Salt (key) string */
e33d6f
-{
e33d6f
-  if (!strncmp(salt, "$1$", 3))
e33d6f
-  {
e33d6f
-   /*
e33d6f
-    * Use MD5 passwords without the benefit of PAM; this is for
e33d6f
-    * Slackware Linux, and the algorithm was taken from the
e33d6f
-    * old shadow-19990827/lib/md5crypt.c source code... :(
e33d6f
-    */
e33d6f
-
e33d6f
-    int			i;		/* Looping var */
e33d6f
-    unsigned long	n;		/* Output number */
e33d6f
-    int			pwlen;		/* Length of password string */
e33d6f
-    const char		*salt_end;	/* End of "salt" data for MD5 */
e33d6f
-    char		*ptr;		/* Pointer into result string */
e33d6f
-    _cups_md5_state_t	state;		/* Primary MD5 state info */
e33d6f
-    _cups_md5_state_t	state2;		/* Secondary MD5 state info */
e33d6f
-    unsigned char	digest[16];	/* MD5 digest result */
e33d6f
-    static char		result[120];	/* Final password string */
e33d6f
-
e33d6f
-
e33d6f
-   /*
e33d6f
-    * Get the salt data between dollar signs, e.g. $1$saltdata$md5.
e33d6f
-    * Get a maximum of 8 characters of salt data after $1$...
e33d6f
-    */
e33d6f
-
e33d6f
-    for (salt_end = salt + 3; *salt_end && (salt_end - salt) < 11; salt_end ++)
e33d6f
-      if (*salt_end == '$')
e33d6f
-        break;
e33d6f
-
e33d6f
-   /*
e33d6f
-    * Compute the MD5 sum we need...
e33d6f
-    */
e33d6f
-
e33d6f
-    pwlen = strlen(pw);
e33d6f
-
e33d6f
-    _cupsMD5Init(&state);
e33d6f
-    _cupsMD5Append(&state, (unsigned char *)pw, pwlen);
e33d6f
-    _cupsMD5Append(&state, (unsigned char *)salt, salt_end - salt);
e33d6f
-
e33d6f
-    _cupsMD5Init(&state2);
e33d6f
-    _cupsMD5Append(&state2, (unsigned char *)pw, pwlen);
e33d6f
-    _cupsMD5Append(&state2, (unsigned char *)salt + 3, salt_end - salt - 3);
e33d6f
-    _cupsMD5Append(&state2, (unsigned char *)pw, pwlen);
e33d6f
-    _cupsMD5Finish(&state2, digest);
e33d6f
-
e33d6f
-    for (i = pwlen; i > 0; i -= 16)
e33d6f
-      _cupsMD5Append(&state, digest, i > 16 ? 16 : i);
e33d6f
-
e33d6f
-    for (i = pwlen; i > 0; i >>= 1)
e33d6f
-      _cupsMD5Append(&state, (unsigned char *)((i & 1) ? "" : pw), 1);
e33d6f
-
e33d6f
-    _cupsMD5Finish(&state, digest);
e33d6f
-
e33d6f
-    for (i = 0; i < 1000; i ++)
e33d6f
-    {
e33d6f
-      _cupsMD5Init(&state);
e33d6f
-
e33d6f
-      if (i & 1)
e33d6f
-        _cupsMD5Append(&state, (unsigned char *)pw, pwlen);
e33d6f
-      else
e33d6f
-        _cupsMD5Append(&state, digest, 16);
e33d6f
-
e33d6f
-      if (i % 3)
e33d6f
-        _cupsMD5Append(&state, (unsigned char *)salt + 3, salt_end - salt - 3);
e33d6f
-
e33d6f
-      if (i % 7)
e33d6f
-        _cupsMD5Append(&state, (unsigned char *)pw, pwlen);
e33d6f
-
e33d6f
-      if (i & 1)
e33d6f
-        _cupsMD5Append(&state, digest, 16);
e33d6f
-      else
e33d6f
-        _cupsMD5Append(&state, (unsigned char *)pw, pwlen);
e33d6f
-
e33d6f
-      _cupsMD5Finish(&state, digest);
e33d6f
-    }
e33d6f
-
e33d6f
-   /*
e33d6f
-    * Copy the final sum to the result string and return...
e33d6f
-    */
e33d6f
-
e33d6f
-    memcpy(result, salt, (size_t)(salt_end - salt));
e33d6f
-    ptr = result + (salt_end - salt);
e33d6f
-    *ptr++ = '$';
e33d6f
-
e33d6f
-    for (i = 0; i < 5; i ++, ptr += 4)
e33d6f
-    {
e33d6f
-      n = ((((unsigned)digest[i] << 8) | (unsigned)digest[i + 6]) << 8);
e33d6f
-
e33d6f
-      if (i < 4)
e33d6f
-        n |= (unsigned)digest[i + 12];
e33d6f
-      else
e33d6f
-        n |= (unsigned)digest[5];
e33d6f
-
e33d6f
-      to64(ptr, n, 4);
e33d6f
-    }
e33d6f
-
e33d6f
-    to64(ptr, (unsigned)digest[11], 2);
e33d6f
-    ptr += 2;
e33d6f
-    *ptr = '\0';
e33d6f
-
e33d6f
-    return (result);
e33d6f
-  }
e33d6f
-  else
e33d6f
-  {
e33d6f
-   /*
e33d6f
-    * Use the standard crypt() function...
e33d6f
-    */
e33d6f
-
e33d6f
-    return (crypt(pw, salt));
e33d6f
-  }
e33d6f
-}
e33d6f
-#endif /* !HAVE_LIBPAM */
e33d6f
-
e33d6f
-
e33d6f
 /*
e33d6f
  * 'free_authmask()' - Free function for auth masks.
e33d6f
  */