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;
143 /*************************************************
144 * SIGALRM handler - crash out *
145 *************************************************/
148 sigalrm_handler_crash(int sig)
150 sig = sig; /* Keep picky compilers happy */
151 printf("\nClient timed out\n");
156 /*************************************************
157 * SIGALRM handler - set flag *
158 *************************************************/
161 sigalrm_handler_flag(int sig)
163 sig = sig; /* Keep picky compilers happy */
169 /****************************************************************************/
170 /****************************************************************************/
173 # ifndef DISABLE_OCSP
175 static STACK_OF(X509) *
176 chain_from_pem_file(const uschar * file)
182 if (!(sk = sk_X509_new_null())) return NULL;
183 if (!(bp = BIO_new_file(CS file, "r"))) return NULL;
184 while ((x = PEM_read_bio_X509(bp, NULL, 0, NULL)))
193 cert_stack_free(STACK_OF(X509) * sk)
195 while (sk_X509_num(sk) > 0) (void) sk_X509_pop(sk);
201 tls_client_stapling_cb(SSL *s, void *arg)
203 const unsigned char *p;
210 len = SSL_get_tlsext_status_ocsp_resp(s, &p);
211 /*BIO_printf(arg, "OCSP response: ");*/
214 BIO_printf(arg, "no OCSP response received\n");
217 if(!(rsp = d2i_OCSP_RESPONSE(NULL, &p, len)))
219 BIO_printf(arg, "OCSP response parse error\n");
220 BIO_dump_indent(arg, (char *)p, len, 4);
223 if(!(bs = OCSP_response_get1_basic(rsp)))
225 BIO_printf(arg, "error parsing OCSP response\n");
230 if (!(sk = chain_from_pem_file((const uschar *)ocsp_stapling)))
232 BIO_printf(arg, "error in cert setup\n");
236 /* OCSP_basic_verify takes a "store" arg, but does not
237 use it for the chain verification, which is all we do
238 when OCSP_NOVERIFY is set. The content from the wire
239 (in "bs") and a cert-stack "sk" are all that is used. */
241 if(OCSP_basic_verify(bs, sk, NULL, OCSP_NOVERIFY) <= 0)
243 BIO_printf(arg, "OCSP status response verify failure\n");
244 ERR_print_errors(arg);
248 BIO_printf(arg, "OCSP status response: good signature\n");
253 # endif /*DISABLE_OCSP*/
256 /*************************************************
257 * Start an OpenSSL TLS session *
258 *************************************************/
261 tls_start(int sock, SSL **ssl, SSL_CTX *ctx)
264 static const unsigned char *sid_ctx = US"exim";
266 RAND_load_file("client.c", -1); /* Not *very* random! */
268 *ssl = SSL_new (ctx);
269 SSL_set_session_id_context(*ssl, sid_ctx, strlen(CS sid_ctx));
270 SSL_set_fd (*ssl, sock);
271 SSL_set_connect_state(*ssl);
276 SSL_CTX_set_tlsext_status_cb(ctx, tls_client_stapling_cb);
277 SSL_CTX_set_tlsext_status_arg(ctx, BIO_new_fp(stdout, BIO_NOCLOSE));
278 SSL_set_tlsext_status_type(*ssl, TLSEXT_STATUSTYPE_ocsp);
282 signal(SIGALRM, sigalrm_handler_flag);
285 rc = SSL_connect (*ssl);
290 printf("SSL_connect timed out\n");
296 ERR_print_errors_fp(stdout);
300 /* printf("SSL connection using %s\n", SSL_get_cipher (*ssl)); */
305 /*************************************************
306 * SSL Information callback *
307 *************************************************/
310 info_callback(SSL *s, int where, int ret)
314 printf("SSL info: %s\n", SSL_state_string_long(s));
319 /****************************************************************************/
320 /****************************************************************************/
324 /*************************************************
325 * Handle GnuTLS error *
326 *************************************************/
328 /* Called from lots of places when errors occur before actually starting to do
329 the TLS handshake, that is, while the session is still in clear.
333 err a GnuTLS error number, or 0 if local error
335 Returns: doesn't - it dies
339 gnutls_error(uschar *prefix, int err)
341 fprintf(stderr, "GnuTLS connection error: %s:", prefix);
342 if (err != 0) fprintf(stderr, " %s", gnutls_strerror(err));
343 fprintf(stderr, "\n");
349 /*************************************************
350 * Setup up DH parameters *
351 *************************************************/
353 /* For the test suite, the parameters should always be available in the spool
362 uschar filename[200];
365 /* Initialize the data structures for holding the parameters */
367 ret = gnutls_dh_params_init(&dh_params);
368 if (ret < 0) gnutls_error(US"init dh_params", ret);
370 /* Open the cache file for reading and if successful, read it and set up the
373 fd = open("aux-fixed/gnutls-params", O_RDONLY, 0);
376 fprintf(stderr, "Failed to open spool/gnutls-params: %s\n", strerror(errno));
380 if (fstat(fd, &statbuf) < 0)
383 return gnutls_error(US"TLS cache stat failed", 0);
386 m.size = statbuf.st_size;
387 m.data = malloc(m.size);
389 return gnutls_error(US"memory allocation failed", 0);
390 if (read(fd, m.data, m.size) != m.size)
391 return gnutls_error(US"TLS cache read failed", 0);
394 ret = gnutls_dh_params_import_pkcs3(dh_params, &m, GNUTLS_X509_FMT_PEM);
395 if (ret < 0) return gnutls_error(US"DH params import", ret);
402 /*************************************************
403 * Initialize for GnuTLS *
404 *************************************************/
408 certificate certificate file
409 privatekey private key file
413 tls_init(uschar *certificate, uschar *privatekey)
417 rc = gnutls_global_init();
418 if (rc < 0) gnutls_error(US"gnutls_global_init", rc);
420 /* Read D-H parameters from the cache file. */
424 /* Create the credentials structure */
426 rc = gnutls_certificate_allocate_credentials(&x509_cred);
427 if (rc < 0) gnutls_error(US"certificate_allocate_credentials", rc);
429 /* Set the certificate and private keys */
431 if (certificate != NULL)
433 rc = gnutls_certificate_set_x509_key_file(x509_cred, CS certificate,
434 CS privatekey, GNUTLS_X509_FMT_PEM);
435 if (rc < 0) gnutls_error(US"gnutls_certificate", rc);
438 /* Associate the parameters with the x509 credentials structure. */
440 gnutls_certificate_set_dh_params(x509_cred, dh_params);
442 /* set the CA info for server-cert verify */
444 gnutls_certificate_set_x509_trust_file(x509_cred, ocsp_stapling,
445 GNUTLS_X509_FMT_PEM);
450 /*************************************************
451 * Initialize a single GNUTLS session *
452 *************************************************/
454 static gnutls_session_t
455 tls_session_init(void)
457 gnutls_session_t session;
459 gnutls_init(&session, GNUTLS_CLIENT | GNUTLS_NO_EXTENSIONS);
461 # if GNUTLS_VERSION_NUMBER < 0x030400
462 gnutls_cipher_set_priority(session, default_cipher_priority);
463 gnutls_compression_set_priority(session, comp_priority);
464 gnutls_kx_set_priority(session, kx_priority);
465 gnutls_protocol_set_priority(session, protocol_priority);
466 gnutls_mac_set_priority(session, mac_priority);
468 gnutls_cred_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
472 gnutls_priority_t priority_cache;
475 gnutls_priority_init(&priority_cache, pri_string, &errpos);
476 gnutls_priority_set(session, priority_cache);
479 gnutls_set_default_priority(session);
480 gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
483 gnutls_dh_set_prime_bits(session, DH_BITS);
484 gnutls_db_set_cache_expiration(session, ssl_session_timeout);
491 /****************************************************************************/
492 /* Turn "\n" and "\r" into the relevant characters. This is a hack. */
495 unescape_buf(unsigned char * buf, int len)
501 for (s = buf; s < buf+len; s++) if (*s == '\\')
505 default: c = s[1]; shift = 1; break;
506 case 'n': c = '\n'; shift = 1; break;
507 case 'r': c = '\r'; shift = 1; break;
510 if (t >= 'A' && t <= 'F') t -= 'A'-'9'-1;
511 else if (t >= 'a' && t <= 'f') t -= 'a'-'9'-1;
515 if (t >= 'A' && t <= 'F') t -= 'A'-'9'-1;
516 else if (t >= 'a' && t <= 'f') t -= 'a'-'9'-1;
523 memmove(s+1, s+shift+1, len-shift);
530 /****************************************************************************/
542 do_file(srv_ctx * srv, FILE * f, int timeout,
543 unsigned char * inbuffer, unsigned bsiz, unsigned char * inptr)
545 unsigned char outbuffer[1024 * 20];
547 while (fgets(CS outbuffer, sizeof(outbuffer), f) != NULL)
549 int n = (int)strlen(CS outbuffer);
553 /* Strip trailing newline */
554 if (outbuffer[n-1] == '\n') outbuffer[--n] = 0;
556 /* Expect incoming */
558 if ( strncmp(CS outbuffer, "???", 3) == 0
559 && (outbuffer[3] == ' ' || outbuffer[3] == '*' || outbuffer[3] == '?')
562 unsigned char *lineptr;
563 unsigned exp_eof = outbuffer[3] == '*';
564 unsigned resp_optional = outbuffer[3] == '?';
566 printf("%s\n", outbuffer);
567 n = unescape_buf(outbuffer, n);
570 if (*inptr == 0) /* Refill input buffer */
572 unsigned char *inbufferp = inbuffer;
581 DEBUG { printf("call SSL_read\n"); fflush(stdout); }
582 rc = SSL_read(srv->ssl, inbufferp, bsiz - (inbufferp - inbuffer) - 1);
583 DEBUG { printf("SSL_read: %d\n", rc); fflush(stdout); }
585 switch (error = SSL_get_error(srv->ssl, rc))
587 case SSL_ERROR_ZERO_RETURN:
589 case SSL_ERROR_SYSCALL:
590 printf("%s\n", ERR_error_string(ERR_get_error(), NULL));
594 printf("%s\nTLS terminated\n", ERR_error_string(ERR_get_error(), NULL));
595 SSL_shutdown(srv->ssl);
597 srv->tls_active = FALSE;
598 { /* OpenSSL leaves it in restartsys mode */
599 struct sigaction act = {.sa_handler = sigalrm_handler_flag, .sa_flags = 0};
601 sigaction(SIGALRM, &act, NULL);
604 DEBUG { printf("go round\n"); fflush(stdout); }
607 printf("SSL error code %d\n", error);
612 DEBUG { printf("call gnutls_record_recv\n"); fflush(stdout); }
613 rc = gnutls_record_recv(tls_session, CS inbufferp, bsiz - (inbufferp - inbuffer) - 1);
616 DEBUG { printf("gnutls_record_recv: %s\n", gnutls_strerror(rc)); fflush(stdout); }
617 if (rc == GNUTLS_E_INTERRUPTED || rc == GNUTLS_E_AGAIN)
619 printf("%s\n", gnutls_strerror(rc));
620 srv->tls_active = FALSE;
622 DEBUG { printf("go round\n"); fflush(stdout); }
625 DEBUG { printf("gnutls_record_recv: %d\n", rc); fflush(stdout); }
630 DEBUG { printf("call read\n"); fflush(stdout); }
631 rc = read(srv->sock, inbufferp, bsiz - (inbufferp - inbuffer) - 1);
632 DEBUG { printf("read: %d\n", rc); fflush(stdout); }
635 if (rc > 0) inbufferp[rc] = '\0';
636 if (rc <= 0 || strchr(inbufferp, '\n')) break;
638 if (inbufferp >= inbuffer + bsiz)
640 printf("Input buffer overrun, need more than %d bytes input buffer\n", bsiz);
643 DEBUG { printf("read more\n"); }
649 if (errno == EINTR && sigalrm_seen && resp_optional)
650 continue; /* next scriptline */
651 printf("Read error: %s\n", strerror(errno));
657 printf("Expected EOF read\n");
660 else if (resp_optional)
661 continue; /* next scriptline */
664 printf("Unexpected EOF read\n");
670 printf("Expected EOF not read\n");
677 DEBUG { printf("read: '%s'\n", inptr); fflush(stdout); }
680 while (*inptr != 0 && *inptr != '\r' && *inptr != '\n') inptr++;
684 if (*inptr == '\n') inptr++;
687 if (strncmp(CS lineptr, CS outbuffer + 4, n - 4) != 0)
690 inptr = lineptr; /* consume scriptline, not inputline */
695 printf("<<< %s\n", lineptr);
696 printf("\n******** Input mismatch ********\n");
700 /* Input matched script. Output the inputline, unless optional */
701 DEBUG { printf("read matched\n"); fflush(stdout); }
704 printf("<<< %s\n", lineptr);
707 /* If there is further input after this line, consume inputline but not
708 scriptline in case there are several matching. Nonmatches are dealt with
715 if (srv->sent_starttls)
717 if (lineptr[0] == '2')
721 printf("Attempting to start TLS\n");
725 srv->tls_active = tls_start(srv->sock, &srv->ssl, srv->ctx);
732 struct timeval tv = { 0, 2000 };
734 sigalrm_seen = FALSE;
737 rc = gnutls_handshake(tls_session);
738 } while (rc < 0 && gnutls_error_is_fatal(rc) == 0);
739 srv->tls_active = rc >= 0;
742 if (!srv->tls_active) printf("%s\n", gnutls_strerror(rc));
744 /* look for an error on the TLS conn */
746 FD_SET(srv->sock, &rfd);
747 if (select(srv->sock+1, &rfd, NULL, NULL, &tv) > 0)
750 DEBUG { printf("call gnutls_record_recv\n"); fflush(stdout); }
751 rc = gnutls_record_recv(tls_session, CS inbuffer, bsiz - 1);
754 DEBUG { printf("gnutls_record_recv: %s\n", gnutls_strerror(rc)); fflush(stdout); }
755 if (rc == GNUTLS_E_INTERRUPTED || rc == GNUTLS_E_AGAIN)
757 printf("%s\n", gnutls_strerror(rc));
758 srv->tls_active = FALSE;
760 DEBUG { printf("gnutls_record_recv: %d\n", rc); fflush(stdout); }
763 # endif /*HAVE_GNUTLS*/
765 if (!srv->tls_active)
767 printf("Failed to start TLS\n");
772 else if (ocsp_stapling)
773 printf("Succeeded in starting TLS (with OCSP)\n");
777 else if (ocsp_stapling)
779 if ((rc= gnutls_certificate_verify_peers2(tls_session, &verify)) < 0)
781 printf("Failed to verify certificate: %s\n", gnutls_strerror(rc));
784 else if (verify & (GNUTLS_CERT_INVALID|GNUTLS_CERT_REVOKED))
786 printf("Bad certificate\n");
789 # ifdef HAVE_GNUTLS_OCSP
790 else if (gnutls_ocsp_status_request_is_checked(tls_session, 0) == 0)
792 printf("Failed to verify certificate status\n");
794 gnutls_datum_t stapling;
795 gnutls_ocsp_resp_t resp;
796 gnutls_datum_t printed;
797 if ( (rc= gnutls_ocsp_status_request_get(tls_session, &stapling)) == 0
798 && (rc= gnutls_ocsp_resp_init(&resp)) == 0
799 && (rc= gnutls_ocsp_resp_import(resp, &stapling)) == 0
800 && (rc= gnutls_ocsp_resp_print(resp, GNUTLS_OCSP_PRINT_FULL, &printed)) == 0
803 fprintf(stderr, "%.4096s", printed.data);
804 gnutls_free(printed.data);
807 (void) fprintf(stderr,"ocsp decode: %s", gnutls_strerror(rc));
813 printf("OCSP status response: good signature\n");
814 printf("Succeeded in starting TLS (with OCSP)\n");
816 # endif /*HAVE_GNUTLS_OCSP*/
818 # endif /*HAVE_GNUTLS*/
821 printf("Succeeded in starting TLS\n");
824 printf("Abandoning TLS start attempt\n");
826 srv->sent_starttls = 0;
830 /* Wait for a bit before proceeding */
832 else if (strncmp(CS outbuffer, "+++ ", 4) == 0)
834 printf("%s\n", outbuffer);
835 sleep(atoi(CS outbuffer + 4));
838 /* Stack new input file */
840 else if (strncmp(CS outbuffer, "<<< ", 4) == 0)
843 if (!(new_f = fopen((const char *)outbuffer+4 , "r")))
845 printf("Unable to open '%s': %s", inptr, strerror(errno));
848 do_file(srv, new_f, timeout, inbuffer, bsiz, inptr);
852 /* Send line outgoing, but barf if unconsumed incoming */
856 unsigned char * out = outbuffer;
858 if (strncmp(CS outbuffer, ">>> ", 4) == 0)
867 printf("Unconsumed input: %s", inptr);
868 printf(" About to send: %s\n", out);
876 if (strcmp(CS out, "stoptls") == 0 ||
877 strcmp(CS out, "STOPTLS") == 0)
879 if (!srv->tls_active)
881 printf("STOPTLS read when TLS not active\n");
884 printf("Shutting down TLS encryption\n");
887 SSL_shutdown(srv->ssl);
892 gnutls_bye(tls_session, GNUTLS_SHUT_WR);
893 gnutls_deinit(tls_session);
895 gnutls_global_deinit();
902 /* Remember that we sent STARTTLS */
904 srv->sent_starttls = (strcmp(CS out, "starttls") == 0 ||
905 strcmp(CS out, "STARTTLS") == 0);
907 /* Fudge: if the command is "starttls_wait", we send the starttls bit,
908 but we haven't set the flag, so that there is no negotiation. This is for
909 testing the server's timeout. */
911 if (strcmp(CS out, "starttls_wait") == 0)
918 printf(">>> %s\n", out);
921 strcpy(CS out + n, "\r\n");
925 n = unescape_buf(out, n);
933 rc = SSL_write (srv->ssl, out, n);
936 if ((rc = gnutls_record_send(tls_session, CS out, n)) < 0)
938 printf("GnuTLS write error: %s\n", gnutls_strerror(rc));
944 rc = write(srv->sock, out, n);
949 printf("Write error: %s\n", strerror(errno));
959 /*************************************************
961 *************************************************/
963 const char * const HELP_MESSAGE = "\n\
971 [-p priority-string]\n"
975 [-tn] n seconds timeout\n\
978 [<outgoing interface>]\n\
984 main(int argc, char **argv)
986 struct sockaddr *s_ptr;
987 struct sockaddr_in s_in4;
988 char *interface = NULL;
989 char *address = NULL;
990 char *certfile = NULL;
991 char *keyfile = NULL;
994 int host_af, port, s_len, rc, save_errno;
996 int tls_on_connect = 0;
1000 struct sockaddr_in6 s_in6;
1005 unsigned char inbuffer[100 * 1024];
1006 unsigned char *inptr = inbuffer;
1008 *inptr = 0; /* Buffer empty */
1010 srv.sent_starttls = 0;
1014 while (argc >= argi + 1 && argv[argi][0] == '-')
1016 if (strcmp(argv[argi], "-help") == 0 ||
1017 strcmp(argv[argi], "--help") == 0 ||
1018 strcmp(argv[argi], "-h") == 0)
1023 if (strcmp(argv[argi], "-tls-on-connect") == 0)
1029 else if (strcmp(argv[argi], "-ocsp") == 0)
1031 if (argc < ++argi + 1)
1033 fprintf(stderr, "Missing required certificate file for ocsp option\n");
1036 ocsp_stapling = argv[argi++];
1039 else if (strcmp(argv[argi], "-p") == 0)
1041 if (argc < ++argi + 1)
1043 fprintf(stderr, "Missing priority string\n");
1046 pri_string = argv[argi++];
1051 else if (argv[argi][1] == 't' && isdigit(argv[argi][2]))
1053 tmplong = strtol(argv[argi]+2, &end, 10);
1054 if (end == argv[argi]+2 || *end)
1056 fprintf(stderr, "Failed to parse seconds from option <%s>\n",
1060 if (tmplong > 10000L)
1062 fprintf(stderr, "Unreasonably long wait of %ld seconds requested\n",
1068 fprintf(stderr, "Timeout must not be negative (%ld)\n", tmplong);
1071 timeout = (int) tmplong;
1076 fprintf(stderr, "Unrecognized option %s\n", argv[argi]);
1081 /* Mandatory 1st arg is IP address */
1085 fprintf(stderr, "No IP address given\n");
1089 address = argv[argi++];
1090 host_af = (strchr(address, ':') != NULL)? AF_INET6 : AF_INET;
1092 /* Mandatory 2nd arg is port */
1096 fprintf(stderr, "No port number given\n");
1100 port = atoi(argv[argi++]);
1102 /* Optional next arg is interface */
1105 (isdigit((unsigned char)argv[argi][0]) || argv[argi][0] == ':'))
1106 interface = argv[argi++];
1108 /* Any more arguments are the name of a certificate file and key file */
1110 if (argc > argi) certfile = argv[argi++];
1111 if (argc > argi) keyfile = argv[argi++];
1115 /* For an IPv6 address, use an IPv6 sockaddr structure. */
1117 if (host_af == AF_INET6)
1119 s_ptr = (struct sockaddr *)&s_in6;
1120 s_len = sizeof(s_in6);
1125 /* For an IPv4 address, use an IPv4 sockaddr structure,
1126 even on an IPv6 system. */
1129 s_ptr = (struct sockaddr *)&s_in4;
1130 s_len = sizeof(s_in4);
1133 printf("Connecting to %s port %d ... ", address, port);
1135 srv.sock = socket(host_af, SOCK_STREAM, 0);
1138 printf("socket creation failed: %s\n", strerror(errno));
1142 /* Bind to a specific interface if requested. On an IPv6 system, this has
1143 to be of the same family as the address we are calling. On an IPv4 system the
1144 test is redundant, but it keeps the code tidier. */
1146 if (interface != NULL)
1148 int interface_af = (strchr(interface, ':') != NULL)? AF_INET6 : AF_INET;
1150 if (interface_af == host_af)
1154 /* Set up for IPv6 binding */
1156 if (host_af == AF_INET6)
1158 memset(&s_in6, 0, sizeof(s_in6));
1159 s_in6.sin6_family = AF_INET6;
1160 s_in6.sin6_port = 0;
1161 if (inet_pton(AF_INET6, interface, &s_in6.sin6_addr) != 1)
1163 printf("Unable to parse \"%s\"", interface);
1170 /* Set up for IPv4 binding */
1173 memset(&s_in4, 0, sizeof(s_in4));
1174 s_in4.sin_family = AF_INET;
1176 s_in4.sin_addr.s_addr = (S_ADDR_TYPE)inet_addr(interface);
1181 if (bind(srv.sock, s_ptr, s_len) < 0)
1183 printf("Unable to bind outgoing SMTP call to %s: %s",
1184 interface, strerror(errno));
1190 /* Set up a remote IPv6 address */
1193 if (host_af == AF_INET6)
1195 # ifdef HAVE_GETADDRINFO
1196 struct addrinfo hints, *res;
1197 memset(&hints, 0, sizeof(hints));
1198 hints.ai_family = AF_INET6;
1199 hints.ai_socktype = SOCK_STREAM;
1200 hints.ai_flags = AI_NUMERICHOST;
1201 if ((rc = getaddrinfo(address, NULL, &hints, &res)) != 0 || res == NULL)
1203 printf("unable to parse \"%s\" as an IP address: %s\n", address,
1204 rc == 0 ? "NULL result returned" : gai_strerror(rc));
1207 memcpy(&s_in6, res->ai_addr, res->ai_addrlen);
1210 memset(&s_in6, 0, sizeof(s_in6));
1211 s_in6.sin6_family = AF_INET6;
1212 if (inet_pton(host_af, address, &s_in6.sin6_addr) != 1)
1214 printf("Unable to parse \"%s\"", address);
1218 s_in6.sin6_port = htons(port);
1223 /* Set up a remote IPv4 address */
1226 memset(&s_in4, 0, sizeof(s_in4));
1227 s_in4.sin_family = AF_INET;
1228 s_in4.sin_port = htons(port);
1229 s_in4.sin_addr.s_addr = (S_ADDR_TYPE)inet_addr(address);
1232 /* SIGALRM handler crashes out */
1234 signal(SIGALRM, sigalrm_handler_crash);
1236 rc = connect(srv.sock, s_ptr, s_len);
1240 /* A failure whose error code is "Interrupted system call" is in fact
1241 an externally applied timeout if the signal handler has been run. */
1246 printf("connect failed: %s\n", strerror(save_errno));
1253 (void) setsockopt(srv.sock, IPPROTO_TCP, TCP_QUICKACK, US &off, sizeof(off));
1257 printf("connected\n");
1260 /* --------------- Set up for OpenSSL --------------- */
1264 SSL_load_error_strings();
1266 if (!(srv.ctx = SSL_CTX_new(SSLv23_method())))
1268 printf ("SSL_CTX_new failed\n");
1274 if (!SSL_CTX_use_certificate_file(srv.ctx, certfile, SSL_FILETYPE_PEM))
1276 printf("SSL_CTX_use_certificate_file failed\n");
1279 printf("Certificate file = %s\n", certfile);
1284 if (!SSL_CTX_use_PrivateKey_file(srv.ctx, keyfile, SSL_FILETYPE_PEM))
1286 printf("SSL_CTX_use_PrivateKey_file failed\n");
1289 printf("Key file = %s\n", keyfile);
1292 SSL_CTX_set_session_cache_mode(srv.ctx, SSL_SESS_CACHE_BOTH);
1293 SSL_CTX_set_timeout(srv.ctx, 200);
1294 SSL_CTX_set_info_callback(srv.ctx, (void (*)())info_callback);
1298 /* --------------- Set up for GnuTLS --------------- */
1301 if (certfile != NULL) printf("Certificate file = %s\n", certfile);
1302 if (keyfile != NULL) printf("Key file = %s\n", keyfile);
1303 tls_init(US certfile, US keyfile);
1304 tls_session = tls_session_init();
1305 #ifdef HAVE_GNUTLS_OCSP
1307 gnutls_ocsp_status_request_enable_client(tls_session, NULL, 0, NULL);
1309 gnutls_transport_set_ptr(tls_session, (gnutls_transport_ptr_t)(intptr_t)srv.sock);
1311 /* When the server asks for a certificate and the client does not have one,
1312 there is a SIGPIPE error in the gnutls_handshake() function for some reason
1313 that is not understood. As luck would have it, this has never hit Exim itself
1314 because it ignores SIGPIPE errors. Doing the same here allows it all to work as
1317 signal(SIGPIPE, SIG_IGN);
1320 /* ---------------------------------------------- */
1323 /* Start TLS session if configured to do so without STARTTLS */
1328 printf("Attempting to start TLS\n");
1331 srv.tls_active = tls_start(srv.sock, &srv.ssl, srv.ctx);
1337 sigalrm_seen = FALSE;
1340 rc = gnutls_handshake(tls_session);
1341 } while (rc < 0 && gnutls_error_is_fatal(rc) == 0);
1342 srv.tls_active = rc >= 0;
1345 if (!srv.tls_active) printf("%s\n", gnutls_strerror(rc));
1349 if (!srv.tls_active)
1350 printf("Failed to start TLS\n");
1351 #if defined(HAVE_GNUTLS) && defined(HAVE_GNUTLS_OCSP)
1352 else if ( ocsp_stapling
1353 && gnutls_ocsp_status_request_is_checked(tls_session, 0) == 0)
1354 printf("Failed to verify certificate status\n");
1357 printf("Succeeded in starting TLS%s\n", ocsp_stapling ? " (with OCSP)":"");
1361 do_file(&srv, stdin, timeout, inbuffer, sizeof(inbuffer), inptr);
1363 printf("End of script\n");
1364 shutdown(srv.sock, SHUT_WR);
1365 if (fcntl(srv.sock, F_SETFL, O_NONBLOCK) == 0)
1366 while (read(srv.sock, inbuffer, sizeof(inbuffer)) > 0) ;
1372 /* End of client.c */