1 #include <u.h> 2 #include <libc.h> 3 #include <auth.h> 4 5 int eof; /* send an eof if true */ 6 char *note = "die: yankee dog"; 7 8 void rex(int, char*); 9 void dkexec(int, char*, char*); 10 void tcpexec(int, char*, char*); 11 int call(char *, char*, char*, char**); 12 char *buildargs(char*[]); 13 int send(int); 14 void error(char*, char*); 15 16 void 17 usage(void) 18 { 19 fprint(2, "usage: %s [-e] net!host command...\n", argv0); 20 exits("usage"); 21 } 22 23 void 24 main(int argc, char *argv[]) 25 { 26 char *host, *addr, *args; 27 int fd; 28 29 eof = 1; 30 ARGBEGIN{ 31 case 'e': 32 eof = 0; 33 break; 34 default: 35 usage(); 36 }ARGEND 37 38 if(argc < 2) 39 usage(); 40 host = argv[0]; 41 args = buildargs(&argv[1]); 42 43 /* generic attempts */ 44 fd = call(0, host, "rexexec", &addr); 45 if(fd >= 0) 46 rex(fd, args); 47 fd = call(0, host, "exec", &addr); 48 if(fd >= 0) 49 dkexec(fd, addr, args); 50 51 /* specific attempts */ 52 fd = call("tcp", host, "shell", &addr); 53 tcpexec(fd, addr, args); 54 fd = call("dk", host, "exec", &addr); 55 if(fd >= 0) 56 dkexec(fd, addr, args); 57 58 error("can't dial", host); 59 exits(0); 60 } 61 62 int 63 call(char *net, char *host, char *service, char **na) 64 { 65 *na = netmkaddr(host, net, service); 66 return dial(*na, 0, 0, 0); 67 } 68 69 void 70 rex(int fd, char *cmd) 71 { 72 char buf[4096]; 73 int kid, n; 74 75 if(auth(fd) < 0){ 76 close(fd); 77 error("authenticate fails", 0); 78 } 79 write(fd, cmd, strlen(cmd)+1); 80 81 kid = send(fd); 82 while((n=read(fd, buf, sizeof buf))>0) 83 if(write(1, buf, n)!=n) 84 error("write error", 0); 85 sleep(250); 86 postnote(PNPROC, kid, note);/**/ 87 exits(0); 88 } 89 90 void 91 dkexec(int fd, char *addr, char *cmd) 92 { 93 char buf[4096]; 94 int kid, n; 95 96 if(read(fd, buf, 1)!=1 || *buf!='O' 97 || read(fd, buf, 1)!=1 || *buf!='K'){ 98 close(fd); 99 error("can't authenticate to", addr); 100 } 101 102 write(fd, cmd, strlen(cmd)+1); 103 kid = send(fd); 104 while((n=read(fd, buf, sizeof buf))>0) 105 if(write(1, buf, n)!=n) 106 error("write error", 0); 107 sleep(250); 108 postnote(PNPROC, kid, note);/**/ 109 exits(0); 110 } 111 112 void 113 tcpexec(int fd, char *addr, char *cmd) 114 { 115 char *u, buf[4096]; 116 int kid, n; 117 118 /* 119 * do the ucb authentication and send command 120 */ 121 u = getuser(); 122 if(write(fd, "", 1)<0 || write(fd, u, strlen(u)+1)<0 123 || write(fd, u, strlen(u)+1)<0 || write(fd, cmd, strlen(cmd)+1)<0){ 124 close(fd); 125 error("can't authenticate to", addr); 126 } 127 128 /* 129 * get authentication reply 130 */ 131 if(read(fd, buf, 1) != 1){ 132 close(fd); 133 error("can't authenticate to", addr); 134 } 135 if(buf[0] != 0){ 136 while(read(fd, buf, 1) == 1){ 137 write(2, buf, 1); 138 if(buf[0] == '\n') 139 break; 140 } 141 close(fd); 142 error("rejected by", addr); 143 } 144 145 kid = send(fd); 146 while((n=read(fd, buf, sizeof buf))>0) 147 if(write(1, buf, n)!=n) 148 error("write error", 0); 149 sleep(250); 150 postnote(PNPROC, kid, note);/**/ 151 exits(0); 152 } 153 154 int 155 send(int fd) 156 { 157 char buf[4096]; 158 int n; 159 int kid; 160 switch(kid = fork()){ 161 case -1: 162 error("fork error", 0); 163 case 0: 164 break; 165 default: 166 return kid; 167 } 168 while((n=read(0, buf, sizeof buf))>0) 169 if(write(fd, buf, n)!=n) 170 exits("write error"); 171 if(eof) 172 write(fd, buf, 0); 173 174 exits(0); 175 return 0; /* to keep compiler happy */ 176 } 177 178 void 179 error(char *s, char *z) 180 { 181 if(z == 0) 182 fprint(2, "%s: %s: %r\n", argv0, s); 183 else 184 fprint(2, "%s: %s %s: %r\n", argv0, s, z); 185 exits(s); 186 } 187 188 char * 189 buildargs(char *argv[]) 190 { 191 char *args; 192 int m, n; 193 194 args = malloc(1); 195 args[0] = '\0'; 196 n = 0; 197 while(*argv){ 198 m = strlen(*argv) + 1; 199 args = realloc(args, n+m +1); 200 if(args == 0) 201 error("malloc fail", 0); 202 args[n] = ' '; /* smashes old null */ 203 strcpy(args+n+1, *argv); 204 n += m; 205 argv++; 206 } 207 return args; 208 } 209