Start
[exim.git] / src / src / tls-openssl.c
CommitLineData
059ec3d9
PH
1/* $Cambridge: exim/src/src/tls-openssl.c,v 1.1 2004/10/07 10:39:01 ph10 Exp $ */
2
3/*************************************************
4* Exim - an Internet mail transport agent *
5*************************************************/
6
7/* Copyright (c) University of Cambridge 1995 - 2004 */
8/* See the file NOTICE for conditions of use and distribution. */
9
10/* This module provides the TLS (aka SSL) support for Exim using the OpenSSL
11library. It is #included into the tls.c file when that library is used. The
12code herein is based on a patch that was originally contributed by Steve
13Haslam. It was adapted from stunnel, a GPL program by Michal Trojnara.
14
15No cryptographic code is included in Exim. All this module does is to call
16functions from the OpenSSL library. */
17
18
19/* Heading stuff */
20
21#include <openssl/lhash.h>
22#include <openssl/ssl.h>
23#include <openssl/err.h>
24#include <openssl/rand.h>
25
26/* Structure for collecting random data for seeding. */
27
28typedef struct randstuff {
29 time_t t;
30 pid_t p;
31} randstuff;
32
33/* Local static variables */
34
35static BOOL verify_callback_called = FALSE;
36static const uschar *sid_ctx = US"exim";
37
38static SSL_CTX *ctx = NULL;
39static SSL *ssl = NULL;
40
41static char ssl_errstring[256];
42
43static int ssl_session_timeout = 200;
44static BOOL verify_optional = FALSE;
45
46
47
48
49
50/*************************************************
51* Handle TLS error *
52*************************************************/
53
54/* Called from lots of places when errors occur before actually starting to do
55the TLS handshake, that is, while the session is still in clear. Always returns
56DEFER for a server and FAIL for a client so that most calls can use "return
57tls_error(...)" to do this processing and then give an appropriate return. A
58single function is used for both server and client, because it is called from
59some shared functions.
60
61Argument:
62 prefix text to include in the logged error
63 host NULL if setting up a server;
64 the connected host if setting up a client
65
66Returns: OK/DEFER/FAIL
67*/
68
69static int
70tls_error(uschar *prefix, host_item *host)
71{
72ERR_error_string(ERR_get_error(), ssl_errstring);
73if (host == NULL)
74 {
75 log_write(0, LOG_MAIN, "TLS error on connection from %s (%s): %s",
76 (sender_fullhost != NULL)? sender_fullhost : US"local process",
77 prefix, ssl_errstring);
78 return DEFER;
79 }
80else
81 {
82 log_write(0, LOG_MAIN, "TLS error on connection to %s [%s] (%s): %s",
83 host->name, host->address, prefix, ssl_errstring);
84 return FAIL;
85 }
86}
87
88
89
90/*************************************************
91* Callback to generate RSA key *
92*************************************************/
93
94/*
95Arguments:
96 s SSL connection
97 export not used
98 keylength keylength
99
100Returns: pointer to generated key
101*/
102
103static RSA *
104rsa_callback(SSL *s, int export, int keylength)
105{
106RSA *rsa_key;
107export = export; /* Shut picky compilers up */
108DEBUG(D_tls) debug_printf("Generating %d bit RSA key...\n", keylength);
109rsa_key = RSA_generate_key(keylength, RSA_F4, NULL, NULL);
110if (rsa_key == NULL)
111 {
112 ERR_error_string(ERR_get_error(), ssl_errstring);
113 log_write(0, LOG_MAIN|LOG_PANIC, "TLS error (RSA_generate_key): %s",
114 ssl_errstring);
115 return NULL;
116 }
117return rsa_key;
118}
119
120
121
122
123/*************************************************
124* Callback for verification *
125*************************************************/
126
127/* The SSL library does certificate verification if set up to do so. This
128callback has the current yes/no state is in "state". If verification succeeded,
129we set up the tls_peerdn string. If verification failed, what happens depends
130on whether the client is required to present a verifiable certificate or not.
131
132If verification is optional, we change the state to yes, but still log the
133verification error. For some reason (it really would help to have proper
134documentation of OpenSSL), this callback function then gets called again, this
135time with state = 1. In fact, that's useful, because we can set up the peerdn
136value, but we must take care not to set the private verified flag on the second
137time through.
138
139Note: this function is not called if the client fails to present a certificate
140when asked. We get here only if a certificate has been received. Handling of
141optional verification for this case is done when requesting SSL to verify, by
142setting SSL_VERIFY_FAIL_IF_NO_PEER_CERT in the non-optional case.
143
144Arguments:
145 state current yes/no state as 1/0
146 x509ctx certificate information.
147
148Returns: 1 if verified, 0 if not
149*/
150
151static int
152verify_callback(int state, X509_STORE_CTX *x509ctx)
153{
154static uschar txt[256];
155
156X509_NAME_oneline(X509_get_subject_name(x509ctx->current_cert),
157 CS txt, sizeof(txt));
158
159if (state == 0)
160 {
161 log_write(0, LOG_MAIN, "SSL verify error: depth=%d error=%s cert=%s",
162 x509ctx->error_depth,
163 X509_verify_cert_error_string(x509ctx->error),
164 txt);
165 tls_certificate_verified = FALSE;
166 verify_callback_called = TRUE;
167 if (!verify_optional) return 0; /* reject */
168 DEBUG(D_tls) debug_printf("SSL verify failure overridden (host in "
169 "tls_try_verify_hosts)\n");
170 return 1; /* accept */
171 }
172
173if (x509ctx->error_depth != 0)
174 {
175 DEBUG(D_tls) debug_printf("SSL verify ok: depth=%d cert=%s\n",
176 x509ctx->error_depth, txt);
177 }
178else
179 {
180 DEBUG(D_tls) debug_printf("SSL%s peer: %s\n",
181 verify_callback_called? "" : " authenticated", txt);
182 tls_peerdn = txt;
183 }
184
185
186debug_printf("+++verify_callback_called=%d\n", verify_callback_called);
187
188if (!verify_callback_called) tls_certificate_verified = TRUE;
189verify_callback_called = TRUE;
190
191return 1; /* accept */
192}
193
194
195
196/*************************************************
197* Information callback *
198*************************************************/
199
200/* The SSL library functions call this from time to time to indicate what they
201are doing. We copy the string to the debugging output when the level is high
202enough.
203
204Arguments:
205 s the SSL connection
206 where
207 ret
208
209Returns: nothing
210*/
211
212static void
213info_callback(SSL *s, int where, int ret)
214{
215where = where;
216ret = ret;
217DEBUG(D_tls) debug_printf("SSL info: %s\n", SSL_state_string_long(s));
218}
219
220
221
222/*************************************************
223* Initialize for DH *
224*************************************************/
225
226/* If dhparam is set, expand it, and load up the parameters for DH encryption.
227
228Arguments:
229 dhparam DH parameter file
230
231Returns: TRUE if OK (nothing to set up, or setup worked)
232*/
233
234static BOOL
235init_dh(uschar *dhparam)
236{
237BOOL yield = TRUE;
238BIO *bio;
239DH *dh;
240uschar *dhexpanded;
241
242if (!expand_check(dhparam, US"tls_dhparam", &dhexpanded))
243 return FALSE;
244
245if (dhexpanded == NULL) return TRUE;
246
247if ((bio = BIO_new_file(CS dhexpanded, "r")) == NULL)
248 {
249 log_write(0, LOG_MAIN, "DH: could not read %s: %s", dhexpanded,
250 strerror(errno));
251 yield = FALSE;
252 }
253else
254 {
255 if ((dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL)) == NULL)
256 {
257 log_write(0, LOG_MAIN, "DH: could not load params from %s",
258 dhexpanded);
259 yield = FALSE;
260 }
261 else
262 {
263 SSL_CTX_set_tmp_dh(ctx, dh);
264 DEBUG(D_tls)
265 debug_printf("Diffie-Hellman initialized from %s with %d-bit key\n",
266 dhexpanded, 8*DH_size(dh));
267 DH_free(dh);
268 }
269 BIO_free(bio);
270 }
271
272return yield;
273}
274
275
276
277
278/*************************************************
279* Initialize for TLS *
280*************************************************/
281
282/* Called from both server and client code, to do preliminary initialization of
283the library.
284
285Arguments:
286 host connected host, if client; NULL if server
287 dhparam DH parameter file
288 certificate certificate file
289 privatekey private key
290 addr address if client; NULL if server (for some randomness)
291
292Returns: OK/DEFER/FAIL
293*/
294
295static int
296tls_init(host_item *host, uschar *dhparam, uschar *certificate, uschar *privatekey,
297 address_item *addr)
298{
299SSL_load_error_strings(); /* basic set up */
300OpenSSL_add_ssl_algorithms();
301
302/* Create a context */
303
304ctx = SSL_CTX_new((host == NULL)?
305 SSLv23_server_method() : SSLv23_client_method());
306
307if (ctx == NULL) return tls_error(US"SSL_CTX_new", host);
308
309/* It turns out that we need to seed the random number generator this early in
310order to get the full complement of ciphers to work. It took me roughly a day
311of work to discover this by experiment.
312
313On systems that have /dev/urandom, SSL may automatically seed itself from
314there. Otherwise, we have to make something up as best we can. Double check
315afterwards. */
316
317if (!RAND_status())
318 {
319 randstuff r;
320 r.t = time(NULL);
321 r.p = getpid();
322
323 RAND_seed((uschar *)(&r), sizeof(r));
324 RAND_seed((uschar *)big_buffer, big_buffer_size);
325 if (addr != NULL) RAND_seed((uschar *)addr, sizeof(addr));
326
327 if (!RAND_status())
328 {
329 if (host == NULL)
330 {
331 log_write(0, LOG_MAIN, "TLS error on connection from %s: "
332 "unable to seed random number generator",
333 (sender_fullhost != NULL)? sender_fullhost : US"local process");
334 return DEFER;
335 }
336 else
337 {
338 log_write(0, LOG_MAIN, "TLS error on connection to %s [%s]: "
339 "unable to seed random number generator",
340 host->name, host->address);
341 return FAIL;
342 }
343 }
344 }
345
346/* Set up the information callback, which outputs if debugging is at a suitable
347level. */
348
349if (!(SSL_CTX_set_info_callback(ctx, (void (*)())info_callback)))
350 return tls_error(US"SSL_CTX_set_info_callback", host);
351
352/* The following patch was supplied by Robert Roselius */
353
354#if OPENSSL_VERSION_NUMBER > 0x00906040L
355/* Enable client-bug workaround.
356 Versions of OpenSSL as of 0.9.6d include a "CBC countermeasure" feature,
357 which causes problems with some clients (such as the Certicom SSL Plus
358 library used by Eudora). This option, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS,
359 disables the coutermeasure allowing Eudora to connect.
360 Some poppers and MTAs use SSL_OP_ALL, which enables all such bug
361 workarounds. */
362/* XXX (Silently?) ignore failure here? XXX*/
363
364if (!(SSL_CTX_set_options(ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)))
365 return tls_error(US"SSL_CTX_set_option", host);
366#endif
367
368/* Initialize with DH parameters if supplied */
369
370if (!init_dh(dhparam)) return DEFER;
371
372/* Set up certificate and key */
373
374if (certificate != NULL)
375 {
376 uschar *expanded;
377 if (!expand_check(certificate, US"tls_certificate", &expanded))
378 return DEFER;
379
380 if (expanded != NULL)
381 {
382 DEBUG(D_tls) debug_printf("tls_certificate file %s\n", expanded);
383 if (!SSL_CTX_use_certificate_chain_file(ctx, CS expanded))
384 return tls_error(US"SSL_CTX_use_certificate_chain_file", host);
385 }
386
387 if (privatekey != NULL &&
388 !expand_check(privatekey, US"tls_privatekey", &expanded))
389 return DEFER;
390
391 if (expanded != NULL)
392 {
393 DEBUG(D_tls) debug_printf("tls_privatekey file %s\n", expanded);
394 if (!SSL_CTX_use_PrivateKey_file(ctx, CS expanded, SSL_FILETYPE_PEM))
395 return tls_error(US"SSL_CTX_use_PrivateKey_file", host);
396 }
397 }
398
399/* Set up the RSA callback */
400
401SSL_CTX_set_tmp_rsa_callback(ctx, rsa_callback);
402
403/* Finally, set the timeout, and we are done */
404
405SSL_CTX_set_timeout(ctx, ssl_session_timeout);
406DEBUG(D_tls) debug_printf("Initialized TLS\n");
407return OK;
408}
409
410
411
412
413/*************************************************
414* Get name of cipher in use *
415*************************************************/
416
417/* The answer is left in a static buffer, and tls_cipher is set to point
418to it.
419
420Argument: pointer to an SSL structure for the connection
421Returns: nothing
422*/
423
424static void
425construct_cipher_name(SSL *ssl)
426{
427static uschar cipherbuf[256];
428SSL_CIPHER *c;
429uschar *ver;
430int bits;
431
432switch (ssl->session->ssl_version)
433 {
434 case SSL2_VERSION:
435 ver = US"SSLv2";
436 break;
437
438 case SSL3_VERSION:
439 ver = US"SSLv3";
440 break;
441
442 case TLS1_VERSION:
443 ver = US"TLSv1";
444 break;
445
446 default:
447 ver = US"UNKNOWN";
448 }
449
450c = SSL_get_current_cipher(ssl);
451SSL_CIPHER_get_bits(c, &bits);
452
453string_format(cipherbuf, sizeof(cipherbuf), "%s:%s:%u", ver,
454 SSL_CIPHER_get_name(c), bits);
455tls_cipher = cipherbuf;
456
457DEBUG(D_tls) debug_printf("Cipher: %s\n", cipherbuf);
458}
459
460
461
462
463
464/*************************************************
465* Set up for verifying certificates *
466*************************************************/
467
468/* Called by both client and server startup
469
470Arguments:
471 certs certs file or NULL
472 crl CRL file or NULL
473 host NULL in a server; the remote host in a client
474 optional TRUE if called from a server for a host in tls_try_verify_hosts;
475 otherwise passed as FALSE
476
477Returns: OK/DEFER/FAIL
478*/
479
480static int
481setup_certs(uschar *certs, uschar *crl, host_item *host, BOOL optional)
482{
483uschar *expcerts, *expcrl;
484
485if (!expand_check(certs, US"tls_verify_certificates", &expcerts))
486 return DEFER;
487
488if (expcerts != NULL)
489 {
490 struct stat statbuf;
491 if (!SSL_CTX_set_default_verify_paths(ctx))
492 return tls_error(US"SSL_CTX_set_default_verify_paths", host);
493
494 if (Ustat(expcerts, &statbuf) < 0)
495 {
496 log_write(0, LOG_MAIN|LOG_PANIC,
497 "failed to stat %s for certificates", expcerts);
498 return DEFER;
499 }
500 else
501 {
502 uschar *file, *dir;
503 if ((statbuf.st_mode & S_IFMT) == S_IFDIR)
504 { file = NULL; dir = expcerts; }
505 else
506 { file = expcerts; dir = NULL; }
507
508 /* If a certificate file is empty, the next function fails with an
509 unhelpful error message. If we skip it, we get the correct behaviour (no
510 certificates are recognized, but the error message is still misleading (it
511 says no certificate was supplied.) But this is better. */
512
513 if ((file == NULL || statbuf.st_size > 0) &&
514 !SSL_CTX_load_verify_locations(ctx, CS file, CS dir))
515 return tls_error(US"SSL_CTX_load_verify_locations", host);
516
517 if (file != NULL)
518 {
519 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(CS file));
520 }
521 }
522
523 /* Handle a certificate revocation list. */
524
525 #if OPENSSL_VERSION_NUMBER > 0x00907000L
526
527 if (!expand_check(crl, US"tls_crl", &expcrl)) return DEFER;
528 if (expcrl != NULL && *expcrl != 0)
529 {
530 BIO *crl_bio;
531 X509_CRL *crl_x509;
532 X509_STORE *cvstore;
533
534 cvstore = SSL_CTX_get_cert_store(ctx); /* cert validation store */
535
536 crl_bio = BIO_new(BIO_s_file_internal());
537 if (crl_bio != NULL)
538 {
539 if (BIO_read_filename(crl_bio, expcrl))
540 {
541 crl_x509 = PEM_read_bio_X509_CRL(crl_bio, NULL, NULL, NULL);
542 BIO_free(crl_bio);
543 X509_STORE_add_crl(cvstore, crl_x509);
544 X509_CRL_free(crl_x509);
545 X509_STORE_set_flags(cvstore,
546 X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
547 }
548 else
549 {
550 BIO_free(crl_bio);
551 return tls_error(US"BIO_read_filename", host);
552 }
553 }
554 else return tls_error(US"BIO_new", host);
555 }
556
557 #endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */
558
559 /* If verification is optional, don't fail if no certificate */
560
561 SSL_CTX_set_verify(ctx,
562 SSL_VERIFY_PEER | (optional? 0 : SSL_VERIFY_FAIL_IF_NO_PEER_CERT),
563 verify_callback);
564 }
565
566return OK;
567}
568
569
570
571/*************************************************
572* Start a TLS session in a server *
573*************************************************/
574
575/* This is called when Exim is running as a server, after having received
576the STARTTLS command. It must respond to that command, and then negotiate
577a TLS session.
578
579Arguments:
580 require_ciphers allowed ciphers
581
582Returns: OK on success
583 DEFER for errors before the start of the negotiation
584 FAIL for errors during the negotation; the server can't
585 continue running.
586*/
587
588int
589tls_server_start(uschar *require_ciphers)
590{
591int rc;
592uschar *expciphers;
593
594/* Check for previous activation */
595
596if (tls_active >= 0)
597 {
598 log_write(0, LOG_MAIN, "STARTTLS received in already encrypted "
599 "connection from %s",
600 (sender_fullhost != NULL)? sender_fullhost : US"local process");
601 smtp_printf("554 Already in TLS\r\n");
602 return FAIL;
603 }
604
605/* Initialize the SSL library. If it fails, it will already have logged
606the error. */
607
608rc = tls_init(NULL, tls_dhparam, tls_certificate, tls_privatekey, NULL);
609if (rc != OK) return rc;
610
611if (!expand_check(require_ciphers, US"tls_require_ciphers", &expciphers))
612 return FAIL;
613
614/* In OpenSSL, cipher components are separated by hyphens. In GnuTLS, they
615are separated by underscores. So that I can use either form in my tests, and
616also for general convenience, we turn underscores into hyphens here. */
617
618if (expciphers != NULL)
619 {
620 uschar *s = expciphers;
621 while (*s != 0) { if (*s == '_') *s = '-'; s++; }
622 DEBUG(D_tls) debug_printf("required ciphers: %s\n", expciphers);
623 if (!SSL_CTX_set_cipher_list(ctx, CS expciphers))
624 return tls_error(US"SSL_CTX_set_cipher_list", NULL);
625 }
626
627/* If this is a host for which certificate verification is mandatory or
628optional, set up appropriately. */
629
630tls_certificate_verified = FALSE;
631verify_callback_called = FALSE;
632
633if (verify_check_host(&tls_verify_hosts) == OK)
634 {
635 rc = setup_certs(tls_verify_certificates, tls_crl, NULL, FALSE);
636 if (rc != OK) return rc;
637 verify_optional = FALSE;
638 }
639else if (verify_check_host(&tls_try_verify_hosts) == OK)
640 {
641 rc = setup_certs(tls_verify_certificates, tls_crl, NULL, TRUE);
642 if (rc != OK) return rc;
643 verify_optional = TRUE;
644 }
645
646/* Prepare for new connection */
647
648if ((ssl = SSL_new(ctx)) == NULL) return tls_error(US"SSL_new", NULL);
649SSL_clear(ssl);
650
651/* Set context and tell client to go ahead, except in the case of TLS startup
652on connection, where outputting anything now upsets the clients and tends to
653make them disconnect. We need to have an explicit fflush() here, to force out
654the response. Other smtp_printf() calls do not need it, because in non-TLS
655mode, the fflush() happens when smtp_getc() is called. */
656
657SSL_set_session_id_context(ssl, sid_ctx, Ustrlen(sid_ctx));
658if (!tls_on_connect)
659 {
660 smtp_printf("220 TLS go ahead\r\n");
661 fflush(smtp_out);
662 }
663
664/* Now negotiate the TLS session. We put our own timer on it, since it seems
665that the OpenSSL library doesn't. */
666
667SSL_set_fd(ssl, fileno(smtp_out));
668SSL_set_accept_state(ssl);
669
670DEBUG(D_tls) debug_printf("Calling SSL_accept\n");
671
672sigalrm_seen = FALSE;
673if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
674rc = SSL_accept(ssl);
675alarm(0);
676
677if (rc <= 0)
678 {
679 if (sigalrm_seen) Ustrcpy(ssl_errstring, "timed out");
680 else ERR_error_string(ERR_get_error(), ssl_errstring);
681 log_write(0, LOG_MAIN, "TLS error on connection from %s (SSL_accept): %s",
682 (sender_fullhost != NULL)? sender_fullhost : US"local process",
683 ssl_errstring);
684 return FAIL;
685 }
686
687DEBUG(D_tls) debug_printf("SSL_accept was successful\n");
688
689/* TLS has been set up. Adjust the input functions to read via TLS,
690and initialize things. */
691
692construct_cipher_name(ssl);
693
694DEBUG(D_tls)
695 {
696 uschar buf[2048];
697 if (SSL_get_shared_ciphers(ssl, CS buf, sizeof(buf)) != NULL)
698 debug_printf("Shared ciphers: %s\n", buf);
699 }
700
701
702ssl_xfer_buffer = store_malloc(ssl_xfer_buffer_size);
703ssl_xfer_buffer_lwm = ssl_xfer_buffer_hwm = 0;
704ssl_xfer_eof = ssl_xfer_error = 0;
705
706receive_getc = tls_getc;
707receive_ungetc = tls_ungetc;
708receive_feof = tls_feof;
709receive_ferror = tls_ferror;
710
711tls_active = fileno(smtp_out);
712return OK;
713}
714
715
716
717
718
719/*************************************************
720* Start a TLS session in a client *
721*************************************************/
722
723/* Called from the smtp transport after STARTTLS has been accepted.
724
725Argument:
726 fd the fd of the connection
727 host connected host (for messages)
728 dhparam DH parameter file
729 certificate certificate file
730 privatekey private key file
731 verify_certs file for certificate verify
732 crl file containing CRL
733 require_ciphers list of allowed ciphers
734
735Returns: OK on success
736 FAIL otherwise - note that tls_error() will not give DEFER
737 because this is not a server
738*/
739
740int
741tls_client_start(int fd, host_item *host, address_item *addr, uschar *dhparam,
742 uschar *certificate, uschar *privatekey, uschar *verify_certs, uschar *crl,
743 uschar *require_ciphers, int timeout)
744{
745static uschar txt[256];
746uschar *expciphers;
747X509* server_cert;
748int rc;
749
750rc = tls_init(host, dhparam, certificate, privatekey, addr);
751if (rc != OK) return rc;
752
753tls_certificate_verified = FALSE;
754verify_callback_called = FALSE;
755
756if (!expand_check(require_ciphers, US"tls_require_ciphers", &expciphers))
757 return FAIL;
758
759/* In OpenSSL, cipher components are separated by hyphens. In GnuTLS, they
760are separated by underscores. So that I can use either form in my tests, and
761also for general convenience, we turn underscores into hyphens here. */
762
763if (expciphers != NULL)
764 {
765 uschar *s = expciphers;
766 while (*s != 0) { if (*s == '_') *s = '-'; s++; }
767 DEBUG(D_tls) debug_printf("required ciphers: %s\n", expciphers);
768 if (!SSL_CTX_set_cipher_list(ctx, CS expciphers))
769 return tls_error(US"SSL_CTX_set_cipher_list", host);
770 }
771
772rc = setup_certs(verify_certs, crl, host, FALSE);
773if (rc != OK) return rc;
774
775if ((ssl = SSL_new(ctx)) == NULL) return tls_error(US"SSL_new", host);
776SSL_set_session_id_context(ssl, sid_ctx, Ustrlen(sid_ctx));
777SSL_set_fd(ssl, fd);
778SSL_set_connect_state(ssl);
779
780/* There doesn't seem to be a built-in timeout on connection. */
781
782DEBUG(D_tls) debug_printf("Calling SSL_connect\n");
783sigalrm_seen = FALSE;
784alarm(timeout);
785rc = SSL_connect(ssl);
786alarm(0);
787
788if (rc <= 0)
789 {
790 if (sigalrm_seen)
791 {
792 log_write(0, LOG_MAIN, "TLS error on connection to %s [%s]: "
793 "SSL_connect timed out", host->name, host->address);
794 return FAIL;
795 }
796 else return tls_error(US"SSL_connect", host);
797 }
798
799DEBUG(D_tls) debug_printf("SSL_connect succeeded\n");
800
801server_cert = SSL_get_peer_certificate (ssl);
802tls_peerdn = US X509_NAME_oneline(X509_get_subject_name(server_cert),
803 CS txt, sizeof(txt));
804tls_peerdn = txt;
805
806construct_cipher_name(ssl); /* Sets tls_cipher */
807
808tls_active = fd;
809return OK;
810}
811
812
813
814
815
816/*************************************************
817* TLS version of getc *
818*************************************************/
819
820/* This gets the next byte from the TLS input buffer. If the buffer is empty,
821it refills the buffer via the SSL reading function.
822
823Arguments: none
824Returns: the next character or EOF
825*/
826
827int
828tls_getc(void)
829{
830if (ssl_xfer_buffer_lwm >= ssl_xfer_buffer_hwm)
831 {
832 int error;
833 int inbytes;
834
835 DEBUG(D_tls) debug_printf("Calling SSL_read(%lx, %lx, %u)\n", (long)ssl,
836 (long)ssl_xfer_buffer, ssl_xfer_buffer_size);
837
838 if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
839 inbytes = SSL_read(ssl, CS ssl_xfer_buffer, ssl_xfer_buffer_size);
840 error = SSL_get_error(ssl, inbytes);
841 alarm(0);
842
843 /* SSL_ERROR_ZERO_RETURN appears to mean that the SSL session has been
844 closed down, not that the socket itself has been closed down. Revert to
845 non-SSL handling. */
846
847 if (error == SSL_ERROR_ZERO_RETURN)
848 {
849 DEBUG(D_tls) debug_printf("Got SSL_ERROR_ZERO_RETURN\n");
850
851 receive_getc = smtp_getc;
852 receive_ungetc = smtp_ungetc;
853 receive_feof = smtp_feof;
854 receive_ferror = smtp_ferror;
855
856 SSL_free(ssl);
857 ssl = NULL;
858 tls_active = -1;
859 tls_cipher = NULL;
860 tls_peerdn = NULL;
861
862 return smtp_getc();
863 }
864
865 /* Handle genuine errors */
866
867 else if (error != SSL_ERROR_NONE)
868 {
869 DEBUG(D_tls) debug_printf("Got SSL error %d\n", error);
870 ssl_xfer_error = 1;
871 return EOF;
872 }
873
874 ssl_xfer_buffer_hwm = inbytes;
875 ssl_xfer_buffer_lwm = 0;
876 }
877
878/* Something in the buffer; return next uschar */
879
880return ssl_xfer_buffer[ssl_xfer_buffer_lwm++];
881}
882
883
884
885/*************************************************
886* Read bytes from TLS channel *
887*************************************************/
888
889/*
890Arguments:
891 buff buffer of data
892 len size of buffer
893
894Returns: the number of bytes read
895 -1 after a failed read
896*/
897
898int
899tls_read(uschar *buff, size_t len)
900{
901int inbytes;
902int error;
903
904DEBUG(D_tls) debug_printf("Calling SSL_read(%lx, %lx, %u)\n", (long)ssl,
905 (long)buff, (unsigned int)len);
906
907inbytes = SSL_read(ssl, CS buff, len);
908error = SSL_get_error(ssl, inbytes);
909
910if (error == SSL_ERROR_ZERO_RETURN)
911 {
912 DEBUG(D_tls) debug_printf("Got SSL_ERROR_ZERO_RETURN\n");
913 return -1;
914 }
915else if (error != SSL_ERROR_NONE)
916 {
917 return -1;
918 }
919
920return inbytes;
921}
922
923
924
925
926
927/*************************************************
928* Write bytes down TLS channel *
929*************************************************/
930
931/*
932Arguments:
933 buff buffer of data
934 len number of bytes
935
936Returns: the number of bytes after a successful write,
937 -1 after a failed write
938*/
939
940int
941tls_write(const uschar *buff, size_t len)
942{
943int outbytes;
944int error;
945int left = len;
946
947DEBUG(D_tls) debug_printf("tls_do_write(%lx, %d)\n", (long)buff, left);
948while (left > 0)
949 {
950 DEBUG(D_tls) debug_printf("SSL_write(SSL, %lx, %d)\n", (long)buff, left);
951 outbytes = SSL_write(ssl, CS buff, left);
952 error = SSL_get_error(ssl, outbytes);
953 DEBUG(D_tls) debug_printf("outbytes=%d error=%d\n", outbytes, error);
954 switch (error)
955 {
956 case SSL_ERROR_SSL:
957 ERR_error_string(ERR_get_error(), ssl_errstring);
958 log_write(0, LOG_MAIN, "TLS error (SSL_write): %s", ssl_errstring);
959 return -1;
960
961 case SSL_ERROR_NONE:
962 left -= outbytes;
963 buff += outbytes;
964 break;
965
966 case SSL_ERROR_ZERO_RETURN:
967 log_write(0, LOG_MAIN, "SSL channel closed on write");
968 return -1;
969
970 default:
971 log_write(0, LOG_MAIN, "SSL_write error %d", error);
972 return -1;
973 }
974 }
975return len;
976}
977
978
979
980/*************************************************
981* Close down a TLS session *
982*************************************************/
983
984/* This is also called from within a delivery subprocess forked from the
985daemon, to shut down the TLS library, without actually doing a shutdown (which
986would tamper with the SSL session in the parent process).
987
988Arguments: TRUE if SSL_shutdown is to be called
989Returns: nothing
990*/
991
992void
993tls_close(BOOL shutdown)
994{
995if (tls_active < 0) return; /* TLS was not active */
996
997if (shutdown)
998 {
999 DEBUG(D_tls) debug_printf("tls_close(): shutting down SSL\n");
1000 SSL_shutdown(ssl);
1001 }
1002
1003SSL_free(ssl);
1004ssl = NULL;
1005
1006tls_active = -1;
1007}
1008
1009/* End of tls-openssl.c */