File 0003-use-crypt_gensalt_rn-from-glibc.diff of Package pam-modules

From 97692d668c87cf67a80e4e89cf0984924bb276f7 Mon Sep 17 00:00:00 2001
From: Ludwig Nussel <ludwig.nussel@suse.de>
Date: Wed, 6 Jul 2011 10:21:04 +0200
Subject: [PATCH 3/4] use crypt_gensalt_rn from glibc

---
 src/Makefile.am     |    2 +-
 src/crypt_gensalt.c |  375 ---------------------------------------------------
 src/unix_passwd.c   |    8 +-
 3 files changed, 3 insertions(+), 382 deletions(-)
 delete mode 100644 src/crypt_gensalt.c

Index: pam_unix2-2.9.1/src/Makefile.am
===================================================================
--- pam_unix2-2.9.1.orig/src/Makefile.am
+++ pam_unix2-2.9.1/src/Makefile.am
@@ -20,9 +20,10 @@ pam_PROGRAMS = pam_unix2.so
 
 pam_unix2_so_LDFLAGS = -Wl,-soname,pam_unix2.so \
 	-Wl,--version-script=$(srcdir)/pam_unix2.map
+pam_unix2_so_LDADD = -lowcrypt
 
 pam_unix2_so_SOURCES = passwd_nss.c unix_acct.c get_options.c \
 	unix_passwd.c yppasswd_xdr.c support.c \
 	unix_auth.c unix_sess.c read-files.c getuser.c copy_xattr.c \
-	selinux_utils.c logindefs.c crypt_gensalt.c
+	selinux_utils.c logindefs.c
 
