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.
This commit is contained in:
nekral-guest 2007-11-19 22:14:19 +00:00
parent cfc3378a0b
commit b8d8d0de00
7 changed files with 102 additions and 17 deletions

View File

@ -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.

2
NEWS
View File

@ -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.

View 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

View 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},

View 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;

View 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.
*/

View 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--) {