diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2020-02-15 17:08:49 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2020-02-15 17:08:49 -0800 |
commit | 4247fc89d9dba503a1eb6e211eae604835d782f7 (patch) | |
tree | d54ec9d63195e5af4c15fede15703ccb1b0fffff /sysif.c | |
parent | c3a0ceb2cea1a9d43f2baf5a2e63d0d712c8df19 (diff) | |
download | txr-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.c | 39 |
1 files changed, 22 insertions, 17 deletions
@@ -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 |