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;
136 char * pri_string = NULL;
140 /*************************************************
141 * SIGALRM handler - crash out *
142 *************************************************/
145 sigalrm_handler_crash(int sig)
147 sig = sig; /* Keep picky compilers happy */
148 printf("\nClient timed out\n");
153 /*************************************************
154 * SIGALRM handler - set flag *
155 *************************************************/
158 sigalrm_handler_flag(int sig)
160 sig = sig; /* Keep picky compilers happy */
166 /****************************************************************************/
167 /****************************************************************************/
170 # ifndef DISABLE_OCSP
172 static STACK_OF(X509) *
173 chain_from_pem_file(const uschar * file)
179 if (!(sk = sk_X509_new_null())) return NULL;
180 if (!(bp = BIO_new_file(CS file, "r"))) return NULL;
181 while ((x = PEM_read_bio_X509(bp, NULL, 0, NULL)))
190 cert_stack_free(STACK_OF(X509) * sk)
192 while (sk_X509_num(sk) > 0) (void) sk_X509_pop(sk);
198 tls_client_stapling_cb(SSL *s, void *arg)
200 const unsigned char *p;
207 len = SSL_get_tlsext_status_ocsp_resp(s, &p);
208 /*BIO_printf(arg, "OCSP response: ");*/
211 BIO_printf(arg, "no response received\n");
214 if(!(rsp = d2i_OCSP_RESPONSE(NULL, &p, len)))
216 BIO_printf(arg, "response parse error\n");
217 BIO_dump_indent(arg, (char *)p, len, 4);
220 if(!(bs = OCSP_response_get1_basic(rsp)))
222 BIO_printf(arg, "error parsing response\n");
227 if (!(sk = chain_from_pem_file((const uschar *)ocsp_stapling)))
229 BIO_printf(arg, "error in cert setup\n");
233 /* OCSP_basic_verify takes a "store" arg, but does not
234 use it for the chain verification, which is all we do
235 when OCSP_NOVERIFY is set. The content from the wire
236 (in "bs") and a cert-stack "sk" are all that is used. */
238 if(OCSP_basic_verify(bs, sk, NULL, OCSP_NOVERIFY) <= 0)
240 BIO_printf(arg, "Response Verify Failure\n");
241 ERR_print_errors(arg);
245 BIO_printf(arg, "Response verify OK\n");
250 # endif /*DISABLE_OCSP*/
253 /*************************************************
254 * Start an OpenSSL TLS session *
255 *************************************************/
258 tls_start(int sock, SSL **ssl, SSL_CTX *ctx)
261 static const unsigned char *sid_ctx = US"exim";
263 RAND_load_file("client.c", -1); /* Not *very* random! */
265 *ssl = SSL_new (ctx);
266 SSL_set_session_id_context(*ssl, sid_ctx, strlen(CS sid_ctx));
267 SSL_set_fd (*ssl, sock);
268 SSL_set_connect_state(*ssl);
273 SSL_CTX_set_tlsext_status_cb(ctx, tls_client_stapling_cb);
274 SSL_CTX_set_tlsext_status_arg(ctx, BIO_new_fp(stdout, BIO_NOCLOSE));
275 SSL_set_tlsext_status_type(*ssl, TLSEXT_STATUSTYPE_ocsp);
279 signal(SIGALRM, sigalrm_handler_flag);
282 rc = SSL_connect (*ssl);
287 printf("SSL_connect timed out\n");
293 ERR_print_errors_fp(stdout);
297 printf("SSL connection using %s\n", SSL_get_cipher (*ssl));
302 /*************************************************
303 * SSL Information callback *
304 *************************************************/
307 info_callback(SSL *s, int where, int ret)
311 printf("SSL info: %s\n", SSL_state_string_long(s));
316 /****************************************************************************/
317 /****************************************************************************/
321 /*************************************************
322 * Handle GnuTLS error *
323 *************************************************/
325 /* Called from lots of places when errors occur before actually starting to do
326 the TLS handshake, that is, while the session is still in clear.
330 err a GnuTLS error number, or 0 if local error
332 Returns: doesn't - it dies
336 gnutls_error(uschar *prefix, int err)
338 fprintf(stderr, "GnuTLS connection error: %s:", prefix);
339 if (err != 0) fprintf(stderr, " %s", gnutls_strerror(err));
340 fprintf(stderr, "\n");
346 /*************************************************
347 * Setup up DH parameters *
348 *************************************************/
350 /* For the test suite, the parameters should always be available in the spool
359 uschar filename[200];
362 /* Initialize the data structures for holding the parameters */
364 ret = gnutls_dh_params_init(&dh_params);
365 if (ret < 0) gnutls_error(US"init dh_params", ret);
367 /* Open the cache file for reading and if successful, read it and set up the
370 fd = open("aux-fixed/gnutls-params", O_RDONLY, 0);
373 fprintf(stderr, "Failed to open spool/gnutls-params: %s\n", strerror(errno));
377 if (fstat(fd, &statbuf) < 0)
380 return gnutls_error(US"TLS cache stat failed", 0);
383 m.size = statbuf.st_size;
384 m.data = malloc(m.size);
386 return gnutls_error(US"memory allocation failed", 0);
387 if (read(fd, m.data, m.size) != m.size)
388 return gnutls_error(US"TLS cache read failed", 0);
391 ret = gnutls_dh_params_import_pkcs3(dh_params, &m, GNUTLS_X509_FMT_PEM);
392 if (ret < 0) return gnutls_error(US"DH params import", ret);
399 /*************************************************
400 * Initialize for GnuTLS *
401 *************************************************/
405 certificate certificate file
406 privatekey private key file
410 tls_init(uschar *certificate, uschar *privatekey)
414 rc = gnutls_global_init();
415 if (rc < 0) gnutls_error(US"gnutls_global_init", rc);
417 /* Read D-H parameters from the cache file. */
421 /* Create the credentials structure */
423 rc = gnutls_certificate_allocate_credentials(&x509_cred);
424 if (rc < 0) gnutls_error(US"certificate_allocate_credentials", rc);
426 /* Set the certificate and private keys */
428 if (certificate != NULL)
430 rc = gnutls_certificate_set_x509_key_file(x509_cred, CS certificate,
431 CS privatekey, GNUTLS_X509_FMT_PEM);
432 if (rc < 0) gnutls_error("gnutls_certificate", rc);
435 /* Associate the parameters with the x509 credentials structure. */
437 gnutls_certificate_set_dh_params(x509_cred, dh_params);
439 /* set the CA info for server-cert verify */
441 gnutls_certificate_set_x509_trust_file(x509_cred, ocsp_stapling,
442 GNUTLS_X509_FMT_PEM);
447 /*************************************************
448 * Initialize a single GNUTLS session *
449 *************************************************/
451 static gnutls_session_t
452 tls_session_init(void)
454 gnutls_session_t session;
456 gnutls_init(&session, GNUTLS_CLIENT | GNUTLS_NO_EXTENSIONS);
458 # if GNUTLS_VERSION_NUMBER < 0x030400
459 gnutls_cipher_set_priority(session, default_cipher_priority);
460 gnutls_compression_set_priority(session, comp_priority);
461 gnutls_kx_set_priority(session, kx_priority);
462 gnutls_protocol_set_priority(session, protocol_priority);
463 gnutls_mac_set_priority(session, mac_priority);
465 gnutls_cred_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
469 gnutls_priority_t priority_cache;
472 gnutls_priority_init(&priority_cache, pri_string, &errpos);
473 gnutls_priority_set(session, priority_cache);
476 gnutls_set_default_priority(session);
477 gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
480 gnutls_dh_set_prime_bits(session, DH_BITS);
481 gnutls_db_set_cache_expiration(session, ssl_session_timeout);
488 /****************************************************************************/
489 /* Turn "\n" and "\r" into the relevant characters. This is a hack. */
492 unescape_buf(unsigned char * buf, int len)
498 for (s = buf; s < buf+len; s++) if (*s == '\\')
502 default: c = s[1]; shift = 1; break;
503 case 'n': c = '\n'; shift = 1; break;
504 case 'r': c = '\r'; shift = 1; break;
507 if (t >= 'A' && t <= 'F') t -= 'A'-'9'-1;
508 else if (t >= 'a' && t <= 'f') t -= 'a'-'9'-1;
512 if (t >= 'A' && t <= 'F') t -= 'A'-'9'-1;
513 else if (t >= 'a' && t <= 'f') t -= 'a'-'9'-1;
520 memmove(s+1, s+shift+1, len-shift);
527 /****************************************************************************/
539 do_file(srv_ctx * srv, FILE * f, int timeout,
540 unsigned char * inbuffer, unsigned bsiz, unsigned char * inptr)
542 unsigned char outbuffer[1024 * 20];
544 while (fgets(CS outbuffer, sizeof(outbuffer), f) != NULL)
546 int n = (int)strlen(CS outbuffer);
550 /* Strip trailing newline */
551 if (outbuffer[n-1] == '\n') outbuffer[--n] = 0;
553 /* Expect incoming */
555 if ( strncmp(CS outbuffer, "???", 3) == 0
556 && (outbuffer[3] == ' ' || outbuffer[3] == '*' || outbuffer[3] == '?')
559 unsigned char *lineptr;
560 unsigned exp_eof = outbuffer[3] == '*';
561 unsigned resp_optional = outbuffer[3] == '?';
563 printf("%s\n", outbuffer);
564 n = unescape_buf(outbuffer, n);
567 if (*inptr == 0) /* Refill input buffer */
573 rc = SSL_read(srv->ssl, inbuffer, bsiz - 1);
576 rc = gnutls_record_recv(tls_session, CS inbuffer, bsiz - 1);
580 rc = read(srv->sock, inbuffer, bsiz);
585 printf("Read error %s\n", strerror(errno));
591 printf("Expected EOF read\n");
596 printf("Unexpected EOF read\n");
602 printf("Expected EOF not read\n");
614 while (*inptr != 0 && *inptr != '\r' && *inptr != '\n') inptr++;
618 if (*inptr == '\n') inptr++;
621 if (strncmp(CS lineptr, CS outbuffer + 4, n - 4) != 0)
624 inptr = lineptr; /* consume scriptline, not inputline */
629 printf("<<< %s\n", lineptr);
630 printf("\n******** Input mismatch ********\n");
634 /* input matched script */
637 goto nextinput; /* consume inputline, not scriptline */
639 printf("<<< %s\n", lineptr);
642 if (srv->sent_starttls)
644 if (lineptr[0] == '2')
648 printf("Attempting to start TLS\n");
652 srv->tls_active = tls_start(srv->sock, &srv->ssl, srv->ctx);
658 sigalrm_seen = FALSE;
661 rc = gnutls_handshake(tls_session);
662 } while (rc < 0 && gnutls_error_is_fatal(rc) == 0);
663 srv->tls_active = rc >= 0;
666 if (!srv->tls_active) printf("%s\n", gnutls_strerror(rc));
670 if (!srv->tls_active)
672 printf("Failed to start TLS\n");
676 else if (ocsp_stapling)
678 if ((rc= gnutls_certificate_verify_peers2(tls_session, &verify)) < 0)
680 printf("Failed to verify certificate: %s\n", gnutls_strerror(rc));
683 else if (verify & (GNUTLS_CERT_INVALID|GNUTLS_CERT_REVOKED))
685 printf("Bad certificate\n");
689 else if (gnutls_ocsp_status_request_is_checked(tls_session, 0) == 0)
691 printf("Failed to verify certificate status\n");
693 gnutls_datum_t stapling;
694 gnutls_ocsp_resp_t resp;
695 gnutls_datum_t printed;
696 if ( (rc= gnutls_ocsp_status_request_get(tls_session, &stapling)) == 0
697 && (rc= gnutls_ocsp_resp_init(&resp)) == 0
698 && (rc= gnutls_ocsp_resp_import(resp, &stapling)) == 0
699 && (rc= gnutls_ocsp_resp_print(resp, GNUTLS_OCSP_PRINT_FULL, &printed)) == 0
702 fprintf(stderr, "%.4096s", printed.data);
703 gnutls_free(printed.data);
706 (void) fprintf(stderr,"ocsp decode: %s", gnutls_strerror(rc));
714 printf("Succeeded in starting TLS\n");
716 else printf("Abandoning TLS start attempt\n");
718 srv->sent_starttls = 0;
722 /* Wait for a bit before proceeding */
724 else if (strncmp(CS outbuffer, "+++ ", 4) == 0)
726 printf("%s\n", outbuffer);
727 sleep(atoi(CS outbuffer + 4));
730 /* Stack new input file */
732 else if (strncmp(CS outbuffer, "<<< ", 4) == 0)
735 if (!(new_f = fopen((const char *)outbuffer+4 , "r")))
737 printf("Unable to open '%s': %s", inptr, strerror(errno));
740 do_file(srv, new_f, timeout, inbuffer, bsiz, inptr);
744 /* Send line outgoing, but barf if unconsumed incoming */
748 unsigned char * out = outbuffer;
750 if (strncmp(CS outbuffer, ">>> ", 4) == 0)
759 printf("Unconsumed input: %s", inptr);
760 printf(" About to send: %s\n", out);
768 if (strcmp(CS out, "stoptls") == 0 ||
769 strcmp(CS out, "STOPTLS") == 0)
771 if (!srv->tls_active)
773 printf("STOPTLS read when TLS not active\n");
776 printf("Shutting down TLS encryption\n");
779 SSL_shutdown(srv->ssl);
784 gnutls_bye(tls_session, GNUTLS_SHUT_WR);
785 gnutls_deinit(tls_session);
787 gnutls_global_deinit();
794 /* Remember that we sent STARTTLS */
796 srv->sent_starttls = (strcmp(CS out, "starttls") == 0 ||
797 strcmp(CS out, "STARTTLS") == 0);
799 /* Fudge: if the command is "starttls_wait", we send the starttls bit,
800 but we haven't set the flag, so that there is no negotiation. This is for
801 testing the server's timeout. */
803 if (strcmp(CS out, "starttls_wait") == 0)
810 printf(">>> %s\n", out);
813 strcpy(CS out + n, "\r\n");
817 n = unescape_buf(out, n);
825 rc = SSL_write (srv->ssl, out, n);
828 if ((rc = gnutls_record_send(tls_session, CS out, n)) < 0)
830 printf("GnuTLS write error: %s\n", gnutls_strerror(rc));
836 rc = write(srv->sock, out, n);
841 printf("Write error: %s\n", strerror(errno));
851 /*************************************************
853 *************************************************/
855 const char * const HELP_MESSAGE = "\n\
863 [-p priority-string]\n"
867 [-tn] n seconds timeout\n\
870 [<outgoing interface>]\n\
876 main(int argc, char **argv)
878 struct sockaddr *s_ptr;
879 struct sockaddr_in s_in4;
880 char *interface = NULL;
881 char *address = NULL;
882 char *certfile = NULL;
883 char *keyfile = NULL;
886 int host_af, port, s_len, rc, save_errno;
888 int tls_on_connect = 0;
892 struct sockaddr_in6 s_in6;
897 unsigned char inbuffer[10240];
898 unsigned char *inptr = inbuffer;
900 *inptr = 0; /* Buffer empty */
902 srv.sent_starttls = 0;
906 while (argc >= argi + 1 && argv[argi][0] == '-')
908 if (strcmp(argv[argi], "-help") == 0 ||
909 strcmp(argv[argi], "--help") == 0 ||
910 strcmp(argv[argi], "-h") == 0)
915 if (strcmp(argv[argi], "-tls-on-connect") == 0)
921 else if (strcmp(argv[argi], "-ocsp") == 0)
923 if (argc < ++argi + 1)
925 fprintf(stderr, "Missing required certificate file for ocsp option\n");
928 ocsp_stapling = argv[argi++];
931 else if (strcmp(argv[argi], "-p") == 0)
933 if (argc < ++argi + 1)
935 fprintf(stderr, "Missing priority string\n");
938 pri_string = argv[argi++];
943 else if (argv[argi][1] == 't' && isdigit(argv[argi][2]))
945 tmplong = strtol(argv[argi]+2, &end, 10);
946 if (end == argv[argi]+2 || *end)
948 fprintf(stderr, "Failed to parse seconds from option <%s>\n",
952 if (tmplong > 10000L)
954 fprintf(stderr, "Unreasonably long wait of %ld seconds requested\n",
960 fprintf(stderr, "Timeout must not be negative (%ld)\n", tmplong);
963 timeout = (int) tmplong;
968 fprintf(stderr, "Unrecognized option %s\n", argv[argi]);
973 /* Mandatory 1st arg is IP address */
977 fprintf(stderr, "No IP address given\n");
981 address = argv[argi++];
982 host_af = (strchr(address, ':') != NULL)? AF_INET6 : AF_INET;
984 /* Mandatory 2nd arg is port */
988 fprintf(stderr, "No port number given\n");
992 port = atoi(argv[argi++]);
994 /* Optional next arg is interface */
997 (isdigit((unsigned char)argv[argi][0]) || argv[argi][0] == ':'))
998 interface = argv[argi++];
1000 /* Any more arguments are the name of a certificate file and key file */
1002 if (argc > argi) certfile = argv[argi++];
1003 if (argc > argi) keyfile = argv[argi++];
1007 /* For an IPv6 address, use an IPv6 sockaddr structure. */
1009 if (host_af == AF_INET6)
1011 s_ptr = (struct sockaddr *)&s_in6;
1012 s_len = sizeof(s_in6);
1017 /* For an IPv4 address, use an IPv4 sockaddr structure,
1018 even on an IPv6 system. */
1021 s_ptr = (struct sockaddr *)&s_in4;
1022 s_len = sizeof(s_in4);
1025 printf("Connecting to %s port %d ... ", address, port);
1027 srv.sock = socket(host_af, SOCK_STREAM, 0);
1030 printf("socket creation failed: %s\n", strerror(errno));
1034 /* Bind to a specific interface if requested. On an IPv6 system, this has
1035 to be of the same family as the address we are calling. On an IPv4 system the
1036 test is redundant, but it keeps the code tidier. */
1038 if (interface != NULL)
1040 int interface_af = (strchr(interface, ':') != NULL)? AF_INET6 : AF_INET;
1042 if (interface_af == host_af)
1046 /* Set up for IPv6 binding */
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 = 0;
1053 if (inet_pton(AF_INET6, interface, &s_in6.sin6_addr) != 1)
1055 printf("Unable to parse \"%s\"", interface);
1062 /* Set up for IPv4 binding */
1065 memset(&s_in4, 0, sizeof(s_in4));
1066 s_in4.sin_family = AF_INET;
1068 s_in4.sin_addr.s_addr = (S_ADDR_TYPE)inet_addr(interface);
1073 if (bind(srv.sock, s_ptr, s_len) < 0)
1075 printf("Unable to bind outgoing SMTP call to %s: %s",
1076 interface, strerror(errno));
1082 /* Set up a remote IPv6 address */
1085 if (host_af == AF_INET6)
1087 memset(&s_in6, 0, sizeof(s_in6));
1088 s_in6.sin6_family = AF_INET6;
1089 s_in6.sin6_port = htons(port);
1090 if (inet_pton(host_af, address, &s_in6.sin6_addr) != 1)
1092 printf("Unable to parse \"%s\"", address);
1099 /* Set up a remote IPv4 address */
1102 memset(&s_in4, 0, sizeof(s_in4));
1103 s_in4.sin_family = AF_INET;
1104 s_in4.sin_port = htons(port);
1105 s_in4.sin_addr.s_addr = (S_ADDR_TYPE)inet_addr(address);
1108 /* SIGALRM handler crashes out */
1110 signal(SIGALRM, sigalrm_handler_crash);
1112 rc = connect(srv.sock, s_ptr, s_len);
1116 /* A failure whose error code is "Interrupted system call" is in fact
1117 an externally applied timeout if the signal handler has been run. */
1122 printf("connect failed: %s\n", strerror(save_errno));
1126 printf("connected\n");
1129 /* --------------- Set up for OpenSSL --------------- */
1133 SSL_load_error_strings();
1135 if (!(srv.ctx = SSL_CTX_new(SSLv23_method())))
1137 printf ("SSL_CTX_new failed\n");
1143 if (!SSL_CTX_use_certificate_file(srv.ctx, certfile, SSL_FILETYPE_PEM))
1145 printf("SSL_CTX_use_certificate_file failed\n");
1148 printf("Certificate file = %s\n", certfile);
1153 if (!SSL_CTX_use_PrivateKey_file(srv.ctx, keyfile, SSL_FILETYPE_PEM))
1155 printf("SSL_CTX_use_PrivateKey_file failed\n");
1158 printf("Key file = %s\n", keyfile);
1161 SSL_CTX_set_session_cache_mode(srv.ctx, SSL_SESS_CACHE_BOTH);
1162 SSL_CTX_set_timeout(srv.ctx, 200);
1163 SSL_CTX_set_info_callback(srv.ctx, (void (*)())info_callback);
1167 /* --------------- Set up for GnuTLS --------------- */
1170 if (certfile != NULL) printf("Certificate file = %s\n", certfile);
1171 if (keyfile != NULL) printf("Key file = %s\n", keyfile);
1172 tls_init(certfile, keyfile);
1173 tls_session = tls_session_init();
1176 gnutls_ocsp_status_request_enable_client(tls_session, NULL, 0, NULL);
1178 gnutls_transport_set_ptr(tls_session, (gnutls_transport_ptr_t)(intptr_t)srv.sock);
1180 /* When the server asks for a certificate and the client does not have one,
1181 there is a SIGPIPE error in the gnutls_handshake() function for some reason
1182 that is not understood. As luck would have it, this has never hit Exim itself
1183 because it ignores SIGPIPE errors. Doing the same here allows it all to work as
1186 signal(SIGPIPE, SIG_IGN);
1189 /* ---------------------------------------------- */
1192 /* Start TLS session if configured to do so without STARTTLS */
1197 printf("Attempting to start TLS\n");
1200 srv.tls_active = tls_start(srv.sock, &srv.ssl, srv.ctx);
1206 sigalrm_seen = FALSE;
1209 rc = gnutls_handshake(tls_session);
1210 } while (rc < 0 && gnutls_error_is_fatal(rc) == 0);
1211 srv.tls_active = rc >= 0;
1214 if (!srv.tls_active) printf("%s\n", gnutls_strerror(rc));
1218 if (!srv.tls_active)
1219 printf("Failed to start TLS\n");
1220 #if defined(HAVE_GNUTLS) && defined(HAVE_OCSP)
1221 else if ( ocsp_stapling
1222 && gnutls_ocsp_status_request_is_checked(tls_session, 0) == 0)
1223 printf("Failed to verify certificate status\n");
1226 printf("Succeeded in starting TLS\n");
1230 do_file(&srv, stdin, timeout, inbuffer, sizeof(inbuffer), inptr);
1232 printf("End of script\n");
1233 shutdown(srv.sock, SHUT_WR);
1234 if (fcntl(srv.sock, F_SETFL, O_NONBLOCK) == 0)
1235 while (read(srv.sock, inbuffer, sizeof(inbuffer)) > 0) ;
1241 /* End of client.c */