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 9 void rex(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 case 'l': 35 ruser = ARGF(); 36 break; 37 default: 38 usage(); 39 }ARGEND 40 41 if(argc < 2) 42 usage(); 43 host = argv[0]; 44 args = buildargs(&argv[1]); 45 46 /* specific attempts */ 47 fd = call("tcp", host, "shell", &addr); 48 if(fd >= 0) 49 tcpexec(fd, addr, args); 50 51 /* generic attempts: try p9any then dial again with p9sk2 */ 52 fd = call(0, host, "rexexec", &addr); 53 if(fd >= 0) 54 rex(fd, args, "p9any"); 55 close(fd); 56 fd = call(0, host, "rexexec", &addr); 57 if(fd >= 0) 58 rex(fd, args, "p9sk2"); 59 close(fd); 60 61 error("can't dial", host); 62 exits(0); 63 } 64 65 int 66 call(char *net, char *host, char *service, char **na) 67 { 68 *na = netmkaddr(host, net, service); 69 return dial(*na, 0, 0, 0); 70 } 71 72 void 73 rex(int fd, char *cmd, char *proto) 74 { 75 char buf[4096]; 76 int kid, n; 77 AuthInfo *ai; 78 79 ai = auth_proxy(fd, auth_getkey, "proto=%s role=client", proto); 80 if(ai == nil){ 81 if(strcmp(proto, "p9any") == 0) 82 return; 83 error("auth_proxy", nil); 84 } 85 write(fd, cmd, strlen(cmd)+1); 86 87 kid = send(fd); 88 while((n=read(fd, buf, sizeof buf))>0) 89 if(write(1, buf, n)!=n) 90 error("write error", 0); 91 sleep(250); 92 postnote(PNPROC, kid, note);/**/ 93 exits(0); 94 } 95 96 void 97 tcpexec(int fd, char *addr, char *cmd) 98 { 99 char *u, buf[4096]; 100 int kid, n; 101 char *r; 102 103 /* 104 * do the ucb authentication and send command 105 */ 106 u = getuser(); 107 r = ruser ? ruser : u; 108 if(write(fd, "", 1)<0 || write(fd, u, strlen(u)+1)<0 109 || write(fd, r, strlen(r)+1)<0 || write(fd, cmd, strlen(cmd)+1)<0){ 110 close(fd); 111 error("can't authenticate to", addr); 112 } 113 114 /* 115 * get authentication reply 116 */ 117 if(read(fd, buf, 1) != 1){ 118 close(fd); 119 error("can't authenticate to", addr); 120 } 121 if(buf[0] != 0){ 122 while(read(fd, buf, 1) == 1){ 123 write(2, buf, 1); 124 if(buf[0] == '\n') 125 break; 126 } 127 close(fd); 128 error("rejected by", addr); 129 } 130 131 kid = send(fd); 132 while((n=read(fd, buf, sizeof buf))>0) 133 if(write(1, buf, n)!=n) 134 error("write error", 0); 135 sleep(250); 136 postnote(PNPROC, kid, note);/**/ 137 exits(0); 138 } 139 140 int 141 send(int fd) 142 { 143 char buf[4096]; 144 int n; 145 int kid; 146 switch(kid = fork()){ 147 case -1: 148 error("fork error", 0); 149 case 0: 150 break; 151 default: 152 return kid; 153 } 154 while((n=read(0, buf, sizeof buf))>0) 155 if(write(fd, buf, n)!=n) 156 exits("write error"); 157 if(eof) 158 write(fd, buf, 0); 159 160 exits(0); 161 return 0; /* to keep compiler happy */ 162 } 163 164 void 165 error(char *s, char *z) 166 { 167 if(z == 0) 168 fprint(2, "%s: %s: %r\n", argv0, s); 169 else 170 fprint(2, "%s: %s %s: %r\n", argv0, s, z); 171 exits(s); 172 } 173 174 char * 175 buildargs(char *argv[]) 176 { 177 char *args; 178 int m, n; 179 180 args = malloc(1); 181 args[0] = '\0'; 182 n = 0; 183 while(*argv){ 184 m = strlen(*argv) + 1; 185 args = realloc(args, n+m +1); 186 if(args == 0) 187 error("malloc fail", 0); 188 args[n] = ' '; /* smashes old null */ 189 strcpy(args+n+1, *argv); 190 n += m; 191 argv++; 192 } 193 return args; 194 } 195