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"; 73e12c5d1SDavid du Colombier 8*219b2ee8SDavid du Colombier void rex(int, char*); 93e12c5d1SDavid du Colombier void dkexec(int, char*, char*); 103e12c5d1SDavid du Colombier void tcpexec(int, char*, char*); 113e12c5d1SDavid du Colombier int call(char *, char*, char*, char**); 123e12c5d1SDavid du Colombier char *buildargs(char*[]); 133e12c5d1SDavid du Colombier int send(int); 143e12c5d1SDavid du Colombier void error(char*, char*); 153e12c5d1SDavid du Colombier 163e12c5d1SDavid du Colombier void 173e12c5d1SDavid du Colombier usage(void) 183e12c5d1SDavid du Colombier { 193e12c5d1SDavid du Colombier fprint(2, "usage: %s [-e] net!host command...\n", argv0); 203e12c5d1SDavid du Colombier exits("usage"); 213e12c5d1SDavid du Colombier } 223e12c5d1SDavid du Colombier 233e12c5d1SDavid du Colombier void 243e12c5d1SDavid du Colombier main(int argc, char *argv[]) 253e12c5d1SDavid du Colombier { 263e12c5d1SDavid du Colombier char *host, *addr, *args; 273e12c5d1SDavid du Colombier int fd; 283e12c5d1SDavid du Colombier 293e12c5d1SDavid du Colombier eof = 1; 303e12c5d1SDavid du Colombier ARGBEGIN{ 313e12c5d1SDavid du Colombier case 'e': 323e12c5d1SDavid du Colombier eof = 0; 333e12c5d1SDavid du Colombier break; 343e12c5d1SDavid du Colombier default: 353e12c5d1SDavid du Colombier usage(); 363e12c5d1SDavid du Colombier }ARGEND 373e12c5d1SDavid du Colombier 383e12c5d1SDavid du Colombier if(argc < 2) 393e12c5d1SDavid du Colombier usage(); 403e12c5d1SDavid du Colombier host = argv[0]; 413e12c5d1SDavid du Colombier args = buildargs(&argv[1]); 423e12c5d1SDavid du Colombier 433e12c5d1SDavid du Colombier /* generic attempts */ 443e12c5d1SDavid du Colombier fd = call(0, host, "rexexec", &addr); 453e12c5d1SDavid du Colombier if(fd >= 0) 46*219b2ee8SDavid du Colombier rex(fd, args); 473e12c5d1SDavid du Colombier fd = call(0, host, "exec", &addr); 483e12c5d1SDavid du Colombier if(fd >= 0) 493e12c5d1SDavid du Colombier dkexec(fd, addr, args); 503e12c5d1SDavid du Colombier 513e12c5d1SDavid du Colombier /* specific attempts */ 523e12c5d1SDavid du Colombier fd = call("tcp", host, "shell", &addr); 533e12c5d1SDavid du Colombier tcpexec(fd, addr, args); 543e12c5d1SDavid du Colombier fd = call("dk", host, "exec", &addr); 553e12c5d1SDavid du Colombier if(fd >= 0) 563e12c5d1SDavid du Colombier dkexec(fd, addr, args); 573e12c5d1SDavid du Colombier 583e12c5d1SDavid du Colombier error("can't dial", host); 593e12c5d1SDavid du Colombier exits(0); 603e12c5d1SDavid du Colombier } 613e12c5d1SDavid du Colombier 623e12c5d1SDavid du Colombier int 633e12c5d1SDavid du Colombier call(char *net, char *host, char *service, char **na) 643e12c5d1SDavid du Colombier { 653e12c5d1SDavid du Colombier *na = netmkaddr(host, net, service); 663e12c5d1SDavid du Colombier return dial(*na, 0, 0, 0); 673e12c5d1SDavid du Colombier } 683e12c5d1SDavid du Colombier 693e12c5d1SDavid du Colombier void 70*219b2ee8SDavid du Colombier rex(int fd, char *cmd) 713e12c5d1SDavid du Colombier { 72*219b2ee8SDavid du Colombier char buf[4096]; 733e12c5d1SDavid du Colombier int kid, n; 743e12c5d1SDavid du Colombier 75*219b2ee8SDavid du Colombier if(auth(fd) < 0){ 763e12c5d1SDavid du Colombier close(fd); 77*219b2ee8SDavid du Colombier error("authenticate fails", 0); 783e12c5d1SDavid du Colombier } 793e12c5d1SDavid du Colombier write(fd, cmd, strlen(cmd)+1); 803e12c5d1SDavid du Colombier 813e12c5d1SDavid du Colombier kid = send(fd); 823e12c5d1SDavid du Colombier while((n=read(fd, buf, sizeof buf))>0) 833e12c5d1SDavid du Colombier if(write(1, buf, n)!=n) 843e12c5d1SDavid du Colombier error("write error", 0); 853e12c5d1SDavid du Colombier sleep(250); 86*219b2ee8SDavid du Colombier postnote(PNPROC, kid, note);/**/ 873e12c5d1SDavid du Colombier exits(0); 883e12c5d1SDavid du Colombier } 893e12c5d1SDavid du Colombier 903e12c5d1SDavid du Colombier void 913e12c5d1SDavid du Colombier dkexec(int fd, char *addr, char *cmd) 923e12c5d1SDavid du Colombier { 933e12c5d1SDavid du Colombier char buf[4096]; 943e12c5d1SDavid du Colombier int kid, n; 953e12c5d1SDavid du Colombier 963e12c5d1SDavid du Colombier if(read(fd, buf, 1)!=1 || *buf!='O' 973e12c5d1SDavid du Colombier || read(fd, buf, 1)!=1 || *buf!='K'){ 983e12c5d1SDavid du Colombier close(fd); 993e12c5d1SDavid du Colombier error("can't authenticate to", addr); 1003e12c5d1SDavid du Colombier } 1013e12c5d1SDavid du Colombier 1023e12c5d1SDavid du Colombier write(fd, cmd, strlen(cmd)+1); 1033e12c5d1SDavid du Colombier kid = send(fd); 1043e12c5d1SDavid du Colombier while((n=read(fd, buf, sizeof buf))>0) 1053e12c5d1SDavid du Colombier if(write(1, buf, n)!=n) 1063e12c5d1SDavid du Colombier error("write error", 0); 1073e12c5d1SDavid du Colombier sleep(250); 108*219b2ee8SDavid du Colombier postnote(PNPROC, kid, note);/**/ 1093e12c5d1SDavid du Colombier exits(0); 1103e12c5d1SDavid du Colombier } 1113e12c5d1SDavid du Colombier 1123e12c5d1SDavid du Colombier void 1133e12c5d1SDavid du Colombier tcpexec(int fd, char *addr, char *cmd) 1143e12c5d1SDavid du Colombier { 1153e12c5d1SDavid du Colombier char *u, buf[4096]; 1163e12c5d1SDavid du Colombier int kid, n; 1173e12c5d1SDavid du Colombier 1183e12c5d1SDavid du Colombier /* 1193e12c5d1SDavid du Colombier * do the ucb authentication and send command 1203e12c5d1SDavid du Colombier */ 1213e12c5d1SDavid du Colombier u = getuser(); 1223e12c5d1SDavid du Colombier if(write(fd, "", 1)<0 || write(fd, u, strlen(u)+1)<0 1233e12c5d1SDavid du Colombier || write(fd, u, strlen(u)+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); 150*219b2ee8SDavid du Colombier postnote(PNPROC, kid, note);/**/ 1513e12c5d1SDavid du Colombier exits(0); 1523e12c5d1SDavid du Colombier } 1533e12c5d1SDavid du Colombier 1543e12c5d1SDavid du Colombier int 1553e12c5d1SDavid du Colombier send(int fd) 1563e12c5d1SDavid du Colombier { 1573e12c5d1SDavid du Colombier char buf[4096]; 1583e12c5d1SDavid du Colombier int n; 1593e12c5d1SDavid du Colombier int kid; 1603e12c5d1SDavid du Colombier switch(kid = fork()){ 1613e12c5d1SDavid du Colombier case -1: 1623e12c5d1SDavid du Colombier error("fork error", 0); 1633e12c5d1SDavid du Colombier case 0: 1643e12c5d1SDavid du Colombier break; 1653e12c5d1SDavid du Colombier default: 1663e12c5d1SDavid du Colombier return kid; 1673e12c5d1SDavid du Colombier } 1683e12c5d1SDavid du Colombier while((n=read(0, buf, sizeof buf))>0) 1693e12c5d1SDavid du Colombier if(write(fd, buf, n)!=n) 1703e12c5d1SDavid du Colombier exits("write error"); 1713e12c5d1SDavid du Colombier if(eof) 1723e12c5d1SDavid du Colombier write(fd, buf, 0); 1733e12c5d1SDavid du Colombier 1743e12c5d1SDavid du Colombier exits(0); 1753e12c5d1SDavid du Colombier return 0; /* to keep compiler happy */ 1763e12c5d1SDavid du Colombier } 1773e12c5d1SDavid du Colombier 1783e12c5d1SDavid du Colombier void 1793e12c5d1SDavid du Colombier error(char *s, char *z) 1803e12c5d1SDavid du Colombier { 1813e12c5d1SDavid du Colombier if(z == 0) 182*219b2ee8SDavid du Colombier fprint(2, "%s: %s: %r\n", argv0, s); 1833e12c5d1SDavid du Colombier else 184*219b2ee8SDavid du Colombier fprint(2, "%s: %s %s: %r\n", argv0, s, z); 1853e12c5d1SDavid du Colombier exits(s); 1863e12c5d1SDavid du Colombier } 1873e12c5d1SDavid du Colombier 1883e12c5d1SDavid du Colombier char * 1893e12c5d1SDavid du Colombier buildargs(char *argv[]) 1903e12c5d1SDavid du Colombier { 1913e12c5d1SDavid du Colombier char *args; 1923e12c5d1SDavid du Colombier int m, n; 1933e12c5d1SDavid du Colombier 1943e12c5d1SDavid du Colombier args = malloc(1); 1953e12c5d1SDavid du Colombier args[0] = '\0'; 1963e12c5d1SDavid du Colombier n = 0; 1973e12c5d1SDavid du Colombier while(*argv){ 1983e12c5d1SDavid du Colombier m = strlen(*argv) + 1; 1993e12c5d1SDavid du Colombier args = realloc(args, n+m +1); 2003e12c5d1SDavid du Colombier if(args == 0) 2013e12c5d1SDavid du Colombier error("malloc fail", 0); 2023e12c5d1SDavid du Colombier args[n] = ' '; /* smashes old null */ 2033e12c5d1SDavid du Colombier strcpy(args+n+1, *argv); 2043e12c5d1SDavid du Colombier n += m; 2053e12c5d1SDavid du Colombier argv++; 2063e12c5d1SDavid du Colombier } 2073e12c5d1SDavid du Colombier return args; 2083e12c5d1SDavid du Colombier } 209