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/tlsclient.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/tlsclient.c')
-rwxr-xr-x | sys/src/cmd/tlsclient.c | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/sys/src/cmd/tlsclient.c b/sys/src/cmd/tlsclient.c new file mode 100755 index 000000000..8bfff5d0f --- /dev/null +++ b/sys/src/cmd/tlsclient.c @@ -0,0 +1,92 @@ +#include <u.h> +#include <libc.h> +#include <mp.h> +#include <libsec.h> + +void +usage(void) +{ + fprint(2, "usage: tlsclient [-t /sys/lib/tls/xxx] [-x /sys/lib/tls/xxx.exclude] dialstring\n"); + exits("usage"); +} + +void +xfer(int from, int to) +{ + char buf[12*1024]; + int n; + + while((n = read(from, buf, sizeof buf)) > 0) + if(write(to, buf, n) < 0) + break; +} + +void +main(int argc, char **argv) +{ + int fd, netfd; + uchar digest[20]; + TLSconn conn; + char *addr, *file, *filex; + Thumbprint *thumb; + + file = nil; + filex = nil; + thumb = nil; + ARGBEGIN{ + case 't': + file = EARGF(usage()); + break; + case 'x': + filex = EARGF(usage()); + break; + default: + usage(); + }ARGEND + + if(argc != 1) + usage(); + + if(filex && !file) + sysfatal("specifying -x without -t is useless"); + if(file){ + thumb = initThumbprints(file, filex); + if(thumb == nil) + sysfatal("initThumbprints: %r"); + } + + addr = argv[0]; + if((netfd = dial(addr, 0, 0, 0)) < 0) + sysfatal("dial %s: %r", addr); + + memset(&conn, 0, sizeof conn); + fd = tlsClient(netfd, &conn); + if(fd < 0) + sysfatal("tlsclient: %r"); + if(thumb){ + if(conn.cert==nil || conn.certlen<=0) + sysfatal("server did not provide TLS certificate"); + sha1(conn.cert, conn.certlen, digest, nil); + if(!okThumbprint(digest, thumb)){ + fmtinstall('H', encodefmt); + sysfatal("server certificate %.*H not recognized", SHA1dlen, digest); + } + } + free(conn.cert); + close(netfd); + + rfork(RFNOTEG); + switch(fork()){ + case -1: + fprint(2, "%s: fork: %r\n", argv0); + exits("dial"); + case 0: + xfer(0, fd); + break; + default: + xfer(fd, 1); + break; + } + postnote(PNGROUP, getpid(), "die yankee pig dog"); + exits(0); +} |