diff options
Diffstat (limited to 'data/lighttpd/lighttpd-1.4.53/src/http_auth.c')
-rw-r--r-- | data/lighttpd/lighttpd-1.4.53/src/http_auth.c | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/data/lighttpd/lighttpd-1.4.53/src/http_auth.c b/data/lighttpd/lighttpd-1.4.53/src/http_auth.c new file mode 100644 index 000000000..484da8ff2 --- /dev/null +++ b/data/lighttpd/lighttpd-1.4.53/src/http_auth.c @@ -0,0 +1,171 @@ +#include "first.h" + +#include "http_auth.h" +#include "http_header.h" + +#include <stdlib.h> +#include <string.h> + + +static http_auth_scheme_t http_auth_schemes[8]; + +const http_auth_scheme_t * http_auth_scheme_get (const buffer *name) +{ + int i = 0; + while (NULL != http_auth_schemes[i].name + && 0 != strcmp(http_auth_schemes[i].name, name->ptr)) { + ++i; + } + return (NULL != http_auth_schemes[i].name) ? http_auth_schemes+i : NULL; +} + +void http_auth_scheme_set (const http_auth_scheme_t *scheme) +{ + unsigned int i = 0; + while (NULL != http_auth_schemes[i].name) ++i; + /*(must resize http_auth_schemes[] if too many different auth schemes)*/ + force_assert(i<(sizeof(http_auth_schemes)/sizeof(http_auth_scheme_t))-1); + memcpy(http_auth_schemes+i, scheme, sizeof(http_auth_scheme_t)); +} + + +static http_auth_backend_t http_auth_backends[12]; + +const http_auth_backend_t * http_auth_backend_get (const buffer *name) +{ + int i = 0; + while (NULL != http_auth_backends[i].name + && 0 != strcmp(http_auth_backends[i].name, name->ptr)) { + ++i; + } + return (NULL != http_auth_backends[i].name) ? http_auth_backends+i : NULL; +} + +void http_auth_backend_set (const http_auth_backend_t *backend) +{ + unsigned int i = 0; + while (NULL != http_auth_backends[i].name) ++i; + /*(must resize http_auth_backends[] if too many different auth backends)*/ + force_assert(i<(sizeof(http_auth_backends)/sizeof(http_auth_backend_t))-1); + memcpy(http_auth_backends+i, backend, sizeof(http_auth_backend_t)); +} + + +int http_auth_const_time_memeq (const char *a, const size_t alen, const char *b, const size_t blen) +{ + /* constant time memory compare, unless compiler figures it out + * (similar to mod_secdownload.c:const_time_memeq()) */ + /* round to next multiple of 64 to avoid potentially leaking exact + * password length when subject to high precision timing attacks) */ + size_t lim = ((alen >= blen ? alen : blen) + 0x3F) & ~0x3F; + int diff = 0; + for (size_t i = 0, j = 0; lim; --lim) { + diff |= (a[i] ^ b[j]); + i += (i < alen); + j += (j < blen); + } + return (0 == diff); +} + + +void http_auth_dumbdata_reset (void) +{ + memset(http_auth_schemes, 0, sizeof(http_auth_schemes)); + memset(http_auth_backends, 0, sizeof(http_auth_backends)); +} + + +http_auth_require_t * http_auth_require_init (void) +{ + http_auth_require_t *require = calloc(1, sizeof(http_auth_require_t)); + force_assert(NULL != require); + + require->realm = buffer_init(); + require->valid_user = 0; + require->user = array_init(); + require->group = array_init(); + require->host = array_init(); + + return require; +} + +void http_auth_require_free (http_auth_require_t * const require) +{ + buffer_free(require->realm); + array_free(require->user); + array_free(require->group); + array_free(require->host); + free(require); +} + +/* (case-sensitive version of array.c:array_get_index(), + * and common case expects small num of allowed tokens, + * so it is reasonably performant to simply walk the array) */ +static int http_auth_array_contains (const array * const a, const char * const k, const size_t klen) +{ + for (size_t i = 0, used = a->used; i < used; ++i) { + if (buffer_is_equal_string(a->data[i]->key, k, klen)) { + return 1; + } + } + return 0; +} + +int http_auth_match_rules (const http_auth_require_t * const require, const char * const user, const char * const group, const char * const host) +{ + if (NULL != user + && (require->valid_user + || http_auth_array_contains(require->user, user, strlen(user)))) { + return 1; /* match */ + } + + if (NULL != group + && http_auth_array_contains(require->group, group, strlen(group))) { + return 1; /* match */ + } + + if (NULL != host + && http_auth_array_contains(require->host, host, strlen(host))) { + return 1; /* match */ + } + + return 0; /* no match */ +} + +void http_auth_setenv(connection *con, const char *username, size_t ulen, const char *auth_type, size_t alen) { + http_header_env_set(con, CONST_STR_LEN("REMOTE_USER"), username, ulen); + http_header_env_set(con, CONST_STR_LEN("AUTH_TYPE"), auth_type, alen); +} + +int http_auth_md5_hex2bin (const char *md5hex, size_t len, unsigned char md5bin[16]) +{ + /* validate and transform 32-byte MD5 hex string to 16-byte binary MD5 */ + if (32 != len) return -1; /*(Note: char *md5hex must be a 32-char string)*/ + for (int i = 0; i < 32; i+=2) { + int hi = md5hex[i]; + int lo = md5hex[i+1]; + if ('0' <= hi && hi <= '9') hi -= '0'; + else if ((hi |= 0x20), 'a' <= hi && hi <= 'f') hi += -'a' + 10; + else return -1; + if ('0' <= lo && lo <= '9') lo -= '0'; + else if ((lo |= 0x20), 'a' <= lo && lo <= 'f') lo += -'a' + 10; + else return -1; + md5bin[(i >> 1)] = (unsigned char)((hi << 4) | lo); + } + return 0; +} + +#if 0 +int http_auth_md5_hex2lc (char *md5hex) +{ + /* validate and transform 32-byte MD5 hex string to lowercase */ + int i; + for (i = 0; md5hex[i]; ++i) { + int c = md5hex[i]; + if ('0' <= c && c <= '9') continue; + else if ((c |= 0x20), 'a' <= c && c <= 'f') md5hex[i] = c; + else return -1; + } + return (32 == i) ? 0 : -1; /*(Note: char *md5hex must be a 32-char string)*/ +} +#endif |