diff options
-rw-r--r-- | sysif.c | 81 | ||||
-rw-r--r-- | tests/018/crypt.tl | 18 | ||||
-rw-r--r-- | txr.1 | 9 |
3 files changed, 37 insertions, 71 deletions
@@ -2064,82 +2064,25 @@ static val getgrnam_wrap(val wname) #if HAVE_CRYPT || HAVE_CRYPT_R -static int salt_char_p(wchar_t ch) -{ - return ((ch >= 'a' && ch <= 'z') || - (ch >= 'A' && ch <= 'Z') || - (ch >= '0' && ch <= '9') || - (ch == '.') || (ch == '/')); -} - -static const wchar_t *validate_salt(const wchar_t *salt) -{ - const wchar_t *s = salt; - - if (salt_char_p(*s)) { - if (salt_char_p(*++s)) - return salt; - else - goto badsalt; - } - - if (*s++ != '$') - goto badsalt; - - switch (*s++) { - case '1': case '5': case '6': - break; - case '2': - if (*s >= 'a' && *s++ <= 'z') - break; - /* fallthrough */ - default: - goto badsalt; - } - - if (*s++ != '$') - goto badsalt; - - if (wcsncmp(s, L"rounds=", 7) == 0) { - size_t ispn = wcsspn(s += 7, L"0123456789"); - s += ispn; - if (*s++ != '$') - goto badsalt; - } - - while (salt_char_p(*s)) - s++; - - if (*s && *s != '$') - goto badsalt; - - return salt; - -badsalt: - errno = EINVAL; - return 0; -} - static val crypt_wrap(val wkey, val wsalt) { val self = lit("crypt"); const wchar_t *cwkey = c_str(wkey, self); - const wchar_t *cwsalt = validate_salt(c_str(wsalt, self)); - - if (cwsalt != 0) { - char *key = utf8_dup_to(cwkey); - char *salt = utf8_dup_to(cwsalt); + const wchar_t *cwsalt = c_str(wsalt, self); + char *key = utf8_dup_to(cwkey); + char *salt = utf8_dup_to(cwsalt); #if HAVE_CRYPT_R - struct crypt_data cd; - char *hash = (cd.initialized = 0, crypt_r(key, salt, &cd)); + struct crypt_data cd; + char *hash = (cd.initialized = 0, crypt_r(key, salt, &cd)); #else - char *hash = crypt(key, salt); + char *hash = crypt(key, salt); #endif - free(key); - free(salt); - if (hash != 0) - return string_utf8(hash); - } + + free(key); + free(salt); + + if (hash != 0) + return string_utf8(hash); uw_ethrowf(error_s, lit("crypt failed: ~d/~s"), num(errno), errno_to_str(errno), nao); diff --git a/tests/018/crypt.tl b/tests/018/crypt.tl new file mode 100644 index 00000000..55a897af --- /dev/null +++ b/tests/018/crypt.tl @@ -0,0 +1,18 @@ +(load "../common") + +(mtest + (crypt nil nil) :error + (crypt "a" "b") :error + (crypt "a" "bc") "bcshMw5X24ayQ" + (crypt "a" "bcd") "bcshMw5X24ayQ") + +(if (eq :linux (os-symbol)) + (mtest + (crypt "a" "$0$") :error + (crypt "a" "$9$") :error + (crypt "a" "$1$") "$1$$Ij31LCAysPM23KuPlm1wA/" + (crypt "a" "$1$bcd$") "$1$bcd$cgz778Ks3pkbWfyW.CWae/" + (crypt "a" "$5$") "$5$$QG6CCM7eJAxpUPcBpn0Z2K29NHtaI6Mk1fCpPrpjdj3" + (crypt "a" "$5$bcd$") "$5$bcd$OGt98FNCHtKIrT6qWAKLXOQ8eIApFT5dJngrYreMwF3" + (crypt "a" "$6$") "$6$$ek/ucQg0IM8SQLyD2D66mpoW0vAF26eA0/pqoN95V.F0nZh1IFuENNo0OikacRkDBk5frNqziMYMdVVrQ0o.51" + (crypt "a" "$6$bcd$") "$6$bcd$RK8RFj8wSE1NBJi8s.KDjGQK3EbpI474a6f4UP0LGOkQU50ZQrwykBaSjx7tZFVEpanpL44zd1p6A9q.sy.YH0")) @@ -72856,8 +72856,13 @@ platform function. The hash value is assumed to be UTF-8 and converted to Unicode characters, though it is not expected to contain anything but 7 bit ASCII characters. -Note: the underlying C library function uses a static buffer for its return -value. The return value of the \*(TL function is a copy of that buffer. +Note: if C library function +.code crypt +uses a static buffer for its return value. If that function is used, +the Lisp string returned by the \*(TL function carries its own copy of +that buffer. Where available, the +.code crypt_r +function is used which avoids static storage. .SS* Unix Signal Handling |