tlssrv.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include <mp.h>
  5. #include <libsec.h>
  6. enum{ BufSize = 8192 };
  7. char *remotesys, *logfile;
  8. int debug, p[2];
  9. void
  10. death(void *, char *)
  11. {
  12. int pid;
  13. close(0);
  14. close(1);
  15. close(p[1]);
  16. pid = getpid();
  17. postnote(PNGROUP, pid, "die");
  18. postnote(PNGROUP, pid, "die");
  19. postnote(PNGROUP, pid, "die");
  20. _exits(0);
  21. }
  22. static void
  23. dump(int fd, uchar *buf, int n, char *label)
  24. {
  25. Biobuf bout;
  26. int i;
  27. Binit(&bout, fd, OWRITE);
  28. Bprint(&bout, "%s<%d>: ", label, n);
  29. if(n > 64)
  30. n = 64;
  31. for(i = 0; i < n; i++)
  32. Bprint(&bout, "%2.2x ", buf[i]);
  33. Bprint(&bout, "\n");
  34. Bterm(&bout);
  35. }
  36. static void
  37. xfer(int from, int to, int cfd, char *label)
  38. {
  39. uchar buf[BufSize];
  40. int n;
  41. if(fork() == 0)
  42. return;
  43. close(cfd);
  44. for(;;){
  45. n = read(from, buf, sizeof(buf));
  46. if(n <= 0){
  47. fprint(2, "%s EOF\n", label);
  48. close(to);
  49. close(from);
  50. death(nil, nil);
  51. }
  52. dump(2, buf, n, label);
  53. n = write(to, buf, n);
  54. if(n < 0){
  55. fprint(2, "%s write err\n", label);
  56. close(to);
  57. close(from);
  58. death(nil, nil);
  59. }
  60. }
  61. }
  62. static int
  63. dumper(int fd)
  64. {
  65. int p[2];
  66. if(pipe(p) < 0)
  67. sysfatal("can't make pipe: %r");
  68. xfer(fd, p[0], p[1], "read");
  69. xfer(p[0], fd, p[1], "write");
  70. close(p[0]);
  71. return p[1];
  72. }
  73. static int
  74. reporter(char *fmt, ...)
  75. {
  76. va_list ap;
  77. char buf[2000];
  78. va_start(ap, fmt);
  79. if(logfile){
  80. vsnprint(buf, sizeof buf, fmt, ap);
  81. syslog(0, logfile, "%s tls reports %s", remotesys, buf);
  82. }else{
  83. fprint(2, "%s: %s tls reports ", argv0, remotesys);
  84. vfprint(2, fmt, ap);
  85. fprint(2, "\n");
  86. }
  87. va_end(ap);
  88. return 0;
  89. }
  90. void
  91. main(int argc, char *argv[])
  92. {
  93. TLSconn *conn;
  94. uchar buf[BufSize];
  95. char *cert;
  96. int n, fd, clearfd;
  97. debug = 0;
  98. remotesys = nil;
  99. cert = nil;
  100. logfile = nil;
  101. ARGBEGIN{
  102. case 'D':
  103. debug++;
  104. break;
  105. case 'c':
  106. cert = ARGF();
  107. break;
  108. case 'l':
  109. logfile = ARGF();
  110. break;
  111. case 'r':
  112. remotesys = ARGF();
  113. break;
  114. default:
  115. fprint(2, "usage: tlssrv -c cert [-D] [-l logfile] [-r remotesys] [cmd args...]\n");
  116. fprint(2, " after auth/secretpem key.pem > /mnt/factotum/ctl\n");
  117. exits("usage");
  118. }ARGEND
  119. if(cert == nil)
  120. sysfatal("no certificate specified");
  121. if(remotesys == nil)
  122. remotesys = "";
  123. conn = (TLSconn*)mallocz(sizeof *conn, 1);
  124. if(conn == nil)
  125. sysfatal("out of memory");
  126. conn->chain = readcertchain(cert);
  127. if (conn->chain == nil)
  128. sysfatal("can't read certificate");
  129. conn->cert = conn->chain->pem;
  130. conn->certlen = conn->chain->pemlen;
  131. conn->chain = conn->chain->next;
  132. if(debug)
  133. conn->trace = reporter;
  134. clearfd = 0;
  135. fd = 1;
  136. if(debug > 1)
  137. fd = dumper(fd);
  138. fd = tlsServer(fd, conn);
  139. if(fd < 0){
  140. reporter("failed: %r");
  141. exits(0);
  142. }
  143. reporter("open\n");
  144. if(argc > 0){
  145. if(pipe(p) < 0)
  146. exits("pipe");
  147. switch(fork()){
  148. case 0:
  149. close(fd);
  150. dup(p[0], 0);
  151. dup(p[0], 1);
  152. close(p[1]);
  153. close(p[0]);
  154. exec(argv[0], argv);
  155. reporter("can't exec %s: %r", argv[0]);
  156. _exits("exec");
  157. case -1:
  158. exits("fork");
  159. default:
  160. close(p[0]);
  161. clearfd = p[1];
  162. break;
  163. }
  164. }
  165. rfork(RFNOTEG);
  166. notify(death);
  167. switch(rfork(RFPROC)){
  168. case -1:
  169. sysfatal("can't fork");
  170. case 0:
  171. for(;;){
  172. n = read(clearfd, buf, BufSize);
  173. if(n <= 0)
  174. break;
  175. if(write(fd, buf, n) != n)
  176. break;
  177. }
  178. break;
  179. default:
  180. for(;;){
  181. n = read(fd, buf, BufSize);
  182. if(n <= 0)
  183. break;
  184. if(write(clearfd, buf, n) != n)
  185. break;
  186. }
  187. break;
  188. }
  189. death(nil, nil);
  190. }