Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:lafenghu
pwdutils
0001-add-support-for-sha512.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0001-add-support-for-sha512.diff of Package pwdutils
From eeb5baaeceb5e04c9fa7fe3a4316ab4a3fd3b40c Mon Sep 17 00:00:00 2001 From: Ludwig Nussel <ludwig.nussel@suse.de> Date: Thu, 14 Jul 2011 15:26:07 +0200 Subject: [PATCH] add support for sha512 * use implicit defaults in /etc/default/passwd * make it work without xcrypt --- configure.in | 2 +- etc/default/passwd | 48 +++++++++++++++++++++++++-------- lib/logindefs.c | 2 +- lib/parse_crypt_arg.c | 41 +++++++++++++++++----------- lib/parse_crypt_arg.h | 5 +++- src/chpasswd.c | 66 +++++++-------------------------------------- src/gpasswd.c | 70 ++++++++---------------------------------------- 7 files changed, 90 insertions(+), 144 deletions(-) diff --git a/configure.in b/configure.in index ea0bc27..e9e4cd8 100644 --- a/configure.in +++ b/configure.in @@ -192,7 +192,7 @@ dnl Save old LIBS variable and add crypt library BACKUP_LIBS=$LIBS LIBS="$LIBS $CRYPT_LIB" dnl Function check for blowfish crypt -AC_CHECK_FUNCS(crypt crypt_r xcrypt_gensalt_r) +AC_CHECK_FUNCS(crypt crypt_r xcrypt_gensalt_r crypt_gensalt_rn) dnl restore old LIBS variable LIBS=$BACKUP_LIBS diff --git a/etc/default/passwd b/etc/default/passwd index 87057ea..ec6f0d4 100644 --- a/etc/default/passwd +++ b/etc/default/passwd @@ -2,29 +2,53 @@ # the passwd (1) command and other tools # creating or modifying passwords. -# Define default crypt hash. This hash will be -# used, if there is no hash for a special service -# the user is stored in. -# CRYPT={des,md5,sha256,sha512} -CRYPT=md5 +# Define default crypt hash. +# CRYPT={des,md5,blowfish,sha256,sha512} +CRYPT= # Use another crypt hash for group passwords. # This is used by gpasswd, fallback is the CRYPT entry. # GROUP_CRYPT=des +# We can override the default for a specific service +# by appending the service name (FILES, YP, NISPLUS, LDAP) + +# for local files, use a more secure hash. We +# don't need to be portable here: +# CRYPT_FILES=sha512 +# +# For NIS, we should always use DES: +# CRYPT_YP=des + # We can override the default for a special service # by appending the service name (FILES, YP, NISPLUS, LDAP) # for local files, use a more secure hash. We # don't need to be portable here: -CRYPT_FILES=sha512 -# sometimes we need to specify special options for -# a hash (variable is prepended by the name of the -# crypt hash). +# CRYPT_FILES=blowfish + +# sometimes we need to specify special options for a hash (variable +# is prepended by the name of the crypt hash). In case of blowfish +# and sha* this is the number of rounds # blowfish: 4-31 +# BLOWFISH_CRYPT_FILES=5 # sha256/sha512: 1000-9999999 -#SHA512_CRYPT_FILES=1000 +# SHA512_CRYPT_FILES=1000 -# For NIS, we should always use DES: -CRYPT_YP=des +# In June 2011 it was discovered that the Linux crypt_blowfish +# implementation contained a bug that made passwords with non-ASCII +# characters easier to crack (CVE-2011-2483). Affected passwords are +# also incompatible with the original, correct OpenBSD +# implementation. Therefore the $2a hash identifier previously used +# for blowfish now is ambiguous as it could mean the hash was +# generated with the correct implementation on OpenBSD or the buggy +# one on Linux. To avoid the ambiguity two new identifier were +# introduced. $2x now explicitly identifies hashes that were +# generated with the buggy algorithm while $2y is used for hashes +# generated with the correct algorithm. New passwords are now +# generated with the $2y identifier. +# +# Setting the following option to "yes" tells the sytem that $2a +# hashes are to be treated as generated with the buggy algorithm. +BLOWFISH_2a2x= diff --git a/lib/logindefs.c b/lib/logindefs.c index 42effde..d8826e1 100644 --- a/lib/logindefs.c +++ b/lib/logindefs.c @@ -88,7 +88,7 @@ search (const char *name) while (ptr != NULL) { if (strcasecmp (name, ptr->name) == 0) - return ptr->value; + return *ptr->value?ptr->value:NULL; ptr = ptr->next; } diff --git a/lib/parse_crypt_arg.c b/lib/parse_crypt_arg.c index 1f76ae6..eae7520 100644 --- a/lib/parse_crypt_arg.c +++ b/lib/parse_crypt_arg.c @@ -28,6 +28,10 @@ #if defined(HAVE_XCRYPT_H) #include <xcrypt.h> #elif defined(HAVE_CRYPT_H) +#if defined(HAVE_CRYPT_GENSALT_RN) +#define _OW_SOURCE +#define xcrypt_gensalt_r crypt_gensalt_rn +#endif #include <crypt.h> #endif @@ -38,7 +42,10 @@ #define RANDOM_DEVICE "/dev/urandom" #endif -#if defined(HAVE_XCRYPT_GENSALT_R) +#if defined(HAVE_XCRYPT_GENSALT_R) || defined(HAVE_CRYPT_GENSALT_RN) + +const char* const prefixes[NUM_CRYPT_T] = { NULL, "", "$1$", NULL, "$2y$", "$5$", "$6$" }; + static int read_loop (int fd, char *buffer, int count) { @@ -67,14 +74,9 @@ read_loop (int fd, char *buffer, int count) #endif char * -#if defined(HAVE_XCRYPT_GENSALT_R) make_crypt_salt (const char *crypt_prefix, int crypt_rounds) -#else -make_crypt_salt (const char *crypt_prefix __attribute__ ((unused)), - int crypt_rounds __attribute__ ((unused))) -#endif { -#if defined(HAVE_XCRYPT_GENSALT_R) +#if defined(HAVE_XCRYPT_GENSALT_R) || defined(HAVE_CRYPT_GENSALT_RN) #define CRYPT_GENSALT_OUTPUT_SIZE (7 + 22 + 1) int fd; char entropy[16]; @@ -131,21 +133,28 @@ make_crypt_salt (const char *crypt_prefix __attribute__ ((unused)), crypt_t parse_crypt_arg (const char *arg) { + if (!arg || !*arg) + goto out; + if (strcasecmp (arg, "des") == 0) return DES; else if (strcasecmp (arg, "md5") == 0) return MD5; +#if defined(HAVE_XCRYPT_GENSALT_R) || defined(HAVE_CRYPT_GENSALT_RN) else if (strcasecmp (arg, "blowfish") == 0 || strcasecmp (arg, "bf") == 0) - { -#if defined(HAVE_XCRYPT_GENSALT_R) - return BLOWFISH; + return BLOWFISH; + else if (strcasecmp (arg, "sha256") == 0) + return SHA256; + else if (strcasecmp (arg, "sha512") == 0) + return SHA512; + + fprintf (stderr, _("No support for %s available, using SHA512.\n"), arg); +out: + return SHA512; #else - fprintf (stderr, _("No support for blowfish compiled in, using MD5.\n")); - return MD5; -#endif - } - - fprintf (stderr, _("No support for %s available, using DES.\n"), optarg); + fprintf (stderr, _("No support for %s available, using DES.\n"), arg); +out: return DES; +#endif } diff --git a/lib/parse_crypt_arg.h b/lib/parse_crypt_arg.h index 61ed464..507f9d1 100644 --- a/lib/parse_crypt_arg.h +++ b/lib/parse_crypt_arg.h @@ -17,7 +17,10 @@ #ifndef __PARSE_CRYPT_ARG_H__ #define __PARSE_CRYPT_ARG_H__ -enum crypt_t {DES, MD5, BLOWFISH}; +enum crypt_t {NONE, DES, MD5, BIGCRYPT, BLOWFISH, SHA256, SHA512, NUM_CRYPT_T}; + +extern const char* const prefixes[NUM_CRYPT_T]; + typedef enum crypt_t crypt_t; extern crypt_t parse_crypt_arg (const char *arg); diff --git a/src/chpasswd.c b/src/chpasswd.c index a116161..a00b80a 100644 --- a/src/chpasswd.c +++ b/src/chpasswd.c @@ -56,7 +56,7 @@ static void print_usage (FILE *stream, const char *program) { - fprintf (stream, _("Usage: %s [-D binddn] [-P path] [-e] [-c des|md5|blowfish] [file]\n"), + fprintf (stream, _("Usage: %s [-D binddn] [-P path] [-e] [-c des|md5|blowfish|sha256|sha512] [file]\n"), program); } @@ -72,7 +72,7 @@ print_help (const char *program) #endif fputs (_(" -P path Search passwd and shadow file in \"path\"\n"), stdout); - fputs (_(" -c, --crypt Password should be encrypted with DES, MD5 or blowfish\n"), + fputs (_(" -c, --crypt Password should be encrypted with DES, MD5, blowfish, sha256 or sha512\n"), stdout); fputs (_(" -e, --encrypted The passwords are in encrypted form\n"), stdout); @@ -107,7 +107,7 @@ main (int argc, char *argv[]) open_sec_log (program); - use_crypt = parse_crypt_arg (getlogindefs_str ("CRYPT", "des")); + use_crypt = parse_crypt_arg (getlogindefs_str ("CRYPT", NULL)); while (1) { @@ -303,60 +303,16 @@ main (int argc, char *argv[]) struct crypt_data output; memset (&output, 0, sizeof (output)); - switch (use_crypt) + salt = make_crypt_salt (prefixes[use_crypt], 0); + if (salt != NULL) + pw_data->newpassword = strdup (crypt_r (cp, salt, &output)); + else { - case DES: - /* If we don't support passwords longer 8 characters, - truncate them */ - if (strlen (cp) > 8) - cp[8] = '\0'; - salt = make_crypt_salt ("", 0); - if (salt != NULL) - pw_data->newpassword = strdup (crypt_r (cp, salt, &output)); - else - { - fprintf (stderr, _("Cannot create salt for standard crypt")); - ++errors; - continue; - } - free (salt); - break; - - case MD5: - /* MD5 has a limit of 127 characters */ - if (strlen (cp) > 127) - cp[127] = '\0'; - salt = make_crypt_salt ("$1$", 0); - if (salt != NULL) - pw_data->newpassword = strdup (crypt_r (cp, salt, &output)); - else - { - fprintf (stderr, _("Cannot create salt for MD5 crypt")); - ++errors; - continue; - } - free (salt); - break; - case BLOWFISH: -#if defined(HAVE_XCRYPT_GENSALT_R) - /* blowfish has a limit of 72 characters */ - if (use_crypt == BLOWFISH && strlen (cp) > 72) - cp[72] = '\0'; - salt = make_crypt_salt ("$2a$", 0 /* XXX crypt_rounds */); - if (salt != NULL) - pw_data->newpassword = strdup (crypt_r (cp, salt, &output)); - else - { - fprintf (stderr, _("Cannot create salt for blowfish crypt")); - ++errors; - continue; - } - free (salt); -#endif - break; - default: - abort(); + fprintf (stderr, _("Cannot create salt: %m")); + ++errors; + continue; } + free (salt); } time (&now); pw_data->spn.sp_lstchg = (long int)now / (24L*3600L); diff --git a/src/gpasswd.c b/src/gpasswd.c index 81ea94a..47ffb04 100644 --- a/src/gpasswd.c +++ b/src/gpasswd.c @@ -133,7 +133,7 @@ main (int argc, char **argv) crypt_str = getlogindefs_str ("GROUP_CRYPT", NULL); if (crypt_str == NULL) - crypt_str = getlogindefs_str ("CRYPT", "des"); + crypt_str = getlogindefs_str ("CRYPT", NULL); use_crypt = parse_crypt_arg (crypt_str); /* Parse program arguments */ @@ -408,63 +408,17 @@ main (int argc, char **argv) struct crypt_data output; memset (&output, 0, sizeof (output)); - - switch (use_crypt) - { - case DES: - /* If we don't support passwords longer 8 characters, - truncate them */ - if (strlen (p1) > 8) - p1[8] = '\0'; - salt = make_crypt_salt ("", 0); - if (salt != NULL) - gr_data->newpassword = strdup (crypt_r (p1, salt, &output)); - else - { - free (p1); - fprintf (stderr, _("Cannot create salt for standard crypt")); - goto abort_change; - } - free (salt); - break; - case BLOWFISH: -#if defined(HAVE_XCRYPT_GENSALT_R) - /* blowfish has a limit of 72 characters */ - if (use_crypt == BLOWFISH && strlen (p1) > 72) - p1[72] = '\0'; - salt = make_crypt_salt ("$2a$", 0 /* XXX crypt_rounds */); - if (salt != NULL) - gr_data->newpassword = strdup (crypt_r (p1, salt, &output)); - else - { - free (p1); - fprintf (stderr, _("Cannot create salt for blowfish crypt")); - goto abort_change; - } - free (salt); - break; -#else - fprintf (stderr, - _("No support for blowfish compiled in. Using MD5\n")); -#endif - case MD5: - /* MD5 has a limit of 127 characters */ - if (strlen (p1) > 127) - p1[127] = '\0'; - salt = make_crypt_salt ("$1$", 0); - if (salt != NULL) - gr_data->newpassword = strdup (crypt_r (p1, salt, &output)); - else - { - free (p1); - fprintf (stderr, _("Cannot create salt for MD5 crypt")); - goto abort_change; - } - free (salt); - break; - default: - abort(); - } + puts(prefixes[use_crypt]); + salt = make_crypt_salt (prefixes[use_crypt], 0); + if (salt != NULL) + gr_data->newpassword = strdup (crypt_r (p1, salt, &output)); + else + { + fprintf (stderr, _("Cannot create salt: %m")); + free (p1); + goto abort_change; + } + free (salt); free (p1); } } -- 1.7.3.4
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor