13e12c5d1SDavid du Colombier #include <u.h> 23e12c5d1SDavid du Colombier #include <libc.h> 33e12c5d1SDavid du Colombier #include <auth.h> 43e12c5d1SDavid du Colombier 53e12c5d1SDavid du Colombier int eof; /* send an eof if true */ 63e12c5d1SDavid du Colombier char *note = "die: yankee dog"; 77dd7cddfSDavid du Colombier char *ruser; 81118d624SDavid du Colombier char *key; 93e12c5d1SDavid du Colombier 10a454565bSDavid du Colombier void rex(int, char*, char*); 113e12c5d1SDavid du Colombier void tcpexec(int, char*, char*); 123e12c5d1SDavid du Colombier int call(char *, char*, char*, char**); 133e12c5d1SDavid du Colombier char *buildargs(char*[]); 143e12c5d1SDavid du Colombier int send(int); 153e12c5d1SDavid du Colombier void error(char*, char*); 16*f43e6a25SDavid du Colombier void sshexec(char *host, char *cmd); 173e12c5d1SDavid du Colombier 183e12c5d1SDavid du Colombier void 193e12c5d1SDavid du Colombier usage(void) 203e12c5d1SDavid du Colombier { 211118d624SDavid du Colombier fprint(2, "usage: %s [-e] [-k keypattern] [-l user] net!host command...\n", argv0); 223e12c5d1SDavid du Colombier exits("usage"); 233e12c5d1SDavid du Colombier } 243e12c5d1SDavid du Colombier 253e12c5d1SDavid du Colombier void 263e12c5d1SDavid du Colombier main(int argc, char *argv[]) 273e12c5d1SDavid du Colombier { 283e12c5d1SDavid du Colombier char *host, *addr, *args; 293e12c5d1SDavid du Colombier int fd; 303e12c5d1SDavid du Colombier 311118d624SDavid du Colombier key = ""; 323e12c5d1SDavid du Colombier eof = 1; 333e12c5d1SDavid du Colombier ARGBEGIN{ 343e12c5d1SDavid du Colombier case 'e': 353e12c5d1SDavid du Colombier eof = 0; 363e12c5d1SDavid du Colombier break; 371118d624SDavid du Colombier case 'k': 381118d624SDavid du Colombier key = EARGF(usage()); 391118d624SDavid du Colombier break; 407dd7cddfSDavid du Colombier case 'l': 411118d624SDavid du Colombier ruser = EARGF(usage()); 427dd7cddfSDavid du Colombier break; 433e12c5d1SDavid du Colombier default: 443e12c5d1SDavid du Colombier usage(); 453e12c5d1SDavid du Colombier }ARGEND 463e12c5d1SDavid du Colombier 473e12c5d1SDavid du Colombier if(argc < 2) 483e12c5d1SDavid du Colombier usage(); 493e12c5d1SDavid du Colombier host = argv[0]; 503e12c5d1SDavid du Colombier args = buildargs(&argv[1]); 513e12c5d1SDavid du Colombier 52*f43e6a25SDavid du Colombier /* try erexexec p9any then dial again with p9sk2 */ 533e12c5d1SDavid du Colombier fd = call(0, host, "rexexec", &addr); 543e12c5d1SDavid du Colombier if(fd >= 0) 55a454565bSDavid du Colombier rex(fd, args, "p9any"); 56a454565bSDavid du Colombier close(fd); 57a454565bSDavid du Colombier fd = call(0, host, "rexexec", &addr); 58a454565bSDavid du Colombier if(fd >= 0) 59a454565bSDavid du Colombier rex(fd, args, "p9sk2"); 60a454565bSDavid du Colombier close(fd); 613e12c5d1SDavid du Colombier 62*f43e6a25SDavid du Colombier /* if there's an ssh port, try that */ 63*f43e6a25SDavid du Colombier fd = call("tcp", host, "ssh", &addr); 64*f43e6a25SDavid du Colombier if(fd >= 0){ 65*f43e6a25SDavid du Colombier close(fd); 66*f43e6a25SDavid du Colombier sshexec(host, args); 67*f43e6a25SDavid du Colombier /* falls through if no ssh */ 68*f43e6a25SDavid du Colombier } 69*f43e6a25SDavid du Colombier 701118d624SDavid du Colombier /* specific attempts */ 711118d624SDavid du Colombier fd = call("tcp", host, "shell", &addr); 721118d624SDavid du Colombier if(fd >= 0) 731118d624SDavid du Colombier tcpexec(fd, addr, args); 741118d624SDavid du Colombier 753e12c5d1SDavid du Colombier error("can't dial", host); 763e12c5d1SDavid du Colombier exits(0); 773e12c5d1SDavid du Colombier } 783e12c5d1SDavid du Colombier 793e12c5d1SDavid du Colombier int 803e12c5d1SDavid du Colombier call(char *net, char *host, char *service, char **na) 813e12c5d1SDavid du Colombier { 823e12c5d1SDavid du Colombier *na = netmkaddr(host, net, service); 833e12c5d1SDavid du Colombier return dial(*na, 0, 0, 0); 843e12c5d1SDavid du Colombier } 853e12c5d1SDavid du Colombier 863e12c5d1SDavid du Colombier void 87a454565bSDavid du Colombier rex(int fd, char *cmd, char *proto) 883e12c5d1SDavid du Colombier { 89219b2ee8SDavid du Colombier char buf[4096]; 903e12c5d1SDavid du Colombier int kid, n; 919a747e4fSDavid du Colombier AuthInfo *ai; 923e12c5d1SDavid du Colombier 931118d624SDavid du Colombier ai = auth_proxy(fd, auth_getkey, "proto=%s role=client %s", proto, key); 94a454565bSDavid du Colombier if(ai == nil){ 95a454565bSDavid du Colombier if(strcmp(proto, "p9any") == 0) 96a454565bSDavid du Colombier return; 979a747e4fSDavid du Colombier error("auth_proxy", nil); 98a454565bSDavid du Colombier } 993e12c5d1SDavid du Colombier write(fd, cmd, strlen(cmd)+1); 1003e12c5d1SDavid du Colombier 1013e12c5d1SDavid du Colombier kid = send(fd); 1023e12c5d1SDavid du Colombier while((n=read(fd, buf, sizeof buf))>0) 1033e12c5d1SDavid du Colombier if(write(1, buf, n)!=n) 1043e12c5d1SDavid du Colombier error("write error", 0); 1053e12c5d1SDavid du Colombier sleep(250); 106219b2ee8SDavid du Colombier postnote(PNPROC, kid, note);/**/ 1073e12c5d1SDavid du Colombier exits(0); 1083e12c5d1SDavid du Colombier } 1093e12c5d1SDavid du Colombier 1103e12c5d1SDavid du Colombier void 1113e12c5d1SDavid du Colombier tcpexec(int fd, char *addr, char *cmd) 1123e12c5d1SDavid du Colombier { 1133e12c5d1SDavid du Colombier char *u, buf[4096]; 1143e12c5d1SDavid du Colombier int kid, n; 1157dd7cddfSDavid du Colombier char *r; 1163e12c5d1SDavid du Colombier 1173e12c5d1SDavid du Colombier /* 1183e12c5d1SDavid du Colombier * do the ucb authentication and send command 1193e12c5d1SDavid du Colombier */ 1203e12c5d1SDavid du Colombier u = getuser(); 1217dd7cddfSDavid du Colombier r = ruser ? ruser : u; 1223e12c5d1SDavid du Colombier if(write(fd, "", 1)<0 || write(fd, u, strlen(u)+1)<0 1237dd7cddfSDavid du Colombier || write(fd, r, strlen(r)+1)<0 || write(fd, cmd, strlen(cmd)+1)<0){ 1243e12c5d1SDavid du Colombier close(fd); 1253e12c5d1SDavid du Colombier error("can't authenticate to", addr); 1263e12c5d1SDavid du Colombier } 1273e12c5d1SDavid du Colombier 1283e12c5d1SDavid du Colombier /* 1293e12c5d1SDavid du Colombier * get authentication reply 1303e12c5d1SDavid du Colombier */ 1313e12c5d1SDavid du Colombier if(read(fd, buf, 1) != 1){ 1323e12c5d1SDavid du Colombier close(fd); 1333e12c5d1SDavid du Colombier error("can't authenticate to", addr); 1343e12c5d1SDavid du Colombier } 1353e12c5d1SDavid du Colombier if(buf[0] != 0){ 1363e12c5d1SDavid du Colombier while(read(fd, buf, 1) == 1){ 1373e12c5d1SDavid du Colombier write(2, buf, 1); 1383e12c5d1SDavid du Colombier if(buf[0] == '\n') 1393e12c5d1SDavid du Colombier break; 1403e12c5d1SDavid du Colombier } 1413e12c5d1SDavid du Colombier close(fd); 1423e12c5d1SDavid du Colombier error("rejected by", addr); 1433e12c5d1SDavid du Colombier } 1443e12c5d1SDavid du Colombier 1453e12c5d1SDavid du Colombier kid = send(fd); 1463e12c5d1SDavid du Colombier while((n=read(fd, buf, sizeof buf))>0) 1473e12c5d1SDavid du Colombier if(write(1, buf, n)!=n) 1483e12c5d1SDavid du Colombier error("write error", 0); 1493e12c5d1SDavid du Colombier sleep(250); 150219b2ee8SDavid du Colombier postnote(PNPROC, kid, note);/**/ 1513e12c5d1SDavid du Colombier exits(0); 1523e12c5d1SDavid du Colombier } 1533e12c5d1SDavid du Colombier 154*f43e6a25SDavid du Colombier void 155*f43e6a25SDavid du Colombier sshexec(char *host, char *cmd) 156*f43e6a25SDavid du Colombier { 157*f43e6a25SDavid du Colombier execl("/bin/ssh", "ssh", "-iCm", host, cmd, 0); 158*f43e6a25SDavid du Colombier } 159*f43e6a25SDavid du Colombier 1603e12c5d1SDavid du Colombier int 1613e12c5d1SDavid du Colombier send(int fd) 1623e12c5d1SDavid du Colombier { 1633e12c5d1SDavid du Colombier char buf[4096]; 1643e12c5d1SDavid du Colombier int n; 1653e12c5d1SDavid du Colombier int kid; 1663e12c5d1SDavid du Colombier switch(kid = fork()){ 1673e12c5d1SDavid du Colombier case -1: 1683e12c5d1SDavid du Colombier error("fork error", 0); 1693e12c5d1SDavid du Colombier case 0: 1703e12c5d1SDavid du Colombier break; 1713e12c5d1SDavid du Colombier default: 1723e12c5d1SDavid du Colombier return kid; 1733e12c5d1SDavid du Colombier } 1743e12c5d1SDavid du Colombier while((n=read(0, buf, sizeof buf))>0) 1753e12c5d1SDavid du Colombier if(write(fd, buf, n)!=n) 1763e12c5d1SDavid du Colombier exits("write error"); 1773e12c5d1SDavid du Colombier if(eof) 1783e12c5d1SDavid du Colombier write(fd, buf, 0); 1793e12c5d1SDavid du Colombier 1803e12c5d1SDavid du Colombier exits(0); 1813e12c5d1SDavid du Colombier return 0; /* to keep compiler happy */ 1823e12c5d1SDavid du Colombier } 1833e12c5d1SDavid du Colombier 1843e12c5d1SDavid du Colombier void 1853e12c5d1SDavid du Colombier error(char *s, char *z) 1863e12c5d1SDavid du Colombier { 1873e12c5d1SDavid du Colombier if(z == 0) 188219b2ee8SDavid du Colombier fprint(2, "%s: %s: %r\n", argv0, s); 1893e12c5d1SDavid du Colombier else 190219b2ee8SDavid du Colombier fprint(2, "%s: %s %s: %r\n", argv0, s, z); 1913e12c5d1SDavid du Colombier exits(s); 1923e12c5d1SDavid du Colombier } 1933e12c5d1SDavid du Colombier 1943e12c5d1SDavid du Colombier char * 1953e12c5d1SDavid du Colombier buildargs(char *argv[]) 1963e12c5d1SDavid du Colombier { 1973e12c5d1SDavid du Colombier char *args; 1983e12c5d1SDavid du Colombier int m, n; 1993e12c5d1SDavid du Colombier 2003e12c5d1SDavid du Colombier args = malloc(1); 2013e12c5d1SDavid du Colombier args[0] = '\0'; 2023e12c5d1SDavid du Colombier n = 0; 2033e12c5d1SDavid du Colombier while(*argv){ 2043e12c5d1SDavid du Colombier m = strlen(*argv) + 1; 2053e12c5d1SDavid du Colombier args = realloc(args, n+m +1); 2063e12c5d1SDavid du Colombier if(args == 0) 2073e12c5d1SDavid du Colombier error("malloc fail", 0); 2083e12c5d1SDavid du Colombier args[n] = ' '; /* smashes old null */ 2093e12c5d1SDavid du Colombier strcpy(args+n+1, *argv); 2103e12c5d1SDavid du Colombier n += m; 2113e12c5d1SDavid du Colombier argv++; 2123e12c5d1SDavid du Colombier } 2133e12c5d1SDavid du Colombier return args; 2143e12c5d1SDavid du Colombier } 215