summaryrefslogtreecommitdiffstats
path: root/sysif.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2020-02-15 17:08:49 -0800
committerKaz Kylheku <kaz@kylheku.com>2020-02-15 17:08:49 -0800
commit4247fc89d9dba503a1eb6e211eae604835d782f7 (patch)
treed54ec9d63195e5af4c15fede15703ccb1b0fffff /sysif.c
parentc3a0ceb2cea1a9d43f2baf5a2e63d0d712c8df19 (diff)
downloadtxr-4247fc89d9dba503a1eb6e211eae604835d782f7.tar.gz
txr-4247fc89d9dba503a1eb6e211eae604835d782f7.tar.bz2
txr-4247fc89d9dba503a1eb6e211eae604835d782f7.zip
crypt: refactor hardening a bit.
* sysif.c (validate_salt): Take const wchar_t * argument instead of val. Set errno and return null pointer instead of throwing, so we don't have two places that throw an exception related to crypt. (crypt_wrap): Put exception at the end. Return hash only if validate_salt returns a non-null pointer and so does crypt. In all other cases, reach exception call.
Diffstat (limited to 'sysif.c')
-rw-r--r--sysif.c39
1 files changed, 22 insertions, 17 deletions
diff --git a/sysif.c b/sysif.c
index cb839900..8fdeaf86 100644
--- a/sysif.c
+++ b/sysif.c
@@ -1838,9 +1838,9 @@ static int salt_char_p(wchar_t ch)
(ch == '.') || (ch == '/'));
}
-static const wchar_t *validate_salt(val salt_in)
+static const wchar_t *validate_salt(const wchar_t *salt)
{
- const wchar_t *salt = c_str(salt_in), *s = salt;
+ const wchar_t *s = salt;
if (salt_char_p(*s)) {
if (salt_char_p(*++s))
@@ -1880,29 +1880,34 @@ static const wchar_t *validate_salt(val salt_in)
goto badsalt;
return salt;
+
badsalt:
- uw_throwf(error_s, lit("crypt failed: ~d/~s"), num(EINVAL),
- string_utf8(strerror(EINVAL)), nao);
+ errno = EINVAL;
+ return 0;
}
static val crypt_wrap(val wkey, val wsalt)
{
const wchar_t *cwkey = c_str(wkey);
- const wchar_t *cwsalt = validate_salt(wsalt);
- char *key = utf8_dup_to(cwkey);
- char *salt = utf8_dup_to(cwsalt);
+ const wchar_t *cwsalt = validate_salt(c_str(wsalt));
+
+ if (cwsalt != 0) {
+ 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);
-#endif
- free(key);
- free(salt);
- if (hash == 0)
- uw_throwf(error_s, lit("crypt failed: ~d/~s"), num(errno),
- string_utf8(strerror(errno)), nao);
- return string_utf8(hash);
+ char *hash = crypt(key, salt);
+#endif
+ free(key);
+ free(salt);
+ if (hash != 0)
+ return string_utf8(hash);
+ }
+
+ uw_throwf(error_s, lit("crypt failed: ~d/~s"), num(errno),
+ string_utf8(strerror(errno)), nao);
}
#endif