diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/tlssrv.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/tlssrv.c')
-rwxr-xr-x | sys/src/cmd/tlssrv.c | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/sys/src/cmd/tlssrv.c b/sys/src/cmd/tlssrv.c new file mode 100755 index 000000000..ef27f26d9 --- /dev/null +++ b/sys/src/cmd/tlssrv.c @@ -0,0 +1,216 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include <mp.h> +#include <libsec.h> + +enum{ BufSize = 8192 }; + +char *remotesys, *logfile; +int debug, p[2]; + +void +death(void *, char *) +{ + int pid; + + close(0); + close(1); + close(p[1]); + pid = getpid(); + postnote(PNGROUP, pid, "die"); + postnote(PNGROUP, pid, "die"); + postnote(PNGROUP, pid, "die"); + _exits(0); +} + +static void +dump(int fd, uchar *buf, int n, char *label) +{ + Biobuf bout; + int i; + + Binit(&bout, fd, OWRITE); + Bprint(&bout, "%s<%d>: ", label, n); + if(n > 64) + n = 64; + for(i = 0; i < n; i++) + Bprint(&bout, "%2.2x ", buf[i]); + Bprint(&bout, "\n"); + Bterm(&bout); +} + +static void +xfer(int from, int to, int cfd, char *label) +{ + uchar buf[BufSize]; + int n; + + if(fork() == 0) + return; + + close(cfd); + for(;;){ + n = read(from, buf, sizeof(buf)); + if(n <= 0){ + fprint(2, "%s EOF\n", label); + close(to); + close(from); + death(nil, nil); + } + dump(2, buf, n, label); + n = write(to, buf, n); + if(n < 0){ + fprint(2, "%s write err\n", label); + close(to); + close(from); + death(nil, nil); + } + } +} + +static int +dumper(int fd) +{ + int p[2]; + + if(pipe(p) < 0) + sysfatal("can't make pipe: %r"); + + xfer(fd, p[0], p[1], "read"); + xfer(p[0], fd, p[1], "write"); + close(p[0]); + return p[1]; +} + +static int +reporter(char *fmt, ...) +{ + va_list ap; + char buf[2000]; + + va_start(ap, fmt); + if(logfile){ + vsnprint(buf, sizeof buf, fmt, ap); + syslog(0, logfile, "%s tls reports %s", remotesys, buf); + }else{ + fprint(2, "%s: %s tls reports ", argv0, remotesys); + vfprint(2, fmt, ap); + fprint(2, "\n"); + } + va_end(ap); + return 0; +} + +void +usage(void) +{ + fprint(2, "usage: tlssrv -c cert [-D] [-l logfile] [-r remotesys] [cmd args...]\n"); + fprint(2, " after auth/secretpem key.pem > /mnt/factotum/ctl\n"); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + TLSconn *conn; + uchar buf[BufSize]; + char *cert; + int n, fd, clearfd; + + debug = 0; + remotesys = nil; + cert = nil; + logfile = nil; + ARGBEGIN{ + case 'D': + debug++; + break; + case 'c': + cert = EARGF(usage()); + break; + case 'l': + logfile = EARGF(usage()); + break; + case 'r': + remotesys = EARGF(usage()); + break; + default: + usage(); + }ARGEND + + if(cert == nil) + sysfatal("no certificate specified"); + if(remotesys == nil) + remotesys = ""; + conn = (TLSconn*)mallocz(sizeof *conn, 1); + if(conn == nil) + sysfatal("out of memory"); + conn->chain = readcertchain(cert); + if (conn->chain == nil) + sysfatal("can't read certificate"); + conn->cert = conn->chain->pem; + conn->certlen = conn->chain->pemlen; + conn->chain = conn->chain->next; + if(debug) + conn->trace = reporter; + + clearfd = 0; + fd = 1; + if(debug > 1) + fd = dumper(fd); + fd = tlsServer(fd, conn); + if(fd < 0){ + reporter("failed: %r"); + exits(0); + } + reporter("open"); + + if(argc > 0){ + if(pipe(p) < 0) + exits("pipe"); + switch(fork()){ + case 0: + close(fd); + dup(p[0], 0); + dup(p[0], 1); + close(p[1]); + close(p[0]); + exec(argv[0], argv); + reporter("can't exec %s: %r", argv[0]); + _exits("exec"); + case -1: + exits("fork"); + default: + close(p[0]); + clearfd = p[1]; + break; + } + } + + rfork(RFNOTEG); + notify(death); + switch(rfork(RFPROC)){ + case -1: + sysfatal("can't fork"); + case 0: + for(;;){ + n = read(clearfd, buf, BufSize); + if(n <= 0) + break; + if(write(fd, buf, n) != n) + break; + } + break; + default: + for(;;){ + n = read(fd, buf, BufSize); + if(n <= 0) + break; + if(write(clearfd, buf, n) != n) + break; + } + break; + } + death(nil, nil); +} |