8 static http_auth_scheme_t http_auth_schemes
[8];
10 const http_auth_scheme_t
* http_auth_scheme_get (const buffer
*name
)
13 while (NULL
!= http_auth_schemes
[i
].name
14 && 0 != strcmp(http_auth_schemes
[i
].name
, name
->ptr
)) {
17 return (NULL
!= http_auth_schemes
[i
].name
) ? http_auth_schemes
+i
: NULL
;
20 void http_auth_scheme_set (const http_auth_scheme_t
*scheme
)
23 while (NULL
!= http_auth_schemes
[i
].name
) ++i
;
24 /*(must resize http_auth_schemes[] if too many different auth schemes)*/
25 force_assert(i
<(sizeof(http_auth_schemes
)/sizeof(http_auth_scheme_t
))-1);
26 memcpy(http_auth_schemes
+i
, scheme
, sizeof(http_auth_scheme_t
));
30 static http_auth_backend_t http_auth_backends
[8];
32 const http_auth_backend_t
* http_auth_backend_get (const buffer
*name
)
35 while (NULL
!= http_auth_backends
[i
].name
36 && 0 != strcmp(http_auth_backends
[i
].name
, name
->ptr
)) {
39 return (NULL
!= http_auth_backends
[i
].name
) ? http_auth_backends
+i
: NULL
;
42 void http_auth_backend_set (const http_auth_backend_t
*backend
)
45 while (NULL
!= http_auth_backends
[i
].name
) ++i
;
46 /*(must resize http_auth_backends[] if too many different auth backends)*/
47 force_assert(i
<(sizeof(http_auth_backends
)/sizeof(http_auth_backend_t
))-1);
48 memcpy(http_auth_backends
+i
, backend
, sizeof(http_auth_backend_t
));
52 void http_auth_dumbdata_reset (void)
54 memset(http_auth_schemes
, 0, sizeof(http_auth_schemes
));
55 memset(http_auth_backends
, 0, sizeof(http_auth_backends
));
59 http_auth_require_t
* http_auth_require_init (void)
61 http_auth_require_t
*require
= calloc(1, sizeof(http_auth_require_t
));
62 force_assert(NULL
!= require
);
64 require
->realm
= buffer_init();
65 require
->valid_user
= 0;
66 require
->user
= array_init();
67 require
->group
= array_init();
68 require
->host
= array_init();
73 void http_auth_require_free (http_auth_require_t
* const require
)
75 buffer_free(require
->realm
);
76 array_free(require
->user
);
77 array_free(require
->group
);
78 array_free(require
->host
);
82 /* (case-sensitive version of array.c:array_get_index(),
83 * and common case expects small num of allowed tokens,
84 * so it is reasonably performant to simply walk the array) */
85 static int http_auth_array_contains (const array
* const a
, const char * const k
, const size_t klen
)
87 for (size_t i
= 0, used
= a
->used
; i
< used
; ++i
) {
88 if (buffer_is_equal_string(a
->data
[i
]->key
, k
, klen
)) {
95 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 && (require
->valid_user
99 || http_auth_array_contains(require
->user
, user
, strlen(user
)))) {
100 return 1; /* match */
104 && http_auth_array_contains(require
->group
, group
, strlen(group
))) {
105 return 1; /* match */
109 && http_auth_array_contains(require
->host
, host
, strlen(host
))) {
110 return 1; /* match */
113 return 0; /* no match */
116 void http_auth_setenv(array
*env
, const char *username
, size_t ulen
, const char *auth_type
, size_t alen
) {
121 if (NULL
== (ds
= (data_string
*)array_get_element(env
, "REMOTE_USER"))) {
122 if (NULL
== (ds
= (data_string
*)array_get_unused_element(env
, TYPE_STRING
))) {
123 ds
= data_string_init();
125 buffer_copy_string_len(ds
->key
, CONST_STR_LEN("REMOTE_USER"));
126 array_insert_unique(env
, (data_unset
*)ds
);
128 buffer_copy_string_len(ds
->value
, username
, ulen
);
132 if (NULL
== (ds
= (data_string
*)array_get_element(env
, "AUTH_TYPE"))) {
133 if (NULL
== (ds
= (data_string
*)array_get_unused_element(env
, TYPE_STRING
))) {
134 ds
= data_string_init();
136 buffer_copy_string_len(ds
->key
, CONST_STR_LEN("AUTH_TYPE"));
137 array_insert_unique(env
, (data_unset
*)ds
);
139 buffer_copy_string_len(ds
->value
, auth_type
, alen
);
142 int http_auth_md5_hex2bin (const char *md5hex
, size_t len
, unsigned char md5bin
[16])
144 /* validate and transform 32-byte MD5 hex string to 16-byte binary MD5 */
145 if (32 != len
) return -1; /*(Note: char *md5hex must be a 32-char string)*/
146 for (int i
= 0; i
< 32; i
+=2) {
148 int lo
= md5hex
[i
+1];
149 if ('0' <= hi
&& hi
<= '9') hi
-= '0';
150 else if ((hi
|= 0x20), 'a' <= hi
&& hi
<= 'f') hi
+= -'a' + 10;
152 if ('0' <= lo
&& lo
<= '9') lo
-= '0';
153 else if ((lo
|= 0x20), 'a' <= lo
&& lo
<= 'f') lo
+= -'a' + 10;
155 md5bin
[(i
>> 1)] = (unsigned char)((hi
<< 4) | lo
);
161 int http_auth_md5_hex2lc (char *md5hex
)
163 /* validate and transform 32-byte MD5 hex string to lowercase */
165 for (i
= 0; md5hex
[i
]; ++i
) {
167 if ('0' <= c
&& c
<= '9') continue;
168 else if ((c
|= 0x20), 'a' <= c
&& c
<= 'f') md5hex
[i
] = c
;
171 return (32 == i
) ? 0 : -1; /*(Note: char *md5hex must be a 32-char string)*/