diff options
-rw-r--r-- | src/vmod_basicauth.c | 49 | ||||
-rw-r--r-- | src/vmod_basicauth.vcc | 2 |
2 files changed, 35 insertions, 16 deletions
diff --git a/src/vmod_basicauth.c b/src/vmod_basicauth.c index 9dc99c3..76dbbf3 100644 --- a/src/vmod_basicauth.c +++ b/src/vmod_basicauth.c @@ -81,54 +81,73 @@ base64_decode(const unsigned char *input, size_t input_len, } input += 4; input_len -= 4; } while (input_len > 0); return out - output; } + +static pthread_once_t thread_once = PTHREAD_ONCE_INIT; +static pthread_key_t thread_key; struct priv_data { struct crypt_data cdat; }; +static void +make_key() +{ + pthread_key_create(&thread_key, free); +} + + int init_function(struct vmod_priv *priv, const struct VCL_conf *conf) { - struct priv_data *p = malloc(sizeof(*p)); + pthread_once(&thread_once, make_key); +} + +static struct priv_data * +getpriv(void) +{ + struct priv_data *p = pthread_getspecific(thread_key); - p->cdat.initialized = 0; - priv->priv = p; - priv->free = free; - - return 0; + if (!p) { + p = malloc(sizeof(*p)); + p->cdat.initialized = 0; + if (pthread_setspecific(thread_key, p)) + abort(); + } + return p; } /* Matchers */ static int -crypt_match(const char *pass, const char *hash, struct priv_data *pd) +crypt_match(const char *pass, const char *hash) { + struct priv_data *pd = getpriv(); return strcmp(crypt_r(pass, hash, &pd->cdat), hash); } static int -plain_match(const char *pass, const char *hash, struct priv_data *pd) +plain_match(const char *pass, const char *hash) { 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) { unsigned 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) { 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)); @@ -146,44 +165,44 @@ 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 *); }; 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 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) == 0) return 0; } return 1; } #define BASICPREF "Basic " #define BASICLEN (sizeof(BASICPREF)-1) VCL_BOOL -vmod_match(MOD_CTX sp, struct vmod_priv *priv, VCL_STRING file, VCL_STRING s) +vmod_match(MOD_CTX sp, VCL_STRING file, VCL_STRING s) { char buf[1024]; char lbuf[1024]; char *pass; int n; FILE *fp; @@ -234,13 +253,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, priv->priv) == 0; + rc = match(pass, q) == 0; // syslog(LOG_AUTHPRIV|LOG_DEBUG, "user=%s, rc=%d",p,rc); break; } fclose(fp); return rc; } diff --git a/src/vmod_basicauth.vcc b/src/vmod_basicauth.vcc index cda0d66..bebc1a2 100644 --- a/src/vmod_basicauth.vcc +++ b/src/vmod_basicauth.vcc @@ -27,13 +27,13 @@ The **vmod-basicauth** module implements basic HTTP authentication against the password file created using the **htpasswd** command. Four kinds of password hashes are supported: Apache MD5, crypt, SHA1, and plaintext. $Init init_function -$Function BOOL match(PRIV_VCL, STRING, STRING) +$Function BOOL match(STRING, STRING) Description The **match** function returns **TRUE** or **FALSE** depending on whether the authentication succeeds or not. The *passfile* argument supplies the name of the password file to use. The *authstr* argument is the authentication string (normally, the value of the Authorization HTTP |