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