13ff48bf5SDavid du Colombier /* 23ff48bf5SDavid du Colombier * Test various aspects of the authentication setup. 33ff48bf5SDavid du Colombier */ 43ff48bf5SDavid du Colombier 53ff48bf5SDavid du Colombier #include <u.h> 63ff48bf5SDavid du Colombier #include <libc.h> 73ff48bf5SDavid du Colombier #include <bio.h> 83ff48bf5SDavid du Colombier #include <ndb.h> 93ff48bf5SDavid du Colombier #include <auth.h> 103ff48bf5SDavid du Colombier #include <authsrv.h> 113ff48bf5SDavid du Colombier 123ff48bf5SDavid du Colombier void 133ff48bf5SDavid du Colombier usage(void) 143ff48bf5SDavid du Colombier { 153ff48bf5SDavid du Colombier fprint(2, "usage: auth/debug\n"); 163ff48bf5SDavid du Colombier exits("usage"); 173ff48bf5SDavid du Colombier } 183ff48bf5SDavid du Colombier 193ff48bf5SDavid du Colombier static char* 203ff48bf5SDavid du Colombier readcons(char *prompt, char *def, int raw, char *buf, int nbuf) 213ff48bf5SDavid du Colombier { 223ff48bf5SDavid du Colombier int fdin, fdout, ctl, n, m; 233ff48bf5SDavid du Colombier char line[10]; 243ff48bf5SDavid du Colombier 253ff48bf5SDavid du Colombier fdin = open("/dev/cons", OREAD); 263ff48bf5SDavid du Colombier if(fdin < 0) 273ff48bf5SDavid du Colombier fdin = 0; 283ff48bf5SDavid du Colombier fdout = open("/dev/cons", OWRITE); 293ff48bf5SDavid du Colombier if(fdout < 0) 303ff48bf5SDavid du Colombier fdout = 1; 313ff48bf5SDavid du Colombier if(def != nil) 323ff48bf5SDavid du Colombier fprint(fdout, "%s[%s]: ", prompt, def); 333ff48bf5SDavid du Colombier else 343ff48bf5SDavid du Colombier fprint(fdout, "%s: ", prompt); 353ff48bf5SDavid du Colombier if(raw){ 363ff48bf5SDavid du Colombier ctl = open("/dev/consctl", OWRITE); 373ff48bf5SDavid du Colombier if(ctl >= 0) 383ff48bf5SDavid du Colombier write(ctl, "rawon", 5); 393ff48bf5SDavid du Colombier } else 403ff48bf5SDavid du Colombier ctl = -1; 413ff48bf5SDavid du Colombier 423ff48bf5SDavid du Colombier m = 0; 433ff48bf5SDavid du Colombier for(;;){ 443ff48bf5SDavid du Colombier n = read(fdin, line, 1); 453ff48bf5SDavid du Colombier if(n == 0){ 463ff48bf5SDavid du Colombier close(ctl); 473ff48bf5SDavid du Colombier werrstr("readcons: EOF"); 483ff48bf5SDavid du Colombier return nil; 493ff48bf5SDavid du Colombier } 503ff48bf5SDavid du Colombier if(n < 0){ 513ff48bf5SDavid du Colombier close(ctl); 523ff48bf5SDavid du Colombier werrstr("can't read cons"); 533ff48bf5SDavid du Colombier return nil; 543ff48bf5SDavid du Colombier } 553ff48bf5SDavid du Colombier if(line[0] == 0x7f) 563ff48bf5SDavid du Colombier exits(0); 573ff48bf5SDavid du Colombier if(n == 0 || line[0] == '\n' || line[0] == '\r'){ 583ff48bf5SDavid du Colombier if(raw){ 593ff48bf5SDavid du Colombier write(ctl, "rawoff", 6); 603ff48bf5SDavid du Colombier write(fdout, "\n", 1); 613ff48bf5SDavid du Colombier close(ctl); 623ff48bf5SDavid du Colombier } 633ff48bf5SDavid du Colombier buf[m] = '\0'; 643ff48bf5SDavid du Colombier if(buf[0]=='\0' && def) 653ff48bf5SDavid du Colombier strcpy(buf, def); 663ff48bf5SDavid du Colombier return buf; 673ff48bf5SDavid du Colombier } 683ff48bf5SDavid du Colombier if(line[0] == '\b'){ 693ff48bf5SDavid du Colombier if(m > 0) 703ff48bf5SDavid du Colombier m--; 713ff48bf5SDavid du Colombier }else if(line[0] == 0x15){ /* ^U: line kill */ 723ff48bf5SDavid du Colombier m = 0; 733ff48bf5SDavid du Colombier if(def != nil) 743ff48bf5SDavid du Colombier fprint(fdout, "%s[%s]: ", prompt, def); 753ff48bf5SDavid du Colombier else 763ff48bf5SDavid du Colombier fprint(fdout, "%s: ", prompt); 773ff48bf5SDavid du Colombier }else{ 783ff48bf5SDavid du Colombier if(m >= nbuf-1){ 793ff48bf5SDavid du Colombier fprint(fdout, "line too long\n"); 803ff48bf5SDavid du Colombier m = 0; 813ff48bf5SDavid du Colombier if(def != nil) 823ff48bf5SDavid du Colombier fprint(fdout, "%s[%s]: ", prompt, def); 833ff48bf5SDavid du Colombier else 843ff48bf5SDavid du Colombier fprint(fdout, "%s: ", prompt); 853ff48bf5SDavid du Colombier }else 863ff48bf5SDavid du Colombier buf[m++] = line[0]; 873ff48bf5SDavid du Colombier } 883ff48bf5SDavid du Colombier } 893ff48bf5SDavid du Colombier return buf; /* how does this happen */ 903ff48bf5SDavid du Colombier } 913ff48bf5SDavid du Colombier 923ff48bf5SDavid du Colombier void authdialfutz(char*, char*); 933ff48bf5SDavid du Colombier void authfutz(char*, char*); 943ff48bf5SDavid du Colombier 953ff48bf5SDavid du Colombier /* scan factotum for p9sk1 keys; check them */ 963ff48bf5SDavid du Colombier void 973ff48bf5SDavid du Colombier debugfactotumkeys(void) 983ff48bf5SDavid du Colombier { 993ff48bf5SDavid du Colombier char *s, *dom, *proto, *user; 1003ff48bf5SDavid du Colombier int found; 1013ff48bf5SDavid du Colombier Attr *a; 1023ff48bf5SDavid du Colombier Biobuf *b; 1033ff48bf5SDavid du Colombier 1043ff48bf5SDavid du Colombier b = Bopen("/mnt/factotum/ctl", OREAD); 1053ff48bf5SDavid du Colombier if(b == nil){ 1063ff48bf5SDavid du Colombier fprint(2, "cannot open /mnt/factotum/ctl"); 1073ff48bf5SDavid du Colombier return; 1083ff48bf5SDavid du Colombier } 1093ff48bf5SDavid du Colombier found = 0; 1103ff48bf5SDavid du Colombier while((s = Brdstr(b, '\n', 1)) != nil){ 1113ff48bf5SDavid du Colombier if(strncmp(s, "key ", 4) != 0){ 1123ff48bf5SDavid du Colombier print("malformed ctl line: %s\n", s); 1133ff48bf5SDavid du Colombier free(s); 1143ff48bf5SDavid du Colombier continue; 1153ff48bf5SDavid du Colombier } 1163ff48bf5SDavid du Colombier a = _parseattr(s+4); 1173ff48bf5SDavid du Colombier free(s); 118*2ebbfa15SDavid du Colombier proto = _strfindattr(a, "proto"); 1193ff48bf5SDavid du Colombier if(proto==nil || strcmp(proto, "p9sk1")!=0) 1203ff48bf5SDavid du Colombier continue; 121*2ebbfa15SDavid du Colombier dom = _strfindattr(a, "dom"); 1223ff48bf5SDavid du Colombier if(dom == nil){ 1233ff48bf5SDavid du Colombier print("p9sk1 key with no dom: %A\n", a); 1243ff48bf5SDavid du Colombier _freeattr(a); 1253ff48bf5SDavid du Colombier continue; 1263ff48bf5SDavid du Colombier } 127*2ebbfa15SDavid du Colombier user = _strfindattr(a, "user"); 1283ff48bf5SDavid du Colombier if(user == nil){ 1293ff48bf5SDavid du Colombier print("p9sk1 key with no user: %A\n", a); 1303ff48bf5SDavid du Colombier _freeattr(a); 1313ff48bf5SDavid du Colombier continue; 1323ff48bf5SDavid du Colombier } 1333ff48bf5SDavid du Colombier print("p9sk1 key: %A\n", a); 1343ff48bf5SDavid du Colombier found = 1; 1353ff48bf5SDavid du Colombier authdialfutz(dom, user); 1363ff48bf5SDavid du Colombier _freeattr(a); 1373ff48bf5SDavid du Colombier } 1383ff48bf5SDavid du Colombier if(!found) 1393ff48bf5SDavid du Colombier print("no p9sk1 keys found in factotum\n"); 1403ff48bf5SDavid du Colombier } 1413ff48bf5SDavid du Colombier 1423ff48bf5SDavid du Colombier void 1433ff48bf5SDavid du Colombier authdialfutz(char *dom, char *user) 1443ff48bf5SDavid du Colombier { 1453ff48bf5SDavid du Colombier int fd; 1463ff48bf5SDavid du Colombier Ndbtuple *nt; 1473ff48bf5SDavid du Colombier char server[Ndbvlen]; 1483ff48bf5SDavid du Colombier char *addr; 1493ff48bf5SDavid du Colombier 1503ff48bf5SDavid du Colombier fd = authdial(nil, dom); 1513ff48bf5SDavid du Colombier if(fd >= 0){ 1523ff48bf5SDavid du Colombier print("\tsuccessfully dialed auth server\n"); 1533ff48bf5SDavid du Colombier close(fd); 1543ff48bf5SDavid du Colombier authfutz(dom, user); 1553ff48bf5SDavid du Colombier return; 1563ff48bf5SDavid du Colombier } 1573ff48bf5SDavid du Colombier print("\tcannot dial auth server: %r\n"); 1583ff48bf5SDavid du Colombier nt = csgetval(nil, "authdom", dom, "auth", server); 1593ff48bf5SDavid du Colombier if(nt){ 1603ff48bf5SDavid du Colombier print("\tcsquery authdom=%q auth=%s\n", dom, server); 1613ff48bf5SDavid du Colombier return; 1623ff48bf5SDavid du Colombier } 1633ff48bf5SDavid du Colombier print("\tcsquery authdom=%q auth=* failed\n", dom); 1643ff48bf5SDavid du Colombier nt = csgetval(nil, "dom", dom, "auth", server); 1653ff48bf5SDavid du Colombier if(nt){ 1663ff48bf5SDavid du Colombier print("\tcsquery dom=%q auth=%q\n", dom, server); 1673ff48bf5SDavid du Colombier return; 1683ff48bf5SDavid du Colombier } 1693ff48bf5SDavid du Colombier print("\tcsquery dom=%q auth=%q\n", dom, server); 1703ff48bf5SDavid du Colombier 1713ff48bf5SDavid du Colombier fd = dial(addr=netmkaddr(server, nil, "ticket"), 0, 0, 0); 1723ff48bf5SDavid du Colombier if(fd >= 0){ 1733ff48bf5SDavid du Colombier print("\tdial %s succeeded\n", addr); 1743ff48bf5SDavid du Colombier close(fd); 1753ff48bf5SDavid du Colombier return; 1763ff48bf5SDavid du Colombier } 1773ff48bf5SDavid du Colombier print("\tdial %s failed: %r\n", addr); 1783ff48bf5SDavid du Colombier } 1793ff48bf5SDavid du Colombier 1803ff48bf5SDavid du Colombier void 1813ff48bf5SDavid du Colombier authfutz(char *dom, char *user) 1823ff48bf5SDavid du Colombier { 1833ff48bf5SDavid du Colombier int fd, nobootes; 1843ff48bf5SDavid du Colombier char pw[128], prompt[128], key[DESKEYLEN], booteskey[DESKEYLEN], tbuf[2*TICKETLEN], 1853ff48bf5SDavid du Colombier trbuf[TICKREQLEN]; 1863ff48bf5SDavid du Colombier Ticket t; 1873ff48bf5SDavid du Colombier Ticketreq tr; 1883ff48bf5SDavid du Colombier 1893ff48bf5SDavid du Colombier snprint(prompt, sizeof prompt, "\tpassword for %s@%s [hit enter to skip test]", user, dom); 1903ff48bf5SDavid du Colombier readcons(prompt, nil, 1, pw, sizeof pw); 1913ff48bf5SDavid du Colombier if(pw[0] == '\0') 1923ff48bf5SDavid du Colombier return; 1933ff48bf5SDavid du Colombier passtokey(key, pw); 1943ff48bf5SDavid du Colombier 1953ff48bf5SDavid du Colombier fd = authdial(nil, dom); 1963ff48bf5SDavid du Colombier if(fd < 0){ 1973ff48bf5SDavid du Colombier print("\tauthdial failed(!): %r\n"); 1983ff48bf5SDavid du Colombier return; 1993ff48bf5SDavid du Colombier } 2003ff48bf5SDavid du Colombier 2013ff48bf5SDavid du Colombier /* try ticket request using just user key */ 2023ff48bf5SDavid du Colombier tr.type = AuthTreq; 2033ff48bf5SDavid du Colombier strecpy(tr.authid, tr.authid+sizeof tr.authid, user); 2043ff48bf5SDavid du Colombier strecpy(tr.authdom, tr.authdom+sizeof tr.authdom, dom); 2053ff48bf5SDavid du Colombier strecpy(tr.hostid, tr.hostid+sizeof tr.hostid, user); 2063ff48bf5SDavid du Colombier strecpy(tr.uid, tr.uid+sizeof tr.uid, user); 2073ff48bf5SDavid du Colombier memset(tr.chal, 0xAA, sizeof tr.chal); 2083ff48bf5SDavid du Colombier convTR2M(&tr, trbuf); 2093ff48bf5SDavid du Colombier if(_asgetticket(fd, trbuf, tbuf) < 0){ 2103ff48bf5SDavid du Colombier close(fd); 2113ff48bf5SDavid du Colombier print("\t_asgetticket failed: %r\n"); 2123ff48bf5SDavid du Colombier return; 2133ff48bf5SDavid du Colombier } 2143ff48bf5SDavid du Colombier convM2T(tbuf, &t, key); 2153ff48bf5SDavid du Colombier if(t.num != AuthTc){ 2163ff48bf5SDavid du Colombier print("\tcannot decrypt ticket1 from auth server (bad t.num=0x%.2ux)\n", t.num); 2173ff48bf5SDavid du Colombier print("\tauth server and you do not agree on key for %s@%s\n", user, dom); 2183ff48bf5SDavid du Colombier return; 2193ff48bf5SDavid du Colombier } 2203ff48bf5SDavid du Colombier if(memcmp(t.chal, tr.chal, sizeof tr.chal) != 0){ 2213ff48bf5SDavid du Colombier print("\tbad challenge1 from auth server got %.*H wanted %.*H\n", 2223ff48bf5SDavid du Colombier sizeof t.chal, t.chal, sizeof tr.chal, tr.chal); 2233ff48bf5SDavid du Colombier print("\tauth server is rogue\n"); 2243ff48bf5SDavid du Colombier return; 2253ff48bf5SDavid du Colombier } 2263ff48bf5SDavid du Colombier 2273ff48bf5SDavid du Colombier convM2T(tbuf+TICKETLEN, &t, key); 2283ff48bf5SDavid du Colombier if(t.num != AuthTs){ 2293ff48bf5SDavid du Colombier print("\tcannot decrypt ticket2 from auth server (bad t.num=0x%.2ux)\n", t.num); 2303ff48bf5SDavid du Colombier print("\tauth server and you do not agree on key for %s@%s\n", user, dom); 2313ff48bf5SDavid du Colombier return; 2323ff48bf5SDavid du Colombier } 2333ff48bf5SDavid du Colombier if(memcmp(t.chal, tr.chal, sizeof tr.chal) != 0){ 2343ff48bf5SDavid du Colombier print("\tbad challenge2 from auth server got %.*H wanted %.*H\n", 2353ff48bf5SDavid du Colombier sizeof t.chal, t.chal, sizeof tr.chal, tr.chal); 2363ff48bf5SDavid du Colombier print("\tauth server is rogue\n"); 2373ff48bf5SDavid du Colombier return; 2383ff48bf5SDavid du Colombier } 2393ff48bf5SDavid du Colombier print("\tticket request using %s@%s key succeeded\n", user, dom); 2403ff48bf5SDavid du Colombier 2413ff48bf5SDavid du Colombier /* try ticket request using bootes key */ 2423ff48bf5SDavid du Colombier snprint(prompt, sizeof prompt, "\tcpu server owner for domain %s ", dom); 2433ff48bf5SDavid du Colombier readcons(prompt, "bootes", 0, tr.authid, sizeof tr.authid); 2443ff48bf5SDavid du Colombier convTR2M(&tr, trbuf); 2453ff48bf5SDavid du Colombier if(_asgetticket(fd, trbuf, tbuf) < 0){ 2463ff48bf5SDavid du Colombier close(fd); 2473ff48bf5SDavid du Colombier print("\t_asgetticket failed: %r\n"); 2483ff48bf5SDavid du Colombier return; 2493ff48bf5SDavid du Colombier } 2503ff48bf5SDavid du Colombier convM2T(tbuf, &t, key); 2513ff48bf5SDavid du Colombier if(t.num != AuthTc){ 2523ff48bf5SDavid du Colombier print("\tcannot decrypt ticket1 from auth server (bad t.num=0x%.2ux)\n", t.num); 2533ff48bf5SDavid du Colombier print("\tauth server and you do not agree on key for %s@%s\n", user, dom); 2543ff48bf5SDavid du Colombier return; 2553ff48bf5SDavid du Colombier } 2563ff48bf5SDavid du Colombier if(memcmp(t.chal, tr.chal, sizeof tr.chal) != 0){ 2573ff48bf5SDavid du Colombier print("\tbad challenge1 from auth server got %.*H wanted %.*H\n", 2583ff48bf5SDavid du Colombier sizeof t.chal, t.chal, sizeof tr.chal, tr.chal); 2593ff48bf5SDavid du Colombier print("\tauth server is rogue\n"); 2603ff48bf5SDavid du Colombier return; 2613ff48bf5SDavid du Colombier } 2623ff48bf5SDavid du Colombier 2633ff48bf5SDavid du Colombier snprint(prompt, sizeof prompt, "\tpassword for %s@%s [hit enter to skip test]", tr.authid, dom); 2643ff48bf5SDavid du Colombier readcons(prompt, nil, 1, pw, sizeof pw); 2653ff48bf5SDavid du Colombier if(pw[0] == '\0'){ 2663ff48bf5SDavid du Colombier nobootes=1; 2673ff48bf5SDavid du Colombier goto Nobootes; 2683ff48bf5SDavid du Colombier } 2693ff48bf5SDavid du Colombier nobootes = 0; 2703ff48bf5SDavid du Colombier passtokey(booteskey, pw); 2713ff48bf5SDavid du Colombier 2723ff48bf5SDavid du Colombier convM2T(tbuf+TICKETLEN, &t, booteskey); 2733ff48bf5SDavid du Colombier if(t.num != AuthTs){ 2743ff48bf5SDavid du Colombier print("\tcannot decrypt ticket2 from auth server (bad t.num=0x%.2ux)\n", t.num); 2753ff48bf5SDavid du Colombier print("\tauth server and you do not agree on key for %s@%s\n", tr.authid, dom); 2763ff48bf5SDavid du Colombier return; 2773ff48bf5SDavid du Colombier } 2783ff48bf5SDavid du Colombier if(memcmp(t.chal, tr.chal, sizeof tr.chal) != 0){ 2793ff48bf5SDavid du Colombier print("\tbad challenge2 from auth server got %.*H wanted %.*H\n", 2803ff48bf5SDavid du Colombier sizeof t.chal, t.chal, sizeof tr.chal, tr.chal); 2813ff48bf5SDavid du Colombier print("\tauth server is rogue\n"); 2823ff48bf5SDavid du Colombier return; 2833ff48bf5SDavid du Colombier } 2843ff48bf5SDavid du Colombier print("\tticket request using %s@%s key succeeded\n", tr.authid, dom); 2853ff48bf5SDavid du Colombier 2863ff48bf5SDavid du Colombier Nobootes:; 2873ff48bf5SDavid du Colombier 2883ff48bf5SDavid du Colombier /* try p9sk1 exchange with local factotum to test that key is right */ 2893ff48bf5SDavid du Colombier 2903ff48bf5SDavid du Colombier 2913ff48bf5SDavid du Colombier /* 2923ff48bf5SDavid du Colombier * try p9sk1 exchange with factotum on 2933ff48bf5SDavid du Colombier * auth server (assumes running cpu service) 2943ff48bf5SDavid du Colombier * to test that bootes key is right over there 2953ff48bf5SDavid du Colombier */ 2963ff48bf5SDavid du Colombier 2973ff48bf5SDavid du Colombier } 2983ff48bf5SDavid du Colombier 2993ff48bf5SDavid du Colombier void 3003ff48bf5SDavid du Colombier main(int argc, char **argv) 3013ff48bf5SDavid du Colombier { 3023ff48bf5SDavid du Colombier quotefmtinstall(); 3033ff48bf5SDavid du Colombier fmtinstall('A', _attrfmt); 3043ff48bf5SDavid du Colombier fmtinstall('H', encodefmt); 3053ff48bf5SDavid du Colombier 3063ff48bf5SDavid du Colombier ARGBEGIN{ 3073ff48bf5SDavid du Colombier default: 3083ff48bf5SDavid du Colombier usage(); 3093ff48bf5SDavid du Colombier }ARGEND 3103ff48bf5SDavid du Colombier 3113ff48bf5SDavid du Colombier if(argc != 0) 3123ff48bf5SDavid du Colombier usage(); 3133ff48bf5SDavid du Colombier 3143ff48bf5SDavid du Colombier debugfactotumkeys(); 3153ff48bf5SDavid du Colombier } 316