Fixes for glibc 2.22 Also sorts sha512 and sha256 before others. Signed-off-by: Thomas Backlund <tmb@mageia.org> diff -Nurp glibc-2.22.orig/crypt/crypt_gensalt.c glibc-2.22/crypt/crypt_gensalt.c --- glibc-2.22.orig/crypt/crypt_gensalt.c 2015-08-15 23:53:48.896515795 +0300 +++ glibc-2.22/crypt/crypt_gensalt.c 2015-08-16 00:36:54.141929119 +0300 @@ -123,11 +123,13 @@ char *_crypt_gensalt_md5_rn(const char * return output; } -char *_crypt_gensalt_sha256c_rn(unsigned long count, +char *_crypt_gensalt_sha256c_rn(const char *prefix, unsigned long count, const char *input, int size, char *output, int output_size) { unsigned long value; + (void) prefix; + if (size < 3 || output_size < 3 + 4 + 1 || (count && count != 1000)) { if (output_size > 0) output[0] = '\0'; __set_errno((output_size < 3 + 4 + 1) ? ERANGE : EINVAL); @@ -161,11 +163,13 @@ char *_crypt_gensalt_sha256c_rn(unsigned } -char *_crypt_gensalt_sha512c_rn(unsigned long count, +char *_crypt_gensalt_sha512c_rn(const char *prefix, unsigned long count, const char *input, int size, char *output, int output_size) { unsigned long value; + (void) prefix; + if (size < 3 || output_size < 3 + 4 + 1 || (count && count != 1000)) { if (output_size > 0) output[0] = '\0'; __set_errno((output_size < 3 + 4 + 1) ? ERANGE : EINVAL); diff -Nurp glibc-2.22.orig/crypt/crypt_gensalt.h glibc-2.22/crypt/crypt_gensalt.h --- glibc-2.22.orig/crypt/crypt_gensalt.h 2015-08-15 23:53:48.896515795 +0300 +++ glibc-2.22/crypt/crypt_gensalt.h 2015-08-16 00:37:58.388410672 +0300 @@ -26,9 +26,9 @@ extern char *_crypt_gensalt_extended_rn( const char *input, int size, char *output, int output_size); extern char *_crypt_gensalt_md5_rn(const char *prefix, unsigned long count, const char *input, int size, char *output, int output_size); -extern char *_crypt_gensalt_sha256c_rn(unsigned long count, +extern char *_crypt_gensalt_sha256c_rn(const char *prefix, unsigned long count, const char *input, int size, char *output, int output_size); -extern char *_crypt_gensalt_sha512c_rn(unsigned long count, +extern char *_crypt_gensalt_sha512c_rn(const char *prefix, unsigned long count, const char *input, int size, char *output, int output_size); #endif diff -Nurp glibc-2.22.orig/crypt/wrapper.c glibc-2.22/crypt/wrapper.c --- glibc-2.22.orig/crypt/wrapper.c 2015-08-15 23:53:48.897515803 +0300 +++ glibc-2.22/crypt/wrapper.c 2015-08-16 00:46:45.160036499 +0300 @@ -141,14 +141,14 @@ char *__crypt_rn(__const char *key, __co { char *retval; + if (setting[0] == '$' && setting[1] == '6') + return __sha512_crypt_r(key, setting, (char *)data, size); + if (setting[0] == '$' && setting[1] == '5') + return __sha256_crypt_r(key, setting, (char *)data, size); if (setting[0] == '$' && setting[1] == '2') return _crypt_blowfish_rn(key, setting, (char *)data, size); if (setting[0] == '$' && setting[1] == '1') return __md5_crypt_r(key, setting, (char *)data, size); - if (setting[0] == '$' && setting[1] == '5') - return __sha256_crypt_r(key, setting, (char *)data, size); - if (setting[0] == '$' && setting[1] == '6') - return __sha512_crypt_r(key, setting, (char *)data, size); if (setting[0] == '$') goto out_einval; if (setting[0] == '_') { if (size < sizeof(struct _crypt_extended_data)) goto out_erange; @@ -178,25 +178,25 @@ char *__crypt_ra(__const char *key, __co { char *retval; - if (setting[0] == '$' && setting[1] == '2') { + if (setting[0] == '$' && setting[1] == '6') { if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE)) return NULL; - return _crypt_blowfish_rn(key, setting, (char *)*data, *size); + return __sha512_crypt_r(key, setting, (char *)*data, *size); } - if (setting[0] == '$' && setting[1] == '1') { + if (setting[0] == '$' && setting[1] == '5') { if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE)) return NULL; - return __md5_crypt_r(key, setting, (char *)*data, *size); + return __sha256_crypt_r(key, setting, (char *)*data, *size); } - if (setting[0] == '$' && setting[1] == '5') { + if (setting[0] == '$' && setting[1] == '2') { if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE)) return NULL; - return __sha256_crypt_r(key, setting, (char *)*data, *size); + return _crypt_blowfish_rn(key, setting, (char *)*data, *size); } - if (setting[0] == '$' && setting[1] == '6') { + if (setting[0] == '$' && setting[1] == '1') { if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE)) return NULL; - return __sha512_crypt_r(key, setting, (char *)*data, *size); + return __md5_crypt_r(key, setting, (char *)*data, *size); } if (setting[0] == '$') goto out_einval; if (setting[0] == '_') { @@ -283,6 +283,12 @@ char *__crypt_gensalt_rn(const char *pre return NULL; } + if (!strncmp(prefix, "$6$", 3)) + use = _crypt_gensalt_sha512c_rn; + else + if (!strncmp(prefix, "$5$", 3)) + use = _crypt_gensalt_sha256c_rn; + else if (!strncmp(prefix, "$2a$", 4) || !strncmp(prefix, "$2b$", 4) || !strncmp(prefix, "$2y$", 4)) use = _crypt_gensalt_blowfish_rn; @@ -290,12 +296,6 @@ char *__crypt_gensalt_rn(const char *pre if (!strncmp(prefix, "$1$", 3)) use = _crypt_gensalt_md5_rn; else - if (!strncmp(prefix, "$5$", 3)) - use = _crypt_gensalt_sha256c_rn; - else - if (!strncmp(prefix, "$6$", 3)) - use = _crypt_gensalt_sha512c_rn; - else if (prefix[0] == '_') use = _crypt_gensalt_extended_rn; else