diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-10-25 12:42:31 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-10-25 12:42:31 +0300 |
commit | b1c79452b9f4cfe5ad432a7757f16d64e7050830 (patch) | |
tree | a7b9183bdeea93abae8190c71efb64ce5f67accc | |
parent | 09f076dfdab4d7b7a71bbac96848260db8f55511 (diff) | |
download | vmod-basicauth-b1c79452b9f4cfe5ad432a7757f16d64e7050830.tar.gz vmod-basicauth-b1c79452b9f4cfe5ad432a7757f16d64e7050830.tar.bz2 |
Test for the presence of crypt.h and crypt_r call. Improve the testsuite.
-rw-r--r-- | NEWS | 9 | ||||
-rw-r--r-- | configure.ac | 9 | ||||
-rw-r--r-- | src/vmod_basicauth.c | 40 | ||||
-rw-r--r-- | tests/aprmd5.at | 12 | ||||
-rw-r--r-- | tests/crypt.at | 12 | ||||
-rw-r--r-- | tests/plain.at | 13 | ||||
-rw-r--r-- | tests/sha1.at | 12 |
7 files changed, 92 insertions, 15 deletions
@@ -1,12 +1,19 @@ -Vmod-basicauth NEWS -- history of user-visible changes. 2017-08-10 +Vmod-basicauth NEWS -- history of user-visible changes. 2017-10-25 Copyright (C) 2013-2017 Sergey Poznyakoff See the end of file for copying conditions. Please send Vmod-basicauth bug reports to <gray@gnu.org> +Version 1.5.90 (Git) + +* Improved testsute + +* Doesn't require presence of the crypt_r function + + Version 1.5, 2017-08-10 * Support for Varnish 5.1 Version 1.4, 2017-08-06 diff --git a/configure.ac b/configure.ac index 416884e..bf33983 100644 --- a/configure.ac +++ b/configure.ac @@ -11,13 +11,13 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with vmod-basicauth. If not, see <http://www.gnu.org/licenses/>. AC_PREREQ(2.69) -AC_INIT([vmod-basicauth], 1.5, [gray@gnu.org]) +AC_INIT([vmod-basicauth], 1.5.90, [gray@gnu.org]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_SRCDIR(src/vmod_basicauth.vcc) AM_CONFIG_HEADER(config.h) AC_SUBST([AC_VMOD_BASENAME],[basicauth]) AC_CANONICAL_SYSTEM @@ -37,16 +37,21 @@ AC_PROG_CPP AC_PROG_INSTALL AC_PROG_LIBTOOL AC_PROG_MAKE_SET # Checks for header files. AC_HEADER_STDC -AC_CHECK_HEADERS([sys/stdlib.h]) +AC_CHECK_HEADERS([sys/stdlib.h crypt.h]) AM_VARNISHAPI([4.1],[5.1]) +saved_LIBS=$LIBS +LIBS=-lcrypt +AC_CHECK_FUNCS([crypt_r]) +LIBS=$saved_LIBS + AC_CONFIG_TESTDIR(tests) AC_CONFIG_FILES([tests/Makefile tests/atlocal]) AM_MISSING_PROG([AUTOM4TE], [autom4te]) AC_CONFIG_FILES([ Makefile diff --git a/src/vmod_basicauth.c b/src/vmod_basicauth.c index bd58140..943fba9 100644 --- a/src/vmod_basicauth.c +++ b/src/vmod_basicauth.c @@ -20,13 +20,15 @@ #include <stdlib.h> #include <errno.h> #include <string.h> #include <syslog.h> #include <unistd.h> #include <stdbool.h> +#ifdef HAVE_CRYPT_H # include <crypt.h> +#endif #include "vcl.h" #include "vrt.h" #include "vcc_if.h" #include "pthread.h" @@ -77,12 +79,13 @@ base64_decode(const unsigned char *input, size_t input_len, input += 4; input_len -= 4; } while (input_len > 0); return out - output; } +#ifdef HAVE_CRYPT_R struct priv_data { struct crypt_data cdat; }; static struct priv_data * get_priv_data(struct vmod_priv *priv) @@ -92,44 +95,56 @@ get_priv_data(struct vmod_priv *priv) p->cdat.initialized = 0; priv->priv = p; priv->free = free; } return priv->priv; } +#else +static pthread_mutex_t pass_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif /* Matchers */ static int -crypt_match(const char *pass, const char *hash, struct priv_data *pd) +crypt_match(const char *pass, const char *hash, struct vmod_priv *priv) { - return strcmp(crypt_r(pass, hash, &pd->cdat), hash); + int res; +#ifdef HAVE_CRYPT_R + res = strcmp(crypt_r(pass, hash, &get_priv_data(priv)->cdat), hash); +#else + pthread_mutex_lock(&pass_mutex); + res = strcmp(crypt(pass, hash), hash); + pthread_mutex_unlock(&pass_mutex); +#endif + return res; } static int -plain_match(const char *pass, const char *hash, struct priv_data *pd) +plain_match(const char *pass, const char *hash, struct vmod_priv *priv) { return strcmp(pass, hash); } static int -apr_match(const char *pass, const char *hash, struct priv_data *pd) +apr_match(const char *pass, const char *hash, struct vmod_priv *priv) { - unsigned char buf[120]; + char buf[120]; return strcmp(apr_md5_encode(pass, hash, buf, sizeof(buf)), hash); } #define SHA1_DIGEST_SIZE 20 static int -sha1_match(const char *pass, const char *hash, struct priv_data *pd) +sha1_match(const char *pass, const char *hash, struct vmod_priv *priv) { char hashbuf[SHA1_DIGEST_SIZE], resbuf[SHA1_DIGEST_SIZE]; int n; hash += 5; /* Skip past {SHA} */ - n = base64_decode(hash, strlen(hash), hashbuf, sizeof(hashbuf)); + n = base64_decode((const unsigned char *)hash, strlen(hash), + (unsigned char *)hashbuf, sizeof(hashbuf)); if (n < 0) { syslog(LOG_AUTHPRIV|LOG_ERR, "cannot decode %s", hash); return 1; } if (n != SHA1_DIGEST_SIZE) { syslog(LOG_AUTHPRIV|LOG_ERR, "bad hash length: %s %d", hash, n); @@ -141,34 +156,34 @@ sha1_match(const char *pass, const char *hash, struct priv_data *pd) } /* Matcher table */ struct matcher { char *cm_pfx; size_t cm_len; - int (*cm_match)(const char *, const char *, struct priv_data *); + int (*cm_match)(const char *, const char *, struct vmod_priv *priv); }; static struct matcher match_tab[] = { #define S(s) #s, sizeof(#s)-1 { S($apr1$), apr_match }, { S({SHA}), sha1_match }, { "", 0, crypt_match }, { "", 0, plain_match }, { NULL } }; static int -match(const char *pass, const char *hash, struct priv_data *pd) +match(const char *pass, const char *hash, struct vmod_priv *priv) { struct matcher *p; size_t plen = strlen(hash); for (p = match_tab; p->cm_match; p++) { if (p->cm_len < plen && memcmp(p->cm_pfx, hash, p->cm_len) == 0 && - p->cm_match(pass, hash, pd) == 0) + p->cm_match(pass, hash, priv) == 0) return 0; } return 1; } #define BASICPREF "Basic " @@ -185,13 +200,14 @@ vmod_match(MOD_CTX sp, struct vmod_priv *priv, VCL_STRING file, VCL_STRING s) int rc; // openlog("basicauth",LOG_NDELAY|LOG_PERROR|LOG_PID,LOG_AUTHPRIV); if (!s || strncmp(s, BASICPREF, BASICLEN)) return false; s += BASICLEN; - n = base64_decode(s, strlen(s), buf, sizeof(buf)); + n = base64_decode((const unsigned char *)s, strlen(s), + (unsigned char *)buf, sizeof(buf)); if (n < 0) { syslog(LOG_AUTHPRIV|LOG_ERR, "cannot decode %s", s); return false; } else if (n == sizeof(buf)) { syslog(LOG_AUTHPRIV|LOG_ERR, "hash too long"); return false; @@ -229,13 +245,13 @@ vmod_match(MOD_CTX sp, struct vmod_priv *priv, VCL_STRING file, VCL_STRING s) q = strchr(p, ':'); if (!q) continue; *q++ = 0; if (strcmp(p, buf)) continue; - rc = match(pass, q, get_priv_data(priv)) == 0; + rc = match(pass, q, priv) == 0; // syslog(LOG_AUTHPRIV|LOG_DEBUG, "user=%s, rc=%d",p,rc); break; } fclose(fp); return rc; } diff --git a/tests/aprmd5.at b/tests/aprmd5.at index 9e8f6db..d6292ef 100644 --- a/tests/aprmd5.at +++ b/tests/aprmd5.at @@ -25,8 +25,20 @@ AT_VARNISHTEST([ rxresp expect resp.http.result == true ], [ rxreq txresp ]) +AT_VARNISHTEST([ + sub vcl_deliver { + set resp.http.result = basicauth.match("\${vmod_topsrc}/tests/htpasswd", "Basic bWV0aG9kLW1kNTp3cm9uZy1wYXNzd29yZAo="); + } +], +[ txreq -url "/" + rxresp + expect resp.http.result == false +], +[ rxreq + txresp +]) AT_CLEANUP diff --git a/tests/crypt.at b/tests/crypt.at index b5e12f7..7ffbfc0 100644 --- a/tests/crypt.at +++ b/tests/crypt.at @@ -25,8 +25,20 @@ AT_VARNISHTEST([ rxresp expect resp.http.result == true ], [ rxreq txresp ]) +AT_VARNISHTEST([ + sub vcl_deliver { + set resp.http.result = basicauth.match("\${vmod_topsrc}/tests/htpasswd", "Basic bWV0aG9kLWNyeXB0Ondyb25nLXBhc3N3b3JkCg=="); + } +], +[ txreq -url "/" + rxresp + expect resp.http.result == false +], +[ rxreq + txresp +]) AT_CLEANUP diff --git a/tests/plain.at b/tests/plain.at index e6b056a..7aad896 100644 --- a/tests/plain.at +++ b/tests/plain.at @@ -25,8 +25,21 @@ AT_VARNISHTEST([ rxresp expect resp.http.result == true ], [ rxreq txresp ]) + +AT_VARNISHTEST([ + sub vcl_deliver { + set resp.http.result = basicauth.match("\${vmod_topsrc}/tests/htpasswd", "Basic bWV0aG9kLXBsYWluOndyb25nLXBhc3N3b3JkCg=="); + } +], +[ txreq -url "/" + rxresp + expect resp.http.result == false +], +[ rxreq + txresp +]) AT_CLEANUP diff --git a/tests/sha1.at b/tests/sha1.at index 1c4818a..0a45055 100644 --- a/tests/sha1.at +++ b/tests/sha1.at @@ -25,8 +25,20 @@ AT_VARNISHTEST([ rxresp expect resp.http.result == true ], [ rxreq txresp ]) +AT_VARNISHTEST([ + sub vcl_deliver { + set resp.http.result = basicauth.match("\${vmod_topsrc}/tests/htpasswd", "Basic bWV0aG9kLXNoYTE6d3JvbmctcGFzc3dvcmQK"); + } +], +[ txreq -url "/" + rxresp + expect resp.http.result == false +], +[ rxreq + txresp +]) AT_CLEANUP |