diff options
Diffstat (limited to 'src/vmod_basicauth.c')
-rw-r--r-- | src/vmod_basicauth.c | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/src/vmod_basicauth.c b/src/vmod_basicauth.c index 4af9569..0e66290 100644 --- a/src/vmod_basicauth.c +++ b/src/vmod_basicauth.c @@ -25,12 +25,13 @@ #include <crypt.h> #include "vrt.h" #include "vcc_if.h" #include "basicauth.h" +#include "sha1.h" static int b64val[128] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, @@ -42,16 +43,17 @@ static int b64val[128] = { static int base64_decode(const unsigned char *input, size_t input_len, unsigned char *output, size_t output_len) { unsigned char *out = output; -#define AC(c) do { if (--output_len == 0) return -1; *out++ = (c); } while (0) +#define AC(c) do { if (output_len-- == 0) return -1; *out++ = (c); } while (0) if (!out) return -1; + do { if (input[0] > 127 || b64val[input[0]] == -1 || input[1] > 127 || b64val[input[1]] == -1 || input[2] > 127 || ((input[2] != '=') && (b64val[input[2]] == -1)) || input[3] > 127 || @@ -107,23 +109,46 @@ static int apr_match(const char *pass, const char *hash, struct priv_data *pd) { 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) +{ + 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)); + 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); + return 1; + } + sha1_buffer(pass, strlen(pass), resbuf); + + return memcmp(resbuf, hashbuf, SHA1_DIGEST_SIZE); +} /* Matcher table */ struct matcher { char *cm_pfx; size_t cm_len; int (*cm_match)(const char *, const char *, struct priv_data *); }; 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 |