1 /* A little hacked up program that makes a TCP/IP call and reads a script to
2 drive it, for testing Exim server code running as a daemon. It's got a bit
3 messy with the addition of support for either OpenSSL or GnuTLS. The code for
4 those was hacked out of Exim itself, then code for OpenSSL OCSP stapling was
5 ripped from the openssl ocsp and s_client utilities. */
7 /* ANSI C standard includes */
22 #include <sys/types.h>
24 #include <netinet/in_systm.h>
25 #include <netinet/in.h>
26 #include <netinet/ip.h>
27 #include <netinet/tcp.h>
30 #include <arpa/inet.h>
32 #include <sys/resource.h>
33 #include <sys/socket.h>
44 #define S_ADDR_TYPE u_long
47 typedef unsigned char uschar;
50 #define US (unsigned char *)
57 static int sigalrm_seen = 0;
60 /* TLS support can be optionally included, either for OpenSSL or GnuTLS. The
61 latter needs a whole pile of tables. */
64 # include <openssl/crypto.h>
65 # include <openssl/x509.h>
66 # include <openssl/pem.h>
67 # include <openssl/ssl.h>
68 # include <openssl/err.h>
69 # include <openssl/rand.h>
71 # if OPENSSL_VERSION_NUMBER < 0x0090806fL && !defined(DISABLE_OCSP) && !defined(OPENSSL_NO_TLSEXT)
72 # warning "OpenSSL library version too old; define DISABLE_OCSP in Makefile"
76 # include <openssl/ocsp.h>
83 # include <gnutls/gnutls.h>
84 # include <gnutls/x509.h>
85 # if GNUTLS_VERSION_NUMBER >= 0x030103
87 # include <gnutls/ocsp.h>
89 # ifndef GNUTLS_NO_EXTENSIONS
90 # define GNUTLS_NO_EXTENSIONS 0
95 /* Local static variables for GNUTLS */
97 static gnutls_dh_params_t dh_params = NULL;
99 static gnutls_certificate_credentials_t x509_cred = NULL;
100 static gnutls_session_t tls_session = NULL;
102 static int ssl_session_timeout = 200;
104 /* Priorities for TLS algorithms to use. */
106 #if GNUTLS_VERSION_NUMBER < 0x030400
107 static const int protocol_priority[16] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 };
109 static const int kx_priority[16] = {
115 static int default_cipher_priority[16] = {
116 GNUTLS_CIPHER_AES_256_CBC,
117 GNUTLS_CIPHER_AES_128_CBC,
118 GNUTLS_CIPHER_3DES_CBC,
119 GNUTLS_CIPHER_ARCFOUR_128,
122 static const int mac_priority[16] = {
127 static const int comp_priority[16] = { GNUTLS_COMP_NULL, 0 };
130 #endif /*HAVE_GNUTLS*/
135 char * ocsp_stapling = NULL;
139 /*************************************************
140 * SIGALRM handler - crash out *
141 *************************************************/
144 sigalrm_handler_crash(int sig)
146 sig = sig; /* Keep picky compilers happy */
147 printf("\nClient timed out\n");
152 /*************************************************
153 * SIGALRM handler - set flag *
154 *************************************************/
157 sigalrm_handler_flag(int sig)
159 sig = sig; /* Keep picky compilers happy */
165 /****************************************************************************/
166 /****************************************************************************/
169 # ifndef DISABLE_OCSP
171 static STACK_OF(X509) *
172 chain_from_pem_file(const uschar * file)
178 if (!(sk = sk_X509_new_null())) return NULL;
179 if (!(bp = BIO_new_file(CS file, "r"))) return NULL;
180 while ((x = PEM_read_bio_X509(bp, NULL, 0, NULL)))
189 cert_stack_free(STACK_OF(X509) * sk)
191 while (sk_X509_num(sk) > 0) (void) sk_X509_pop(sk);
197 tls_client_stapling_cb(SSL *s, void *arg)
199 const unsigned char *p;
206 len = SSL_get_tlsext_status_ocsp_resp(s, &p);
207 /*BIO_printf(arg, "OCSP response: ");*/
210 BIO_printf(arg, "no response received\n");
213 if(!(rsp = d2i_OCSP_RESPONSE(NULL, &p, len)))
215 BIO_printf(arg, "response parse error\n");
216 BIO_dump_indent(arg, (char *)p, len, 4);
219 if(!(bs = OCSP_response_get1_basic(rsp)))
221 BIO_printf(arg, "error parsing response\n");
226 if (!(sk = chain_from_pem_file(ocsp_stapling)))
228 BIO_printf(arg, "error in cert setup\n");
232 /* OCSP_basic_verify takes a "store" arg, but does not
233 use it for the chain verification, which is all we do
234 when OCSP_NOVERIFY is set. The content from the wire
235 (in "bs") and a cert-stack "sk" are all that is used. */
237 if(OCSP_basic_verify(bs, sk, NULL, OCSP_NOVERIFY) <= 0)
239 BIO_printf(arg, "Response Verify Failure\n");
240 ERR_print_errors(arg);
244 BIO_printf(arg, "Response verify OK\n");
249 # endif /*DISABLE_OCSP*/
252 /*************************************************
253 * Start an OpenSSL TLS session *
254 *************************************************/
257 tls_start(int sock, SSL **ssl, SSL_CTX *ctx)
260 static const unsigned char *sid_ctx = US"exim";
262 RAND_load_file("client.c", -1); /* Not *very* random! */
264 *ssl = SSL_new (ctx);
265 SSL_set_session_id_context(*ssl, sid_ctx, strlen(CS sid_ctx));
266 SSL_set_fd (*ssl, sock);
267 SSL_set_connect_state(*ssl);
272 SSL_CTX_set_tlsext_status_cb(ctx, tls_client_stapling_cb);
273 SSL_CTX_set_tlsext_status_arg(ctx, BIO_new_fp(stdout, BIO_NOCLOSE));
274 SSL_set_tlsext_status_type(*ssl, TLSEXT_STATUSTYPE_ocsp);
278 signal(SIGALRM, sigalrm_handler_flag);
281 rc = SSL_connect (*ssl);
286 printf("SSL_connect timed out\n");
292 ERR_print_errors_fp(stdout);
296 printf("SSL connection using %s\n", SSL_get_cipher (*ssl));
301 /*************************************************
302 * SSL Information callback *
303 *************************************************/
306 info_callback(SSL *s, int where, int ret)
310 printf("SSL info: %s\n", SSL_state_string_long(s));
315 /****************************************************************************/
316 /****************************************************************************/
320 /*************************************************
321 * Handle GnuTLS error *
322 *************************************************/
324 /* Called from lots of places when errors occur before actually starting to do
325 the TLS handshake, that is, while the session is still in clear.
329 err a GnuTLS error number, or 0 if local error
331 Returns: doesn't - it dies
335 gnutls_error(uschar *prefix, int err)
337 fprintf(stderr, "GnuTLS connection error: %s:", prefix);
338 if (err != 0) fprintf(stderr, " %s", gnutls_strerror(err));
339 fprintf(stderr, "\n");
345 /*************************************************
346 * Setup up DH parameters *
347 *************************************************/
349 /* For the test suite, the parameters should always be available in the spool
358 uschar filename[200];
361 /* Initialize the data structures for holding the parameters */
363 ret = gnutls_dh_params_init(&dh_params);
364 if (ret < 0) gnutls_error(US"init dh_params", ret);
366 /* Open the cache file for reading and if successful, read it and set up the
369 fd = open("aux-fixed/gnutls-params", O_RDONLY, 0);
372 fprintf(stderr, "Failed to open spool/gnutls-params: %s\n", strerror(errno));
376 if (fstat(fd, &statbuf) < 0)
379 return gnutls_error(US"TLS cache stat failed", 0);
382 m.size = statbuf.st_size;
383 m.data = malloc(m.size);
385 return gnutls_error(US"memory allocation failed", 0);
386 if (read(fd, m.data, m.size) != m.size)
387 return gnutls_error(US"TLS cache read failed", 0);
390 ret = gnutls_dh_params_import_pkcs3(dh_params, &m, GNUTLS_X509_FMT_PEM);
391 if (ret < 0) return gnutls_error(US"DH params import", ret);
398 /*************************************************
399 * Initialize for GnuTLS *
400 *************************************************/
404 certificate certificate file
405 privatekey private key file
409 tls_init(uschar *certificate, uschar *privatekey)
413 rc = gnutls_global_init();
414 if (rc < 0) gnutls_error(US"gnutls_global_init", rc);
416 /* Read D-H parameters from the cache file. */
420 /* Create the credentials structure */
422 rc = gnutls_certificate_allocate_credentials(&x509_cred);
423 if (rc < 0) gnutls_error(US"certificate_allocate_credentials", rc);
425 /* Set the certificate and private keys */
427 if (certificate != NULL)
429 rc = gnutls_certificate_set_x509_key_file(x509_cred, CS certificate,
430 CS privatekey, GNUTLS_X509_FMT_PEM);
431 if (rc < 0) gnutls_error("gnutls_certificate", rc);
434 /* Associate the parameters with the x509 credentials structure. */
436 gnutls_certificate_set_dh_params(x509_cred, dh_params);
438 /* set the CA info for server-cert verify */
440 gnutls_certificate_set_x509_trust_file(x509_cred, ocsp_stapling,
441 GNUTLS_X509_FMT_PEM);
446 /*************************************************
447 * Initialize a single GNUTLS session *
448 *************************************************/
450 static gnutls_session_t
451 tls_session_init(void)
453 gnutls_session_t session;
455 gnutls_init(&session, GNUTLS_CLIENT | GNUTLS_NO_EXTENSIONS);
457 #if GNUTLS_VERSION_NUMBER < 0x030400
458 gnutls_cipher_set_priority(session, default_cipher_priority);
459 gnutls_compression_set_priority(session, comp_priority);
460 gnutls_kx_set_priority(session, kx_priority);
461 gnutls_protocol_set_priority(session, protocol_priority);
462 gnutls_mac_set_priority(session, mac_priority);
464 gnutls_cred_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
466 gnutls_set_default_priority(session);
467 gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
470 gnutls_dh_set_prime_bits(session, DH_BITS);
471 gnutls_db_set_cache_expiration(session, ssl_session_timeout);
478 /****************************************************************************/
479 /* Turn "\n" and "\r" into the relevant characters. This is a hack. */
482 unescape_buf(unsigned char * buf, int len)
488 for (s = buf; s < buf+len; s++) if (*s == '\\')
492 default: c = s[1]; shift = 1; break;
493 case 'n': c = '\n'; shift = 1; break;
494 case 'r': c = '\r'; shift = 1; break;
497 if (t >= 'A' && t <= 'F') t -= 'A'-'9'-1;
498 else if (t >= 'a' && t <= 'f') t -= 'a'-'9'-1;
502 if (t >= 'A' && t <= 'F') t -= 'A'-'9'-1;
503 else if (t >= 'a' && t <= 'f') t -= 'a'-'9'-1;
510 memmove(s+1, s+shift+1, len-shift);
517 /****************************************************************************/
529 do_file(srv_ctx * srv, FILE * f, int timeout,
530 unsigned char * inbuffer, unsigned bsiz, unsigned char * inptr)
532 unsigned char outbuffer[1024 * 20];
534 while (fgets(CS outbuffer, sizeof(outbuffer), f) != NULL)
536 int n = (int)strlen(CS outbuffer);
540 /* Strip trailing newline */
541 if (outbuffer[n-1] == '\n') outbuffer[--n] = 0;
543 /* Expect incoming */
545 if ( strncmp(CS outbuffer, "???", 3) == 0
546 && (outbuffer[3] == ' ' || outbuffer[3] == '*')
549 unsigned char *lineptr;
550 unsigned exp_eof = outbuffer[3] == '*';
552 printf("%s\n", outbuffer);
553 n = unescape_buf(outbuffer, n);
555 if (*inptr == 0) /* Refill input buffer */
560 rc = SSL_read (srv->ssl, inbuffer, bsiz - 1);
563 rc = gnutls_record_recv(tls_session, CS inbuffer, bsiz - 1);
569 rc = read(srv->sock, inbuffer, bsiz);
575 printf("Read error %s\n", strerror(errno));
581 printf("Expected EOF read\n");
586 printf("Unexpected EOF read\n");
592 printf("Expected EOF not read\n");
604 while (*inptr != 0 && *inptr != '\r' && *inptr != '\n') inptr++;
608 if (*inptr == '\n') inptr++;
611 printf("<<< %s\n", lineptr);
612 if (strncmp(CS lineptr, CS outbuffer + 4, n - 4) != 0)
614 printf("\n******** Input mismatch ********\n");
619 if (srv->sent_starttls)
621 if (lineptr[0] == '2')
626 printf("Attempting to start TLS\n");
630 srv->tls_active = tls_start(srv->sock, &srv->ssl, srv->ctx);
636 sigalrm_seen = FALSE;
639 rc = gnutls_handshake(tls_session);
640 } while (rc < 0 && gnutls_error_is_fatal(rc) == 0);
641 srv->tls_active = rc >= 0;
644 if (!srv->tls_active) printf("%s\n", gnutls_strerror(rc));
648 if (!srv->tls_active)
650 printf("Failed to start TLS\n");
654 else if (ocsp_stapling)
656 if ((rc= gnutls_certificate_verify_peers2(tls_session, &verify)) < 0)
658 printf("Failed to verify certificate: %s\n", gnutls_strerror(rc));
661 else if (verify & (GNUTLS_CERT_INVALID|GNUTLS_CERT_REVOKED))
663 printf("Bad certificate\n");
667 else if (gnutls_ocsp_status_request_is_checked(tls_session, 0) == 0)
669 printf("Failed to verify certificate status\n");
671 gnutls_datum_t stapling;
672 gnutls_ocsp_resp_t resp;
673 gnutls_datum_t printed;
674 if ( (rc= gnutls_ocsp_status_request_get(tls_session, &stapling)) == 0
675 && (rc= gnutls_ocsp_resp_init(&resp)) == 0
676 && (rc= gnutls_ocsp_resp_import(resp, &stapling)) == 0
677 && (rc= gnutls_ocsp_resp_print(resp, GNUTLS_OCSP_PRINT_FULL, &printed)) == 0
680 fprintf(stderr, "%.4096s", printed.data);
681 gnutls_free(printed.data);
684 (void) fprintf(stderr,"ocsp decode: %s", gnutls_strerror(rc));
692 printf("Succeeded in starting TLS\n");
694 else printf("Abandoning TLS start attempt\n");
696 srv->sent_starttls = 0;
700 /* Wait for a bit before proceeding */
702 else if (strncmp(CS outbuffer, "+++ ", 4) == 0)
704 printf("%s\n", outbuffer);
705 sleep(atoi(CS outbuffer + 4));
708 /* Stack new input file */
710 else if (strncmp(CS outbuffer, "<<< ", 4) == 0)
713 if (!(new_f = fopen(outbuffer+4 , "r")))
715 printf("Unable to open '%s': %s", inptr, sys_errlist[errno]);
718 do_file(srv, new_f, timeout, inbuffer, bsiz, inptr);
722 /* Send line outgoing, but barf if unconsumed incoming */
726 unsigned char * out = outbuffer;
728 if (strncmp(CS outbuffer, ">>> ", 4) == 0)
737 printf("Unconsumed input: %s", inptr);
738 printf(" About to send: %s\n", out);
746 if (strcmp(CS out, "stoptls") == 0 ||
747 strcmp(CS out, "STOPTLS") == 0)
749 if (!srv->tls_active)
751 printf("STOPTLS read when TLS not active\n");
754 printf("Shutting down TLS encryption\n");
757 SSL_shutdown(srv->ssl);
762 gnutls_bye(tls_session, GNUTLS_SHUT_WR);
763 gnutls_deinit(tls_session);
765 gnutls_global_deinit();
772 /* Remember that we sent STARTTLS */
774 srv->sent_starttls = (strcmp(CS out, "starttls") == 0 ||
775 strcmp(CS out, "STARTTLS") == 0);
777 /* Fudge: if the command is "starttls_wait", we send the starttls bit,
778 but we haven't set the flag, so that there is no negotiation. This is for
779 testing the server's timeout. */
781 if (strcmp(CS out, "starttls_wait") == 0)
788 printf(">>> %s\n", out);
791 strcpy(CS out + n, "\r\n");
795 n = unescape_buf(out, n);
803 rc = SSL_write (srv->ssl, out, n);
806 if ((rc = gnutls_record_send(tls_session, CS out, n)) < 0)
808 printf("GnuTLS write error: %s\n", gnutls_strerror(rc));
814 rc = write(srv->sock, out, n);
819 printf("Write error: %s\n", strerror(errno));
829 /*************************************************
831 *************************************************/
833 const char * const HELP_MESSAGE = "\n\
841 [-tn] n seconds timeout\n\
844 [<outgoing interface>]\n\
850 main(int argc, char **argv)
852 struct sockaddr *s_ptr;
853 struct sockaddr_in s_in4;
854 char *interface = NULL;
855 char *address = NULL;
856 char *certfile = NULL;
857 char *keyfile = NULL;
860 int host_af, port, s_len, rc, save_errno;
862 int tls_on_connect = 0;
866 struct sockaddr_in6 s_in6;
871 unsigned char inbuffer[10240];
872 unsigned char *inptr = inbuffer;
874 *inptr = 0; /* Buffer empty */
876 srv.sent_starttls = 0;
880 while (argc >= argi + 1 && argv[argi][0] == '-')
882 if (strcmp(argv[argi], "-help") == 0 ||
883 strcmp(argv[argi], "--help") == 0 ||
884 strcmp(argv[argi], "-h") == 0)
889 if (strcmp(argv[argi], "-tls-on-connect") == 0)
895 else if (strcmp(argv[argi], "-ocsp") == 0)
897 if (argc < ++argi + 1)
899 fprintf(stderr, "Missing required certificate file for ocsp option\n");
902 ocsp_stapling = argv[argi++];
906 else if (argv[argi][1] == 't' && isdigit(argv[argi][2]))
908 tmplong = strtol(argv[argi]+2, &end, 10);
909 if (end == argv[argi]+2 || *end)
911 fprintf(stderr, "Failed to parse seconds from option <%s>\n",
915 if (tmplong > 10000L)
917 fprintf(stderr, "Unreasonably long wait of %ld seconds requested\n",
923 fprintf(stderr, "Timeout must not be negative (%ld)\n", tmplong);
926 timeout = (int) tmplong;
931 fprintf(stderr, "Unrecognized option %s\n", argv[argi]);
936 /* Mandatory 1st arg is IP address */
940 fprintf(stderr, "No IP address given\n");
944 address = argv[argi++];
945 host_af = (strchr(address, ':') != NULL)? AF_INET6 : AF_INET;
947 /* Mandatory 2nd arg is port */
951 fprintf(stderr, "No port number given\n");
955 port = atoi(argv[argi++]);
957 /* Optional next arg is interface */
960 (isdigit((unsigned char)argv[argi][0]) || argv[argi][0] == ':'))
961 interface = argv[argi++];
963 /* Any more arguments are the name of a certificate file and key file */
965 if (argc > argi) certfile = argv[argi++];
966 if (argc > argi) keyfile = argv[argi++];
970 /* For an IPv6 address, use an IPv6 sockaddr structure. */
972 if (host_af == AF_INET6)
974 s_ptr = (struct sockaddr *)&s_in6;
975 s_len = sizeof(s_in6);
980 /* For an IPv4 address, use an IPv4 sockaddr structure,
981 even on an IPv6 system. */
984 s_ptr = (struct sockaddr *)&s_in4;
985 s_len = sizeof(s_in4);
988 printf("Connecting to %s port %d ... ", address, port);
990 srv.sock = socket(host_af, SOCK_STREAM, 0);
993 printf("socket creation failed: %s\n", strerror(errno));
997 /* Bind to a specific interface if requested. On an IPv6 system, this has
998 to be of the same family as the address we are calling. On an IPv4 system the
999 test is redundant, but it keeps the code tidier. */
1001 if (interface != NULL)
1003 int interface_af = (strchr(interface, ':') != NULL)? AF_INET6 : AF_INET;
1005 if (interface_af == host_af)
1009 /* Set up for IPv6 binding */
1011 if (host_af == AF_INET6)
1013 memset(&s_in6, 0, sizeof(s_in6));
1014 s_in6.sin6_family = AF_INET6;
1015 s_in6.sin6_port = 0;
1016 if (inet_pton(AF_INET6, interface, &s_in6.sin6_addr) != 1)
1018 printf("Unable to parse \"%s\"", interface);
1025 /* Set up for IPv4 binding */
1028 memset(&s_in4, 0, sizeof(s_in4));
1029 s_in4.sin_family = AF_INET;
1031 s_in4.sin_addr.s_addr = (S_ADDR_TYPE)inet_addr(interface);
1036 if (bind(srv.sock, s_ptr, s_len) < 0)
1038 printf("Unable to bind outgoing SMTP call to %s: %s",
1039 interface, strerror(errno));
1045 /* Set up a remote IPv6 address */
1048 if (host_af == AF_INET6)
1050 memset(&s_in6, 0, sizeof(s_in6));
1051 s_in6.sin6_family = AF_INET6;
1052 s_in6.sin6_port = htons(port);
1053 if (inet_pton(host_af, address, &s_in6.sin6_addr) != 1)
1055 printf("Unable to parse \"%s\"", address);
1062 /* Set up a remote IPv4 address */
1065 memset(&s_in4, 0, sizeof(s_in4));
1066 s_in4.sin_family = AF_INET;
1067 s_in4.sin_port = htons(port);
1068 s_in4.sin_addr.s_addr = (S_ADDR_TYPE)inet_addr(address);
1071 /* SIGALRM handler crashes out */
1073 signal(SIGALRM, sigalrm_handler_crash);
1075 rc = connect(srv.sock, s_ptr, s_len);
1079 /* A failure whose error code is "Interrupted system call" is in fact
1080 an externally applied timeout if the signal handler has been run. */
1085 printf("connect failed: %s\n", strerror(save_errno));
1089 printf("connected\n");
1092 /* --------------- Set up for OpenSSL --------------- */
1096 SSL_load_error_strings();
1098 if (!(srv.ctx = SSL_CTX_new(SSLv23_method())))
1100 printf ("SSL_CTX_new failed\n");
1106 if (!SSL_CTX_use_certificate_file(srv.ctx, certfile, SSL_FILETYPE_PEM))
1108 printf("SSL_CTX_use_certificate_file failed\n");
1111 printf("Certificate file = %s\n", certfile);
1116 if (!SSL_CTX_use_PrivateKey_file(srv.ctx, keyfile, SSL_FILETYPE_PEM))
1118 printf("SSL_CTX_use_PrivateKey_file failed\n");
1121 printf("Key file = %s\n", keyfile);
1124 SSL_CTX_set_session_cache_mode(srv.ctx, SSL_SESS_CACHE_BOTH);
1125 SSL_CTX_set_timeout(srv.ctx, 200);
1126 SSL_CTX_set_info_callback(srv.ctx, (void (*)())info_callback);
1130 /* --------------- Set up for GnuTLS --------------- */
1133 if (certfile != NULL) printf("Certificate file = %s\n", certfile);
1134 if (keyfile != NULL) printf("Key file = %s\n", keyfile);
1135 tls_init(certfile, keyfile);
1136 tls_session = tls_session_init();
1139 gnutls_ocsp_status_request_enable_client(tls_session, NULL, 0, NULL);
1141 gnutls_transport_set_ptr(tls_session, (gnutls_transport_ptr_t)(intptr_t)srv.sock);
1143 /* When the server asks for a certificate and the client does not have one,
1144 there is a SIGPIPE error in the gnutls_handshake() function for some reason
1145 that is not understood. As luck would have it, this has never hit Exim itself
1146 because it ignores SIGPIPE errors. Doing the same here allows it all to work as
1149 signal(SIGPIPE, SIG_IGN);
1152 /* ---------------------------------------------- */
1155 /* Start TLS session if configured to do so without STARTTLS */
1160 printf("Attempting to start TLS\n");
1163 srv.tls_active = tls_start(srv.sock, &srv.ssl, srv.ctx);
1169 sigalrm_seen = FALSE;
1172 rc = gnutls_handshake(tls_session);
1173 } while (rc < 0 && gnutls_error_is_fatal(rc) == 0);
1174 srv.tls_active = rc >= 0;
1177 if (!srv.tls_active) printf("%s\n", gnutls_strerror(rc));
1181 if (!srv.tls_active)
1182 printf("Failed to start TLS\n");
1183 #if defined(HAVE_GNUTLS) && defined(HAVE_OCSP)
1184 else if ( ocsp_stapling
1185 && gnutls_ocsp_status_request_is_checked(tls_session, 0) == 0)
1186 printf("Failed to verify certificate status\n");
1189 printf("Succeeded in starting TLS\n");
1193 do_file(&srv, stdin, timeout, inbuffer, sizeof(inbuffer), inptr);
1195 printf("End of script\n");
1196 shutdown(srv.sock, SHUT_WR);
1197 while (read(srv.sock, inbuffer, sizeof(inbuffer)) > 0) ;
1203 /* End of client.c */