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
));
51 http_auth_require_t
* http_auth_require_init (void)
53 http_auth_require_t
*require
= calloc(1, sizeof(http_auth_require_t
));
54 force_assert(NULL
!= require
);
56 require
->realm
= buffer_init();
57 require
->valid_user
= 0;
58 require
->user
= array_init();
59 require
->group
= array_init();
60 require
->host
= array_init();
65 void http_auth_require_free (http_auth_require_t
* const require
)
67 buffer_free(require
->realm
);
68 array_free(require
->user
);
69 array_free(require
->group
);
70 array_free(require
->host
);
74 /* (case-sensitive version of array.c:array_get_index(),
75 * and common case expects small num of allowed tokens,
76 * so it is reasonably performant to simply walk the array) */
77 static int http_auth_array_contains (const array
* const a
, const char * const k
, const size_t klen
)
79 for (size_t i
= 0, used
= a
->used
; i
< used
; ++i
) {
80 if (buffer_is_equal_string(a
->data
[i
]->key
, k
, klen
)) {
87 int http_auth_match_rules (const http_auth_require_t
* const require
, const char * const user
, const char * const group
, const char * const host
)
90 && (require
->valid_user
91 || http_auth_array_contains(require
->user
, user
, strlen(user
)))) {
96 && http_auth_array_contains(require
->group
, group
, strlen(group
))) {
101 && http_auth_array_contains(require
->host
, host
, strlen(host
))) {
102 return 1; /* match */
105 return 0; /* no match */
108 void http_auth_setenv(array
*env
, const char *username
, size_t ulen
, const char *auth_type
, size_t alen
) {
113 if (NULL
== (ds
= (data_string
*)array_get_element(env
, "REMOTE_USER"))) {
114 if (NULL
== (ds
= (data_string
*)array_get_unused_element(env
, TYPE_STRING
))) {
115 ds
= data_string_init();
117 buffer_copy_string_len(ds
->key
, CONST_STR_LEN("REMOTE_USER"));
118 array_insert_unique(env
, (data_unset
*)ds
);
120 buffer_copy_string_len(ds
->value
, username
, ulen
);
124 if (NULL
== (ds
= (data_string
*)array_get_element(env
, "AUTH_TYPE"))) {
125 if (NULL
== (ds
= (data_string
*)array_get_unused_element(env
, TYPE_STRING
))) {
126 ds
= data_string_init();
128 buffer_copy_string_len(ds
->key
, CONST_STR_LEN("AUTH_TYPE"));
129 array_insert_unique(env
, (data_unset
*)ds
);
131 buffer_copy_string_len(ds
->value
, auth_type
, alen
);
134 int http_auth_md5_hex2bin (const char *md5hex
, size_t len
, unsigned char md5bin
[16])
136 /* validate and transform 32-byte MD5 hex string to 16-byte binary MD5 */
137 if (32 != len
) return -1; /*(Note: char *md5hex must be a 32-char string)*/
138 for (int i
= 0; i
< 32; i
+=2) {
140 int lo
= md5hex
[i
+1];
141 if ('0' <= hi
&& hi
<= '9') hi
-= '0';
142 else if ((hi
|= 0x20), 'a' <= hi
&& hi
<= 'f') hi
+= -'a' + 10;
144 if ('0' <= lo
&& lo
<= '9') lo
-= '0';
145 else if ((lo
|= 0x20), 'a' <= lo
&& lo
<= 'f') lo
+= -'a' + 10;
147 md5bin
[(i
>> 1)] = (unsigned char)((hi
<< 4) | lo
);
153 int http_auth_md5_hex2lc (char *md5hex
)
155 /* validate and transform 32-byte MD5 hex string to lowercase */
157 for (i
= 0; md5hex
[i
]; ++i
) {
159 if ('0' <= c
&& c
<= '9') continue;
160 else if ((c
|= 0x20), 'a' <= c
&& c
<= 'f') md5hex
[i
] = c
;
163 return (32 == i
) ? 0 : -1; /*(Note: char *md5hex must be a 32-char string)*/