/* * mod_auth_api - HTTP Auth backend registration, low-level shared funcs * * Fully-rewritten from original * Copyright(c) 2016 Glenn Strauss gstrauss()gluelogic.com All rights reserved * License: BSD 3-clause (same as lighttpd) */ #include "first.h" #include "mod_auth_api.h" #include "http_header.h" #include #include 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)); } 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) { return ck_calloc(1, sizeof(http_auth_require_t)); } void http_auth_require_free (http_auth_require_t * const require) { array_free_data(&require->user); array_free_data(&require->group); array_free_data(&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) */ __attribute_pure__ 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_eq_slen(&((data_string *)a->data[i])->value, 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(request_st * const r, const char *username, size_t ulen, const char *auth_type, size_t alen) { http_header_env_set(r, CONST_STR_LEN("REMOTE_USER"), username, ulen); http_header_env_set(r, CONST_STR_LEN("AUTH_TYPE"), auth_type, alen); } unsigned int http_auth_digest_len (int algo) { if (algo & (HTTP_AUTH_DIGEST_SHA256 | HTTP_AUTH_DIGEST_SHA512_256)) { /* HTTP_AUTH_DIGEST_SHA512_256_BINLEN */ return HTTP_AUTH_DIGEST_SHA256_BINLEN; } if (algo & HTTP_AUTH_DIGEST_MD5) { return HTTP_AUTH_DIGEST_MD5_BINLEN; } return 0; }