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
http_auth_scheme_get(const buffer * name)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
http_auth_scheme_set(const http_auth_scheme_t * scheme)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
http_auth_backend_get(const buffer * name)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
http_auth_backend_set(const http_auth_backend_t * backend)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
http_auth_dumbdata_reset(void)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
http_auth_require_init(void)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
http_auth_require_free(http_auth_require_t * const require)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__
http_auth_array_contains(const array * const a,const char * const k,const size_t klen)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_is_equal_string(&a->data[i]->key, k, klen)) {
91 return 1;
92 }
93 }
94 return 0;
95 }
96
http_auth_match_rules(const http_auth_require_t * const require,const char * const user,const char * const group,const char * const host)97 int http_auth_match_rules (const http_auth_require_t * const require, const char * const user, const char * const group, const char * const host)
98 {
99 if (NULL != user
100 && (require->valid_user
101 || http_auth_array_contains(&require->user, user, strlen(user)))) {
102 return 1; /* match */
103 }
104
105 if (NULL != group
106 && http_auth_array_contains(&require->group, group, strlen(group))) {
107 return 1; /* match */
108 }
109
110 if (NULL != host
111 && http_auth_array_contains(&require->host, host, strlen(host))) {
112 return 1; /* match */
113 }
114
115 return 0; /* no match */
116 }
117
http_auth_setenv(request_st * const r,const char * username,size_t ulen,const char * auth_type,size_t alen)118 void http_auth_setenv(request_st * const r, const char *username, size_t ulen, const char *auth_type, size_t alen) {
119 http_header_env_set(r, CONST_STR_LEN("REMOTE_USER"), username, ulen);
120 http_header_env_set(r, CONST_STR_LEN("AUTH_TYPE"), auth_type, alen);
121 }
122
http_auth_digest_len(int algo)123 unsigned int http_auth_digest_len (int algo)
124 {
125 if (algo & (HTTP_AUTH_DIGEST_SHA256 | HTTP_AUTH_DIGEST_SHA512_256)) {
126 /* HTTP_AUTH_DIGEST_SHA512_256_BINLEN */
127 return HTTP_AUTH_DIGEST_SHA256_BINLEN;
128 }
129 if (algo & HTTP_AUTH_DIGEST_MD5) {
130 return HTTP_AUTH_DIGEST_MD5_BINLEN;
131 }
132
133 return 0;
134 }
135