]> granicus.if.org Git - shadow/commitdiff
Add support for SHA256 and SHA512 encrypt methods. Apply RedHat's patch
authornekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>
Mon, 19 Nov 2007 22:14:19 +0000 (22:14 +0000)
committernekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>
Mon, 19 Nov 2007 22:14:19 +0000 (22:14 +0000)
shadow-4.0.18.1-sha256.patch. Thanks to Peter Vrabec. Hardly no changes
except re-indent and changes related to recent modifications (max_salt_len
in crypt_make_salt). Changes in lib/defines.h not applied (definition of
ENCRYPTMETHOD_SELECT). I will add a configure check or flag.

ChangeLog
NEWS
etc/login.defs
lib/getdef.c
libmisc/obscure.c
libmisc/salt.c
src/passwd.c

index ca6d2e023014adbf41e374b5714acc5baee8c076..541e3982ddfc3f3a25b928fe5349308109a04f8f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2007-11-19  Nicolas François  <nicolas.francois@centraliens.net>
+
+       * NEWS, libmisc/obscure.c, libmisc/salt.c, src/passwd.c,
+       lib/getdef.c, etc/login.defs: Add support for SHA256 and SHA512
+       encrypt methods. Apply RedHat's patch shadow-4.0.18.1-sha256.patch.
+       Thanks to Peter Vrabec. Hardly no changes except re-indent and
+       changes related to recent modifications (max_salt_len in
+       crypt_make_salt). Changes in lib/defines.h not applied (definition
+       of ENCRYPTMETHOD_SELECT). I will add a configure check or flag.
+
 2007-11-19  Nicolas François  <nicolas.francois@centraliens.net>
 
        * man/de/Makefile.am: Add su.1 to the generated manpages.
diff --git a/NEWS b/NEWS
index 1f6316ceddf94ba6f9dfbf969735db10b72cca22..ec519be6c8ea75e5b0b7be1fefd1b0eb92d28128 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,8 @@ $Id$
 shadow-4.0.18.1 -> shadow-4.0.18.2                                     UNRELEASED
 
 *** general:
+- Add support for SHA256 and SHA512 encrypt methods (supported by new
+  libc).
 - useradd: Allow non numerical group identifier to be specified with
   useradd's -g option.
 - chgpasswd, chpasswd: Fix chpasswd and chgpasswd stack overflow.
index d31cbed400a1c51313142d9f44592c739f2f58af..04d20aa30ec1c401dec3bc015c628a422e38d431 100644 (file)
@@ -278,6 +278,16 @@ CHFN_RESTRICT              rwh
 #
 #MD5_CRYPT_ENAB        no
 
+#
+# Only works if compiled with ENCRYPTMETHOD_SELECT defined:
+# If set to MD5 , MD5-based algorithm will be used for encrypting password
+# If set to SHA256, SHA256-based algorithm will be used for encrypting password
+# If set to SHA512, SHA512-based algorithm will be used for encrypting password
+# If set to DES, DES-based algorithm will be used for encrypting password (default)
+# Overrides the MD5_CRYPT_ENAB option
+#
+#ENCRYPT_METHOD DES
+
 #
 # List of groups to add to the user's supplementary group set
 # when logging in on the console (as determined by the CONSOLE
