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>
39 /* Set to TRUE to enable debug output */
40 #define DEBUG if (FALSE)
47 #define S_ADDR_TYPE u_long
50 typedef unsigned char uschar;
53 #define US (unsigned char *)
60 static int sigalrm_seen = 0;
63 /* TLS support can be optionally included, either for OpenSSL or GnuTLS. The
64 latter needs a whole pile of tables. */
67 # include <openssl/crypto.h>
68 # include <openssl/x509.h>
69 # include <openssl/pem.h>
70 # include <openssl/ssl.h>
71 # include <openssl/err.h>
72 # include <openssl/rand.h>
74 # if OPENSSL_VERSION_NUMBER < 0x0090806fL && !defined(DISABLE_OCSP) && !defined(OPENSSL_NO_TLSEXT)
75 # warning "OpenSSL library version too old; define DISABLE_OCSP in Makefile"
79 # include <openssl/ocsp.h>
86 # include <gnutls/gnutls.h>
87 # include <gnutls/x509.h>
88 # if GNUTLS_VERSION_NUMBER >= 0x030103
89 # define HAVE_GNUTLS_OCSP
90 # include <gnutls/ocsp.h>
92 # ifndef GNUTLS_NO_EXTENSIONS
93 # define GNUTLS_NO_EXTENSIONS 0
98 /* Local static variables for GNUTLS */
100 static gnutls_dh_params_t dh_params = NULL;
102 static gnutls_certificate_credentials_t x509_cred = NULL;
103 static gnutls_session_t tls_session = NULL;
105 static int ssl_session_timeout = 200;
107 /* Priorities for TLS algorithms to use. */
109 # if GNUTLS_VERSION_NUMBER < 0x030400
110 static const int protocol_priority[16] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 };
112 static const int kx_priority[16] = {
118 static int default_cipher_priority[16] = {
119 GNUTLS_CIPHER_AES_256_CBC,
120 GNUTLS_CIPHER_AES_128_CBC,
121 GNUTLS_CIPHER_3DES_CBC,
122 GNUTLS_CIPHER_ARCFOUR_128,
125 static const int mac_priority[16] = {
130 static const int comp_priority[16] = { GNUTLS_COMP_NULL, 0 };
133 #endif /*HAVE_GNUTLS*/
138 char * ocsp_stapling = NULL;
139 char * pri_string = NULL;
144 /*************************************************
145 * SIGALRM handler - crash out *
146 *************************************************/
149 sigalrm_handler_crash(int sig)
151 sig = sig; /* Keep picky compilers happy */
152 printf("\nClient timed out\n");
157 /*************************************************
158 * SIGALRM handler - set flag *
159 *************************************************/
162 sigalrm_handler_flag(int sig)
164 sig = sig; /* Keep picky compilers happy */
170 /****************************************************************************/
171 /****************************************************************************/
174 # ifndef DISABLE_OCSP
176 static STACK_OF(X509) *
177 chain_from_pem_file(const uschar * file)
183 if (!(sk = sk_X509_new_null())) return NULL;
184 if (!(bp = BIO_new_file(CS file, "r"))) return NULL;
185 while ((x = PEM_read_bio_X509(bp, NULL, 0, NULL)))
194 cert_stack_free(STACK_OF(X509) * sk)
196 while (sk_X509_num(sk) > 0) (void) sk_X509_pop(sk);
202 tls_client_stapling_cb(SSL *s, void *arg)
204 const unsigned char *p;
211 len = SSL_get_tlsext_status_ocsp_resp(s, &p);
212 /*BIO_printf(arg, "OCSP response: ");*/
215 BIO_printf(arg, "no OCSP response received\n");
218 if(!(rsp = d2i_OCSP_RESPONSE(NULL, &p, len)))
220 BIO_printf(arg, "OCSP response parse error\n");
221 BIO_dump_indent(arg, (char *)p, len, 4);
224 if(!(bs = OCSP_response_get1_basic(rsp)))
226 BIO_printf(arg, "error parsing OCSP response\n");
231 if (!(sk = chain_from_pem_file((const uschar *)ocsp_stapling)))
233 BIO_printf(arg, "error in cert setup\n");
237 /* OCSP_basic_verify takes a "store" arg, but does not
238 use it for the chain verification, which is all we do
239 when OCSP_NOVERIFY is set. The content from the wire
240 (in "bs") and a cert-stack "sk" are all that is used. */
242 if(OCSP_basic_verify(bs, sk, NULL, OCSP_NOVERIFY) <= 0)
244 BIO_printf(arg, "OCSP status response verify failure\n");
245 ERR_print_errors(arg);
249 BIO_printf(arg, "OCSP status response: good signature\n");
254 # endif /*DISABLE_OCSP*/
257 /*************************************************
258 * Start an OpenSSL TLS session *
259 *************************************************/
262 tls_start(int sock, SSL **ssl, SSL_CTX *ctx)
265 static const unsigned char *sid_ctx = US"exim";
267 RAND_load_file("client.c", -1); /* Not *very* random! */
269 *ssl = SSL_new (ctx);
270 SSL_set_session_id_context(*ssl, sid_ctx, strlen(CS sid_ctx));
271 SSL_set_fd (*ssl, sock);
272 SSL_set_connect_state(*ssl);
277 SSL_CTX_set_tlsext_status_cb(ctx, tls_client_stapling_cb);
278 SSL_CTX_set_tlsext_status_arg(ctx, BIO_new_fp(stdout, BIO_NOCLOSE));
279 SSL_set_tlsext_status_type(*ssl, TLSEXT_STATUSTYPE_ocsp);
283 signal(SIGALRM, sigalrm_handler_flag);
286 rc = SSL_connect (*ssl);
291 printf("SSL_connect timed out\n");
297 ERR_print_errors_fp(stdout);
301 /* printf("SSL connection using %s\n", SSL_get_cipher (*ssl)); */
306 /*************************************************
307 * SSL Information callback *
308 *************************************************/
311 info_callback(SSL *s, int where, int ret)
315 printf("SSL info: %s\n", SSL_state_string_long(s));
320 /****************************************************************************/
321 /****************************************************************************/
325 /*************************************************
326 * Handle GnuTLS error *
327 *************************************************/
329 /* Called from lots of places when errors occur before actually starting to do
330 the TLS handshake, that is, while the session is still in clear.
334 err a GnuTLS error number, or 0 if local error
336 Returns: doesn't - it dies
340 gnutls_error(uschar *prefix, int err)
342 fprintf(stderr, "GnuTLS connection error: %s:", prefix);
343 if (err != 0) fprintf(stderr, " %s", gnutls_strerror(err));
344 fprintf(stderr, "\n");
350 /*************************************************
351 * Setup up DH parameters *
352 *************************************************/
354 /* For the test suite, the parameters should always be available in the spool
363 uschar filename[200];
366 /* Initialize the data structures for holding the parameters */
368 ret = gnutls_dh_params_init(&dh_params);
369 if (ret < 0) gnutls_error(US"init dh_params", ret);
371 /* Open the cache file for reading and if successful, read it and set up the
374 fd = open("aux-fixed/gnutls-params", O_RDONLY, 0);
377 fprintf(stderr, "Failed to open spool/gnutls-params: %s\n", strerror(errno));
381 if (fstat(fd, &statbuf) < 0)
384 return gnutls_error(US"TLS cache stat failed", 0);
387 m.size = statbuf.st_size;
388 m.data = malloc(m.size);
390 return gnutls_error(US"memory allocation failed", 0);
391 if (read(fd, m.data, m.size) != m.size)
392 return gnutls_error(US"TLS cache read failed", 0);
395 ret = gnutls_dh_params_import_pkcs3(dh_params, &m, GNUTLS_X509_FMT_PEM);
396 if (ret < 0) return gnutls_error(US"DH params import", ret);
403 /*************************************************
404 * Initialize for GnuTLS *
405 *************************************************/
409 certificate certificate file
410 privatekey private key file
414 tls_init(uschar *certificate, uschar *privatekey)
418 rc = gnutls_global_init();
419 if (rc < 0) gnutls_error(US"gnutls_global_init", rc);
421 /* Read D-H parameters from the cache file. */
425 /* Create the credentials structure */
427 rc = gnutls_certificate_allocate_credentials(&x509_cred);
428 if (rc < 0) gnutls_error(US"certificate_allocate_credentials", rc);
430 /* Set the certificate and private keys */
432 if (certificate != NULL)
434 rc = gnutls_certificate_set_x509_key_file(x509_cred, CS certificate,
435 CS privatekey, GNUTLS_X509_FMT_PEM);
436 if (rc < 0) gnutls_error(US"gnutls_certificate", rc);
439 /* Associate the parameters with the x509 credentials structure. */
441 gnutls_certificate_set_dh_params(x509_cred, dh_params);
443 /* set the CA info for server-cert verify */
445 gnutls_certificate_set_x509_trust_file(x509_cred, ocsp_stapling,
446 GNUTLS_X509_FMT_PEM);
451 /*************************************************
452 * Initialize a single GNUTLS session *
453 *************************************************/
455 static gnutls_session_t
456 tls_session_init(void)
458 gnutls_session_t session;
460 gnutls_init(&session, GNUTLS_CLIENT | GNUTLS_NO_EXTENSIONS);
462 # if GNUTLS_VERSION_NUMBER < 0x030400
463 gnutls_cipher_set_priority(session, default_cipher_priority);
464 gnutls_compression_set_priority(session, comp_priority);
465 gnutls_kx_set_priority(session, kx_priority);
466 gnutls_protocol_set_priority(session, protocol_priority);
467 gnutls_mac_set_priority(session, mac_priority);
469 gnutls_cred_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
473 gnutls_priority_t priority_cache;
476 gnutls_priority_init(&priority_cache, pri_string, &errpos);
477 gnutls_priority_set(session, priority_cache);
480 gnutls_set_default_priority(session);
481 gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
484 gnutls_dh_set_prime_bits(session, DH_BITS);
485 gnutls_db_set_cache_expiration(session, ssl_session_timeout);
492 /****************************************************************************/
493 /* Turn "\n" and "\r" into the relevant characters. This is a hack. */
496 unescape_buf(unsigned char * buf, int len)
502 for (s = buf; s < buf+len; s++) if (*s == '\\')
506 default: c = s[1]; shift = 1; break;
507 case 'n': c = '\n'; shift = 1; break;
508 case 'r': c = '\r'; shift = 1; break;
511 if (t >= 'A' && t <= 'F') t -= 'A'-'9'-1;
512 else if (t >= 'a' && t <= 'f') t -= 'a'-'9'-1;
516 if (t >= 'A' && t <= 'F') t -= 'A'-'9'-1;
517 else if (t >= 'a' && t <= 'f') t -= 'a'-'9'-1;
524 memmove(s+1, s+shift+1, len-shift);
531 /****************************************************************************/
543 do_file(srv_ctx * srv, FILE * f, int timeout,
544 unsigned char * inbuffer, unsigned bsiz, unsigned char * inptr)
546 unsigned char outbuffer[1024 * 20];
548 while (fgets(CS outbuffer, sizeof(outbuffer), f) != NULL)
550 int n = (int)strlen(CS outbuffer);
554 /* Strip trailing newline */
555 if (outbuffer[n-1] == '\n') outbuffer[--n] = 0;
557 /* Expect incoming */
559 if ( strncmp(CS outbuffer, "???", 3) == 0
560 && (outbuffer[3] == ' ' || outbuffer[3] == '*' || outbuffer[3] == '?')
563 unsigned char *lineptr;
564 unsigned exp_eof = outbuffer[3] == '*';
565 unsigned resp_optional = outbuffer[3] == '?';
567 printf("%s\n", outbuffer);
568 n = unescape_buf(outbuffer, n);
571 if (*inptr == 0) /* Refill input buffer */
573 unsigned char *inbufferp = inbuffer;
582 DEBUG { printf("call SSL_read\n"); fflush(stdout); }
583 rc = SSL_read(srv->ssl, inbufferp, bsiz - (inbufferp - inbuffer) - 1);
584 DEBUG { printf("SSL_read: %d\n", rc); fflush(stdout); }
586 switch (error = SSL_get_error(srv->ssl, rc))
588 case SSL_ERROR_ZERO_RETURN:
590 case SSL_ERROR_SYSCALL:
591 printf("%s\n", ERR_error_string(ERR_get_error(), NULL));
595 printf("%s\nTLS terminated\n", ERR_error_string(ERR_get_error(), NULL));
596 SSL_shutdown(srv->ssl);
598 srv->tls_active = FALSE;
599 { /* OpenSSL leaves it in restartsys mode */
600 struct sigaction act = {.sa_handler = sigalrm_handler_flag, .sa_flags = 0};
602 sigaction(SIGALRM, &act, NULL);
605 DEBUG { printf("go round\n"); fflush(stdout); }
608 printf("SSL error code %d\n", error);
613 DEBUG { printf("call gnutls_record_recv\n"); fflush(stdout); }
614 rc = gnutls_record_recv(tls_session, CS inbufferp, bsiz - (inbufferp - inbuffer) - 1);
617 DEBUG { printf("gnutls_record_recv: %s\n", gnutls_strerror(rc)); fflush(stdout); }
618 if (rc == GNUTLS_E_INTERRUPTED || rc == GNUTLS_E_AGAIN)
620 printf("%s\n", gnutls_strerror(rc));
621 srv->tls_active = FALSE;
623 DEBUG { printf("go round\n"); fflush(stdout); }
626 DEBUG { printf("gnutls_record_recv: %d\n", rc); fflush(stdout); }
631 DEBUG { printf("call read\n"); fflush(stdout); }
632 rc = read(srv->sock, inbufferp, bsiz - (inbufferp - inbuffer) - 1);
633 DEBUG { printf("read: %d\n", rc); fflush(stdout); }
636 if (rc > 0) inbufferp[rc] = '\0';
637 if (rc <= 0 || strchr(inbufferp, '\n')) break;
639 if (inbufferp >= inbuffer + bsiz)
641 printf("Input buffer overrun, need more than %d bytes input buffer\n", bsiz);
644 DEBUG { printf("read more\n"); }
650 if (errno == EINTR && sigalrm_seen && resp_optional)
651 continue; /* next scriptline */
652 printf("Read error: %s\n", strerror(errno));
658 printf("Expected EOF read\n");
661 else if (resp_optional)
662 continue; /* next scriptline */
665 printf("Unexpected EOF read\n");
671 printf("Expected EOF not read\n");
678 DEBUG { printf("read: '%s'\n", inptr); fflush(stdout); }
681 while (*inptr != 0 && *inptr != '\r' && *inptr != '\n') inptr++;
685 if (*inptr == '\n') inptr++;
688 if (strncmp(CS lineptr, CS outbuffer + 4, n - 4) != 0)
691 inptr = lineptr; /* consume scriptline, not inputline */
696 printf("<<< %s\n", lineptr);
697 printf("\n******** Input mismatch ********\n");
701 /* Input matched script. Output the inputline, unless optional */
702 DEBUG { printf("read matched\n"); fflush(stdout); }
705 printf("<<< %s\n", lineptr);
708 /* If there is further input after this line, consume inputline but not
709 scriptline in case there are several matching. Nonmatches are dealt with
716 if (srv->sent_starttls)
718 if (lineptr[0] == '2')
722 printf("Attempting to start TLS\n");
726 srv->tls_active = tls_start(srv->sock, &srv->ssl, srv->ctx);
733 struct timeval tv = { 0, 2000 };
735 sigalrm_seen = FALSE;
738 rc = gnutls_handshake(tls_session);
739 } while (rc < 0 && gnutls_error_is_fatal(rc) == 0);
740 srv->tls_active = rc >= 0;
743 if (!srv->tls_active && !tls_quiet) printf("gnutls_handshake: %s\n", gnutls_strerror(rc));
745 /* look for an error on the TLS conn */
747 FD_SET(srv->sock, &rfd);
748 if (select(srv->sock+1, &rfd, NULL, NULL, &tv) > 0)
751 DEBUG { printf("call gnutls_record_recv\n"); fflush(stdout); }
752 rc = gnutls_record_recv(tls_session, CS inbuffer, bsiz - 1);
755 DEBUG { printf("gnutls_record_recv: %s\n", gnutls_strerror(rc)); fflush(stdout); }
756 if (rc == GNUTLS_E_INTERRUPTED || rc == GNUTLS_E_AGAIN)
758 if (!tls_quiet) printf("gnutls_record_recv: %s\n", gnutls_strerror(rc));
759 srv->tls_active = FALSE;
761 DEBUG { printf("gnutls_record_recv: %d\n", rc); fflush(stdout); }
764 # endif /*HAVE_GNUTLS*/
767 if (!srv->tls_active)
769 printf("Failed to start TLS\n");
774 else if (ocsp_stapling)
775 printf("Succeeded in starting TLS (with OCSP)\n");
779 else if (ocsp_stapling)
781 if ((rc= gnutls_certificate_verify_peers2(tls_session, &verify)) < 0)
783 printf("Failed to verify certificate: %s\n", gnutls_strerror(rc));
786 else if (verify & (GNUTLS_CERT_INVALID|GNUTLS_CERT_REVOKED))
788 printf("Bad certificate\n");
791 # ifdef HAVE_GNUTLS_OCSP
792 else if (gnutls_ocsp_status_request_is_checked(tls_session, 0) == 0)
794 printf("Failed to verify certificate status\n");
796 gnutls_datum_t stapling;
797 gnutls_ocsp_resp_t resp;
798 gnutls_datum_t printed;
799 if ( (rc= gnutls_ocsp_status_request_get(tls_session, &stapling)) == 0
800 && (rc= gnutls_ocsp_resp_init(&resp)) == 0
801 && (rc= gnutls_ocsp_resp_import(resp, &stapling)) == 0
802 && (rc= gnutls_ocsp_resp_print(resp, GNUTLS_OCSP_PRINT_FULL, &printed)) == 0
805 fprintf(stderr, "%.4096s", printed.data);
806 gnutls_free(printed.data);
809 (void) fprintf(stderr,"ocsp decode: %s", gnutls_strerror(rc));
815 printf("OCSP status response: good signature\n");
816 printf("Succeeded in starting TLS (with OCSP)\n");
818 # endif /*HAVE_GNUTLS_OCSP*/
820 # endif /*HAVE_GNUTLS*/
823 printf("Succeeded in starting TLS\n");
826 printf("Abandoning TLS start attempt\n");
828 srv->sent_starttls = 0;
832 /* Wait for a bit before proceeding */
834 else if (strncmp(CS outbuffer, "+++ ", 4) == 0)
836 printf("%s\n", outbuffer);
837 sleep(atoi(CS outbuffer + 4));
840 /* Stack new input file */
842 else if (strncmp(CS outbuffer, "<<< ", 4) == 0)
845 if (!(new_f = fopen((const char *)outbuffer+4 , "r")))
847 printf("Unable to open '%s': %s", inptr, strerror(errno));
850 do_file(srv, new_f, timeout, inbuffer, bsiz, inptr);
854 /* Send line outgoing, but barf if unconsumed incoming */
858 unsigned char * out = outbuffer;
860 if (strncmp(CS outbuffer, ">>> ", 4) == 0)
869 printf("Unconsumed input: %s", inptr);
870 printf(" About to send: %s\n", out);
878 if (strcmp(CS out, "stoptls") == 0 ||
879 strcmp(CS out, "STOPTLS") == 0)
881 if (!srv->tls_active)
883 printf("STOPTLS read when TLS not active\n");
886 printf("Shutting down TLS encryption\n");
889 SSL_shutdown(srv->ssl);
894 gnutls_bye(tls_session, GNUTLS_SHUT_WR);
895 gnutls_deinit(tls_session);
897 gnutls_global_deinit();
904 /* Remember that we sent STARTTLS */
906 srv->sent_starttls = (strcmp(CS out, "starttls") == 0 ||
907 strcmp(CS out, "STARTTLS") == 0);
909 /* Fudge: if the command is "starttls_wait", we send the starttls bit,
910 but we haven't set the flag, so that there is no negotiation. This is for
911 testing the server's timeout. */
913 if (strcmp(CS out, "starttls_wait") == 0)
920 printf(">>> %s\n", out);
923 strcpy(CS out + n, "\r\n");
927 n = unescape_buf(out, n);
935 rc = SSL_write (srv->ssl, out, n);
938 if ((rc = gnutls_record_send(tls_session, CS out, n)) < 0)
940 printf("GnuTLS write error: %s\n", gnutls_strerror(rc));
946 rc = write(srv->sock, out, n);
951 printf("Write error: %s\n", strerror(errno));
961 /*************************************************
963 *************************************************/
965 const char * const HELP_MESSAGE = "\n\
974 [-p priority-string]\n"
978 [-tn] n seconds timeout\n\
981 [<outgoing interface>]\n\
987 main(int argc, char **argv)
989 struct sockaddr *s_ptr;
990 struct sockaddr_in s_in4;
991 char *interface = NULL;
992 char *address = NULL;
993 char *certfile = NULL;
994 char *keyfile = NULL;
997 int host_af, port, s_len, rc, save_errno;
999 int tls_on_connect = 0;
1003 struct sockaddr_in6 s_in6;
1008 unsigned char inbuffer[100 * 1024];
1009 unsigned char *inptr = inbuffer;
1011 *inptr = 0; /* Buffer empty */
1013 srv.sent_starttls = 0;
1017 while (argc >= argi + 1 && argv[argi][0] == '-')
1019 if (strcmp(argv[argi], "-help") == 0 ||
1020 strcmp(argv[argi], "--help") == 0 ||
1021 strcmp(argv[argi], "-h") == 0)
1027 if (strcmp(argv[argi], "-tls-on-connect") == 0)
1032 else if (strcmp(argv[argi], "-tls-quiet") == 0)
1037 else if (strcmp(argv[argi], "-ocsp") == 0)
1039 if (argc < ++argi + 1)
1041 fprintf(stderr, "Missing required certificate file for ocsp option\n");
1044 ocsp_stapling = argv[argi++];
1047 else if (strcmp(argv[argi], "-p") == 0)
1049 if (argc < ++argi + 1)
1051 fprintf(stderr, "Missing priority string\n");
1054 pri_string = argv[argi++];
1058 else if (argv[argi][1] == 't' && isdigit(argv[argi][2]))
1060 tmplong = strtol(argv[argi]+2, &end, 10);
1061 if (end == argv[argi]+2 || *end)
1063 fprintf(stderr, "Failed to parse seconds from option <%s>\n",
1067 if (tmplong > 10000L)
1069 fprintf(stderr, "Unreasonably long wait of %ld seconds requested\n",
1075 fprintf(stderr, "Timeout must not be negative (%ld)\n", tmplong);
1078 timeout = (int) tmplong;
1083 fprintf(stderr, "Unrecognized option %s\n", argv[argi]);
1088 /* Mandatory 1st arg is IP address */
1092 fprintf(stderr, "No IP address given\n");
1096 address = argv[argi++];
1097 host_af = (strchr(address, ':') != NULL)? AF_INET6 : AF_INET;
1099 /* Mandatory 2nd arg is port */
1103 fprintf(stderr, "No port number given\n");
1107 port = atoi(argv[argi++]);
1109 /* Optional next arg is interface */
1112 (isdigit((unsigned char)argv[argi][0]) || argv[argi][0] == ':'))
1113 interface = argv[argi++];
1115 /* Any more arguments are the name of a certificate file and key file */
1117 if (argc > argi) certfile = argv[argi++];
1118 if (argc > argi) keyfile = argv[argi++];
1122 /* For an IPv6 address, use an IPv6 sockaddr structure. */
1124 if (host_af == AF_INET6)
1126 s_ptr = (struct sockaddr *)&s_in6;
1127 s_len = sizeof(s_in6);
1132 /* For an IPv4 address, use an IPv4 sockaddr structure,
1133 even on an IPv6 system. */
1136 s_ptr = (struct sockaddr *)&s_in4;
1137 s_len = sizeof(s_in4);
1140 printf("Connecting to %s port %d ... ", address, port);
1142 srv.sock = socket(host_af, SOCK_STREAM, 0);
1145 printf("socket creation failed: %s\n", strerror(errno));
1149 /* Bind to a specific interface if requested. On an IPv6 system, this has
1150 to be of the same family as the address we are calling. On an IPv4 system the
1151 test is redundant, but it keeps the code tidier. */
1153 if (interface != NULL)
1155 int interface_af = (strchr(interface, ':') != NULL)? AF_INET6 : AF_INET;
1157 if (interface_af == host_af)
1161 /* Set up for IPv6 binding */
1163 if (host_af == AF_INET6)
1165 memset(&s_in6, 0, sizeof(s_in6));
1166 s_in6.sin6_family = AF_INET6;
1167 s_in6.sin6_port = 0;
1168 if (inet_pton(AF_INET6, interface, &s_in6.sin6_addr) != 1)
1170 printf("Unable to parse \"%s\"", interface);
1177 /* Set up for IPv4 binding */
1180 memset(&s_in4, 0, sizeof(s_in4));
1181 s_in4.sin_family = AF_INET;
1183 s_in4.sin_addr.s_addr = (S_ADDR_TYPE)inet_addr(interface);
1188 if (bind(srv.sock, s_ptr, s_len) < 0)
1190 printf("Unable to bind outgoing SMTP call to %s: %s",
1191 interface, strerror(errno));
1197 /* Set up a remote IPv6 address */
1200 if (host_af == AF_INET6)
1202 # ifdef HAVE_GETADDRINFO
1203 struct addrinfo hints, *res;
1204 memset(&hints, 0, sizeof(hints));
1205 hints.ai_family = AF_INET6;
1206 hints.ai_socktype = SOCK_STREAM;
1207 hints.ai_flags = AI_NUMERICHOST;
1208 if ((rc = getaddrinfo(address, NULL, &hints, &res)) != 0 || res == NULL)
1210 printf("unable to parse \"%s\" as an IP address: %s\n", address,
1211 rc == 0 ? "NULL result returned" : gai_strerror(rc));
1214 memcpy(&s_in6, res->ai_addr, res->ai_addrlen);
1217 memset(&s_in6, 0, sizeof(s_in6));
1218 s_in6.sin6_family = AF_INET6;
1219 if (inet_pton(host_af, address, &s_in6.sin6_addr) != 1)
1221 printf("Unable to parse \"%s\"", address);
1225 s_in6.sin6_port = htons(port);
1230 /* Set up a remote IPv4 address */
1233 memset(&s_in4, 0, sizeof(s_in4));
1234 s_in4.sin_family = AF_INET;
1235 s_in4.sin_port = htons(port);
1236 s_in4.sin_addr.s_addr = (S_ADDR_TYPE)inet_addr(address);
1239 /* SIGALRM handler crashes out */
1241 signal(SIGALRM, sigalrm_handler_crash);
1243 rc = connect(srv.sock, s_ptr, s_len);
1247 /* A failure whose error code is "Interrupted system call" is in fact
1248 an externally applied timeout if the signal handler has been run. */
1253 printf("connect failed: %s\n", strerror(save_errno));
1260 (void) setsockopt(srv.sock, IPPROTO_TCP, TCP_QUICKACK, US &off, sizeof(off));
1264 printf("connected\n");
1267 /* --------------- Set up for OpenSSL --------------- */
1271 SSL_load_error_strings();
1273 if (!(srv.ctx = SSL_CTX_new(SSLv23_method())))
1275 printf ("SSL_CTX_new failed\n");
1281 if (!SSL_CTX_use_certificate_file(srv.ctx, certfile, SSL_FILETYPE_PEM))
1283 printf("SSL_CTX_use_certificate_file failed\n");
1286 printf("Certificate file = %s\n", certfile);
1291 if (!SSL_CTX_use_PrivateKey_file(srv.ctx, keyfile, SSL_FILETYPE_PEM))
1293 printf("SSL_CTX_use_PrivateKey_file failed\n");
1296 printf("Key file = %s\n", keyfile);
1299 SSL_CTX_set_session_cache_mode(srv.ctx, SSL_SESS_CACHE_BOTH);
1300 SSL_CTX_set_timeout(srv.ctx, 200);
1301 SSL_CTX_set_info_callback(srv.ctx, (void (*)())info_callback);
1305 /* --------------- Set up for GnuTLS --------------- */
1308 if (certfile != NULL) printf("Certificate file = %s\n", certfile);
1309 if (keyfile != NULL) printf("Key file = %s\n", keyfile);
1310 tls_init(US certfile, US keyfile);
1311 tls_session = tls_session_init();
1312 #ifdef HAVE_GNUTLS_OCSP
1314 gnutls_ocsp_status_request_enable_client(tls_session, NULL, 0, NULL);
1316 gnutls_transport_set_ptr(tls_session, (gnutls_transport_ptr_t)(intptr_t)srv.sock);
1318 /* When the server asks for a certificate and the client does not have one,
1319 there is a SIGPIPE error in the gnutls_handshake() function for some reason
1320 that is not understood. As luck would have it, this has never hit Exim itself
1321 because it ignores SIGPIPE errors. Doing the same here allows it all to work as
1324 signal(SIGPIPE, SIG_IGN);
1327 /* ---------------------------------------------- */
1330 /* Start TLS session if configured to do so without STARTTLS */
1335 printf("Attempting to start TLS\n");
1338 srv.tls_active = tls_start(srv.sock, &srv.ssl, srv.ctx);
1344 sigalrm_seen = FALSE;
1347 rc = gnutls_handshake(tls_session);
1348 } while (rc < 0 && gnutls_error_is_fatal(rc) == 0);
1349 srv.tls_active = rc >= 0;
1352 if (!srv.tls_active) printf("%s\n", gnutls_strerror(rc));
1357 if (!srv.tls_active)
1358 printf("Failed to start TLS\n");
1359 #if defined(HAVE_GNUTLS) && defined(HAVE_GNUTLS_OCSP)
1360 else if ( ocsp_stapling
1361 && gnutls_ocsp_status_request_is_checked(tls_session, 0) == 0)
1362 printf("Failed to verify certificate status\n");
1365 printf("Succeeded in starting TLS%s\n", ocsp_stapling ? " (with OCSP)":"");
1369 do_file(&srv, stdin, timeout, inbuffer, sizeof(inbuffer), inptr);
1371 printf("End of script\n");
1372 shutdown(srv.sock, SHUT_WR);
1373 if (fcntl(srv.sock, F_SETFL, O_NONBLOCK) == 0)
1374 while (read(srv.sock, inbuffer, sizeof(inbuffer)) > 0) ;
1380 /* End of client.c */