tlssrv.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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. usage(void)
  92. {
  93. fprint(2, "usage: tlssrv -c cert [-D] [-l logfile] [-r remotesys] [cmd args...]\n");
  94. fprint(2, " after auth/secretpem key.pem > /mnt/factotum/ctl\n");
  95. exits("usage");
  96. }
  97. void
  98. main(int argc, char *argv[])
  99. {
  100. TLSconn *conn;
  101. uchar buf[BufSize];
  102. char *cert;
  103. int n, fd, clearfd;
  104. debug = 0;
  105. remotesys = nil;
  106. cert = nil;
  107. logfile = nil;
  108. ARGBEGIN{
  109. case 'D':
  110. debug++;
  111. break;
  112. case 'c':
  113. cert = EARGF(usage());
  114. break;
  115. case 'l':
  116. logfile = EARGF(usage());
  117. break;
  118. case 'r':
  119. remotesys = EARGF(usage());
  120. break;
  121. default:
  122. usage();
  123. }ARGEND
  124. if(cert == nil)
  125. sysfatal("no certificate specified");
  126. if(remotesys == nil)
  127. remotesys = "";
  128. conn = (TLSconn*)mallocz(sizeof *conn, 1);
  129. if(conn == nil)
  130. sysfatal("out of memory");
  131. conn->chain = readcertchain(cert);
  132. if (conn->chain == nil)
  133. sysfatal("can't read certificate");
  134. conn->cert = conn->chain->pem;
  135. conn->certlen = conn->chain->pemlen;
  136. conn->chain = conn->chain->next;
  137. if(debug)
  138. conn->trace = reporter;
  139. clearfd = 0;
  140. fd = 1;
  141. if(debug > 1)
  142. fd = dumper(fd);
  143. fd = tlsServer(fd, conn);
  144. if(fd < 0){
  145. reporter("failed: %r");
  146. exits(0);
  147. }
  148. reporter("open\n");
  149. if(argc > 0){
  150. if(pipe(p) < 0)
  151. exits("pipe");
  152. switch(fork()){
  153. case 0:
  154. close(fd);
  155. dup(p[0], 0);
  156. dup(p[0], 1);
  157. close(p[1]);
  158. close(p[0]);
  159. exec(argv[0], argv);
  160. reporter("can't exec %s: %r", argv[0]);
  161. _exits("exec");
  162. case -1:
  163. exits("fork");
  164. default:
  165. close(p[0]);
  166. clearfd = p[1];
  167. break;
  168. }
  169. }
  170. rfork(RFNOTEG);
  171. notify(death);
  172. switch(rfork(RFPROC)){
  173. case -1:
  174. sysfatal("can't fork");
  175. case 0:
  176. for(;;){
  177. n = read(clearfd, buf, BufSize);
  178. if(n <= 0)
  179. break;
  180. if(write(fd, buf, n) != n)
  181. break;
  182. }
  183. break;
  184. default:
  185. for(;;){
  186. n = read(fd, buf, BufSize);
  187. if(n <= 0)
  188. break;
  189. if(write(clearfd, buf, n) != n)
  190. break;
  191. }
  192. break;
  193. }
  194. death(nil, nil);
  195. }