diff options
Diffstat (limited to 'godzilla.c')
-rw-r--r-- | godzilla.c | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/godzilla.c b/godzilla.c new file mode 100644 index 0000000..002ed96 --- /dev/null +++ b/godzilla.c @@ -0,0 +1,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(); +} + |