diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/auth/debug.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/auth/debug.c')
-rwxr-xr-x | sys/src/cmd/auth/debug.c | 344 |
1 files changed, 344 insertions, 0 deletions
diff --git a/sys/src/cmd/auth/debug.c b/sys/src/cmd/auth/debug.c new file mode 100755 index 000000000..56b5202bf --- /dev/null +++ b/sys/src/cmd/auth/debug.c @@ -0,0 +1,344 @@ +/* + * Test various aspects of the authentication setup. + */ + +#include <u.h> +#include <libc.h> +#include <bio.h> +#include <ndb.h> +#include <auth.h> +#include <authsrv.h> + +/* private copy with added debugging */ +int +authdial(char *netroot, char *dom) +{ + char *p; + int rv; + + if(dom != nil){ + /* look up an auth server in an authentication domain */ + p = csgetvalue(netroot, "authdom", dom, "auth", nil); + + /* if that didn't work, just try the IP domain */ + if(p == nil) + p = csgetvalue(netroot, "dom", dom, "auth", nil); + if(p == nil){ + werrstr("no auth server found for %s", dom); + return -1; + } + print("\tdialing auth server %s\n", + netmkaddr(p, netroot, "ticket")); + rv = dial(netmkaddr(p, netroot, "ticket"), 0, 0, 0); + free(p); + return rv; + } else + /* look for one relative to my machine */ + return dial(netmkaddr("$auth", netroot, "ticket"), 0, 0, 0); +} + +void +usage(void) +{ + fprint(2, "usage: auth/debug\n"); + exits("usage"); +} + +static char* +readcons(char *prompt, char *def, int raw, char *buf, int nbuf) +{ + int fdin, fdout, ctl, n, m; + char line[10]; + + fdin = open("/dev/cons", OREAD); + if(fdin < 0) + fdin = 0; + fdout = open("/dev/cons", OWRITE); + if(fdout < 0) + fdout = 1; + if(def != nil) + fprint(fdout, "%s[%s]: ", prompt, def); + else + fprint(fdout, "%s: ", prompt); + if(raw){ + ctl = open("/dev/consctl", OWRITE); + if(ctl >= 0) + write(ctl, "rawon", 5); + } else + ctl = -1; + + m = 0; + for(;;){ + n = read(fdin, line, 1); + if(n == 0){ + close(ctl); + werrstr("readcons: EOF"); + return nil; + } + if(n < 0){ + close(ctl); + werrstr("can't read cons"); + return nil; + } + if(line[0] == 0x7f) + exits(0); + if(n == 0 || line[0] == '\n' || line[0] == '\r'){ + if(raw){ + write(ctl, "rawoff", 6); + write(fdout, "\n", 1); + close(ctl); + } + buf[m] = '\0'; + if(buf[0]=='\0' && def) + strcpy(buf, def); + return buf; + } + if(line[0] == '\b'){ + if(m > 0) + m--; + }else if(line[0] == 0x15){ /* ^U: line kill */ + m = 0; + if(def != nil) + fprint(fdout, "%s[%s]: ", prompt, def); + else + fprint(fdout, "%s: ", prompt); + }else{ + if(m >= nbuf-1){ + fprint(fdout, "line too long\n"); + m = 0; + if(def != nil) + fprint(fdout, "%s[%s]: ", prompt, def); + else + fprint(fdout, "%s: ", prompt); + }else + buf[m++] = line[0]; + } + } +} + +void authdialfutz(char*, char*); +void authfutz(char*, char*); + +/* scan factotum for p9sk1 keys; check them */ +void +debugfactotumkeys(void) +{ + char *s, *dom, *proto, *user; + int found; + Attr *a; + Biobuf *b; + + b = Bopen("/mnt/factotum/ctl", OREAD); + if(b == nil){ + fprint(2, "debug: cannot open /mnt/factotum/ctl\n"); + return; + } + found = 0; + while((s = Brdstr(b, '\n', 1)) != nil){ + if(strncmp(s, "key ", 4) != 0){ + print("malformed ctl line: %s\n", s); + free(s); + continue; + } + a = _parseattr(s+4); + free(s); + proto = _strfindattr(a, "proto"); + if(proto==nil || strcmp(proto, "p9sk1")!=0) + continue; + dom = _strfindattr(a, "dom"); + if(dom == nil){ + print("p9sk1 key with no dom: %A\n", a); + _freeattr(a); + continue; + } + user = _strfindattr(a, "user"); + if(user == nil){ + print("p9sk1 key with no user: %A\n", a); + _freeattr(a); + continue; + } + print("p9sk1 key: %A\n", a); + found = 1; + authdialfutz(dom, user); + _freeattr(a); + } + if(!found) + print("no p9sk1 keys found in factotum\n"); +} + +void +authdialfutz(char *dom, char *user) +{ + int fd; + char *server; + char *addr; + + fd = authdial(nil, dom); + if(fd >= 0){ + print("\tsuccessfully dialed auth server\n"); + close(fd); + authfutz(dom, user); + return; + } + print("\tcannot dial auth server: %r\n"); + server = csgetvalue(nil, "authdom", dom, "auth", nil); + if(server){ + print("\tcsquery authdom=%q auth=%s\n", dom, server); + free(server); + return; + } + print("\tcsquery authdom=%q auth=* failed\n", dom); + server = csgetvalue(nil, "dom", dom, "auth", nil); + if(server){ + print("\tcsquery dom=%q auth=%q\n", dom, server); + free(server); + return; + } + print("\tcsquery dom=%q auth=*\n", dom); + + fd = dial(addr=netmkaddr("$auth", nil, "ticket"), 0, 0, 0); + if(fd >= 0){ + print("\tdial %s succeeded\n", addr); + close(fd); + return; + } + print("\tdial %s failed: %r\n", addr); +} + +void +authfutz(char *dom, char *user) +{ + int fd, nobootes; + char pw[128], prompt[128], key[DESKEYLEN], booteskey[DESKEYLEN], tbuf[2*TICKETLEN], + trbuf[TICKREQLEN]; + Ticket t; + Ticketreq tr; + + snprint(prompt, sizeof prompt, "\tpassword for %s@%s [hit enter to skip test]", user, dom); + readcons(prompt, nil, 1, pw, sizeof pw); + if(pw[0] == '\0') + return; + passtokey(key, pw); + + fd = authdial(nil, dom); + if(fd < 0){ + print("\tauthdial failed(!): %r\n"); + return; + } + + /* try ticket request using just user key */ + tr.type = AuthTreq; + strecpy(tr.authid, tr.authid+sizeof tr.authid, user); + strecpy(tr.authdom, tr.authdom+sizeof tr.authdom, dom); + strecpy(tr.hostid, tr.hostid+sizeof tr.hostid, user); + strecpy(tr.uid, tr.uid+sizeof tr.uid, user); + memset(tr.chal, 0xAA, sizeof tr.chal); + convTR2M(&tr, trbuf); + if(_asgetticket(fd, trbuf, tbuf) < 0){ + close(fd); + print("\t_asgetticket failed: %r\n"); + return; + } + convM2T(tbuf, &t, key); + if(t.num != AuthTc){ + print("\tcannot decrypt ticket1 from auth server (bad t.num=0x%.2ux)\n", t.num); + print("\tauth server and you do not agree on key for %s@%s\n", user, dom); + return; + } + if(memcmp(t.chal, tr.chal, sizeof tr.chal) != 0){ + print("\tbad challenge1 from auth server got %.*H wanted %.*H\n", + sizeof t.chal, t.chal, sizeof tr.chal, tr.chal); + print("\tauth server is rogue\n"); + return; + } + + convM2T(tbuf+TICKETLEN, &t, key); + if(t.num != AuthTs){ + print("\tcannot decrypt ticket2 from auth server (bad t.num=0x%.2ux)\n", t.num); + print("\tauth server and you do not agree on key for %s@%s\n", user, dom); + return; + } + if(memcmp(t.chal, tr.chal, sizeof tr.chal) != 0){ + print("\tbad challenge2 from auth server got %.*H wanted %.*H\n", + sizeof t.chal, t.chal, sizeof tr.chal, tr.chal); + print("\tauth server is rogue\n"); + return; + } + print("\tticket request using %s@%s key succeeded\n", user, dom); + + /* try ticket request using bootes key */ + snprint(prompt, sizeof prompt, "\tcpu server owner for domain %s ", dom); + readcons(prompt, "bootes", 0, tr.authid, sizeof tr.authid); + convTR2M(&tr, trbuf); + if(_asgetticket(fd, trbuf, tbuf) < 0){ + close(fd); + print("\t_asgetticket failed: %r\n"); + return; + } + convM2T(tbuf, &t, key); + if(t.num != AuthTc){ + print("\tcannot decrypt ticket1 from auth server (bad t.num=0x%.2ux)\n", t.num); + print("\tauth server and you do not agree on key for %s@%s\n", user, dom); + return; + } + if(memcmp(t.chal, tr.chal, sizeof tr.chal) != 0){ + print("\tbad challenge1 from auth server got %.*H wanted %.*H\n", + sizeof t.chal, t.chal, sizeof tr.chal, tr.chal); + print("\tauth server is rogue\n"); + return; + } + + snprint(prompt, sizeof prompt, "\tpassword for %s@%s [hit enter to skip test]", tr.authid, dom); + readcons(prompt, nil, 1, pw, sizeof pw); + if(pw[0] == '\0'){ + nobootes=1; + goto Nobootes; + } + nobootes = 0; + passtokey(booteskey, pw); + + convM2T(tbuf+TICKETLEN, &t, booteskey); + if(t.num != AuthTs){ + print("\tcannot decrypt ticket2 from auth server (bad t.num=0x%.2ux)\n", t.num); + print("\tauth server and you do not agree on key for %s@%s\n", tr.authid, dom); + return; + } + if(memcmp(t.chal, tr.chal, sizeof tr.chal) != 0){ + print("\tbad challenge2 from auth server got %.*H wanted %.*H\n", + sizeof t.chal, t.chal, sizeof tr.chal, tr.chal); + print("\tauth server is rogue\n"); + return; + } + print("\tticket request using %s@%s key succeeded\n", tr.authid, dom); + +Nobootes:; + USED(nobootes); + + /* try p9sk1 exchange with local factotum to test that key is right */ + + + /* + * try p9sk1 exchange with factotum on + * auth server (assumes running cpu service) + * to test that bootes key is right over there + */ + +} + +void +main(int argc, char **argv) +{ + quotefmtinstall(); + fmtinstall('A', _attrfmt); + fmtinstall('H', encodefmt); + + ARGBEGIN{ + default: + usage(); + }ARGEND + + if(argc != 0) + usage(); + + debugfactotumkeys(); +} |