xref: /lighttpd1.4/src/mod_auth_api.c (revision a01e62bb)
1 /*
2  * mod_auth_api - HTTP Auth backend registration, low-level shared funcs
3  *
4  * Fully-rewritten from original
5  * Copyright(c) 2016 Glenn Strauss gstrauss()gluelogic.com  All rights reserved
6  * License: BSD 3-clause (same as lighttpd)
7  */
8 #include "first.h"
9 
10 #include "mod_auth_api.h"
11 #include "http_header.h"
12 
13 #include <stdlib.h>
14 #include <string.h>
15 
16 
17 static http_auth_scheme_t http_auth_schemes[8];
18 
19 const http_auth_scheme_t * http_auth_scheme_get (const buffer *name)
20 {
21     int i = 0;
22     while (NULL != http_auth_schemes[i].name
23            && 0 != strcmp(http_auth_schemes[i].name, name->ptr)) {
24         ++i;
25     }
26     return (NULL != http_auth_schemes[i].name) ? http_auth_schemes+i : NULL;
27 }
28 
29 void http_auth_scheme_set (const http_auth_scheme_t *scheme)
30 {
31     unsigned int i = 0;
32     while (NULL != http_auth_schemes[i].name) ++i;
33     /*(must resize http_auth_schemes[] if too many different auth schemes)*/
34     force_assert(i<(sizeof(http_auth_schemes)/sizeof(http_auth_scheme_t))-1);
35     memcpy(http_auth_schemes+i, scheme, sizeof(http_auth_scheme_t));
36 }
37 
38 
39 static http_auth_backend_t http_auth_backends[12];
40 
41 const http_auth_backend_t * http_auth_backend_get (const buffer *name)
42 {
43     int i = 0;
44     while (NULL != http_auth_backends[i].name
45            && 0 != strcmp(http_auth_backends[i].name, name->ptr)) {
46         ++i;
47     }
48     return (NULL != http_auth_backends[i].name) ? http_auth_backends+i : NULL;
49 }
50 
51 void http_auth_backend_set (const http_auth_backend_t *backend)
52 {
53     unsigned int i = 0;
54     while (NULL != http_auth_backends[i].name) ++i;
55     /*(must resize http_auth_backends[] if too many different auth backends)*/
56     force_assert(i<(sizeof(http_auth_backends)/sizeof(http_auth_backend_t))-1);
57     memcpy(http_auth_backends+i, backend, sizeof(http_auth_backend_t));
58 }
59 
60 
61 void http_auth_dumbdata_reset (void)
62 {
63     memset(http_auth_schemes, 0, sizeof(http_auth_schemes));
64     memset(http_auth_backends, 0, sizeof(http_auth_backends));
65 }
66 
67 
68 http_auth_require_t * http_auth_require_init (void)
69 {
70     http_auth_require_t *require = calloc(1, sizeof(http_auth_require_t));
71     force_assert(NULL != require);
72     return require;
73 }
74 
75 void http_auth_require_free (http_auth_require_t * const require)
76 {
77     array_free_data(&require->user);
78     array_free_data(&require->group);
79     array_free_data(&require->host);
80     free(require);
81 }
82 
83 /* (case-sensitive version of array.c:array_get_index(),
84  *  and common case expects small num of allowed tokens,
85  *  so it is reasonably performant to simply walk the array) */
86 __attribute_pure__
87 static int http_auth_array_contains (const array * const a, const char * const k, const size_t klen)
88 {
89     for (size_t i = 0, used = a->used; i < used; ++i) {
90         if (buffer_eq_slen(&((data_string *)a->data[i])->value, k, klen))
91             return 1;
92     }
93     return 0;
94 }
95 
96 int http_auth_match_rules (const http_auth_require_t * const require, const char * const user, const char * const group, const char * const host)
97 {
98     if (NULL != user
99         && (require->valid_user
100             || http_auth_array_contains(&require->user, user, strlen(user)))) {
101         return 1; /* match */
102     }
103 
104     if (NULL != group
105         && http_auth_array_contains(&require->group, group, strlen(group))) {
106         return 1; /* match */
107     }
108 
109     if (NULL != host
110         && http_auth_array_contains(&require->host, host, strlen(host))) {
111         return 1; /* match */
112     }
113 
114     return 0; /* no match */
115 }
116 
117 void http_auth_setenv(request_st * const r, const char *username, size_t ulen, const char *auth_type, size_t alen) {
118     http_header_env_set(r, CONST_STR_LEN("REMOTE_USER"), username, ulen);
119     http_header_env_set(r, CONST_STR_LEN("AUTH_TYPE"), auth_type, alen);
120 }
121 
122 unsigned int http_auth_digest_len (int algo)
123 {
124     if (algo & (HTTP_AUTH_DIGEST_SHA256 | HTTP_AUTH_DIGEST_SHA512_256)) {
125         /* HTTP_AUTH_DIGEST_SHA512_256_BINLEN */
126         return HTTP_AUTH_DIGEST_SHA256_BINLEN;
127     }
128     if (algo & HTTP_AUTH_DIGEST_MD5) {
129         return HTTP_AUTH_DIGEST_MD5_BINLEN;
130     }
131 
132     return 0;
133 }
134