For *real* improvement, wouldn't storing in socache be the optimal method? On Jan 1, 2013, at 3:16 PM, s...@apache.org wrote:
> Author: sf > Date: Tue Jan 1 20:16:30 2013 > New Revision: 1427548 > > URL: http://svn.apache.org/viewvc?rev=1427548&view=rev > Log: > Add some caching for password hash validation. > > Password hash functions must be expensive in order to be secure. But > if they have to be re-evaluated for every request, performance > suffers. > > As a minimal remedy, cache the most recent result for every > connection. This gives a great performance boost if a web browser > does many requests on the same connection with the same > user+password. In principle, this may keep the plain text password > around longer than before. But in practice, there won't be much > difference since user+password can already remain in some unused > data bucket for longer than the request duration. > > A proper solution still needs to be found for connections from > proxies which may carry requests for many different users. > > While it currently only requires the conn_rec, the new > ap_password_validate() function takes username and request_rec to > allow future extensions, like detection of brute-force attempts. > > > Modified: > httpd/httpd/trunk/CHANGES > httpd/httpd/trunk/include/ap_mmn.h > httpd/httpd/trunk/include/httpd.h > httpd/httpd/trunk/modules/aaa/mod_authn_dbd.c > httpd/httpd/trunk/modules/aaa/mod_authn_dbm.c > httpd/httpd/trunk/modules/aaa/mod_authn_file.c > httpd/httpd/trunk/modules/aaa/mod_authn_socache.c > httpd/httpd/trunk/server/util.c > > Modified: httpd/httpd/trunk/CHANGES > URL: > http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1427548&r1=1427547&r2=1427548&view=diff > ============================================================================== > --- httpd/httpd/trunk/CHANGES [utf-8] (original) > +++ httpd/httpd/trunk/CHANGES [utf-8] Tue Jan 1 20:16:30 2013 > @@ -1,6 +1,11 @@ > -*- coding: utf-8 -*- > Changes with Apache 2.5.0 > > + *) mod_authn_file, mod_authn_dbd, mod_authn_dbm, mod_authn_socache: > + Cache the result of the most recent password hash verification for every > + keep-alive connection. This saves some expensive calculations. > + [Stefan Fritsch] > + > *) http: Remove support for Request-Range header sent by Navigator 2-3 and > MSIE 3. [Stefan Fritsch] > > > Modified: httpd/httpd/trunk/include/ap_mmn.h > URL: > http://svn.apache.org/viewvc/httpd/httpd/trunk/include/ap_mmn.h?rev=1427548&r1=1427547&r2=1427548&view=diff > ============================================================================== > --- httpd/httpd/trunk/include/ap_mmn.h (original) > +++ httpd/httpd/trunk/include/ap_mmn.h Tue Jan 1 20:16:30 2013 > @@ -412,6 +412,7 @@ > * core_server_config again, add http09_enable > * 20121222.1 (2.5.0-dev) Add http_conformance to core_server_config, > * add ap_has_cntrl() > + * 20121222.2 (2.5.0-dev) Add ap_password_validate() > */ > > #define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */ > @@ -419,7 +420,7 @@ > #ifndef MODULE_MAGIC_NUMBER_MAJOR > #define MODULE_MAGIC_NUMBER_MAJOR 20121222 > #endif > -#define MODULE_MAGIC_NUMBER_MINOR 1 /* 0...n */ > +#define MODULE_MAGIC_NUMBER_MINOR 2 /* 0...n */ > > /** > * Determine if the server's current MODULE_MAGIC_NUMBER is at least a > > Modified: httpd/httpd/trunk/include/httpd.h > URL: > http://svn.apache.org/viewvc/httpd/httpd/trunk/include/httpd.h?rev=1427548&r1=1427547&r2=1427548&view=diff > ============================================================================== > --- httpd/httpd/trunk/include/httpd.h (original) > +++ httpd/httpd/trunk/include/httpd.h Tue Jan 1 20:16:30 2013 > @@ -2274,6 +2274,24 @@ AP_DECLARE(void) ap_bin2hex(const void * > AP_DECLARE(int) ap_has_cntrl(const char *str) > AP_FN_ATTR_NONNULL_ALL; > > +/** > + * Wrapper for @a apr_password_validate() to cache expensive calculations > + * @param r the current request > + * @param username username of the user > + * @param passwd password string > + * @param hash hash string to be passwd to @a apr_password_validate() > + * @return APR_SUCCESS if passwords match, APR_EMISMATCH or error otherwise > + * @note Currently, ap_password_validate() only caches the result of the > + * most recent call with the same connection as @a r. > + * In the future, it may also do rate-limiting against brute-force > + * attacks. > + */ > +AP_DECLARE(apr_status_t) ap_password_validate(request_rec *r, > + const char *username, > + const char *passwd, > + const char *hash); > + > + > #define AP_NORESTART APR_OS_START_USEERR + 1 > > #ifdef __cplusplus > > Modified: httpd/httpd/trunk/modules/aaa/mod_authn_dbd.c > URL: > http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/aaa/mod_authn_dbd.c?rev=1427548&r1=1427547&r2=1427548&view=diff > ============================================================================== > --- httpd/httpd/trunk/modules/aaa/mod_authn_dbd.c (original) > +++ httpd/httpd/trunk/modules/aaa/mod_authn_dbd.c Tue Jan 1 20:16:30 2013 > @@ -179,7 +179,7 @@ static authn_status authn_dbd_password(r > } > AUTHN_CACHE_STORE(r, user, NULL, dbd_password); > > - rv = apr_password_validate(password, dbd_password); > + rv = ap_password_validate(r, user, password, dbd_password); > > if (rv != APR_SUCCESS) { > return AUTH_DENIED; > > Modified: httpd/httpd/trunk/modules/aaa/mod_authn_dbm.c > URL: > http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/aaa/mod_authn_dbm.c?rev=1427548&r1=1427547&r2=1427548&view=diff > ============================================================================== > --- httpd/httpd/trunk/modules/aaa/mod_authn_dbm.c (original) > +++ httpd/httpd/trunk/modules/aaa/mod_authn_dbm.c Tue Jan 1 20:16:30 2013 > @@ -27,7 +27,6 @@ > #include "apr_want.h" > #include "apr_strings.h" > #include "apr_dbm.h" > -#include "apr_md5.h" /* for apr_password_validate */ > > #include "ap_provider.h" > #include "httpd.h" > @@ -144,7 +143,7 @@ static authn_status check_dbm_pw(request > } > AUTHN_CACHE_STORE(r, user, NULL, dbm_password); > > - rv = apr_password_validate(password, dbm_password); > + rv = ap_password_validate(r, user, password, dbm_password); > > if (rv != APR_SUCCESS) { > return AUTH_DENIED; > > Modified: httpd/httpd/trunk/modules/aaa/mod_authn_file.c > URL: > http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/aaa/mod_authn_file.c?rev=1427548&r1=1427547&r2=1427548&view=diff > ============================================================================== > --- httpd/httpd/trunk/modules/aaa/mod_authn_file.c (original) > +++ httpd/httpd/trunk/modules/aaa/mod_authn_file.c Tue Jan 1 20:16:30 2013 > @@ -15,7 +15,6 @@ > */ > > #include "apr_strings.h" > -#include "apr_md5.h" /* for apr_password_validate */ > > #include "ap_config.h" > #include "ap_provider.h" > @@ -112,7 +111,7 @@ static authn_status check_password(reque > } > AUTHN_CACHE_STORE(r, user, NULL, file_password); > > - status = apr_password_validate(password, file_password); > + status = ap_password_validate(r, user, password, file_password); > if (status != APR_SUCCESS) { > return AUTH_DENIED; > } > > Modified: httpd/httpd/trunk/modules/aaa/mod_authn_socache.c > URL: > http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/aaa/mod_authn_socache.c?rev=1427548&r1=1427547&r2=1427548&view=diff > ============================================================================== > --- httpd/httpd/trunk/modules/aaa/mod_authn_socache.c (original) > +++ httpd/httpd/trunk/modules/aaa/mod_authn_socache.c Tue Jan 1 20:16:30 2013 > @@ -15,7 +15,6 @@ > */ > > #include "apr_strings.h" > -#include "apr_md5.h" /* for apr_password_validate */ > > #include "ap_config.h" > #include "ap_provider.h" > @@ -375,7 +374,7 @@ static authn_status check_password(reque > return AUTH_USER_NOT_FOUND; > } > > - rv = apr_password_validate(password, (char*) val); > + rv = ap_password_validate(r, user, password, (char*) val); > if (rv != APR_SUCCESS) { > return AUTH_DENIED; > } > > Modified: httpd/httpd/trunk/server/util.c > URL: > http://svn.apache.org/viewvc/httpd/httpd/trunk/server/util.c?rev=1427548&r1=1427547&r2=1427548&view=diff > ============================================================================== > --- httpd/httpd/trunk/server/util.c (original) > +++ httpd/httpd/trunk/server/util.c Tue Jan 1 20:16:30 2013 > @@ -30,6 +30,7 @@ > #include "apr.h" > #include "apr_strings.h" > #include "apr_lib.h" > +#include "apr_md5.h" /* for apr_password_validate */ > > #define APR_WANT_STDIO > #define APR_WANT_STRFUNC > @@ -2896,3 +2897,42 @@ AP_DECLARE(void) ap_get_loadavg(ap_loada > } > #endif > } > + > +static const char * const pw_cache_note_name = "conn_cache_note"; > +struct pw_cache { > + /* varbuf contains concatenated password and hash */ > + struct ap_varbuf vb; > + apr_size_t pwlen; > + apr_status_t result; > +}; > + > +AP_DECLARE(apr_status_t) ap_password_validate(request_rec *r, > + const char *username, > + const char *passwd, > + const char *hash) > +{ > + struct pw_cache *cache; > + apr_size_t hashlen; > + > + cache = (struct pw_cache *)apr_table_get(r->connection->notes, > pw_cache_note_name); > + if (cache != NULL) { > + if (strncmp(passwd, cache->vb.buf, cache->pwlen) == 0 > + && strcmp(hash, cache->vb.buf + cache->pwlen) == 0) { > + return cache->result; > + } > + /* make ap_varbuf_grow below not copy the old data */ > + cache->vb.strlen = 0; > + } > + else { > + cache = apr_palloc(r->connection->pool, sizeof(struct pw_cache)); > + ap_varbuf_init(r->connection->pool, &cache->vb, 0); > + apr_table_setn(r->connection->notes, pw_cache_note_name, (void > *)cache); > + } > + cache->pwlen = strlen(passwd); > + hashlen = strlen(hash); > + ap_varbuf_grow(&cache->vb, cache->pwlen + hashlen + 1); > + memcpy(cache->vb.buf, passwd, cache->pwlen); > + memcpy(cache->vb.buf + cache->pwlen, hash, hashlen + 1); > + cache->result = apr_password_validate(passwd, hash); > + return cache->result; > +} > >