xref: /lighttpd1.4/src/mod_auth_api.c (revision 5e14db43)
13538f8f2SGlenn Strauss /*
23538f8f2SGlenn Strauss  * mod_auth_api - HTTP Auth backend registration, low-level shared funcs
33538f8f2SGlenn Strauss  *
43538f8f2SGlenn Strauss  * Fully-rewritten from original
53538f8f2SGlenn Strauss  * Copyright(c) 2016 Glenn Strauss gstrauss()gluelogic.com  All rights reserved
63538f8f2SGlenn Strauss  * License: BSD 3-clause (same as lighttpd)
73538f8f2SGlenn Strauss  */
83538f8f2SGlenn Strauss #include "first.h"
93538f8f2SGlenn Strauss 
103538f8f2SGlenn Strauss #include "mod_auth_api.h"
113538f8f2SGlenn Strauss #include "http_header.h"
123538f8f2SGlenn Strauss 
133538f8f2SGlenn Strauss #include <stdlib.h>
143538f8f2SGlenn Strauss #include <string.h>
153538f8f2SGlenn Strauss 
163538f8f2SGlenn Strauss 
173538f8f2SGlenn Strauss static http_auth_scheme_t http_auth_schemes[8];
183538f8f2SGlenn Strauss 
http_auth_scheme_get(const buffer * name)193538f8f2SGlenn Strauss const http_auth_scheme_t * http_auth_scheme_get (const buffer *name)
203538f8f2SGlenn Strauss {
213538f8f2SGlenn Strauss     int i = 0;
223538f8f2SGlenn Strauss     while (NULL != http_auth_schemes[i].name
233538f8f2SGlenn Strauss            && 0 != strcmp(http_auth_schemes[i].name, name->ptr)) {
243538f8f2SGlenn Strauss         ++i;
253538f8f2SGlenn Strauss     }
263538f8f2SGlenn Strauss     return (NULL != http_auth_schemes[i].name) ? http_auth_schemes+i : NULL;
273538f8f2SGlenn Strauss }
283538f8f2SGlenn Strauss 
http_auth_scheme_set(const http_auth_scheme_t * scheme)293538f8f2SGlenn Strauss void http_auth_scheme_set (const http_auth_scheme_t *scheme)
303538f8f2SGlenn Strauss {
313538f8f2SGlenn Strauss     unsigned int i = 0;
323538f8f2SGlenn Strauss     while (NULL != http_auth_schemes[i].name) ++i;
333538f8f2SGlenn Strauss     /*(must resize http_auth_schemes[] if too many different auth schemes)*/
343538f8f2SGlenn Strauss     force_assert(i<(sizeof(http_auth_schemes)/sizeof(http_auth_scheme_t))-1);
353538f8f2SGlenn Strauss     memcpy(http_auth_schemes+i, scheme, sizeof(http_auth_scheme_t));
363538f8f2SGlenn Strauss }
373538f8f2SGlenn Strauss 
383538f8f2SGlenn Strauss 
393538f8f2SGlenn Strauss static http_auth_backend_t http_auth_backends[12];
403538f8f2SGlenn Strauss 
http_auth_backend_get(const buffer * name)413538f8f2SGlenn Strauss const http_auth_backend_t * http_auth_backend_get (const buffer *name)
423538f8f2SGlenn Strauss {
433538f8f2SGlenn Strauss     int i = 0;
443538f8f2SGlenn Strauss     while (NULL != http_auth_backends[i].name
453538f8f2SGlenn Strauss            && 0 != strcmp(http_auth_backends[i].name, name->ptr)) {
463538f8f2SGlenn Strauss         ++i;
473538f8f2SGlenn Strauss     }
483538f8f2SGlenn Strauss     return (NULL != http_auth_backends[i].name) ? http_auth_backends+i : NULL;
493538f8f2SGlenn Strauss }
503538f8f2SGlenn Strauss 
http_auth_backend_set(const http_auth_backend_t * backend)513538f8f2SGlenn Strauss void http_auth_backend_set (const http_auth_backend_t *backend)
523538f8f2SGlenn Strauss {
533538f8f2SGlenn Strauss     unsigned int i = 0;
543538f8f2SGlenn Strauss     while (NULL != http_auth_backends[i].name) ++i;
553538f8f2SGlenn Strauss     /*(must resize http_auth_backends[] if too many different auth backends)*/
563538f8f2SGlenn Strauss     force_assert(i<(sizeof(http_auth_backends)/sizeof(http_auth_backend_t))-1);
573538f8f2SGlenn Strauss     memcpy(http_auth_backends+i, backend, sizeof(http_auth_backend_t));
583538f8f2SGlenn Strauss }
593538f8f2SGlenn Strauss 
603538f8f2SGlenn Strauss 
http_auth_dumbdata_reset(void)613538f8f2SGlenn Strauss void http_auth_dumbdata_reset (void)
623538f8f2SGlenn Strauss {
633538f8f2SGlenn Strauss     memset(http_auth_schemes, 0, sizeof(http_auth_schemes));
643538f8f2SGlenn Strauss     memset(http_auth_backends, 0, sizeof(http_auth_backends));
653538f8f2SGlenn Strauss }
663538f8f2SGlenn Strauss 
673538f8f2SGlenn Strauss 
http_auth_require_init(void)683538f8f2SGlenn Strauss http_auth_require_t * http_auth_require_init (void)
693538f8f2SGlenn Strauss {
70*5e14db43SGlenn Strauss     return ck_calloc(1, sizeof(http_auth_require_t));
713538f8f2SGlenn Strauss }
723538f8f2SGlenn Strauss 
http_auth_require_free(http_auth_require_t * const require)733538f8f2SGlenn Strauss void http_auth_require_free (http_auth_require_t * const require)
743538f8f2SGlenn Strauss {
753538f8f2SGlenn Strauss     array_free_data(&require->user);
763538f8f2SGlenn Strauss     array_free_data(&require->group);
773538f8f2SGlenn Strauss     array_free_data(&require->host);
783538f8f2SGlenn Strauss     free(require);
793538f8f2SGlenn Strauss }
803538f8f2SGlenn Strauss 
813538f8f2SGlenn Strauss /* (case-sensitive version of array.c:array_get_index(),
823538f8f2SGlenn Strauss  *  and common case expects small num of allowed tokens,
833538f8f2SGlenn Strauss  *  so it is reasonably performant to simply walk the array) */
843538f8f2SGlenn Strauss __attribute_pure__
http_auth_array_contains(const array * const a,const char * const k,const size_t klen)853538f8f2SGlenn Strauss static int http_auth_array_contains (const array * const a, const char * const k, const size_t klen)
863538f8f2SGlenn Strauss {
873538f8f2SGlenn Strauss     for (size_t i = 0, used = a->used; i < used; ++i) {
888b296531SGlenn Strauss         if (buffer_eq_slen(&((data_string *)a->data[i])->value, k, klen))
893538f8f2SGlenn Strauss             return 1;
903538f8f2SGlenn Strauss     }
913538f8f2SGlenn Strauss     return 0;
923538f8f2SGlenn Strauss }
933538f8f2SGlenn Strauss 
http_auth_match_rules(const http_auth_require_t * const require,const char * const user,const char * const group,const char * const host)943538f8f2SGlenn Strauss int http_auth_match_rules (const http_auth_require_t * const require, const char * const user, const char * const group, const char * const host)
953538f8f2SGlenn Strauss {
963538f8f2SGlenn Strauss     if (NULL != user
973538f8f2SGlenn Strauss         && (require->valid_user
983538f8f2SGlenn Strauss             || http_auth_array_contains(&require->user, user, strlen(user)))) {
993538f8f2SGlenn Strauss         return 1; /* match */
1003538f8f2SGlenn Strauss     }
1013538f8f2SGlenn Strauss 
1023538f8f2SGlenn Strauss     if (NULL != group
1033538f8f2SGlenn Strauss         && http_auth_array_contains(&require->group, group, strlen(group))) {
1043538f8f2SGlenn Strauss         return 1; /* match */
1053538f8f2SGlenn Strauss     }
1063538f8f2SGlenn Strauss 
1073538f8f2SGlenn Strauss     if (NULL != host
1083538f8f2SGlenn Strauss         && http_auth_array_contains(&require->host, host, strlen(host))) {
1093538f8f2SGlenn Strauss         return 1; /* match */
1103538f8f2SGlenn Strauss     }
1113538f8f2SGlenn Strauss 
1123538f8f2SGlenn Strauss     return 0; /* no match */
1133538f8f2SGlenn Strauss }
1143538f8f2SGlenn Strauss 
http_auth_setenv(request_st * const r,const char * username,size_t ulen,const char * auth_type,size_t alen)1153538f8f2SGlenn Strauss void http_auth_setenv(request_st * const r, const char *username, size_t ulen, const char *auth_type, size_t alen) {
1163538f8f2SGlenn Strauss     http_header_env_set(r, CONST_STR_LEN("REMOTE_USER"), username, ulen);
1173538f8f2SGlenn Strauss     http_header_env_set(r, CONST_STR_LEN("AUTH_TYPE"), auth_type, alen);
1183538f8f2SGlenn Strauss }
1193538f8f2SGlenn Strauss 
http_auth_digest_len(int algo)1203538f8f2SGlenn Strauss unsigned int http_auth_digest_len (int algo)
1213538f8f2SGlenn Strauss {
1223538f8f2SGlenn Strauss     if (algo & (HTTP_AUTH_DIGEST_SHA256 | HTTP_AUTH_DIGEST_SHA512_256)) {
1233538f8f2SGlenn Strauss         /* HTTP_AUTH_DIGEST_SHA512_256_BINLEN */
1243538f8f2SGlenn Strauss         return HTTP_AUTH_DIGEST_SHA256_BINLEN;
1253538f8f2SGlenn Strauss     }
1263538f8f2SGlenn Strauss     if (algo & HTTP_AUTH_DIGEST_MD5) {
1273538f8f2SGlenn Strauss         return HTTP_AUTH_DIGEST_MD5_BINLEN;
1283538f8f2SGlenn Strauss     }
1293538f8f2SGlenn Strauss 
1303538f8f2SGlenn Strauss     return 0;
1313538f8f2SGlenn Strauss }
132