tlsclient.c 1.6 KB

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