summaryrefslogtreecommitdiffstats
path: root/sysif.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-10-31 07:18:41 -0700
committerKaz Kylheku <kaz@kylheku.com>2022-10-31 07:18:41 -0700
commit00d7b468e94d23646bb58b1774f5bec33b7c9fb1 (patch)
treef694ebdf6167de879ea9614279bf51b50297ac4e /sysif.c
parent746dddd01f28dc4499825c855c42aa5e95d5055a (diff)
downloadtxr-00d7b468e94d23646bb58b1774f5bec33b7c9fb1.tar.gz
txr-00d7b468e94d23646bb58b1774f5bec33b7c9fb1.tar.bz2
txr-00d7b468e94d23646bb58b1774f5bec33b7c9fb1.zip
crypt: remove dubious validator.
The validate_salt function was introduced in commit c3a0ceb2cea1a9d43f2baf5a2e63d0d712c8df19, February 2020. I cannot reproduce the internal crash in crypt which it alleges, and I neglected to mention the bad inputs in the commit or add tests. I'm not able to reproduce the alleged behavior in spite of trying all sorts of bad inputs; and looking at the crypt source in glibc, I don't see any obvious problem. And so, on this Halowe'en, we exorcise the ghost that has been haunting the crypt. * sysif.c (salt_char_p, validate_salt): Static functions removed. (crypt_wrap): Don't call validate_salt, and so cwsalt need not be tested for null. * tests/018/crypt.tl: New file. * txr.1: Mention that crypt_r is used if available, which avoids static storage.
Diffstat (limited to 'sysif.c')
-rw-r--r--sysif.c81
1 files changed, 12 insertions, 69 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);