#include <strings.h>
#include "../public/auth.h"
#include "../daemon/config.h"
#include "../daemon/session.h"
#include "auth.h"
static const unsigned char pr2six[
256] = {
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
62,
64,
64,
64,
63,
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,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
64,
64,
64,
64,
64,
64,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
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,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64
};
char *_uudecode(
pool_handle_t *pool,
char *bufcoded) {
register char *bufin = bufcoded;
register unsigned char *bufout;
register int nprbytes;
unsigned char *bufplain;
int nbytesdecoded;
while(pr2six[(
int)*(bufin++)] <=
63);
nprbytes = bufin - bufcoded -
1;
nbytesdecoded = ((nprbytes+
3)/
4) *
3;
bufout = pool_malloc(pool, nbytesdecoded +
1);
bufplain = bufout;
bufin = bufcoded;
while (nprbytes >
0) {
*(bufout++) = (
unsigned char)
(pr2six[(
int)(*bufin)] <<
2 | pr2six[(
int)bufin[
1]] >>
4);
*(bufout++) = (
unsigned char)
(pr2six[(
int)bufin[
1]] <<
4 | pr2six[(
int)bufin[
2]] >>
2);
*(bufout++) = (
unsigned char)
(pr2six[(
int)bufin[
2]] <<
6 | pr2six[(
int)bufin[
3]]);
bufin +=
4;
nprbytes -=
4;
}
if(nprbytes &
03) {
if(pr2six[(
int)bufin[-
2]] >
63)
nbytesdecoded -=
2;
else
nbytesdecoded -=
1;
}
bufplain[nbytesdecoded] =
'\0';
return (
char *)bufplain;
}
int basicauth_getuser(Session *sn, Request *rq,
char **user,
char **pw) {
char *auth =
NULL;
*user =
NULL;
*pw =
NULL;
char *u;
char *p;
if(request_header(
"authorization", &auth, sn, rq) ==
REQ_ABORTED) {
return REQ_ABORTED;
}
if(!auth) {
return REQ_NOACTION;
}
while(*auth && (*auth ==
' '))
++auth;
if(!(*auth)) {
protocol_status(sn, rq,
PROTOCOL_FORBIDDEN,
NULL);
return REQ_ABORTED;
}
if((strlen(auth) <
6) || strncasecmp(auth,
"basic ",
6)) {
return REQ_NOACTION;
}
auth +=
6;
while(*auth && (*auth ==
' ')) {
++auth;
}
if(!*auth) {
return REQ_NOACTION;
}
if(!(u = _uudecode(sn->pool, auth))) {
return REQ_NOACTION;
}
if(!(p = strchr(u,
':'))) {
pool_free(sn->pool, u);
return REQ_NOACTION;
}
*p++ =
'\0';
*user = u;
*pw = p;
return REQ_PROCEED;
}
int auth_basic(pblock *param, Session *sn, Request *rq)
{
char *pwfile, *grpfile, *type, *auth, *user, *pw;
char *pwfn, *grpfn;
pblock *npb;
pb_param *pp;
int ret;
rq->directive_is_cacheable =
1;
type = pblock_findval(
"auth-type", param);
pwfile = pblock_findval(
"userdb", param);
grpfile = pblock_findval(
"groupdb", param);
pwfn = pblock_findval(
"userfn", param);
grpfn = pblock_findval(
"groupfn", param);
if((!type) || (!pwfile) || (!pwfn) || (grpfile && !grpfn)) {
log_ereport(
LOG_MISCONFIG,
"basic-auth: missing parameter");
protocol_status(sn, rq,
PROTOCOL_SERVER_ERROR,
NULL);
return REQ_ABORTED;
}
ret = basicauth_getuser(sn, rq, &user, &pw);
if(ret !=
REQ_PROCEED) {
return ret;
}
npb = pblock_create(
4);
pblock_nvinsert(
"user", user, npb);
pblock_nvinsert(
"pw", pw, npb);
pblock_nvinsert(
"userdb", pwfile, npb);
if(grpfile)
pblock_nvinsert(
"groupdb", grpfile, npb);
pblock_nvinsert(
"fn", pwfn, npb);
if ((ret = func_exec(npb, sn, rq)) !=
REQ_PROCEED)
{
goto bye;
}
pblock_nvinsert(
"auth-type",
"basic", rq->vars);
pblock_nvinsert(
"auth-user", user, rq->vars);
pblock_nvinsert(
"auth-db", pwfile, rq->vars);
#if defined(
XP_WIN32) || defined(
MCC_ADMSERV)
pblock_nvinsert(
"auth-password", pw, rq->vars);
#endif
if(grpfile) {
pblock_nvinsert(
"groupdb", grpfile, npb);
pp = pblock_find(
"fn", npb);
free(pp->value);
pp->value = strdup(grpfn);
if( (ret = func_exec(npb, sn, rq)) !=
REQ_PROCEED )
goto bye;
}
ret =
REQ_PROCEED;
bye:
pblock_free(npb);
return ret;
}
int auth_db(pblock *param, Session *sn, Request *rq) {
char *db;
char *user;
char *pw;
db = pblock_findval(
"db", param);
if(!db) {
log_ereport(
LOG_MISCONFIG,
"basic-auth: missing db parameter");
protocol_status(sn, rq,
PROTOCOL_SERVER_ERROR,
NULL);
return REQ_ABORTED;
}
int ret = basicauth_getuser(sn, rq, &user, &pw);
if(ret !=
REQ_PROCEED) {
return ret;
}
ServerConfiguration *config = session_get_config(sn);
AuthDB *authdb = cxMapGet(config->authdbs, cx_hash_key_str(db));
User *auth_user = authdb->get_user(authdb, sn, rq, user);
if(auth_user && !auth_user->verify_password(auth_user, pw)) {
fprintf(stderr,
"authdb user not authenticated: %s\n", user);
free(user);
auth_user->free(auth_user);
return REQ_NOACTION;
}
pblock_nvinsert(
"auth-type",
"basic", rq->vars);
pblock_nvinsert(
"auth-user", user, rq->vars);
pblock_nvinsert(
"auth-db", db, rq->vars);
if(auth_user) {
auth_user->free(auth_user);
}
return REQ_PROCEED;
}