index b2dd4716504fa6ae7083a7a8e2a71f1e351ac54f..93546b9d7363e05391711a7db784d9c5ab179aed 100644 (file)
@@ -84,6 +84,7 @@ static struct itemdef def_table[] = {
        {"CHFN_AUTH", NULL},
        {"CHSH_AUTH", NULL},
        {"CRACKLIB_DICTPATH", NULL},
+       {"ENCRYPT_METHOD", NULL},
        {"ENV_HZ", NULL},
        {"ENVIRON_FILE", NULL},
        {"ENV_TZ", NULL},
index b3345af7a6bed4d54820498dae19e72e2c45004d..d45b084f1c2a1b9346718890c88edf7513fa5796 100644 (file)
@@ -210,6 +210,9 @@ static const char *password_check (const char *old, const char *new,
        int maxlen, oldlen, newlen;
        char *new1, *old1;
        const char *msg;
+#ifdef ENCRYPTMETHOD_SELECT
+       char *result;
+#endif
 
        oldlen = strlen (old);
        newlen = strlen (new);
@@ -227,15 +230,28 @@ static const char *password_check (const char *old, const char *new,
        if (msg)
                return msg;
 
+#ifdef ENCRYPTMETHOD_SELECT
+       if ((result = getdef_str ("ENCRYPT_METHOD")) == NULL) {
+#endif
        /* The traditional crypt() truncates passwords to 8 chars.  It is
           possible to circumvent the above checks by choosing an easy
           8-char password and adding some random characters to it...
           Example: "password$%^&*123".  So check it again, this time
           truncated to the maximum length.  Idea from npasswd.  --marekm */
 
-       if (getdef_bool ("MD5_CRYPT_ENAB"))
-               return NULL;    /* unlimited password length */
+               if (getdef_bool ("MD5_CRYPT_ENAB"))
+                       return NULL;
+
+#ifdef ENCRYPTMETHOD_SELECT
+       } else {
 
+               if (!strncmp (result, "MD5"   , 3) ||
+                   !strncmp (result, "SHA256", 6) ||
+                   !strncmp (result, "SHA512", 6))
+                       return NULL;
+
+       }
+#endif
        maxlen = getdef_num ("PASS_MAX_LEN", 8);
        if (oldlen <= maxlen && newlen <= maxlen)
                return NULL;
index 4ccf36ccee77af7615b3e0dd855ef3c7c9bf992c..9e78a7674f9dc9891d86677a4309c6d4ffa2b165 100644 (file)
@@ -58,20 +58,44 @@ char *l64a(long value)
  * (magic) and pw_encrypt() will execute the MD5-based FreeBSD-compatible
  * version of crypt() instead of the standard one.
  */
+
+#define MAGNUM(array,ch) (array)[0]= (array)[2] = '$',(array)[1]=(ch)
+
 char *crypt_make_salt (void)
 {
        struct timeval tv;
        static char result[40];
        int max_salt_len = 8;
+       char *method;
 
-       result[0] = '\0';
 #ifndef USE_PAM
-       if (getdef_bool ("MD5_CRYPT_ENAB")) {
-               strcpy (result, "$1$"); /* magic for the new MD5 crypt() */
                max_salt_len += 3;
-       }
+#ifdef ENCRYPTMETHOD_SELECT
+       if ((method = getdef_str ("ENCRYPT_METHOD")) == NULL) {
 #endif
-
+               if (getdef_bool ("MD5_CRYPT_ENAB")) {
+                       MAGNUM(result,'1');
+                       max_salt_len = 11;
+               } else
+                       result[0] = '\0';
+#ifdef ENCRYPTMETHOD_SELECT
+       } else {
+               if (!strncmp (method, "MD5", 3)) {
+                       MAGNUM(result, '1');
+                       max_salt_len = 11;
+               } else if (!strncmp (method, "SHA256", 6)) {
+                       MAGNUM(result, '5');
+                       max_salt_len = 11; /* XXX: should not be fixed */
+               } else if (!strncmp (method, "SHA512", 6)) {
+                       MAGNUM(result, '6');
+                       max_salt_len = 11; /* XXX: should not be fixed */
+               } else if (!strncmp (method, "DES", 3))
+                       result[0] = '\0';
+               else
+                       result[0] = '\0';
+       }
+#endif                         /* ENCRYPTMETHOD_SELECT */
+#endif                         /* USE_PAM */
        /*
         * Generate 8 chars of salt, the old crypt() will use only first 2.
         */
index 8775e87c17fbf36bc64384fe36306260184d394a..1f57e705b31ff1840e85bcc4047af0bea8510a8a 100644 (file)
@@ -190,7 +190,10 @@ static int new_password (const struct passwd *pw)
        char pass[200];         /* New password */
        int i;                  /* Counter for retries */
        int warned;
-       int pass_max_len;
+       int pass_max_len = -1;
+#ifdef ENCRYPTMETHOD_SELECT
+       char *method;
+#endif
 
 #ifdef HAVE_LIBCRACK_HIST
        int HistUpdate (const char *, const char *);
@@ -228,15 +231,34 @@ static int new_password (const struct passwd *pw)
         * for strength, unless it is the root user. This provides an escape
         * for initial login passwords.
         */
-       if (getdef_bool ("MD5_CRYPT_ENAB"))
-               pass_max_len = 127;
-       else
-               pass_max_len = getdef_num ("PASS_MAX_LEN", 8);
-
-       if (!qflg)
-               printf (_("\
-Enter the new password (minimum of %d, maximum of %d characters)\n\
-Please use a combination of upper and lower case letters and numbers.\n"), getdef_num ("PASS_MIN_LEN", 5), pass_max_len);
+#ifdef ENCRYPTMETHOD_SELECT
+       if ((method = getdef_str ("ENCRYPT_METHOD")) == NULL) {
+#endif
+               if (!getdef_bool ("MD5_CRYPT_ENAB"))
+                       pass_max_len = getdef_num ("PASS_MAX_LEN", 8);
+#ifdef ENCRYPTMETHOD_SELECT
+       } else {
+               if (!strncmp (method, "MD5"   , 3) ||
+                   !strncmp (method, "SHA256", 6) ||
+                   !strncmp (method, "SHA512", 6))
+                       pass_max_len = -1;
+               else
+                       pass_max_len = getdef_num ("PASS_MAX_LEN", 8);
+       }
+#endif
+       if (!qflg) {
+               if (pass_max_len == -1) {
+                       printf (_(
+"Enter the new password (minimum of %d characters)\n"
+"Please use a combination of upper and lower case letters and numbers.\n"),
+                               getdef_num ("PASS_MIN_LEN", 5));
+               } else {
+                       printf (_(
+"Enter the new password (minimum of %d, maximum of %d characters)\n"
+"Please use a combination of upper and lower case letters and numbers.\n"),
+                               getdef_num ("PASS_MIN_LEN", 5), pass_max_len);
+               }
+       }
 
        warned = 0;
        for (i = getdef_num ("PASS_CHANGE_TRIES", 5); i > 0; i--) {