Index: pam_unix2-2.9.1/src/crypt_gensalt.c
===================================================================
--- pam_unix2-2.9.1.orig/src/crypt_gensalt.c
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * Written by Solar Designer and placed in the public domain.
- * See crypt_blowfish.c for more information.
- *
- * This file contains salt generation functions for the traditional and
- * other common crypt(3) algorithms, except for bcrypt which is defined
- * entirely in crypt_blowfish.c.
- */
-
-
-#if defined(HAVE_CONFIG_H)
-#include "config.h"
-#endif
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <errno.h>
-#ifndef __set_errno
-#define __set_errno(val) errno = (val)
-#endif
-
-#undef __CONST
-#ifdef __GNUC__
-#define __CONST __const
-#else
-#define __CONST
-#endif
-
-static unsigned char _xcrypt_itoa64[64 + 1] =
-	"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-
-static char *_xcrypt_gensalt_traditional_rn(unsigned long count,
-	__CONST char *input, int size, char *output, int output_size)
-{
-	if (size < 2 || output_size < 2 + 1 || (count && count != 25)) {
-		if (output_size > 0) output[0] = '\0';
-		__set_errno((output_size < 2 + 1) ? ERANGE : EINVAL);
-		return NULL;
-	}
-
-	output[0] = _xcrypt_itoa64[(unsigned int)input[0] & 0x3f];
-	output[1] = _xcrypt_itoa64[(unsigned int)input[1] & 0x3f];
-	output[2] = '\0';
-
-	return output;
-}
-
-static char *_xcrypt_gensalt_extended_rn(unsigned long count,
-	__CONST char *input, int size, char *output, int output_size)
-{
-	unsigned long value;
-
-/* Even iteration counts make it easier to detect weak DES keys from a look
- * at the hash, so they should be avoided */
-	if (size < 3 || output_size < 1 + 4 + 4 + 1 ||
-	    (count && (count > 0xffffff || !(count & 1)))) {
-		if (output_size > 0) output[0] = '\0';
-		__set_errno((output_size < 1 + 4 + 4 + 1) ? ERANGE : EINVAL);
-		return NULL;
-	}
-
-	if (!count) count = 725;
-
-	output[0] = '_';
-	output[1] = _xcrypt_itoa64[count & 0x3f];
-	output[2] = _xcrypt_itoa64[(count >> 6) & 0x3f];
-	output[3] = _xcrypt_itoa64[(count >> 12) & 0x3f];
-	output[4] = _xcrypt_itoa64[(count >> 18) & 0x3f];
-	value = (unsigned long)(unsigned char)input[0] |
-		((unsigned long)(unsigned char)input[1] << 8) |
-		((unsigned long)(unsigned char)input[2] << 16);
-	output[5] = _xcrypt_itoa64[value & 0x3f];
-	output[6] = _xcrypt_itoa64[(value >> 6) & 0x3f];
-	output[7] = _xcrypt_itoa64[(value >> 12) & 0x3f];
-	output[8] = _xcrypt_itoa64[(value >> 18) & 0x3f];
-	output[9] = '\0';
-
-	return output;
-}
-
-static char *
-_xcrypt_gensalt_md5_rn (unsigned long count __attribute__((unused)),
-			const char *input, int size,
-			char *output, int output_size)
-{
-  unsigned long value;
-
-  if (size < 3 || output_size < 3 + 4 + 1)
-    {
-      if (output_size > 0)
-	output[0] = '\0';
-      errno = ERANGE;
-      return NULL;
-    }
-
-  output[0] = '$';
-  output[1] = '1';
-  output[2] = '$';
-  value = (unsigned long)(unsigned char)input[0] |
-    ((unsigned long)(unsigned char)input[1] << 8) |
-    ((unsigned long)(unsigned char)input[2] << 16);
-  output[3] = _xcrypt_itoa64[value & 0x3f];
-  output[4] = _xcrypt_itoa64[(value >> 6) & 0x3f];
-  output[5] = _xcrypt_itoa64[(value >> 12) & 0x3f];
-  output[6] = _xcrypt_itoa64[(value >> 18) & 0x3f];
-  output[7] = '\0';
-
-  if (size >= 6 && output_size >= 3 + 4 + 4 + 1) {
-    value = (unsigned long)(unsigned char)input[3] |
-      ((unsigned long)(unsigned char)input[4] << 8) |
-      ((unsigned long)(unsigned char)input[5] << 16);
-    output[7] = _xcrypt_itoa64[value & 0x3f];
-    output[8] = _xcrypt_itoa64[(value >> 6) & 0x3f];
-    output[9] = _xcrypt_itoa64[(value >> 12) & 0x3f];
-    output[10] = _xcrypt_itoa64[(value >> 18) & 0x3f];
-    output[11] = '\0';
-  }
-
-  return output;
-}
-
-static char *
-_xcrypt_gensalt_sha256_rn (unsigned long count, const char *input, int size,
-			   char *output, int output_size)
-{
-  unsigned long value;
-  char *buf;
-  char buf2[12];
-
-  if (count > 0)
-    {
-      if (asprintf (&buf, "$5$rounds=%ld$", count) < 0)
-	{
-	  if (output_size > 0)
-	    output[0] = '\0';
-	  errno = ENOMEM;
-	  return NULL;
-	}
-    }
-  else
-    {
-      if (asprintf (&buf, "$5$") < 0)
-	{
-	  if (output_size > 0)
-	    output[0] = '\0';
-	  errno = ENOMEM;
-	  return NULL;
-	}
-    }
-
-  if (size < 3 || output_size < (int)strlen (buf) + 4 + 1)
-    {
-      free (buf);
-      if (output_size > 0)
-	output[0] = '\0';
-      errno = ERANGE;
-      return NULL;
-    }
-
-  value = (unsigned long)(unsigned char)input[0] |
-    ((unsigned long)(unsigned char)input[1] << 8) |
-    ((unsigned long)(unsigned char)input[2] << 16);
-  buf2[0] = _xcrypt_itoa64[value & 0x3f];
-  buf2[1] = _xcrypt_itoa64[(value >> 6) & 0x3f];
-  buf2[2] = _xcrypt_itoa64[(value >> 12) & 0x3f];
-  buf2[3] = _xcrypt_itoa64[(value >> 18) & 0x3f];
-  buf2[4] = '\0';
-
-  if (size >= 6 && output_size >= (int)strlen (buf) + 4 + 4 + 1)
-    {
-      value = (unsigned long)(unsigned char)input[3] |
-	((unsigned long)(unsigned char)input[4] << 8) |
-	((unsigned long)(unsigned char)input[5] << 16);
-      buf2[4] = _xcrypt_itoa64[value & 0x3f];
-      buf2[5] = _xcrypt_itoa64[(value >> 6) & 0x3f];
-      buf2[6] = _xcrypt_itoa64[(value >> 12) & 0x3f];
-      buf2[7] = _xcrypt_itoa64[(value >> 18) & 0x3f];
-      buf2[8] = '\0';
-    }
-
-  snprintf (output, output_size, "%s%s", buf, buf2);
-  free (buf);
-
-  return output;
-}
-
-static char *
-_xcrypt_gensalt_sha512_rn (unsigned long count, const char *input, int size,
-			   char *output, int output_size)
-{
-  unsigned long value;
-  char *buf;
-  char buf2[12];
-
-  if (count > 0)
-    {
-      if (asprintf (&buf, "$6$rounds=%ld$", count) < 0)
-	{
-	  if (output_size > 0)
-	    output[0] = '\0';
-	  errno = ENOMEM;
-	  return NULL;
-	}
-    }
-  else
-    {
-      if (asprintf (&buf, "$6$") < 0)
-	{
-	  if (output_size > 0)
-	    output[0] = '\0';
-	  errno = ENOMEM;
-	  return NULL;
-	}
-    }
-
-  if (size < 3 || output_size < (int)strlen (buf) + 4 + 1)
-    {
-      free (buf);
-      if (output_size > 0)
-	output[0] = '\0';
-      __set_errno(ERANGE);
-      return NULL;
-    }
-
-  value = (unsigned long)(unsigned char)input[0] |
-    ((unsigned long)(unsigned char)input[1] << 8) |
-    ((unsigned long)(unsigned char)input[2] << 16);
-  buf2[0] = _xcrypt_itoa64[value & 0x3f];
-  buf2[1] = _xcrypt_itoa64[(value >> 6) & 0x3f];
-  buf2[2] = _xcrypt_itoa64[(value >> 12) & 0x3f];
-  buf2[3] = _xcrypt_itoa64[(value >> 18) & 0x3f];
-  buf2[4] = '\0';
-
-  if (size >= 6 && output_size >= (int)strlen (buf) + 4 + 4 + 1)
-    {
-      value = (unsigned long)(unsigned char)input[3] |
-	((unsigned long)(unsigned char)input[4] << 8) |
-	((unsigned long)(unsigned char)input[5] << 16);
-      buf2[4] = _xcrypt_itoa64[value & 0x3f];
-      buf2[5] = _xcrypt_itoa64[(value >> 6) & 0x3f];
-      buf2[6] = _xcrypt_itoa64[(value >> 12) & 0x3f];
-      buf2[7] = _xcrypt_itoa64[(value >> 18) & 0x3f];
-      buf2[8] = '\0';
-    }
-
-  snprintf (output, output_size, "%s%s", buf, buf2);
-  free (buf);
-
-  return output;
-}
-
-typedef unsigned int BF_word;
-static unsigned char BF_itoa64[64 + 1] =
-        "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
-
-static void
-BF_encode (char *dst, __CONST BF_word *src, int size)
-{
-  const unsigned char *sptr = (const unsigned char *)src;
-  const unsigned char *end = sptr + size;
-  unsigned char *dptr = (unsigned char *)dst;
-  unsigned int c1, c2;
-
-  do {
-    c1 = *sptr++;
-    *dptr++ = BF_itoa64[c1 >> 2];
-    c1 = (c1 & 0x03) << 4;
-    if (sptr >= end) {
-      *dptr++ = BF_itoa64[c1];
-      break;
-    }
-
-    c2 = *sptr++;
-    c1 |= c2 >> 4;
-    *dptr++ = BF_itoa64[c1];
-    c1 = (c2 & 0x0f) << 2;
-    if (sptr >= end) {
-      *dptr++ = BF_itoa64[c1];
-      break;
-    }
-
-    c2 = *sptr++;
-    c1 |= c2 >> 6;
-    *dptr++ = BF_itoa64[c1];
-    *dptr++ = BF_itoa64[c2 & 0x3f];
-  } while (sptr < end);
-}
-
-static char *
-_xcrypt_gensalt_blowfish_rn (unsigned long count, __CONST char *input,
-			     int size, char *output, int output_size)
-{
-  if (size < 16 || output_size < 7 + 22 + 1 ||
-      (count && (count < 4 || count > 31))) {
-    if (output_size > 0) output[0] = '\0';
-    __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL);
-    return NULL;
-  }
-
-  if (!count) count = 5;
-
-  output[0] = '$';
-  output[1] = '2';
-  output[2] = 'a';
-  output[3] = '$';
-  output[4] = '0' + count / 10;
-  output[5] = '0' + count % 10;
-  output[6] = '$';
-
-  BF_encode(&output[7], (const unsigned int *)input, 16);
-  output[7 + 22] = '\0';
-
-  return output;
-}
-
-
-
-char *
-crypt_gensalt_r (__const char *prefix, unsigned long count,
-		 __const char *input, int size, char *output,
-		 int output_size)
-{
-  char *(*use) (unsigned long count,
-                __const char *input, int size, char *output, int output_size);
-
-  /* This may be supported on some platforms in the future */
-  if (!input)
-    {
-      __set_errno (EINVAL);
-      return NULL;
-    }
-
-  if (prefix[0] == '$')
-    {
-      char *hash_id = strdup (&prefix[1]);
-      char *c = strchr (hash_id, '$');
-
-      if (c == NULL)
-        {
-          free (hash_id);
-          return NULL;
-        }
-
-      *c = '\0';
-
-      if (hash_id[0] == '1') /* md5 */
-	use = _xcrypt_gensalt_md5_rn;
-      else if (hash_id[0] == '2' && hash_id[1] == 'a') /* blowfish */
-	use = _xcrypt_gensalt_blowfish_rn;
-      else if (hash_id[0] == '5') /* sha256 */
-	use = _xcrypt_gensalt_sha256_rn;
-      else if (hash_id[0] == '6') /* sha512 */
-	use = _xcrypt_gensalt_sha512_rn;
-      else
-	use = _xcrypt_gensalt_traditional_rn;
-
-      free (hash_id);
-    }
-  else if (prefix[0] == '_')
-    use = _xcrypt_gensalt_extended_rn;
-  else if (!prefix[0] ||
-           (prefix[0] && prefix[1] &&
-            memchr (_xcrypt_itoa64, prefix[0], 64) &&
-            memchr (_xcrypt_itoa64, prefix[1], 64)))
-    use = _xcrypt_gensalt_traditional_rn;
-  else
-    {
-      __set_errno (EINVAL);
-      return NULL;
-    }
-
-  return use (count, input, size, output, output_size);
-}
Index: pam_unix2-2.9.1/src/unix_passwd.c
===================================================================
--- pam_unix2-2.9.1.orig/src/unix_passwd.c
+++ pam_unix2-2.9.1/src/unix_passwd.c
@@ -63,6 +63,7 @@
 #endif
 
 #if defined(HAVE_CRYPT_H)
+#define _OW_SOURCE
 #include <crypt.h>
 #endif
 
@@ -87,11 +88,6 @@
 static int __do_setpass (pam_handle_t *pamh, int flags, user_t *user,
 			 options_t *options, struct crypt_data *output);
 
-extern char *
-crypt_gensalt_r (__const char *prefix, unsigned long count,
-		 __const char *input, int size, char *output,
-		 int output_size);
-
 PAM_EXTERN int
 pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv)
 {
@@ -502,7 +498,7 @@ make_crypt_salt (const char *crypt_prefi
 
   close (fd);
 
-  retval = crypt_gensalt_r (crypt_prefix, crypt_rounds, entropy,
+  retval = crypt_gensalt_rn (crypt_prefix, crypt_rounds, entropy,
 			    sizeof (entropy), output, sizeof(output));
 
   memset (entropy, 0, sizeof (entropy));