tlssrv.c 3.3 KB

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