aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2017-10-25 12:42:31 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2017-10-25 12:42:31 +0300
commitb1c79452b9f4cfe5ad432a7757f16d64e7050830 (patch)
treea7b9183bdeea93abae8190c71efb64ce5f67accc
parent09f076dfdab4d7b7a71bbac96848260db8f55511 (diff)
downloadvmod-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--NEWS9
-rw-r--r--configure.ac9
-rw-r--r--src/vmod_basicauth.c44
-rw-r--r--tests/aprmd5.at12
-rw-r--r--tests/crypt.at12
-rw-r--r--tests/plain.at13
-rw-r--r--tests/sha1.at12
7 files changed, 94 insertions, 17 deletions
diff --git a/NEWS b/NEWS
index 3e5f67e..5cd7a9a 100644
--- a/NEWS
+++ b/NEWS
@@ -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>
-#include <crypt.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)
@@ -91,45 +94,57 @@ get_priv_data(struct vmod_priv *priv)
struct priv_data *p = malloc(sizeof(*p));
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

Return to:

Send suggestions and report system problems to the System administrator.