tlssrv.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  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->cert = readcert(cert, &conn->certlen);
  126. if(debug)
  127. conn->trace = reporter;
  128. clearfd = 0;
  129. fd = 1;
  130. if(debug > 1)
  131. fd = dumper(fd);
  132. fd = tlsServer(fd, conn);
  133. if(fd < 0){
  134. reporter("failed: %r\n");
  135. exits(0);
  136. }
  137. reporter("open\n");
  138. if(argc > 0){
  139. if(pipe(p) < 0)
  140. exits("pipe");
  141. switch(fork()){
  142. case 0:
  143. close(fd);
  144. dup(p[0], 0);
  145. dup(p[0], 1);
  146. close(p[1]);
  147. close(p[0]);
  148. exec(argv[0], argv);
  149. reporter("can't exec %s: %r\n", argv[0]);
  150. _exits("exec");
  151. case -1:
  152. exits("fork");
  153. default:
  154. close(p[0]);
  155. clearfd = p[1];
  156. break;
  157. }
  158. }
  159. rfork(RFNOTEG);
  160. notify(death);
  161. switch(rfork(RFPROC)){
  162. case -1:
  163. sysfatal("can't fork");
  164. case 0:
  165. for(;;){
  166. n = read(clearfd, buf, BufSize);
  167. if(n <= 0)
  168. break;
  169. if(write(fd, buf, n) != n)
  170. break;
  171. }
  172. break;
  173. default:
  174. for(;;){
  175. n = read(fd, buf, BufSize);
  176. if(n <= 0)
  177. break;
  178. if(write(clearfd, buf, n) != n)
  179. break;
  180. }
  181. break;
  182. }
  183. death(nil, nil);
  184. }