1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 #include <strings.h>
35
36 #include "../public/auth.h"
37 #include "../daemon/config.h"
38 #include "../daemon/session.h"
39
40 #include "auth.h"
41
42
43
44
45 static const unsigned char pr2six[
256] = {
46 64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
47 64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
62,
64,
64,
64,
63,
48 52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
64,
64,
64,
64,
64,
64,
64,
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
49 10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
64,
64,
64,
64,
64,
64,
26,
27,
50 28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
51 64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
52 64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
53 64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
54 64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
55 64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
56 64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64
57 };
58
59 char *_uudecode(
pool_handle_t *pool,
char *bufcoded) {
60 register char *bufin = bufcoded;
61 register unsigned char *bufout;
62 register int nprbytes;
63 unsigned char *bufplain;
64 int nbytesdecoded;
65
66
67 while(pr2six[(
int)*(bufin++)] <=
63);
68 nprbytes = bufin - bufcoded -
1;
69 nbytesdecoded = ((nprbytes+
3)/
4) *
3;
70
71 bufout = pool_malloc(pool, nbytesdecoded +
1);
72 bufplain = bufout;
73
74 bufin = bufcoded;
75
76 while (nprbytes >
0) {
77 *(bufout++) = (
unsigned char)
78 (pr2six[(
int)(*bufin)] <<
2 | pr2six[(
int)bufin[
1]] >>
4);
79 *(bufout++) = (
unsigned char)
80 (pr2six[(
int)bufin[
1]] <<
4 | pr2six[(
int)bufin[
2]] >>
2);
81 *(bufout++) = (
unsigned char)
82 (pr2six[(
int)bufin[
2]] <<
6 | pr2six[(
int)bufin[
3]]);
83 bufin +=
4;
84 nprbytes -=
4;
85 }
86
87 if(nprbytes &
03) {
88 if(pr2six[(
int)bufin[-
2]] >
63)
89 nbytesdecoded -=
2;
90 else
91 nbytesdecoded -=
1;
92 }
93 bufplain[nbytesdecoded] =
'\0';
94
95 return (
char *)bufplain;
96 }
97
98 int basicauth_getuser(Session *sn, Request *rq,
char **user,
char **pw) {
99 char *auth =
NULL;
100 *user =
NULL;
101 *pw =
NULL;
102 char *u;
103 char *p;
104
105 if(request_header(
"authorization", &auth, sn, rq) ==
REQ_ABORTED) {
106 return REQ_ABORTED;
107 }
108
109 if(!auth) {
110 return REQ_NOACTION;
111 }
112
113
114 while(*auth && (*auth ==
' '))
115 ++auth;
116 if(!(*auth)) {
117 protocol_status(sn, rq,
PROTOCOL_FORBIDDEN,
NULL);
118 return REQ_ABORTED;
119 }
120
121
122 if((strlen(auth) <
6) || strncasecmp(auth,
"basic ",
6)) {
123 return REQ_NOACTION;
124 }
125
126
127 auth +=
6;
128 while(*auth && (*auth ==
' ')) {
129 ++auth;
130 }
131
132 if(!*auth) {
133 return REQ_NOACTION;
134 }
135
136
137 if(!(u = _uudecode(sn->pool, auth))) {
138 return REQ_NOACTION;
139 }
140
141 if(!(p = strchr(u,
':'))) {
142 pool_free(sn->pool, u);
143 return REQ_NOACTION;
144 }
145 *p++ =
'\0';
146
147 *user = u;
148 *pw = p;
149
150 return REQ_PROCEED;
151 }
152
153
154
155 int auth_basic(pblock *param, Session *sn, Request *rq)
156 {
157 char *pwfile, *grpfile, *type, *auth, *user, *pw;
158 char *pwfn, *grpfn;
159 pblock *npb;
160 pb_param *pp;
161 int ret;
162
163
164
165
166
167
168
169 rq->directive_is_cacheable =
1;
170
171 type = pblock_findval(
"auth-type", param);
172 pwfile = pblock_findval(
"userdb", param);
173 grpfile = pblock_findval(
"groupdb", param);
174 pwfn = pblock_findval(
"userfn", param);
175 grpfn = pblock_findval(
"groupfn", param);
176
177 if((!type) || (!pwfile) || (!pwfn) || (grpfile && !grpfn)) {
178 log_ereport(
LOG_MISCONFIG,
"basic-auth: missing parameter");
179 protocol_status(sn, rq,
PROTOCOL_SERVER_ERROR,
NULL);
180 return REQ_ABORTED;
181 }
182
183 ret = basicauth_getuser(sn, rq, &user, &pw);
184 if(ret !=
REQ_PROCEED) {
185 return ret;
186 }
187
188 npb = pblock_create(
4);
189 pblock_nvinsert(
"user", user, npb);
190 pblock_nvinsert(
"pw", pw, npb);
191 pblock_nvinsert(
"userdb", pwfile, npb);
192 if(grpfile)
193 pblock_nvinsert(
"groupdb", grpfile, npb);
194 pblock_nvinsert(
"fn", pwfn, npb);
195
196 if ((ret = func_exec(npb, sn, rq)) !=
REQ_PROCEED)
197 {
198 goto bye;
199 }
200
201 pblock_nvinsert(
"auth-type",
"basic", rq->vars);
202 pblock_nvinsert(
"auth-user", user, rq->vars);
203 pblock_nvinsert(
"auth-db", pwfile, rq->vars);
204 #if defined(
XP_WIN32) || defined(
MCC_ADMSERV)
205
206
207 pblock_nvinsert(
"auth-password", pw, rq->vars);
208 #endif
209
210 if(grpfile) {
211 pblock_nvinsert(
"groupdb", grpfile, npb);
212 pp = pblock_find(
"fn", npb);
213 free(pp->value);
214 pp->value = strdup(grpfn);
215
216 if( (ret = func_exec(npb, sn, rq)) !=
REQ_PROCEED )
217 goto bye;
218 }
219 ret =
REQ_PROCEED;
220 bye:
221 pblock_free(npb);
222 return ret;
223 }
224
225 int auth_db(pblock *param, Session *sn, Request *rq) {
226 char *db;
227 char *user;
228 char *pw;
229
230 db = pblock_findval(
"db", param);
231
232 if(!db) {
233
234 log_ereport(
LOG_MISCONFIG,
"basic-auth: missing db parameter");
235 protocol_status(sn, rq,
PROTOCOL_SERVER_ERROR,
NULL);
236 return REQ_ABORTED;
237 }
238
239 int ret = basicauth_getuser(sn, rq, &user, &pw);
240 if(ret !=
REQ_PROCEED) {
241 return ret;
242 }
243
244
245 ServerConfiguration *config = session_get_config(sn);
246 sstr_t dbname = sstr(db);
247 AuthDB *authdb = ucx_map_sstr_get(config->authdbs, dbname);
248
249 User *auth_user = authdb->get_user(authdb, user);
250 if(auth_user && !auth_user->verify_password(auth_user, pw)) {
251 fprintf(stderr,
"authdb user not authenticated: %s\n", user);
252 free(user);
253 auth_user->free(auth_user);
254 return REQ_NOACTION;
255 }
256
257
258 pblock_nvinsert(
"auth-type",
"basic", rq->vars);
259 pblock_nvinsert(
"auth-user", user, rq->vars);
260 pblock_nvinsert(
"auth-db", db, rq->vars);
261
262 if(auth_user) {
263 auth_user->free(auth_user);
264 }
265
266 return REQ_PROCEED;
267 }
268