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 char *ruser; 8 char *key; 9 10 void rex(int, char*, char*); 11 void tcpexec(int, char*, char*); 12 int call(char *, char*, char*, char**); 13 char *buildargs(char*[]); 14 int send(int); 15 void error(char*, char*); 16 void sshexec(char *host, char *cmd); 17 18 void 19 usage(void) 20 { 21 fprint(2, "usage: %s [-e] [-k keypattern] [-l user] net!host command...\n", argv0); 22 exits("usage"); 23 } 24 25 void 26 main(int argc, char *argv[]) 27 { 28 char *host, *addr, *args; 29 int fd; 30 31 key = ""; 32 eof = 1; 33 ARGBEGIN{ 34 case 'e': 35 eof = 0; 36 break; 37 case 'k': 38 key = EARGF(usage()); 39 break; 40 case 'l': 41 ruser = EARGF(usage()); 42 break; 43 default: 44 usage(); 45 }ARGEND 46 47 if(argc < 2) 48 usage(); 49 host = argv[0]; 50 args = buildargs(&argv[1]); 51 52 /* try erexexec p9any then dial again with p9sk2 */ 53 fd = call(0, host, "rexexec", &addr); 54 if(fd >= 0) 55 rex(fd, args, "p9any"); 56 close(fd); 57 fd = call(0, host, "rexexec", &addr); 58 if(fd >= 0) 59 rex(fd, args, "p9sk2"); 60 close(fd); 61 62 /* if there's an ssh port, try that */ 63 fd = call("tcp", host, "ssh", &addr); 64 if(fd >= 0){ 65 close(fd); 66 sshexec(host, args); 67 /* falls through if no ssh */ 68 } 69 70 /* specific attempts */ 71 fd = call("tcp", host, "shell", &addr); 72 if(fd >= 0) 73 tcpexec(fd, addr, args); 74 75 error("can't dial", host); 76 exits(0); 77 } 78 79 int 80 call(char *net, char *host, char *service, char **na) 81 { 82 *na = netmkaddr(host, net, service); 83 return dial(*na, 0, 0, 0); 84 } 85 86 void 87 rex(int fd, char *cmd, char *proto) 88 { 89 char buf[4096]; 90 int kid, n; 91 AuthInfo *ai; 92 93 ai = auth_proxy(fd, auth_getkey, "proto=%s role=client %s", proto, key); 94 if(ai == nil){ 95 if(strcmp(proto, "p9any") == 0) 96 return; 97 error("auth_proxy", nil); 98 } 99 write(fd, cmd, strlen(cmd)+1); 100 101 kid = send(fd); 102 while((n=read(fd, buf, sizeof buf))>0) 103 if(write(1, buf, n)!=n) 104 error("write error", 0); 105 sleep(250); 106 postnote(PNPROC, kid, note);/**/ 107 exits(0); 108 } 109 110 void 111 tcpexec(int fd, char *addr, char *cmd) 112 { 113 char *u, buf[4096]; 114 int kid, n; 115 char *r; 116 117 /* 118 * do the ucb authentication and send command 119 */ 120 u = getuser(); 121 r = ruser ? ruser : u; 122 if(write(fd, "", 1)<0 || write(fd, u, strlen(u)+1)<0 123 || write(fd, r, strlen(r)+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 void 155 sshexec(char *host, char *cmd) 156 { 157 execl("/bin/ssh", "ssh", "-iCm", host, cmd, 0); 158 } 159 160 int 161 send(int fd) 162 { 163 char buf[4096]; 164 int n; 165 int kid; 166 switch(kid = fork()){ 167 case -1: 168 error("fork error", 0); 169 case 0: 170 break; 171 default: 172 return kid; 173 } 174 while((n=read(0, buf, sizeof buf))>0) 175 if(write(fd, buf, n)!=n) 176 exits("write error"); 177 if(eof) 178 write(fd, buf, 0); 179 180 exits(0); 181 return 0; /* to keep compiler happy */ 182 } 183 184 void 185 error(char *s, char *z) 186 { 187 if(z == 0) 188 fprint(2, "%s: %s: %r\n", argv0, s); 189 else 190 fprint(2, "%s: %s %s: %r\n", argv0, s, z); 191 exits(s); 192 } 193 194 char * 195 buildargs(char *argv[]) 196 { 197 char *args; 198 int m, n; 199 200 args = malloc(1); 201 args[0] = '\0'; 202 n = 0; 203 while(*argv){ 204 m = strlen(*argv) + 1; 205 args = realloc(args, n+m +1); 206 if(args == 0) 207 error("malloc fail", 0); 208 args[n] = ' '; /* smashes old null */ 209 strcpy(args+n+1, *argv); 210 n += m; 211 argv++; 212 } 213 return args; 214 } 215