1 #include <u.h> 2 #include <libc.h> 3 #include <mp.h> 4 #include <libsec.h> 5 6 void 7 usage(void) 8 { 9 fprint(2, "usage: tlsclient [-t /sys/lib/tls/xxx] [-x /sys/lib/tls/xxx.exclude] dialstring\n"); 10 exits("usage"); 11 } 12 13 void 14 xfer(int from, int to) 15 { 16 char buf[12*1024]; 17 int n; 18 19 while((n = read(from, buf, sizeof buf)) > 0) 20 if(write(to, buf, n) < 0) 21 break; 22 } 23 24 void 25 main(int argc, char **argv) 26 { 27 int fd, netfd; 28 uchar digest[20]; 29 TLSconn conn; 30 char *addr, *file, *filex; 31 Thumbprint *thumb; 32 33 file = nil; 34 filex = nil; 35 thumb = nil; 36 ARGBEGIN{ 37 case 't': 38 file = EARGF(usage()); 39 break; 40 case 'x': 41 filex = EARGF(usage()); 42 break; 43 default: 44 usage(); 45 }ARGEND 46 47 if(argc != 1) 48 usage(); 49 50 if(filex && !file) 51 sysfatal("specifying -x without -t is useless"); 52 if(file){ 53 thumb = initThumbprints(file, filex); 54 if(thumb == nil) 55 sysfatal("initThumbprints: %r"); 56 } 57 58 addr = argv[0]; 59 if((netfd = dial(addr, 0, 0, 0)) < 0) 60 sysfatal("dial %s: %r", addr); 61 62 memset(&conn, 0, sizeof conn); 63 fd = tlsClient(netfd, &conn); 64 if(fd < 0) 65 sysfatal("tlsclient: %r"); 66 if(thumb){ 67 if(conn.cert==nil || conn.certlen<=0) 68 sysfatal("server did not provide TLS certificate"); 69 sha1(conn.cert, conn.certlen, digest, nil); 70 if(!okThumbprint(digest, thumb)){ 71 fmtinstall('H', encodefmt); 72 sysfatal("server certificate %.*H not recognized", SHA1dlen, digest); 73 } 74 } 75 free(conn.cert); 76 close(netfd); 77 78 rfork(RFNOTEG); 79 switch(fork()){ 80 case -1: 81 fprint(2, "%s: fork: %r\n", argv0); 82 exits("dial"); 83 case 0: 84 xfer(0, fd); 85 break; 86 default: 87 xfer(fd, 1); 88 break; 89 } 90 postnote(PNGROUP, getpid(), "die yankee pig dog"); 91 exits(0); 92 } 93