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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
#define _XOPEN_SOURCE
#define _DEFAULT_SOURCE
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <shadow.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include <sys/types.h>
#include "config.h"
extern char **environ;
int unauthorized() {
printf("Status: 401\n");
printf("WWW-Authenticate: Basic realm=\"%s\"\n", realm);
printf("Content-Type: text/plain\n\n");
printf("ooooo\n");
return 1;
}
char b64[] ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
char *d64(char *src, char *dec) {
char *tail;
while(1) {
unsigned char c[4];
int n = 0;
tail = src;
while(n < 4) {
char *p;
int ch;
do {
ch = *src;
if(ch == '\0') {
if(n == 0) {
tail = src;
}
goto ret;
}
src++;
p = strchr(b64, ch);
} while(!p);
ch = p - b64;
if(ch == 64)
break;
c[n] = ch;
n++;
}
if(n > 1)
*dec++ = c[0] << 2 | c[1] >> 4;
if(n > 2)
*dec++ = c[1] << 4 | c[2] >> 2;
if(n > 3)
*dec++ = c[2] << 6 | c[3];
}
ret:
return tail;
}
int main(int argc, char **argv) {
char *auth, *raw, *login, *passw, *result;
struct spwd *s;
auth = getenv("HTTP_AUTHORIZATION");
if(!auth || !*auth) return unauthorized();
if(strncmp("Basic ", auth, 6)) return unauthorized();
auth = auth + 6;
raw = calloc(1, strlen(auth));
d64(auth, raw);
login = raw;
passw = strchr(raw, ':');
if(!login || !passw) return unauthorized();
*passw++ = '\0';
s = getspnam(login);
if(!s) return unauthorized();
result = crypt(passw, s->sp_pwdp);
if(!strcmp(result, s->sp_pwdp)) {
struct passwd *user = getpwnam(login);
setgid(user->pw_gid);
setuid(user->pw_uid);
seteuid(user->pw_uid);
initgroups(login, user->pw_gid);
setenv("REMOTE_USER", login, 1);
unsetenv("HTTP_AUTHORIZATION");
return execve(script, argv, environ);
}
return unauthorized();
}
|