summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sysif.c81
-rw-r--r--tests/018/crypt.tl18
-rw-r--r--txr.19
3 files changed, 37 insertions, 71 deletions
diff --git a/sysif.c b/sysif.c
index 339d9962..2043354d 100644
--- a/sysif.c
+++ b/sysif.c
@@ -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"))
diff --git a/txr.1 b/txr.1
index 959dbe33..d6278481 100644
--- a/txr.1
+++ b/txr.1
@@ -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