summaryrefslogtreecommitdiff
path: root/sys/src/cmd/tlsclient.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/tlsclient.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/tlsclient.c')
-rwxr-xr-xsys/src/cmd/tlsclient.c92
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);
+}