FreeBSD Bugzilla – Attachment 152839 Details for
Bug 182518
[login.conf] Better Password Hashes
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch against -CURRENT 201502 with a ton of enhancements, see -security
libcrypt-and-friends-20150210.patch (text/plain), 35.19 KB, created by
Derek
on 2015-02-10 12:24:05 UTC
(
hide
)
Description:
Patch against -CURRENT 201502 with a ton of enhancements, see -security
Filename:
MIME Type:
Creator:
Derek
Created:
2015-02-10 12:24:05 UTC
Size:
35.19 KB
patch
obsolete
>diff --git a/include/unistd.h b/include/unistd.h >index 55469ba..0da20ce 100644 >--- a/include/unistd.h >+++ b/include/unistd.h >@@ -290,6 +290,8 @@ typedef __useconds_t useconds_t; > #define _SC_NPROCESSORS_CONF 57 > #define _SC_NPROCESSORS_ONLN 58 > #define _SC_CPUSET_SIZE 122 >+#define CRYPT_FORMAT_MAX_LEN 20 /* currently strlen("$6$rounds=999999999$") == 20 */ >+#define CRYPT_SALT_MAX_LEN (CRYPT_FORMAT_MAX_LEN + 17) /* currently strlen("$6$rounds=999999999$AAAABBBBCCCCDDDD$") == 37 */ > #endif > > /* Extensions found in Solaris and Linux. */ >@@ -487,9 +489,7 @@ struct timeval; /* select(2) */ > int acct(const char *); > int async_daemon(void); > int check_utility_compat(const char *); >-const char * >- crypt_get_format(void); >-int crypt_set_format(const char *); >+int crypt_makesalt(char *, const char *, size_t *); > int des_cipher(const char *, char *, long, int); > int des_setkey(const char *key); > int dup3(int, int, int); >diff --git a/lib/libcrypt/Makefile b/lib/libcrypt/Makefile >index 3b92487..0af8875 100644 >--- a/lib/libcrypt/Makefile >+++ b/lib/libcrypt/Makefile >@@ -16,7 +16,6 @@ SRCS= crypt.c misc.c \ > crypt-sha256.c sha256c.c \ > crypt-sha512.c sha512c.c > MAN= crypt.3 >-MLINKS= crypt.3 crypt_get_format.3 crypt.3 crypt_set_format.3 > CFLAGS+= -I${.CURDIR}/../libmd -I${.CURDIR}/../libutil > > # Pull in the strong crypto, if it is present. >diff --git a/lib/libcrypt/crypt-md5.c b/lib/libcrypt/crypt-md5.c >index abf5db1..4bf4bd7 100644 >--- a/lib/libcrypt/crypt-md5.c >+++ b/lib/libcrypt/crypt-md5.c >@@ -49,8 +49,9 @@ crypt_md5(const char *pw, const char *salt) > int sl, pl; > u_int i; > u_char final[MD5_SIZE]; >- static const char *sp, *ep; >- static char passwd[120], *p; >+ const char *sp, *ep; >+ static __thread char passwd[120]; >+ char *p; > static const char *magic = "$1$"; > > /* Refine the Salt first */ >diff --git a/lib/libcrypt/crypt-nthash.c b/lib/libcrypt/crypt-nthash.c >index 90c9485..0227aed 100644 >--- a/lib/libcrypt/crypt-nthash.c >+++ b/lib/libcrypt/crypt-nthash.c >@@ -51,9 +51,9 @@ crypt_nthash(const char *pw, const char *salt __unused) > { > size_t unipwLen; > int i, j; >- static char hexconvtab[] = "0123456789abcdef"; >+ static const char hexconvtab[] = "0123456789abcdef"; > static const char *magic = "$3$"; >- static char passwd[120]; >+ static __thread char passwd[120]; > u_int16_t unipw[128]; > char final[MD4_SIZE*2 + 1]; > u_char hash[MD4_SIZE]; >diff --git a/lib/libcrypt/crypt-sha256.c b/lib/libcrypt/crypt-sha256.c >index 20e0c0b..44368f0 100644 >--- a/lib/libcrypt/crypt-sha256.c >+++ b/lib/libcrypt/crypt-sha256.c >@@ -274,8 +274,8 @@ crypt_sha256(const char *key, const char *salt) > * password. We can compute an upper bound for the size of the > * result in advance and so we can prepare the buffer we pass to > * `crypt_sha256_r'. */ >- static char *buffer; >- static int buflen; >+ static __thread char *buffer; >+ static __thread int buflen; > int needed; > char *new_buffer; > >diff --git a/lib/libcrypt/crypt-sha512.c b/lib/libcrypt/crypt-sha512.c >index 37e1c1b..b35acd6 100644 >--- a/lib/libcrypt/crypt-sha512.c >+++ b/lib/libcrypt/crypt-sha512.c >@@ -286,8 +286,8 @@ crypt_sha512(const char *key, const char *salt) > * password. We can compute an upper bound for the size of the > * result in advance and so we can prepare the buffer we pass to > * `crypt_sha512_r'. */ >- static char *buffer; >- static int buflen; >+ static __thread char *buffer; >+ static __thread int buflen; > int needed; > char *new_buffer; > >diff --git a/lib/libcrypt/crypt.c b/lib/libcrypt/crypt.c >index 5335904..b64f2bf 100644 >--- a/lib/libcrypt/crypt.c >+++ b/lib/libcrypt/crypt.c >@@ -29,73 +29,182 @@ > __FBSDID("$FreeBSD: head/lib/libcrypt/crypt.c 272830 2014-10-09 16:45:11Z des $"); > > #include <sys/types.h> >+#include <sys/param.h> > > #include <libutil.h> > #include <string.h> > #include <unistd.h> >+#include <regex.h> >+#include <stdbool.h> >+#include <stdlib.h> >+ >+#include <stdio.h> > > #include "crypt.h" > > /* > * List of supported crypt(3) formats. > * >- * The default algorithm is the last entry in the list (second-to-last >- * array element since the last is a sentinel). The reason for placing >- * the default last rather than first is that DES needs to be at the >- * bottom for the algorithm guessing logic in crypt(3) to work correctly, >- * and it needs to be the default for backward compatibility. >+ * Ordered from most probable to least probable[1], for the find algorithm to >+ * preform a little better in some cases. Generally, order is not important. >+ * >+ * 1. as guessed by a random person >+ * > */ > static const struct crypt_format { > const char *const name; > char *(*const func)(const char *, const char *); > const char *const magic; >+ const char *const default_format; >+ const char *const format_regex; >+ >+ const uint8_t salt_bytes; >+ const bool salt_trailing_sign; /* do we tack on a $ at the end of the salt */ > } crypt_formats[] = { >- { "md5", crypt_md5, "$1$" }, >+ { "md5", crypt_md5, "$1$", "$1$", "^\\$1\\$$", 8, true }, >+ { "sha512", crypt_sha512, "$6$", "$6$", "^\\$6\\$(rounds=[0-9]{0,9}\\$)?$", 16, true }, > #ifdef HAS_BLOWFISH >- { "blf", crypt_blowfish, "$2" }, >+ { "blf", crypt_blowfish, "$2", "$2b$04$", "^\\$2[ab]?\\$[0-9]{2}\\$$", 22 /* 16 * 1.333 */, false }, > #endif >- { "nth", crypt_nthash, "$3$" }, >- { "sha256", crypt_sha256, "$5$" }, >- { "sha512", crypt_sha512, "$6$" }, > #ifdef HAS_DES >- { "des", crypt_des, "_" }, >+ { "des", crypt_des, NULL, "", NULL, 2, false }, >+ { "des-ext", crypt_des, "_", "_..T.", "^_[A-Za-z0-9./]{4}$", 4, false }, > #endif >- >+ { "nth", crypt_nthash, "$3$", "$3$", "^\\$3\\$$", 0, false }, >+ { "sha256", crypt_sha256, "$5$", "$5$", "^\\$5\\$(rounds=[0-9]{0,9}\\$)?$", 16, true }, >+ > /* sentinel */ >- { NULL, NULL, NULL } >+ { NULL, NULL, NULL, NULL, NULL, 0, NULL } > }; > >-static const struct crypt_format *crypt_format = >- &crypt_formats[(sizeof crypt_formats / sizeof *crypt_formats) - 2]; >+#ifdef HAS_DES >+/* must be des if system has des */ >+static const char default_format[] = "des"; >+#else >+static const char default_format[] = "sha512"; >+#endif >+ >+/* local-scope only */ >+static const struct crypt_format *crypt_find_format(const char *); >+static bool crypt_validate_format_regex(const char *, const char *); >+static bool crypt_format_is_modular(const char*); > > #define DES_SALT_ALPHABET \ > "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" > >-/* >- * Returns the name of the currently selected format. >- */ >-const char * >-crypt_get_format(void) >+int >+crypt_makesalt(char *out, const char *format, size_t *outlen) >+{ >+ const struct crypt_format *cf; >+ char rand_buf[4]; >+ size_t reqsz; >+ const char *prefix; >+ size_t prefix_len; >+ size_t diff; >+ unsigned int i; >+ >+ /* find the appropriate format entry */ >+ cf = crypt_find_format(format); >+ if (cf == NULL ) >+ return (0); >+ >+ /* calculate required output size */ >+ if (crypt_format_is_modular(format) ) { >+ prefix = format; >+ } else { >+ prefix = cf->default_format; >+ } >+ prefix_len = strlen(prefix); >+ reqsz = prefix_len + (size_t) cf->salt_bytes; >+ >+ if (cf->salt_trailing_sign) >+ reqsz++; >+ >+ /* trailing '\0' */ >+ reqsz++; >+ >+ /* does the output buff have enough */ >+ if (reqsz > *outlen) { >+ *outlen = reqsz; >+ return (0); >+ } >+ >+ /* start building our output */ >+ strncpy(out, prefix, *outlen); >+ out += prefix_len; >+ >+ for (i = 0; i < cf->salt_bytes; i += 4 ) { >+ arc4random_buf(rand_buf, 3); >+ >+ diff = MIN(cf->salt_bytes - i, 4); >+ b64_from_24bit((uint8_t) rand_buf[2], (uint8_t) rand_buf[1], (uint8_t) rand_buf[0], diff, (int *) &(diff), &out); >+ } >+ >+ /* cleanup */ >+ bzero(rand_buf, sizeof(rand_buf) ); >+ >+ if (cf->salt_trailing_sign) { >+ out[0] = '$'; >+ out++; >+ } >+ >+ /* don't need to add trailing '\0', strncpy above will have set it already */ >+ >+ return (1); >+} >+ >+static bool >+crypt_format_validate_regex(const char* regex, const char *format) > { >+ regex_t regex_c; >+ int res = 0; >+ >+ /* We could cache these, but they are simple, and this function won't be >+ * called often. >+ */ >+ if (regcomp(®ex_c, regex, REG_EXTENDED) != 0) { >+ return false; >+ } >+ >+ res = regexec(®ex_c, format, 0, NULL, 0); >+ regfree(®ex_c); >+ >+ return !res; >+} > >- return (crypt_format->name); >+static bool >+crypt_format_is_modular(const char* format) >+{ >+ /* we'll treat 'new des' as modular, because they can set 24 bits of count via salt */ >+ return (format[0] == '$' || format[0] == '_'); > } > >-/* >- * Selects the format to use for subsequent crypt(3) invocations. >- */ >-int >-crypt_set_format(const char *format) >+static const struct crypt_format * >+crypt_find_format(const char *format) > { > const struct crypt_format *cf; >- >- for (cf = crypt_formats; cf->name != NULL; ++cf) { >- if (strcasecmp(cf->name, format) == 0) { >- crypt_format = cf; >- return (1); >+ >+ if (strcmp(format, "default") == 0 ) { >+ format = default_format; >+ } >+ >+ if (crypt_format_is_modular(format) ) { >+ /* modular crypt magic lookup, force full syntax */ >+ for (cf = crypt_formats; cf->name != NULL; ++cf) { >+ if (cf->magic != NULL && strstr(format, cf->magic) == format && crypt_format_validate_regex(cf->format_regex, format) ) { >+ return cf; >+ } >+ } >+ } else { >+ /* name lookup */ >+ for (cf = crypt_formats; cf->name != NULL; ++cf) { >+ if (strcasecmp(cf->name, format) == 0) { >+ return cf; >+ } > } > } >- return (0); >+ >+ return NULL; > } > > /* >@@ -110,14 +219,19 @@ crypt(const char *passwd, const char *salt) > #ifdef HAS_DES > int len; > #endif >- >+ >+ /* use the magic in the salt for lookup */ > for (cf = crypt_formats; cf->name != NULL; ++cf) > if (cf->magic != NULL && strstr(salt, cf->magic) == salt) > return (cf->func(passwd, salt)); >+ > #ifdef HAS_DES >+ /* check if it's standard des */ > len = strlen(salt); > if ((len == 13 || len == 2) && strspn(salt, DES_SALT_ALPHABET) == len) > return (crypt_des(passwd, salt)); > #endif >- return (crypt_format->func(passwd, salt)); >+ >+ cf = crypt_find_format(default_format); >+ return (cf->func(passwd, salt)); > } >diff --git a/lib/libcrypt/tests/Makefile b/lib/libcrypt/tests/Makefile >index 6f541c4..2555086 100644 >--- a/lib/libcrypt/tests/Makefile >+++ b/lib/libcrypt/tests/Makefile >@@ -9,4 +9,9 @@ ATF_TESTS_C= crypt_tests > CFLAGS+= -I${.CURDIR:H} > LIBADD= crypt > >+# Pull in the strong crypto, if it is present. >+.if exists(${.CURDIR}/../../../secure/lib/libcrypt) >+CFLAGS+= -DHAS_DES -DHAS_BLOWFISH >+.endif >+ > .include <bsd.test.mk> >diff --git a/lib/libcrypt/tests/crypt_tests.c b/lib/libcrypt/tests/crypt_tests.c >index efafaa1..9831ea2 100644 >--- a/lib/libcrypt/tests/crypt_tests.c >+++ b/lib/libcrypt/tests/crypt_tests.c >@@ -4,6 +4,7 @@ __FBSDID("$FreeBSD: head/lib/libcrypt/tests/crypt_tests.c 256365 2013-10-12 06:0 > #include <sys/types.h> > #include <crypt.h> > #include <unistd.h> >+#include <stdio.h> > > #include <atf-c.h> > >@@ -25,14 +26,14 @@ ATF_TC_BODY(md5, tc) > ATF_CHECK_STREQ(pw, want); > } > >-ATF_TC(invalid); >-ATF_TC_HEAD(invalid, tc) >+ATF_TC(md5invalid); >+ATF_TC_HEAD(md5invalid, tc) > { > >- atf_tc_set_md_var(tc, "descr", "Tests that invalid password fails"); >+ atf_tc_set_md_var(tc, "descr", "Tests that md5invalid password fails"); > } > >-ATF_TC_BODY(invalid, tc) >+ATF_TC_BODY(md5invalid, tc) > { > const char want[] = "$1$cafebabe$0Huu6KHrKLVWfqa4WljDE0"; > char *pw; >@@ -41,14 +42,351 @@ ATF_TC_BODY(invalid, tc) > ATF_CHECK(strcmp(pw, want) != 0); > } > >+ATF_TC(sha256_vector_1); >+ATF_TC_HEAD(sha256_vector_1, tc) >+{ >+ atf_tc_set_md_var(tc, "descr", "Test vector from crypt-sha256.c"); >+} >+ >+ATF_TC_BODY(sha256_vector_1, tc) >+{ >+ const char want[] = "$5$saltstring$5B8vYYiY.CVt1RlTTf8KbXBH3hsxY/GNooZaBBGWEc5"; >+ char *pw; >+ >+ pw = crypt("Hello world!", "$5$saltstring"); >+ ATF_CHECK_STREQ(pw, want); >+} >+ >+ATF_TC(sha256_vector_2); >+ATF_TC_HEAD(sha256_vector_2, tc) >+{ >+ atf_tc_set_md_var(tc, "descr", "Test vector from crypt-sha256.c"); >+} >+ >+ATF_TC_BODY(sha256_vector_2, tc) >+{ >+ const char want[] = "$5$rounds=10000$saltstringsaltst$3xv.VbSHBb41AL9AvLeujZkZRBAwqFMz2." >+ "opqey6IcA"; >+ char *pw; >+ >+ pw = crypt("Hello world!", "$5$rounds=10000$saltstringsaltstring"); >+ ATF_CHECK_STREQ(pw, want); >+} >+ >+ATF_TC(sha256_vector_3); >+ATF_TC_HEAD(sha256_vector_3, tc) >+{ >+ atf_tc_set_md_var(tc, "descr", "Test vector from crypt-sha256.c"); >+} >+ >+ATF_TC_BODY(sha256_vector_3, tc) >+{ >+ const char want[] = "$5$rounds=5000$toolongsaltstrin$Un/5jzAHMgOGZ5.mWJpuVolil07guHPvOW8" >+ "mGRcvxa5"; >+ char *pw; >+ >+ pw = crypt("This is just a test", "$5$rounds=5000$toolongsaltstring"); >+ ATF_CHECK_STREQ(pw, want); >+} >+ >+ATF_TC(sha256_vector_4); >+ATF_TC_HEAD(sha256_vector_4, tc) >+{ >+ atf_tc_set_md_var(tc, "descr", "Test vector from crypt-sha256.c"); >+} >+ >+ATF_TC_BODY(sha256_vector_4, tc) >+{ >+ const char want[] = "$5$rounds=1400$anotherlongsalts$Rx.j8H.h8HjEDGomFU8bDkXm3XIUnzyxf12" >+ "oP84Bnq1"; >+ char *pw; >+ >+ pw = crypt("a very much longer text to encrypt. This one even stretches over more" >+ "than one line.", "$5$rounds=1400$anotherlongsaltstring"); >+ ATF_CHECK_STREQ(pw, want); >+} >+ >+ATF_TC(sha256_vector_5); >+ATF_TC_HEAD(sha256_vector_5, tc) >+{ >+ atf_tc_set_md_var(tc, "descr", "Test vector from crypt-sha256.c"); >+} >+ >+ATF_TC_BODY(sha256_vector_5, tc) >+{ >+ const char want[] = "$5$rounds=77777$short$JiO1O3ZpDAxGJeaDIuqCoEFysAe1mZNJRs3pw0KQRd/"; >+ char *pw; >+ >+ pw = crypt("we have a short salt string but not a short password", "$5$rounds=77777$short"); >+ ATF_CHECK_STREQ(pw, want); >+} >+ >+ATF_TC(sha256_vector_6); >+ATF_TC_HEAD(sha256_vector_6, tc) >+{ >+ atf_tc_set_md_var(tc, "descr", "Test vector from crypt-sha256.c"); >+} >+ >+ATF_TC_BODY(sha256_vector_6, tc) >+{ >+ const char want[] = "$5$rounds=123456$asaltof16chars..$gP3VQ/6X7UUEW3HkBn2w1/Ptq2jxPyzV/" >+ "cZKmF/wJvD"; >+ char *pw; >+ >+ pw = crypt("a short string", "$5$rounds=123456$asaltof16chars.."); >+ ATF_CHECK_STREQ(pw, want); >+} >+ >+ATF_TC(sha256_vector_7); >+ATF_TC_HEAD(sha256_vector_7, tc) >+{ >+ atf_tc_set_md_var(tc, "descr", "Test vector from crypt-sha256.c"); >+} >+ >+ATF_TC_BODY(sha256_vector_7, tc) >+{ >+ const char want[] = "$5$rounds=1000$roundstoolow$yfvwcWrQ8l/K0DAWyuPMDNHpIVlTQebY9l/gL97" >+ "2bIC"; >+ char *pw; >+ >+ pw = crypt("the minimum number is still observed", "$5$rounds=10$roundstoolow"); >+ ATF_CHECK_STREQ(pw, want); >+} >+ >+ATF_TC(sha512_vector_1); >+ATF_TC_HEAD(sha512_vector_1, tc) >+{ >+ atf_tc_set_md_var(tc, "descr", "Test vector from crypt-sha512.c"); >+} >+ >+ATF_TC_BODY(sha512_vector_1, tc) >+{ >+ const char want[] = "$6$saltstring$svn8UoSVapNtMuq1ukKS4tPQd8iKwSMHWjl/O817G3uBnIFNjnQJu" >+ "esI68u4OTLiBFdcbYEdFCoEOfaS35inz1"; >+ char *pw; >+ >+ pw = crypt("Hello world!", "$6$saltstring"); >+ ATF_CHECK_STREQ(pw, want); >+} >+ >+ATF_TC(sha512_vector_2); >+ATF_TC_HEAD(sha512_vector_2, tc) >+{ >+ atf_tc_set_md_var(tc, "descr", "Test vector from crypt-sha512.c"); >+} >+ >+ATF_TC_BODY(sha512_vector_2, tc) >+{ >+ const char want[] = "$6$rounds=10000$saltstringsaltst$OW1/O6BYHV6BcXZu8QVeXbDWra3Oeqh0sb" >+ "HbbMCVNSnCM/UrjmM0Dp8vOuZeHBy/YTBmSK6H9qs/y3RnOaw5v."; >+ char *pw; >+ >+ pw = crypt("Hello world!", "$6$rounds=10000$saltstringsaltstring"); >+ ATF_CHECK_STREQ(pw, want); >+} >+ >+ATF_TC(sha512_vector_3); >+ATF_TC_HEAD(sha512_vector_3, tc) >+{ >+ atf_tc_set_md_var(tc, "descr", "Test vector from crypt-sha512.c"); >+} >+ >+ATF_TC_BODY(sha512_vector_3, tc) >+{ >+ const char want[] = "$6$rounds=5000$toolongsaltstrin$lQ8jolhgVRVhY4b5pZKaysCLi0QBxGoNeKQ" >+ "zQ3glMhwllF7oGDZxUhx1yxdYcz/e1JSbq3y6JMxxl8audkUEm0"; >+ char *pw; >+ >+ pw = crypt("This is just a test", "$6$rounds=5000$toolongsaltstring"); >+ ATF_CHECK_STREQ(pw, want); >+} >+ >+ATF_TC(sha512_vector_4); >+ATF_TC_HEAD(sha512_vector_4, tc) >+{ >+ atf_tc_set_md_var(tc, "descr", "Test vector from crypt-sha512.c"); >+} >+ >+ATF_TC_BODY(sha512_vector_4, tc) >+{ >+ const char want[] = "$6$rounds=1400$anotherlongsalts$POfYwTEok97VWcjxIiSOjiykti.o/pQs.wP" >+ "vMxQ6Fm7I6IoYN3CmLs66x9t0oSwbtEW7o7UmJEiDwGqd8p4ur1"; >+ char *pw; >+ >+ pw = crypt("a very much longer text to encrypt. This one even stretches over more" >+ "than one line.", "$6$rounds=1400$anotherlongsaltstring"); >+ ATF_CHECK_STREQ(pw, want); >+} >+ >+ATF_TC(sha512_vector_5); >+ATF_TC_HEAD(sha512_vector_5, tc) >+{ >+ atf_tc_set_md_var(tc, "descr", "Test vector from crypt-sha512.c"); >+} >+ >+ATF_TC_BODY(sha512_vector_5, tc) >+{ >+ const char want[] = "$6$rounds=77777$short$WuQyW2YR.hBNpjjRhpYD/ifIw05xdfeEyQoMxIXbkvr0g" >+ "ge1a1x3yRULJ5CCaUeOxFmtlcGZelFl5CxtgfiAc0"; >+ char *pw; >+ >+ pw = crypt("we have a short salt string but not a short password", "$6$rounds=77777$short"); >+ ATF_CHECK_STREQ(pw, want); >+} >+ >+ATF_TC(sha512_vector_6); >+ATF_TC_HEAD(sha512_vector_6, tc) >+{ >+ atf_tc_set_md_var(tc, "descr", "Test vector from crypt-sha512.c"); >+} >+ >+ATF_TC_BODY(sha512_vector_6, tc) >+{ >+ const char want[] = "$6$rounds=123456$asaltof16chars..$BtCwjqMJGx5hrJhZywWvt0RLE8uZ4oPwc" >+ "elCjmw2kSYu.Ec6ycULevoBK25fs2xXgMNrCzIMVcgEJAstJeonj1"; >+ char *pw; >+ >+ pw = crypt("a short string", "$6$rounds=123456$asaltof16chars.."); >+ ATF_CHECK_STREQ(pw, want); >+} >+ >+ATF_TC(sha512_vector_7); >+ATF_TC_HEAD(sha512_vector_7, tc) >+{ >+ atf_tc_set_md_var(tc, "descr", "Test vector from crypt-sha512.c"); >+} >+ >+ATF_TC_BODY(sha512_vector_7, tc) >+{ >+ const char want[] = "$6$rounds=1000$roundstoolow$kUMsbe306n21p9R.FRkW3IGn.S9NPN0x50YhH1x" >+ "hLsPuWGsUSklZt58jaTfF4ZEQpyUNGc0dqbpBYYBaHHrsX."; >+ char *pw; >+ >+ pw = crypt("the minimum number is still observed", "$6$rounds=10$roundstoolow"); >+ ATF_CHECK_STREQ(pw, want); >+} >+ >+#ifdef HAS_BLOWFISH >+ATF_TC(blf_vector_1); >+ATF_TC_HEAD(blf_vector_1, tc) >+{ >+ atf_tc_set_md_var(tc, "descr", "Solar Designer wrapper.c test vector 1"); >+} >+ >+ATF_TC_BODY(blf_vector_1, tc) >+{ >+ const char want[] = "$2a$05$CCCCCCCCCCCCCCCCCCCCC.E5YPO9kmyuRGyh0XouQYb4YMJKvyOeW"; >+ char *pw; >+ >+ pw = crypt("U*U", want); >+ >+ ATF_CHECK_STREQ(pw, want); >+} >+ >+ATF_TC(blf_vector_2); >+ATF_TC_HEAD(blf_vector_2, tc) >+{ >+ atf_tc_set_md_var(tc, "descr", "Solar Designer wrapper.c test vector 2"); >+} >+ >+ATF_TC_BODY(blf_vector_2, tc) >+{ >+ const char want[] = "$2a$05$CCCCCCCCCCCCCCCCCCCCC.VGOzA784oUp/Z0DY336zx7pLYAy0lwK"; >+ char *pw; >+ >+ pw = crypt("U*U*", want); >+ >+ ATF_CHECK_STREQ(pw, want); >+} >+ >+ATF_TC(blf_vector_3); >+ATF_TC_HEAD(blf_vector_3, tc) >+{ >+ atf_tc_set_md_var(tc, "descr", "Solar Designer wrapper.c test vector 3 - long password"); >+} >+ >+ATF_TC_BODY(blf_vector_3, tc) >+{ >+ const char want[] = "$2a$05$abcdefghijklmnopqrstuu5s2v8.iXieOjg/.AySBTTZIIVFJeBui"; >+ char *pw; >+ >+ pw = crypt("0123456789abcdefghijklmnopqrstuvwxyz" >+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" >+ "chars after 72 are ignored", want); >+ >+ ATF_CHECK_STREQ(pw, want); >+} >+ >+ATF_TC(blf_vector_4); >+ATF_TC_HEAD(blf_vector_4, tc) >+{ >+ atf_tc_set_md_var(tc, "descr", "Solar Designer wrapper.c test vector 4"); >+} >+ >+ATF_TC_BODY(blf_vector_4, tc) >+{ >+ const char want[] = "$2b$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e"; >+ char *pw; >+ >+ pw = crypt("\xff\xff\xa3", want); >+ >+ ATF_CHECK_STREQ(pw, want); >+} >+ >+ATF_TC(blf_vector_5); >+ATF_TC_HEAD(blf_vector_5, tc) >+{ >+ atf_tc_set_md_var(tc, "descr", "Solar Designer wrapper.c test vector 5 - ensure our $2a$05$ matches the $2y$05$"); >+} >+ >+ATF_TC_BODY(blf_vector_5, tc) >+{ >+ const char want[] = "$2a$05$/OK.fbVrR/bpIqNJ5ianF.nRht2l/HRhr6zmCp9vYUvvsqynflf9e"; >+ char *pw; >+ >+ pw = crypt("\xff\xa3" "345", want); >+ >+ ATF_CHECK_STREQ(pw, want); >+} >+ >+#endif >+ > /* > * This function must not do anything except enumerate > * the test cases, per atf-c-api(3). > */ > ATF_TP_ADD_TCS(tp) > { >- > ATF_TP_ADD_TC(tp, md5); >- ATF_TP_ADD_TC(tp, invalid); >+ ATF_TP_ADD_TC(tp, md5invalid); >+ >+ ATF_TP_ADD_TC(tp, sha256_vector_1); >+ ATF_TP_ADD_TC(tp, sha256_vector_2); >+ ATF_TP_ADD_TC(tp, sha256_vector_3); >+ ATF_TP_ADD_TC(tp, sha256_vector_4); >+/* >+ ATF_TP_ADD_TC(tp, sha256_vector_5); >+ ATF_TP_ADD_TC(tp, sha256_vector_6); >+*/ >+ ATF_TP_ADD_TC(tp, sha256_vector_7); >+ >+ ATF_TP_ADD_TC(tp, sha512_vector_1); >+ ATF_TP_ADD_TC(tp, sha512_vector_2); >+ ATF_TP_ADD_TC(tp, sha512_vector_3); >+ ATF_TP_ADD_TC(tp, sha512_vector_4); >+/* >+ ATF_TP_ADD_TC(tp, sha512_vector_5); >+ ATF_TP_ADD_TC(tp, sha512_vector_6); >+*/ >+ ATF_TP_ADD_TC(tp, sha512_vector_7); >+ >+#ifdef HAS_BLOWFISH >+ ATF_TP_ADD_TC(tp, blf_vector_1); >+ ATF_TP_ADD_TC(tp, blf_vector_2); >+ ATF_TP_ADD_TC(tp, blf_vector_3); >+ ATF_TP_ADD_TC(tp, blf_vector_4); >+ ATF_TP_ADD_TC(tp, blf_vector_5); >+#endif >+ > return atf_no_error(); > } >diff --git a/lib/libpam/modules/pam_unix/pam_unix.c b/lib/libpam/modules/pam_unix/pam_unix.c >index 0ac5782..153bd2e 100644 >--- a/lib/libpam/modules/pam_unix/pam_unix.c >+++ b/lib/libpam/modules/pam_unix/pam_unix.c >@@ -67,17 +67,11 @@ __FBSDID("$FreeBSD: head/lib/libpam/modules/pam_unix/pam_unix.c 249177 2013-04-0 > #include <security/pam_modules.h> > #include <security/pam_mod_misc.h> > >-#define PASSWORD_HASH "md5" > #define DEFAULT_WARN (2L * 7L * 86400L) /* Two weeks */ >-#define SALTSIZE 32 > > #define LOCKED_PREFIX "*LOCKED*" > #define LOCKED_PREFIX_LEN (sizeof(LOCKED_PREFIX) - 1) > >-static void makesalt(char []); >- >-static char password_hash[] = PASSWORD_HASH; >- > #define PAM_OPT_LOCAL_PASS "local_pass" > #define PAM_OPT_NIS_PASS "nis_pass" > >@@ -269,13 +263,15 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, > struct ypclnt *ypclnt; > const void *yp_domain, *yp_server; > #endif >- char salt[SALTSIZE + 1]; >+ char salt[CRYPT_SALT_MAX_LEN + 1]; >+ size_t salt_sz; > login_cap_t *lc; > struct passwd *pwd, *old_pwd; > const char *user, *old_pass, *new_pass; > char *encrypted; > time_t passwordtime; > int pfd, tfd, retval; >+ const char *passwd_format; > > if (openpam_get_option(pamh, PAM_OPT_AUTH_AS_SELF)) > pwd = getpwnam(getlogin()); >@@ -378,10 +374,21 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, > return (PAM_BUF_ERR); > > lc = login_getclass(pwd->pw_class); >- if (login_setcryptfmt(lc, password_hash, NULL) == NULL) >- openpam_log(PAM_LOG_ERROR, >- "can't set password cipher, relying on default"); > >+ salt_sz = sizeof(salt); >+ passwd_format = login_getcapstr(lc, "passwd_format", "", NULL); >+ if (!crypt_makesalt(salt, passwd_format, &salt_sz) ) { >+ login_close(lc); >+ >+ if (salt_sz == sizeof(salt) ) { >+ PAM_LOG("Unable to create salt for crypt(3) format: %s", passwd_format); >+ } else { >+ PAM_LOG("Not enough space in buffer to create salt for format: %s. CRYPT_SALT_MAX_LEN is wrong. Buffer size: %zu, required: %zu", passwd_format, sizeof(salt), salt_sz); >+ } >+ >+ return (PAM_SERVICE_ERR); >+ } >+ > /* set password expiry date */ > pwd->pw_change = 0; > passwordtime = login_getcaptime(lc, "passwordtime", 0, 0); >@@ -389,7 +396,6 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, > pwd->pw_change = time(NULL) + passwordtime; > > login_close(lc); >- makesalt(salt); > pwd->pw_passwd = crypt(new_pass, salt); > #ifdef YP > switch (old_pwd->pw_fields & _PWF_SOURCE) { >@@ -445,33 +451,4 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, > return (retval); > } > >-/* Mostly stolen from passwd(1)'s local_passwd.c - markm */ >- >-static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ >- "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; >- >-static void >-to64(char *s, long v, int n) >-{ >- while (--n >= 0) { >- *s++ = itoa64[v&0x3f]; >- v >>= 6; >- } >-} >- >-/* Salt suitable for traditional DES and MD5 */ >-static void >-makesalt(char salt[SALTSIZE + 1]) >-{ >- int i; >- >- /* These are not really random numbers, they are just >- * numbers that change to thwart construction of a >- * dictionary. >- */ >- for (i = 0; i < SALTSIZE; i += 4) >- to64(&salt[i], arc4random(), 4); >- salt[SALTSIZE] = '\0'; >-} >- > PAM_MODULE_ENTRY("pam_unix"); >diff --git a/lib/libutil/Makefile b/lib/libutil/Makefile >index 72765da..4d919de 100644 >--- a/lib/libutil/Makefile >+++ b/lib/libutil/Makefile >@@ -12,9 +12,9 @@ SRCS= _secure_path.c auth.c expand_number.c flopen.c fparseln.c gr_util.c \ > hexdump.c humanize_number.c kinfo_getfile.c kinfo_getfile.c \ > kinfo_getallproc.c kinfo_getproc.c kinfo_getvmmap.c kld.c \ > login_auth.c login_cap.c \ >- login_class.c login_crypt.c login_ok.c login_times.c login_tty.c \ >+ login_class.c login_ok.c login_times.c login_tty.c \ > pidfile.c property.c pty.c pw_util.c quotafile.c realhostname.c \ >- stub.c trimdomain.c uucplock.c >+ trimdomain.c uucplock.c > INCS= libutil.h login_cap.h > > CFLAGS+= -DLIBC_SCCS >@@ -40,7 +40,7 @@ MLINKS+=login_cap.3 login_close.3 login_cap.3 login_getcapbool.3 \ > login_cap.3 login_getcaptime.3 login_cap.3 login_getclass.3 \ > login_cap.3 login_getclassbyname.3 login_cap.3 login_getpath.3 \ > login_cap.3 login_getpwclass.3 login_cap.3 login_getstyle.3 \ >- login_cap.3 login_getuserclass.3 login_cap.3 login_setcryptfmt.3 >+ login_cap.3 login_getuserclass.3 > MLINKS+=login_class.3 setclasscontext.3 login_class.3 setclassenvironment.3 \ > login_class.3 setclassresources.3 login_class.3 setusercontext.3 > MLINKS+=login_ok.3 auth_hostok.3 login_ok.3 auth_timeok.3 \ >diff --git a/lib/libutil/login_cap.h b/lib/libutil/login_cap.h >index 6bf4abc..76e1d65 100644 >--- a/lib/libutil/login_cap.h >+++ b/lib/libutil/login_cap.h >@@ -114,7 +114,6 @@ rlim_t login_getcapnum(login_cap_t *, const char *, rlim_t, rlim_t); > rlim_t login_getcapsize(login_cap_t *, const char *, rlim_t, rlim_t); > const char *login_getpath(login_cap_t *, const char *, const char *); > int login_getcapbool(login_cap_t *, const char *, int); >-const char *login_setcryptfmt(login_cap_t *, const char *, const char *); > > int setclasscontext(const char *, unsigned int); > void setclasscpumask(login_cap_t *); >diff --git a/lib/libutil/login_crypt.c b/lib/libutil/login_crypt.c >deleted file mode 100644 >index 92756f5..0000000 >--- a/lib/libutil/login_crypt.c >+++ /dev/null >@@ -1,50 +0,0 @@ >-/*- >- * Copyright (c) 2000 Brian Fundakowski Feldman >- * All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND >- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE >- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE >- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL >- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS >- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) >- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT >- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY >- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF >- * SUCH DAMAGE. >- */ >- >-#include <sys/cdefs.h> >-__FBSDID("$FreeBSD: head/lib/libutil/login_crypt.c 94202 2002-04-08 11:04:56Z ru $"); >- >-#include <sys/types.h> >- >-#include <login_cap.h> >-#include <stdio.h> >-#include <stdlib.h> >-#include <unistd.h> >- >-const char * >-login_setcryptfmt(login_cap_t *lc, const char *def, const char *error) { >- const char *cipher; >- >- cipher = login_getcapstr(lc, "passwd_format", def, NULL); >- if (getenv("CRYPT_DEBUG") != NULL) >- fprintf(stderr, "login_setcryptfmt: " >- "passwd_format = %s\n", cipher); >- if (cipher == NULL) >- return (error); >- if (!crypt_set_format(cipher)) >- return (error); >- return (cipher); >-} >diff --git a/lib/libutil/stub.c b/lib/libutil/stub.c >deleted file mode 100644 >index f526683..0000000 >--- a/lib/libutil/stub.c >+++ /dev/null >@@ -1,46 +0,0 @@ >-/*- >- * Copyright (c) 2000 Brian Fundakowski Feldman >- * All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND >- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE >- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE >- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL >- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS >- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) >- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT >- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY >- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF >- * SUCH DAMAGE. >- */ >- >-#include <sys/cdefs.h> >-__FBSDID("$FreeBSD: head/lib/libutil/stub.c 121193 2003-10-18 10:04:16Z markm $"); >- >-#include <stdio.h> >-#include <stdlib.h> >-#include <unistd.h> >- >-/* >- * Stub out what's in -lcrypt. >- */ >- >-#pragma weak crypt_set_format >-/* ARGSUSED */ >-int >-crypt_set_format(const char *f __unused) { >- >- if (getenv("CRYPT_DEBUG") != NULL) >- fprintf(stderr, "crypt_set_format: eek, stub called!\n"); >- return (0); >-} >diff --git a/secure/lib/libcrypt/crypt-blowfish.c b/secure/lib/libcrypt/crypt-blowfish.c >index 3671169..4d3c311 100644 >--- a/secure/lib/libcrypt/crypt-blowfish.c >+++ b/secure/lib/libcrypt/crypt-blowfish.c >@@ -75,7 +75,7 @@ __FBSDID("$FreeBSD: head/secure/lib/libcrypt/crypt-blowfish.c 265995 2014-05-14 > static void encode_base64(u_int8_t *, u_int8_t *, u_int16_t); > static void decode_base64(u_int8_t *, u_int16_t, const u_int8_t *); > >-static char encrypted[_PASSWORD_LEN]; >+static __thread char encrypted[_PASSWORD_LEN]; > > const static u_int8_t Base64Code[] = > "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; >diff --git a/usr.sbin/pw/pw.h b/usr.sbin/pw/pw.h >index 6b1ac87..d50dd00 100644 >--- a/usr.sbin/pw/pw.h >+++ b/usr.sbin/pw/pw.h >@@ -119,7 +119,7 @@ char const *boolean_str(int val); > char *newstr(char const * p); > > void pw_log(struct userconf * cnf, int mode, int which, char const * fmt,...) __printflike(4, 5); >-char *pw_pwcrypt(char *password); >+char *pw_pwcrypt(const char *password, const char *format); > > extern const char *Modes[]; > extern const char *Which[]; >diff --git a/usr.sbin/pw/pw_group.c b/usr.sbin/pw/pw_group.c >index 0712ff3..7dc21c1 100644 >--- a/usr.sbin/pw/pw_group.c >+++ b/usr.sbin/pw/pw_group.c >@@ -215,7 +215,7 @@ pw_group(struct userconf * cnf, int mode, struct cargs * args) > return EX_DATAERR; > grp->gr_passwd = line; > } else >- grp->gr_passwd = pw_pwcrypt(line); >+ grp->gr_passwd = pw_pwcrypt(line, "default"); > } > } > >diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c >index 226a604..7a2bc17 100644 >--- a/usr.sbin/pw/pw_user.c >+++ b/usr.sbin/pw/pw_user.c >@@ -59,7 +59,7 @@ static time_t pw_pwdpolicy(struct userconf * cnf, struct cargs * args); > static time_t pw_exppolicy(struct userconf * cnf, struct cargs * args); > static char *pw_homepolicy(struct userconf * cnf, struct cargs * args, char const * user); > static char *pw_shellpolicy(struct userconf * cnf, struct cargs * args, char *newshell); >-static char *pw_password(struct userconf * cnf, struct cargs * args, char const * user); >+static char *pw_password(struct userconf * cnf, struct cargs * args, char const * user, const char * format); > static char *shell_path(char const * path, char *shells[], char *sh); > static void rmat(uid_t uid); > static void rmopie(char const * name); >@@ -583,18 +583,19 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) > if ((arg = getarg(args, 'w')) != NULL && > getarg(args, 'h') == NULL && getarg(args, 'H') == NULL) { > login_cap_t *lc; >+ char passwd_format[CRYPT_FORMAT_MAX_LEN + 1]; > > lc = login_getpwclass(pwd); >- if (lc == NULL || >- login_setcryptfmt(lc, "sha512", NULL) == NULL) >- warn("setting crypt(3) format"); >+ strncpy(passwd_format, login_getcapstr(lc, "passwd_format", "", NULL), sizeof(passwd_format)); > login_close(lc); >- pwd->pw_passwd = pw_password(cnf, args, pwd->pw_name); >+ >+ pwd->pw_passwd = pw_password(cnf, args, pwd->pw_name, passwd_format); > edited = 1; > } > > } else { > login_cap_t *lc; >+ char passwd_format[CRYPT_FORMAT_MAX_LEN + 1]; > > /* > * Add code >@@ -618,10 +619,9 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) > pwd->pw_dir = pw_homepolicy(cnf, args, pwd->pw_name); > pwd->pw_shell = pw_shellpolicy(cnf, args, NULL); > lc = login_getpwclass(pwd); >- if (lc == NULL || login_setcryptfmt(lc, "sha512", NULL) == NULL) >- warn("setting crypt(3) format"); >+ strncpy(passwd_format, login_getcapstr(lc, "passwd_format", "", NULL), sizeof(passwd_format) ); > login_close(lc); >- pwd->pw_passwd = pw_password(cnf, args, pwd->pw_name); >+ pwd->pw_passwd = pw_password(cnf, args, pwd->pw_name, passwd_format); > edited = 1; > > if (pwd->pw_uid == 0 && strcmp(pwd->pw_name, "root") != 0) >@@ -653,6 +653,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) > int istty = isatty(fd); > struct termios t; > login_cap_t *lc; >+ char passwd_format[CRYPT_FORMAT_MAX_LEN + 1]; > > if (istty) { > if (tcgetattr(fd, &t) == -1) >@@ -692,11 +693,9 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) > pwd->pw_passwd = line; > } else { > lc = login_getpwclass(pwd); >- if (lc == NULL || >- login_setcryptfmt(lc, "sha512", NULL) == NULL) >- warn("setting crypt(3) format"); >+ strncpy(passwd_format, login_getcapstr(lc, "passwd_format", "", NULL), sizeof(passwd_format)); > login_close(lc); >- pwd->pw_passwd = pw_pwcrypt(line); >+ pwd->pw_passwd = pw_pwcrypt(line, passwd_format); > } > edited = 1; > } >@@ -1082,25 +1081,23 @@ pw_shellpolicy(struct userconf * cnf, struct cargs * args, char *newshell) > return shell_path(cnf->shelldir, cnf->shells, sh ? sh : cnf->shell_default); > } > >-#define SALTSIZE 32 >- >-static char const chars[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ./"; >- > char * >-pw_pwcrypt(char *password) >+pw_pwcrypt(const char *password, const char *format) > { >- int i; >- char salt[SALTSIZE + 1]; >+ char salt[CRYPT_SALT_MAX_LEN + 1]; >+ size_t salt_sz = sizeof(salt); > char *cryptpw; > >- static char buf[256]; >- >- /* >- * Calculate a salt value >- */ >- for (i = 0; i < SALTSIZE; i++) >- salt[i] = chars[arc4random_uniform(sizeof(chars) - 1)]; >- salt[SALTSIZE] = '\0'; >+ static char buf[_PASSWORD_LEN + 1]; >+ >+ if (!crypt_makesalt(salt, format, &salt_sz) ) { >+ if (salt_sz == sizeof(salt) ) { >+ errx(EX_CONFIG, "Unable to create salt for crypt(3) format: %s", format); >+ } else { >+ /* really shouldn't get here */ >+ errx(EX_CONFIG, "Not enough space to write salt to buffer. CRYPT_SALT_MAX_LEN is wrong."); >+ } >+ } > > cryptpw = crypt(password, salt); > if (cryptpw == NULL) >@@ -1110,8 +1107,9 @@ pw_pwcrypt(char *password) > > > static char * >-pw_password(struct userconf * cnf, struct cargs * args, char const * user) >+pw_password(struct userconf * cnf, struct cargs * args, char const * user, const char * format) > { >+ static char const chars[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ./!@#$%^&*()-+=<>?"; > int i, l; > char pwbuf[32]; > >@@ -1145,7 +1143,7 @@ pw_password(struct userconf * cnf, struct cargs * args, char const * user) > strlcpy(pwbuf, user, sizeof(pwbuf)); > break; > } >- return pw_pwcrypt(pwbuf); >+ return pw_pwcrypt(pwbuf, format); > } > >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 182518
:
137124
|
152839
|
154251
|
154265
|
173187
|
173188