#include #include #include int eof; /* send an eof if true */ char *note = "die: yankee dog"; void rex(int, char*, char*); void dkexec(int, char*, char*); void tcpexec(int, char*, char*); int call(char *, char*, char*, char**); char *buildargs(char*[]); int send(int); void error(char*, char*); void usage(void) { fprint(2, "usage: %s [-e] net!host command...\n", argv0); exits("usage"); } void main(int argc, char *argv[]) { char *host, *addr, *args; int fd; eof = 1; ARGBEGIN{ case 'e': eof = 0; break; default: usage(); }ARGEND if(argc < 2) usage(); host = argv[0]; args = buildargs(&argv[1]); /* generic attempts */ fd = call(0, host, "rexexec", &addr); if(fd >= 0) rex(fd, addr, args); fd = call(0, host, "exec", &addr); if(fd >= 0) dkexec(fd, addr, args); /* specific attempts */ fd = call("tcp", host, "shell", &addr); tcpexec(fd, addr, args); fd = call("dk", host, "exec", &addr); if(fd >= 0) dkexec(fd, addr, args); error("can't dial", host); exits(0); } int call(char *net, char *host, char *service, char **na) { *na = netmkaddr(host, net, service); return dial(*na, 0, 0, 0); } void rex(int fd, char *addr, char *cmd) { char buf[4096], *err; int kid, n; if(err = auth(fd, addr)){ close(fd); if(strcmp(err, "can't read server challenge") == 0) return; error(err, 0); } write(fd, cmd, strlen(cmd)+1); kid = send(fd); while((n=read(fd, buf, sizeof buf))>0) if(write(1, buf, n)!=n) error("write error", 0); sleep(250); postnote(kid, note);/**/ exits(0); } void dkexec(int fd, char *addr, char *cmd) { char buf[4096]; int kid, n; if(read(fd, buf, 1)!=1 || *buf!='O' || read(fd, buf, 1)!=1 || *buf!='K'){ close(fd); error("can't authenticate to", addr); } write(fd, cmd, strlen(cmd)+1); kid = send(fd); while((n=read(fd, buf, sizeof buf))>0) if(write(1, buf, n)!=n) error("write error", 0); sleep(250); postnote(kid, note);/**/ exits(0); } void tcpexec(int fd, char *addr, char *cmd) { char *u, buf[4096]; int kid, n; /* * do the ucb authentication and send command */ u = getuser(); if(write(fd, "", 1)<0 || write(fd, u, strlen(u)+1)<0 || write(fd, u, strlen(u)+1)<0 || write(fd, cmd, strlen(cmd)+1)<0){ close(fd); error("can't authenticate to", addr); } /* * get authentication reply */ if(read(fd, buf, 1) != 1){ close(fd); error("can't authenticate to", addr); } if(buf[0] != 0){ while(read(fd, buf, 1) == 1){ write(2, buf, 1); if(buf[0] == '\n') break; } close(fd); error("rejected by", addr); } kid = send(fd); while((n=read(fd, buf, sizeof buf))>0) if(write(1, buf, n)!=n) error("write error", 0); sleep(250); postnote(kid, note);/**/ exits(0); } int send(int fd) { char buf[4096]; int n; int kid; switch(kid = fork()){ case -1: error("fork error", 0); case 0: break; default: return kid; } while((n=read(0, buf, sizeof buf))>0) if(write(fd, buf, n)!=n) exits("write error"); if(eof) write(fd, buf, 0); exits(0); return 0; /* to keep compiler happy */ } void error(char *s, char *z) { if(z == 0) fprint(2, "%s: %s\n", argv0, s); else fprint(2, "%s: %s %s\n", argv0, s, z); exits(s); } char * buildargs(char *argv[]) { char *args; int m, n; args = malloc(1); args[0] = '\0'; n = 0; while(*argv){ m = strlen(*argv) + 1; args = realloc(args, n+m +1); if(args == 0) error("malloc fail", 0); args[n] = ' '; /* smashes old null */ strcpy(args+n+1, *argv); n += m; argv++; } return args; }