From 3dca923591752bf0e43869e50ebba8bc5b71f7c6 Mon Sep 17 00:00:00 2001 From: Glenn Strauss Date: Wed, 15 Jul 2020 03:16:31 -0400 Subject: [PATCH] [mod_authn_mysql,file] use crypt() to save stack use crypt() instead of crypt_r() to save stack space, as struct crypt_data might be very large. While crypt() is not thread-safe, lighttpd is single-threaded --- src/mod_authn_file.c | 6 ++--- src/mod_authn_mysql.c | 57 ++++++++++++++----------------------------- 2 files changed, 21 insertions(+), 42 deletions(-) diff --git a/src/mod_authn_file.c b/src/mod_authn_file.c index d193eb58..a4a0fd47 100644 --- a/src/mod_authn_file.c +++ b/src/mod_authn_file.c @@ -628,7 +628,7 @@ static handler_t mod_authn_file_htpasswd_basic(request_st * const r, void *p_d, /* a simple DES password is 2 + 11 characters. everything else should be longer. */ else if (buffer_string_length(password) >= 13) { char *crypted; - #if defined(HAVE_CRYPT_R) + #if 0 && defined(HAVE_CRYPT_R) struct crypt_data crypt_tmp_data; #ifdef _AIX memset(&crypt_tmp_data, 0, sizeof(crypt_tmp_data)); @@ -676,7 +676,7 @@ static handler_t mod_authn_file_htpasswd_basic(request_st * const r, void *p_d, memcpy(sample, "$1$", sizeof("$1$")-1); memcpy(sample+sizeof("$1$")-1, b, slen); sample[sizeof("$1$")-1+slen] = '\0'; - #if defined(HAVE_CRYPT_R) + #if 0 && defined(HAVE_CRYPT_R) crypted = crypt_r(ntlmhex, sample, &crypt_tmp_data); #else crypted = crypt(ntlmhex, sample); @@ -690,7 +690,7 @@ static handler_t mod_authn_file_htpasswd_basic(request_st * const r, void *p_d, else #endif { - #if defined(HAVE_CRYPT_R) + #if 0 && defined(HAVE_CRYPT_R) crypted = crypt_r(pw, password->ptr, &crypt_tmp_data); #else crypted = crypt(pw, password->ptr); diff --git a/src/mod_authn_mysql.c b/src/mod_authn_mysql.c index 0e28e06b..47f75bfe 100644 --- a/src/mod_authn_mysql.c +++ b/src/mod_authn_mysql.c @@ -1,5 +1,3 @@ -#include "first.h" - /* mod_authn_mysql * * KNOWN LIMITATIONS: @@ -17,6 +15,17 @@ * (fixed) one-element cache for persistent connection open to last used db * TODO: db connection pool (if asynchronous requests) */ +#include "first.h" + +#if defined(HAVE_CRYPT_R) || defined(HAVE_CRYPT) +#ifndef _XOPEN_CRYPT +#define _XOPEN_CRYPT 1 +#endif +#include /* crypt() */ +#endif +#ifdef HAVE_CRYPT_H +#include +#endif #include @@ -24,18 +33,12 @@ #include "http_auth.h" #include "log.h" #include "plugin.h" +#include "safe_memclear.h" #include #include #include -#if defined(HAVE_CRYPT_R) || defined(HAVE_CRYPT) -#include /* crypt() */ -#endif -#ifdef HAVE_CRYPT_H -#include -#endif - #include "sys-crypto-md.h" typedef struct { @@ -293,36 +296,12 @@ SETDEFAULTS_FUNC(mod_authn_mysql_set_defaults) { static int mod_authn_mysql_password_cmp(const char *userpw, unsigned long userpwlen, const char *reqpw) { #if defined(HAVE_CRYPT_R) || defined(HAVE_CRYPT) - if (userpwlen >= 3 && userpw[0] == '$' && userpw[2] == '$') { - /* md5 crypt() - * request by Nicola Tiling */ - const char *saltb = userpw+3; - const char *salte = strchr(saltb, '$'); - char salt[32]; - size_t slen = (NULL != salte) ? (size_t)(salte - saltb) : sizeof(salt); - - if (slen < sizeof(salt)) { - char *crypted; - #if defined(HAVE_CRYPT_R) - struct crypt_data crypt_tmp_data; - #ifdef _AIX - memset(&crypt_tmp_data, 0, sizeof(crypt_tmp_data)); - #else - crypt_tmp_data.initialized = 0; - #endif - #endif - memcpy(salt, saltb, slen); - salt[slen] = '\0'; - - #if defined(HAVE_CRYPT_R) - crypted = crypt_r(reqpw, salt, &crypt_tmp_data); - #else - crypted = crypt(reqpw, salt); - #endif - if (NULL != crypted) { - return strcmp(userpw, crypted); - } - } + if (userpwlen >= 3 && userpw[0] == '$') { + char *crypted = crypt(reqpw, userpw); + size_t crypwlen = (NULL != crypted) ? strlen(crypted) : 0; + int rc = (crypwlen == userpwlen) ? memcmp(crypted, userpw, crypwlen) : -1; + safe_memclear(crypted, crypwlen); + return rc; } else #endif