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