aboutsummaryrefslogtreecommitdiff
path: root/src/vmod_basicauth.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vmod_basicauth.c')
-rw-r--r--src/vmod_basicauth.c44
1 files changed, 30 insertions, 14 deletions
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;
}

Return to:

Send suggestions and report system problems to the System administrator.