rx.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <auth.h>
  4. int eof; /* send an eof if true */
  5. char *note = "die: yankee dog";
  6. char *ruser;
  7. char *key;
  8. void rex(int, char*, char*);
  9. void tcpexec(int, char*, char*);
  10. int call(char *, char*, char*, char**);
  11. char *buildargs(char*[]);
  12. int send(int);
  13. void error(char*, char*);
  14. void
  15. usage(void)
  16. {
  17. fprint(2, "usage: %s [-e] [-k keypattern] [-l user] net!host command...\n", argv0);
  18. exits("usage");
  19. }
  20. void
  21. main(int argc, char *argv[])
  22. {
  23. char *host, *addr, *args;
  24. int fd;
  25. key = "";
  26. eof = 1;
  27. ARGBEGIN{
  28. case 'e':
  29. eof = 0;
  30. break;
  31. case 'k':
  32. key = EARGF(usage());
  33. break;
  34. case 'l':
  35. ruser = EARGF(usage());
  36. break;
  37. default:
  38. usage();
  39. }ARGEND
  40. if(argc < 2)
  41. usage();
  42. host = argv[0];
  43. args = buildargs(&argv[1]);
  44. /* generic attempts: try p9any then dial again with p9sk2 */
  45. fd = call(0, host, "rexexec", &addr);
  46. if(fd >= 0)
  47. rex(fd, args, "p9any");
  48. close(fd);
  49. fd = call(0, host, "rexexec", &addr);
  50. if(fd >= 0)
  51. rex(fd, args, "p9sk2");
  52. close(fd);
  53. /* specific attempts */
  54. fd = call("tcp", host, "shell", &addr);
  55. if(fd >= 0)
  56. tcpexec(fd, addr, args);
  57. error("can't dial", host);
  58. exits(0);
  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. void
  67. rex(int fd, char *cmd, char *proto)
  68. {
  69. char buf[4096];
  70. int kid, n;
  71. AuthInfo *ai;
  72. ai = auth_proxy(fd, auth_getkey, "proto=%s role=client %s", proto, key);
  73. if(ai == nil){
  74. if(strcmp(proto, "p9any") == 0)
  75. return;
  76. error("auth_proxy", nil);
  77. }
  78. write(fd, cmd, strlen(cmd)+1);
  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. void
  88. tcpexec(int fd, char *addr, char *cmd)
  89. {
  90. char *u, buf[4096];
  91. int kid, n;
  92. char *r;
  93. /*
  94. * do the ucb authentication and send command
  95. */
  96. u = getuser();
  97. r = ruser ? ruser : u;
  98. if(write(fd, "", 1)<0 || write(fd, u, strlen(u)+1)<0
  99. || write(fd, r, strlen(r)+1)<0 || write(fd, cmd, strlen(cmd)+1)<0){
  100. close(fd);
  101. error("can't authenticate to", addr);
  102. }
  103. /*
  104. * get authentication reply
  105. */
  106. if(read(fd, buf, 1) != 1){
  107. close(fd);
  108. error("can't authenticate to", addr);
  109. }
  110. if(buf[0] != 0){
  111. while(read(fd, buf, 1) == 1){
  112. write(2, buf, 1);
  113. if(buf[0] == '\n')
  114. break;
  115. }
  116. close(fd);
  117. error("rejected by", addr);
  118. }
  119. kid = send(fd);
  120. while((n=read(fd, buf, sizeof buf))>0)
  121. if(write(1, buf, n)!=n)
  122. error("write error", 0);
  123. sleep(250);
  124. postnote(PNPROC, kid, note);/**/
  125. exits(0);
  126. }
  127. int
  128. send(int fd)
  129. {
  130. char buf[4096];
  131. int n;
  132. int kid;
  133. switch(kid = fork()){
  134. case -1:
  135. error("fork error", 0);
  136. case 0:
  137. break;
  138. default:
  139. return kid;
  140. }
  141. while((n=read(0, buf, sizeof buf))>0)
  142. if(write(fd, buf, n)!=n)
  143. exits("write error");
  144. if(eof)
  145. write(fd, buf, 0);
  146. exits(0);
  147. return 0; /* to keep compiler happy */
  148. }
  149. void
  150. error(char *s, char *z)
  151. {
  152. if(z == 0)
  153. fprint(2, "%s: %s: %r\n", argv0, s);
  154. else
  155. fprint(2, "%s: %s %s: %r\n", argv0, s, z);
  156. exits(s);
  157. }
  158. char *
  159. buildargs(char *argv[])
  160. {
  161. char *args;
  162. int m, n;
  163. args = malloc(1);
  164. args[0] = '\0';
  165. n = 0;
  166. while(*argv){
  167. m = strlen(*argv) + 1;
  168. args = realloc(args, n+m +1);
  169. if(args == 0)
  170. error("malloc fail", 0);
  171. args[n] = ' '; /* smashes old null */
  172. strcpy(args+n+1, *argv);
  173. n += m;
  174. argv++;
  175. }
  176. return args;
  177. }