rx.c 3.2 KB

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