Don't set $sender_host_name if forward lookup of name obtained from
[exim.git] / src / src / tls-gnu.c
1 /* $Cambridge: exim/src/src/tls-gnu.c,v 1.14 2006/10/16 13:20:18 ph10 Exp $ */
2
3 /*************************************************
4 * Exim - an Internet mail transport agent *
5 *************************************************/
6
7 /* Copyright (c) University of Cambridge 1995 - 2006 */
8 /* See the file NOTICE for conditions of use and distribution. */
9
10 /* This module provides TLS (aka SSL) support for Exim using the GnuTLS
11 library. It is #included into tls.c when that library is used. The code herein
12 is based on a patch that was contributed by Nikos Mavroyanopoulos.
13
14 No cryptographic code is included in Exim. All this module does is to call
15 functions from the GnuTLS library. */
16
17
18 /* Heading stuff for GnuTLS */
19
20 #include <gnutls/gnutls.h>
21 #include <gnutls/x509.h>
22
23
24 #define UNKNOWN_NAME "unknown"
25 #define DH_BITS 768
26 #define PARAM_SIZE 2*1024
27
28
29 /* Values for verify_requirment and initialized */
30
31 enum { VERIFY_NONE, VERIFY_OPTIONAL, VERIFY_REQUIRED };
32 enum { INITIALIZED_NOT, INITIALIZED_SERVER, INITIALIZED_CLIENT };
33
34 /* Local static variables for GNUTLS */
35
36 static BOOL initialized = INITIALIZED_NOT;
37 static host_item *client_host;
38
39 static gnutls_dh_params dh_params = NULL;
40
41 static gnutls_certificate_server_credentials x509_cred = NULL;
42 static gnutls_session tls_session = NULL;
43
44 static char ssl_errstring[256];
45
46 static int ssl_session_timeout = 200;
47 static int verify_requirement;
48
49 /* Priorities for TLS algorithms to use. At present, only the cipher priority
50 vector can be altered. */
51
52 static const int protocol_priority[16] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 };
53
54 static const int kx_priority[16] = {
55 GNUTLS_KX_RSA,
56 GNUTLS_KX_DHE_DSS,
57 GNUTLS_KX_DHE_RSA,
58 0 };
59
60 static int default_cipher_priority[16] = {
61 GNUTLS_CIPHER_AES_256_CBC,
62 GNUTLS_CIPHER_AES_128_CBC,
63 GNUTLS_CIPHER_3DES_CBC,
64 GNUTLS_CIPHER_ARCFOUR_128,
65 0 };
66
67 static int cipher_priority[16];
68
69 static const int mac_priority[16] = {
70 GNUTLS_MAC_SHA,
71 GNUTLS_MAC_MD5,
72 0 };
73
74 static const int comp_priority[16] = { GNUTLS_COMP_NULL, 0 };
75 static const int cert_type_priority[16] = { GNUTLS_CRT_X509, 0 };
76
77 /* Tables of cipher names and equivalent numbers */
78
79 typedef struct pri_item {
80 uschar *name;
81 int *values;
82 } pri_item;
83
84 static int arcfour_128_codes[] = { GNUTLS_CIPHER_ARCFOUR_128, 0 };
85 static int arcfour_40_codes[] = { GNUTLS_CIPHER_ARCFOUR_40, 0 };
86 static int arcfour_codes[] = { GNUTLS_CIPHER_ARCFOUR_128,
87 GNUTLS_CIPHER_ARCFOUR_40, 0 };
88 static int aes_256_codes[] = { GNUTLS_CIPHER_AES_256_CBC, 0 };
89 static int aes_128_codes[] = { GNUTLS_CIPHER_AES_128_CBC, 0 };
90 static int aes_codes[] = { GNUTLS_CIPHER_AES_256_CBC,
91 GNUTLS_CIPHER_AES_128_CBC, 0 };
92 static int des3_codes[] = { GNUTLS_CIPHER_3DES_CBC, 0 };
93
94 static pri_item cipher_index[] = {
95 { US"ARCFOUR_128", arcfour_128_codes },
96 { US"ARCFOUR_40", arcfour_40_codes },
97 { US"ARCFOUR", arcfour_codes },
98 { US"AES_256", aes_256_codes },
99 { US"AES_128", aes_128_codes },
100 { US"AES", aes_codes },
101 { US"3DES", des3_codes }
102 };
103
104
105
106 /*************************************************
107 * Handle TLS error *
108 *************************************************/
109
110 /* Called from lots of places when errors occur before actually starting to do
111 the TLS handshake, that is, while the session is still in clear. Always returns
112 DEFER for a server and FAIL for a client so that most calls can use "return
113 tls_error(...)" to do this processing and then give an appropriate return. A
114 single function is used for both server and client, because it is called from
115 some shared functions.
116
117 Argument:
118 prefix text to include in the logged error
119 host NULL if setting up a server;
120 the connected host if setting up a client
121 err a GnuTLS error number, or 0 if local error
122
123 Returns: OK/DEFER/FAIL
124 */
125
126 static int
127 tls_error(uschar *prefix, host_item *host, int err)
128 {
129 uschar *errtext = US"";
130 if (err != 0) errtext = string_sprintf(": %s", gnutls_strerror(err));
131 if (host == NULL)
132 {
133 log_write(0, LOG_MAIN, "TLS error on connection from %s (%s)%s",
134 (sender_fullhost != NULL)? sender_fullhost : US "local process",
135 prefix, errtext);
136 return DEFER;
137 }
138 else
139 {
140 log_write(0, LOG_MAIN, "TLS error on connection to %s [%s] (%s)%s",
141 host->name, host->address, prefix, errtext);
142 return FAIL;
143 }
144 }
145
146
147
148 /*************************************************
149 * Verify certificate *
150 *************************************************/
151
152 /* Called after a successful handshake, when certificate verification is
153 required or optional, for both server and client.
154
155 Arguments:
156 session GNUTLS session
157 error where to put text giving a reason for failure
158
159 Returns: TRUE/FALSE
160 */
161
162 static BOOL
163 verify_certificate(gnutls_session session, uschar **error)
164 {
165 int verify;
166 uschar *dn_string = US"";
167 const gnutls_datum *cert;
168 unsigned int cert_size = 0;
169
170 *error = NULL;
171
172 /* Get the peer's certificate. If it sent one, extract it's DN, and then
173 attempt to verify the certificate. If no certificate is supplied, verification
174 is forced to fail. */
175
176 cert = gnutls_certificate_get_peers(session, &cert_size);
177 if (cert != NULL)
178 {
179 uschar buff[1024];
180 gnutls_x509_crt gcert;
181
182 gnutls_x509_crt_init(&gcert);
183 dn_string = US"unknown";
184
185 if (gnutls_x509_crt_import(gcert, cert, GNUTLS_X509_FMT_DER) == 0)
186 {
187 size_t bufsize = sizeof(buff);
188 if (gnutls_x509_crt_get_dn(gcert, CS buff, &bufsize) >= 0)
189 dn_string = string_copy_malloc(buff);
190 }
191
192 verify = gnutls_certificate_verify_peers(session);
193 }
194 else
195 {
196 DEBUG(D_tls) debug_printf("no peer certificate supplied\n");
197 verify = GNUTLS_CERT_INVALID;
198 *error = US"not supplied";
199 }
200
201 /* Handle the result of verification. INVALID seems to be set as well
202 as REVOKED, but leave the test for both. */
203
204 if ((verify & (GNUTLS_CERT_INVALID|GNUTLS_CERT_REVOKED)) != 0)
205 {
206 tls_certificate_verified = FALSE;
207 if (*error == NULL) *error = ((verify & GNUTLS_CERT_REVOKED) != 0)?
208 US"revoked" : US"invalid";
209 if (verify_requirement == VERIFY_REQUIRED)
210 {
211 DEBUG(D_tls) debug_printf("TLS certificate verification failed (%s): "
212 "peerdn=%s\n", *error, dn_string);
213 gnutls_alert_send(session, GNUTLS_AL_FATAL, GNUTLS_A_BAD_CERTIFICATE);
214 return FALSE; /* reject */
215 }
216 DEBUG(D_tls) debug_printf("TLS certificate verify failure (%s) overridden "
217 "(host in tls_try_verify_hosts): peerdn=%s\n", *error, dn_string);
218 }
219 else
220 {
221 tls_certificate_verified = TRUE;
222 DEBUG(D_tls) debug_printf("TLS certificate verified: peerdn=%s\n",
223 dn_string);
224 }
225
226 tls_peerdn = dn_string;
227 return TRUE; /* accept */
228 }
229
230
231
232 /*************************************************
233 * Setup up DH parameters *
234 *************************************************/
235
236 /* Generating the D-H parameters may take a long time. They only need to
237 be re-generated every so often, depending on security policy. What we do is to
238 keep these parameters in a file in the spool directory. If the file does not
239 exist, we generate them. This means that it is easy to cause a regeneration.
240
241 The new file is written as a temporary file and renamed, so that an incomplete
242 file is never present. If two processes both compute some new parameters, you
243 waste a bit of effort, but it doesn't seem worth messing around with locking to
244 prevent this.
245
246 Argument:
247 host NULL for server, server for client (for error handling)
248
249 Returns: OK/DEFER/FAIL
250 */
251
252 static int
253 init_dh(host_item *host)
254 {
255 int fd;
256 int ret;
257 gnutls_datum m;
258 uschar filename[200];
259
260 /* Initialize the data structures for holding the parameters */
261
262 ret = gnutls_dh_params_init(&dh_params);
263 if (ret < 0) return tls_error(US"init dh_params", host, ret);
264
265 /* Set up the name of the cache file */
266
267 if (!string_format(filename, sizeof(filename), "%s/gnutls-params",
268 spool_directory))
269 return tls_error(US"overlong filename", host, 0);
270
271 /* Open the cache file for reading and if successful, read it and set up the
272 parameters. */
273
274 fd = Uopen(filename, O_RDONLY, 0);
275 if (fd >= 0)
276 {
277 struct stat statbuf;
278 if (fstat(fd, &statbuf) < 0)
279 {
280 (void)close(fd);
281 return tls_error(US"TLS cache stat failed", host, 0);
282 }
283
284 m.size = statbuf.st_size;
285 m.data = malloc(m.size);
286 if (m.data == NULL)
287 return tls_error(US"memory allocation failed", host, 0);
288 if (read(fd, m.data, m.size) != m.size)
289 return tls_error(US"TLS cache read failed", host, 0);
290 (void)close(fd);
291
292 ret = gnutls_dh_params_import_pkcs3(dh_params, &m, GNUTLS_X509_FMT_PEM);
293 if (ret < 0) return tls_error(US"DH params import", host, ret);
294 DEBUG(D_tls) debug_printf("read D-H parameters from file\n");
295
296 free(m.data);
297 }
298
299 /* If the file does not exist, fall through to compute new data and cache it.
300 If there was any other opening error, it is serious. */
301
302 else if (errno == ENOENT)
303 {
304 ret = -1;
305 DEBUG(D_tls)
306 debug_printf("parameter cache file %s does not exist\n", filename);
307 }
308 else
309 return tls_error(string_open_failed(errno, "%s for reading", filename),
310 host, 0);
311
312 /* If ret < 0, either the cache file does not exist, or the data it contains
313 is not useful. One particular case of this is when upgrading from an older
314 release of Exim in which the data was stored in a different format. We don't
315 try to be clever and support both formats; we just regenerate new data in this
316 case. */
317
318 if (ret < 0)
319 {
320 uschar tempfilename[sizeof(filename) + 10];
321
322 DEBUG(D_tls) debug_printf("generating %d bit Diffie-Hellman key...\n",
323 DH_BITS);
324 ret = gnutls_dh_params_generate2(dh_params, DH_BITS);
325 if (ret < 0) return tls_error(US"D-H key generation", host, ret);
326
327 /* Write the parameters to a file in the spool directory so that we
328 can use them from other Exim processes. */
329
330 sprintf(CS tempfilename, "%s-%d", filename, (int)getpid());
331 fd = Uopen(tempfilename, O_WRONLY|O_CREAT, 0400);
332 if (fd < 0)
333 return tls_error(string_open_failed(errno, "%s for writing", filename),
334 host, 0);
335 (void)fchown(fd, exim_uid, exim_gid); /* Probably not necessary */
336
337 /* export the parameters in a format that can be generated using GNUTLS'
338 * certtool or other programs.
339 *
340 * The commands for certtool are:
341 * $ certtool --generate-dh-params --bits 1024 > params
342 */
343
344 m.size = PARAM_SIZE;
345 m.data = malloc(m.size);
346 if (m.data == NULL)
347 return tls_error(US"memory allocation failed", host, 0);
348
349 m.size = PARAM_SIZE;
350 ret = gnutls_dh_params_export_pkcs3(dh_params, GNUTLS_X509_FMT_PEM, m.data,
351 &m.size);
352 if (ret < 0) return tls_error(US"DH params export", host, ret);
353
354 m.size = Ustrlen(m.data);
355 if (write(fd, m.data, m.size) != m.size || write(fd, "\n", 1) != 1)
356 return tls_error(US"TLS cache write failed", host, 0);
357
358 free(m.data);
359 (void)close(fd);
360
361 if (rename(CS tempfilename, CS filename) < 0)
362 return tls_error(string_sprintf("failed to rename %s as %s: %s",
363 tempfilename, filename, strerror(errno)), host, 0);
364
365 DEBUG(D_tls) debug_printf("wrote D-H parameters to file %s\n", filename);
366 }
367
368 DEBUG(D_tls) debug_printf("initialized D-H parameters\n");
369 return OK;
370 }
371
372
373
374
375 /*************************************************
376 * Initialize for GnuTLS *
377 *************************************************/
378
379 /* Called from both server and client code. In the case of a server, errors
380 before actual TLS negotiation return DEFER.
381
382 Arguments:
383 host connected host, if client; NULL if server
384 certificate certificate file
385 privatekey private key file
386 cas CA certs file
387 crl CRL file
388
389 Returns: OK/DEFER/FAIL
390 */
391
392 static int
393 tls_init(host_item *host, uschar *certificate, uschar *privatekey, uschar *cas,
394 uschar *crl)
395 {
396 int rc;
397 uschar *cert_expanded, *key_expanded, *cas_expanded, *crl_expanded;
398
399 initialized = (host == NULL)? INITIALIZED_SERVER : INITIALIZED_CLIENT;
400
401 rc = gnutls_global_init();
402 if (rc < 0) return tls_error(US"tls-init", host, rc);
403
404 /* Create D-H parameters, or read them from the cache file. This function does
405 its own SMTP error messaging. */
406
407 rc = init_dh(host);
408 if (rc != OK) return rc;
409
410 /* Create the credentials structure */
411
412 rc = gnutls_certificate_allocate_credentials(&x509_cred);
413 if (rc < 0) return tls_error(US"certificate_allocate_credentials", host, rc);
414
415 /* This stuff must be done for each session, because different certificates
416 may be required for different sessions. */
417
418 if (!expand_check(certificate, US"tls_certificate", &cert_expanded))
419 return DEFER;
420
421 key_expanded = NULL;
422 if (privatekey != NULL)
423 {
424 if (!expand_check(privatekey, US"tls_privatekey", &key_expanded))
425 return DEFER;
426 }
427
428 /* If expansion was forced to fail, key_expanded will be NULL. If the result of
429 the expansion is an empty string, ignore it also, and assume that the private
430 key is in the same file as the certificate. */
431
432 if (key_expanded == NULL || *key_expanded == 0)
433 key_expanded = cert_expanded;
434
435 /* Set the certificate and private keys */
436
437 if (cert_expanded != NULL)
438 {
439 DEBUG(D_tls) debug_printf("certificate file = %s\nkey file = %s\n",
440 cert_expanded, key_expanded);
441 rc = gnutls_certificate_set_x509_key_file(x509_cred, CS cert_expanded,
442 CS key_expanded, GNUTLS_X509_FMT_PEM);
443 if (rc < 0)
444 {
445 uschar *msg = string_sprintf("cert/key setup: cert=%s key=%s",
446 cert_expanded, key_expanded);
447 return tls_error(msg, host, rc);
448 }
449 }
450
451 /* A certificate is mandatory in a server, but not in a client */
452
453 else
454 {
455 if (host == NULL)
456 return tls_error(US"no TLS server certificate is specified", host, 0);
457 DEBUG(D_tls) debug_printf("no TLS client certificate is specified\n");
458 }
459
460 /* Set the trusted CAs file if one is provided, and then add the CRL if one is
461 provided. Experiment shows that, if the certificate file is empty, an unhelpful
462 error message is provided. However, if we just refrain from setting anything up
463 in that case, certificate verification fails, which seems to be the correct
464 behaviour. */
465
466 if (cas != NULL)
467 {
468 struct stat statbuf;
469
470 if (!expand_check(cas, US"tls_verify_certificates", &cas_expanded))
471 return DEFER;
472
473 if (stat(CS cas_expanded, &statbuf) < 0)
474 {
475 log_write(0, LOG_MAIN|LOG_PANIC, "could not stat %s "
476 "(tls_verify_certificates): %s", cas_expanded, strerror(errno));
477 return DEFER;
478 }
479
480 DEBUG(D_tls) debug_printf("verify certificates = %s size=" OFF_T_FMT "\n",
481 cas_expanded, statbuf.st_size);
482
483 /* If the cert file is empty, there's no point in loading the CRL file. */
484
485 if (statbuf.st_size > 0)
486 {
487 rc = gnutls_certificate_set_x509_trust_file(x509_cred, CS cas_expanded,
488 GNUTLS_X509_FMT_PEM);
489 if (rc < 0) return tls_error(US"setup_certs", host, rc);
490
491 if (crl != NULL && *crl != 0)
492 {
493 if (!expand_check(crl, US"tls_crl", &crl_expanded))
494 return DEFER;
495 DEBUG(D_tls) debug_printf("loading CRL file = %s\n", crl_expanded);
496 rc = gnutls_certificate_set_x509_crl_file(x509_cred, CS crl_expanded,
497 GNUTLS_X509_FMT_PEM);
498 if (rc < 0) return tls_error(US"CRL setup", host, rc);
499 }
500 }
501 }
502
503 /* Associate the parameters with the x509 credentials structure. */
504
505 gnutls_certificate_set_dh_params(x509_cred, dh_params);
506
507 DEBUG(D_tls) debug_printf("initialized certificate stuff\n");
508 return OK;
509 }
510
511
512
513
514 /*************************************************
515 * Remove ciphers from priority list *
516 *************************************************/
517
518 /* Cautiously written so that it will remove duplicates if present.
519
520 Arguments:
521 list a zero-terminated list
522 remove_list a zero-terminated list to be removed
523
524 Returns: nothing
525 */
526
527 static void
528 remove_ciphers(int *list, int *remove_list)
529 {
530 for (; *remove_list != 0; remove_list++)
531 {
532 int *p = list;
533 while (*p != 0)
534 {
535 if (*p == *remove_list)
536 {
537 int *pp = p;
538 do { pp[0] = pp[1]; pp++; } while (*pp != 0);
539 }
540 else p++;
541 }
542 }
543 }
544
545
546
547 /*************************************************
548 * Add ciphers to priority list *
549 *************************************************/
550
551 /* Cautiously written to check the list size
552
553 Arguments:
554 list a zero-terminated list
555 list_max maximum offset in the list
556 add_list a zero-terminated list to be added
557
558 Returns: TRUE if OK; FALSE if list overflows
559 */
560
561 static BOOL
562 add_ciphers(int *list, int list_max, int *add_list)
563 {
564 int next = 0;
565 while (list[next] != 0) next++;
566 while (*add_list != 0)
567 {
568 if (next >= list_max) return FALSE;
569 list[next++] = *add_list++;
570 }
571 list[next] = 0;
572 return TRUE;
573 }
574
575
576
577 /*************************************************
578 * Initialize a single GNUTLS session *
579 *************************************************/
580
581 /* Set the algorithm, the db backend, whether to request certificates etc.
582
583 TLS in Exim was first implemented using OpenSSL. This has a function to which
584 you pass a list of cipher suites that are permitted/not permitted. GnuTLS works
585 differently. It operates using priority lists for the different components of
586 cipher suites.
587
588 For compatibility of configuration, we scan a list of cipher suites and set
589 priorities therefrom. However, at the moment, we pay attention only to the bulk
590 cipher.
591
592 Arguments:
593 side one of GNUTLS_SERVER, GNUTLS_CLIENT
594 expciphers expanded ciphers list
595
596 Returns: a gnutls_session, or NULL if there is a problem
597 */
598
599 static gnutls_session
600 tls_session_init(int side, uschar *expciphers)
601 {
602 gnutls_session session;
603
604 gnutls_init(&session, side);
605
606 /* Handle the list of permitted ciphers */
607
608 memcpy(cipher_priority, default_cipher_priority, sizeof(cipher_priority));
609
610 if (expciphers != NULL)
611 {
612 int sep = 0;
613 BOOL first = TRUE;
614 uschar *cipher;
615
616 /* The names OpenSSL uses are of the form DES-CBC3-SHA, using hyphen
617 separators. GnuTLS uses underscore separators. So that I can use either form
618 in my tests, and also for general convenience, we turn hyphens into
619 underscores before scanning the list. */
620
621 uschar *s = expciphers;
622 while (*s != 0) { if (*s == '-') *s = '_'; s++; }
623
624 while ((cipher = string_nextinlist(&expciphers, &sep, big_buffer,
625 big_buffer_size)) != NULL)
626 {
627 int i;
628 BOOL exclude = cipher[0] == '!';
629 if (first && !exclude) cipher_priority[0] = 0;
630 first = FALSE;
631
632 for (i = 0; i < sizeof(cipher_index)/sizeof(pri_item); i++)
633 {
634 uschar *ss = strstric(cipher, cipher_index[i].name, FALSE);
635 if (ss != NULL)
636 {
637 uschar *endss = ss + Ustrlen(cipher_index[i].name);
638 if ((ss == cipher || !isalnum(ss[-1])) && !isalnum(*endss))
639 {
640 if (exclude)
641 remove_ciphers(cipher_priority, cipher_index[i].values);
642 else
643 {
644 if (!add_ciphers(cipher_priority,
645 sizeof(cipher_priority)/sizeof(pri_item),
646 cipher_index[i].values))
647 {
648 log_write(0, LOG_MAIN|LOG_PANIC, "GnuTLS init failed: cipher "
649 "priority table overflow");
650 gnutls_deinit(session);
651 return NULL;
652 }
653 }
654 }
655 }
656 }
657 }
658
659 DEBUG(D_tls)
660 {
661 int *ptr = cipher_priority;
662 debug_printf("adjusted cipher priorities:");
663 while (*ptr != 0) debug_printf(" %d", *ptr++);
664 debug_printf("\n");
665 }
666 }
667
668 /* Define the various priorities */
669
670 gnutls_cipher_set_priority(session, cipher_priority);
671 gnutls_compression_set_priority(session, comp_priority);
672 gnutls_kx_set_priority(session, kx_priority);
673 gnutls_protocol_set_priority(session, protocol_priority);
674 gnutls_mac_set_priority(session, mac_priority);
675
676 gnutls_cred_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
677
678 gnutls_dh_set_prime_bits(session, DH_BITS);
679
680 /* Request or demand a certificate of the peer, as configured. This will
681 happen only in a server. */
682
683 if (verify_requirement != VERIFY_NONE)
684 gnutls_certificate_server_set_request(session,
685 (verify_requirement == VERIFY_OPTIONAL)?
686 GNUTLS_CERT_REQUEST : GNUTLS_CERT_REQUIRE);
687
688 gnutls_db_set_cache_expiration(session, ssl_session_timeout);
689
690 DEBUG(D_tls) debug_printf("initialized GnuTLS session\n");
691 return session;
692 }
693
694
695
696 /*************************************************
697 * Get name of cipher in use *
698 *************************************************/
699
700 /* The answer is left in a static buffer, and tls_cipher is set to point
701 to it.
702
703 Argument: pointer to a GnuTLS session
704 Returns: nothing
705 */
706
707 static void
708 construct_cipher_name(gnutls_session session)
709 {
710 static uschar cipherbuf[256];
711 uschar *ver;
712 int bits, c, kx, mac;
713
714 ver = string_copy(
715 US gnutls_protocol_get_name(gnutls_protocol_get_version(session)));
716 if (Ustrncmp(ver, "TLS ", 4) == 0) ver[3] = '-'; /* Don't want space */
717
718 c = gnutls_cipher_get(session);
719 bits = gnutls_cipher_get_key_size(c);
720
721 mac = gnutls_mac_get(session);
722 kx = gnutls_kx_get(session);
723
724 string_format(cipherbuf, sizeof(cipherbuf), "%s:%s:%u", ver,
725 gnutls_cipher_suite_get_name(kx, c, mac), bits);
726 tls_cipher = cipherbuf;
727
728 DEBUG(D_tls) debug_printf("cipher: %s\n", cipherbuf);
729 }
730
731
732
733 /*************************************************
734 * Start a TLS session in a server *
735 *************************************************/
736
737 /* This is called when Exim is running as a server, after having received
738 the STARTTLS command. It must respond to that command, and then negotiate
739 a TLS session.
740
741 Arguments:
742 require_ciphers list of allowed ciphers
743
744 Returns: OK on success
745 DEFER for errors before the start of the negotiation
746 FAIL for errors during the negotation; the server can't
747 continue running.
748 */
749
750 int
751 tls_server_start(uschar *require_ciphers)
752 {
753 int rc;
754 uschar *error;
755 uschar *expciphers = NULL;
756
757 /* Check for previous activation */
758
759 if (tls_active >= 0)
760 {
761 log_write(0, LOG_MAIN, "STARTTLS received in already encrypted "
762 "connection from %s",
763 (sender_fullhost != NULL)? sender_fullhost : US"local process");
764 smtp_printf("554 Already in TLS\r\n");
765 return FAIL;
766 }
767
768 /* Initialize the library. If it fails, it will already have logged the error
769 and sent an SMTP response. */
770
771 DEBUG(D_tls) debug_printf("initializing GnuTLS as a server\n");
772
773 rc = tls_init(NULL, tls_certificate, tls_privatekey, tls_verify_certificates,
774 tls_crl);
775 if (rc != OK) return rc;
776
777 if (!expand_check(require_ciphers, US"tls_require_ciphers", &expciphers))
778 return FAIL;
779
780 /* If this is a host for which certificate verification is mandatory or
781 optional, set up appropriately. */
782
783 tls_certificate_verified = FALSE;
784 verify_requirement = VERIFY_NONE;
785
786 if (verify_check_host(&tls_verify_hosts) == OK)
787 verify_requirement = VERIFY_REQUIRED;
788 else if (verify_check_host(&tls_try_verify_hosts) == OK)
789 verify_requirement = VERIFY_OPTIONAL;
790
791 /* Prepare for new connection */
792
793 tls_session = tls_session_init(GNUTLS_SERVER, expciphers);
794 if (tls_session == NULL)
795 return tls_error(US"tls_session_init", NULL, GNUTLS_E_MEMORY_ERROR);
796
797 /* Set context and tell client to go ahead, except in the case of TLS startup
798 on connection, where outputting anything now upsets the clients and tends to
799 make them disconnect. We need to have an explicit fflush() here, to force out
800 the response. Other smtp_printf() calls do not need it, because in non-TLS
801 mode, the fflush() happens when smtp_getc() is called. */
802
803 if (!tls_on_connect)
804 {
805 smtp_printf("220 TLS go ahead\r\n");
806 fflush(smtp_out);
807 }
808
809 /* Now negotiate the TLS session. We put our own timer on it, since it seems
810 that the GnuTLS library doesn't. */
811
812 gnutls_transport_set_ptr(tls_session, (gnutls_transport_ptr)fileno(smtp_out));
813
814 sigalrm_seen = FALSE;
815 if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
816 rc = gnutls_handshake(tls_session);
817 alarm(0);
818
819 if (rc < 0)
820 {
821 if (sigalrm_seen)
822 Ustrcpy(ssl_errstring, "timed out");
823 else
824 Ustrcpy(ssl_errstring, gnutls_strerror(rc));
825 log_write(0, LOG_MAIN,
826 "TLS error on connection from %s (gnutls_handshake): %s",
827 (sender_fullhost != NULL)? sender_fullhost : US"local process",
828 ssl_errstring);
829
830 /* It seems that, except in the case of a timeout, we have to close the
831 connection right here; otherwise if the other end is running OpenSSL it hangs
832 until the server times out. */
833
834 if (!sigalrm_seen)
835 {
836 (void)fclose(smtp_out);
837 (void)fclose(smtp_in);
838 }
839
840 return FAIL;
841 }
842
843 DEBUG(D_tls) debug_printf("gnutls_handshake was successful\n");
844
845 if (verify_requirement != VERIFY_NONE &&
846 !verify_certificate(tls_session, &error))
847 {
848 log_write(0, LOG_MAIN,
849 "TLS error on connection from %s: certificate verification failed (%s)",
850 (sender_fullhost != NULL)? sender_fullhost : US"local process", error);
851 return FAIL;
852 }
853
854 construct_cipher_name(tls_session);
855
856 /* TLS has been set up. Adjust the input functions to read via TLS,
857 and initialize appropriately. */
858
859 ssl_xfer_buffer = store_malloc(ssl_xfer_buffer_size);
860 ssl_xfer_buffer_lwm = ssl_xfer_buffer_hwm = 0;
861 ssl_xfer_eof = ssl_xfer_error = 0;
862
863 receive_getc = tls_getc;
864 receive_ungetc = tls_ungetc;
865 receive_feof = tls_feof;
866 receive_ferror = tls_ferror;
867
868 tls_active = fileno(smtp_out);
869
870 return OK;
871 }
872
873
874
875
876 /*************************************************
877 * Start a TLS session in a client *
878 *************************************************/
879
880 /* Called from the smtp transport after STARTTLS has been accepted.
881
882 Arguments:
883 fd the fd of the connection
884 host connected host (for messages)
885 addr
886 dhparam DH parameter file
887 certificate certificate file
888 privatekey private key file
889 verify_certs file for certificate verify
890 verify_crl CRL for verify
891 require_ciphers list of allowed ciphers
892 timeout startup timeout
893
894 Returns: OK/DEFER/FAIL (because using common functions),
895 but for a client, DEFER and FAIL have the same meaning
896 */
897
898 int
899 tls_client_start(int fd, host_item *host, address_item *addr, uschar *dhparam,
900 uschar *certificate, uschar *privatekey, uschar *verify_certs,
901 uschar *verify_crl, uschar *require_ciphers, int timeout)
902 {
903 const gnutls_datum *server_certs;
904 uschar *expciphers = NULL;
905 uschar *error;
906 unsigned int server_certs_size;
907 int rc;
908
909 DEBUG(D_tls) debug_printf("initializing GnuTLS as a client\n");
910
911 client_host = host;
912 verify_requirement = (verify_certs == NULL)? VERIFY_NONE : VERIFY_REQUIRED;
913 rc = tls_init(host, certificate, privatekey, verify_certs, verify_crl);
914 if (rc != OK) return rc;
915
916 if (!expand_check(require_ciphers, US"tls_require_ciphers", &expciphers))
917 return FAIL;
918
919 tls_session = tls_session_init(GNUTLS_CLIENT, expciphers);
920 if (tls_session == NULL)
921 return tls_error(US "tls_session_init", host, GNUTLS_E_MEMORY_ERROR);
922
923 gnutls_transport_set_ptr(tls_session, (gnutls_transport_ptr)fd);
924
925 /* There doesn't seem to be a built-in timeout on connection. */
926
927 sigalrm_seen = FALSE;
928 alarm(timeout);
929 rc = gnutls_handshake(tls_session);
930 alarm(0);
931
932 if (rc < 0)
933 {
934 if (sigalrm_seen)
935 {
936 log_write(0, LOG_MAIN, "TLS error on connection to %s [%s]: "
937 "gnutls_handshake timed out", host->name, host->address);
938 return FAIL;
939 }
940 else return tls_error(US "gnutls_handshake", host, rc);
941 }
942
943 server_certs = gnutls_certificate_get_peers(tls_session, &server_certs_size);
944
945 if (server_certs != NULL)
946 {
947 uschar buff[1024];
948 gnutls_x509_crt gcert;
949
950 gnutls_x509_crt_init(&gcert);
951 tls_peerdn = US"unknown";
952
953 if (gnutls_x509_crt_import(gcert, server_certs, GNUTLS_X509_FMT_DER) == 0)
954 {
955 size_t bufsize = sizeof(buff);
956 if (gnutls_x509_crt_get_dn(gcert, CS buff, &bufsize) >= 0)
957 tls_peerdn = string_copy_malloc(buff);
958 }
959 }
960
961 /* Should we also verify the hostname here? */
962
963 if (verify_requirement != VERIFY_NONE &&
964 !verify_certificate(tls_session, &error))
965 {
966 log_write(0, LOG_MAIN,
967 "TLS error on connection to %s [%s]: certificate verification failed (%s)",
968 host->name, host->address, error);
969 return FAIL;
970 }
971
972 construct_cipher_name(tls_session); /* Sets tls_cipher */
973 tls_active = fd;
974 return OK;
975 }
976
977
978
979 /*************************************************
980 * Deal with logging errors during I/O *
981 *************************************************/
982
983 /* We have to get the identity of the peer from saved data.
984
985 Argument:
986 ec the GnuTLS error code, or 0 if it's a local error
987 when text identifying read or write
988 text local error text when ec is 0
989
990 Returns: nothing
991 */
992
993 static void
994 record_io_error(int ec, uschar *when, uschar *text)
995 {
996 uschar *additional = US"";
997
998 if (ec == GNUTLS_E_FATAL_ALERT_RECEIVED)
999 additional = string_sprintf(": %s",
1000 gnutls_alert_get_name(gnutls_alert_get(tls_session)));
1001
1002 if (initialized == INITIALIZED_SERVER)
1003 log_write(0, LOG_MAIN, "TLS %s error on connection from %s: %s%s", when,
1004 (sender_fullhost != NULL)? sender_fullhost : US "local process",
1005 (ec == 0)? text : US gnutls_strerror(ec), additional);
1006
1007 else
1008 log_write(0, LOG_MAIN, "TLS %s error on connection to %s [%s]: %s%s", when,
1009 client_host->name, client_host->address,
1010 (ec == 0)? text : US gnutls_strerror(ec), additional);
1011 }
1012
1013
1014
1015 /*************************************************
1016 * TLS version of getc *
1017 *************************************************/
1018
1019 /* This gets the next byte from the TLS input buffer. If the buffer is empty,
1020 it refills the buffer via the GnuTLS reading function.
1021
1022 Arguments: none
1023 Returns: the next character or EOF
1024 */
1025
1026 int
1027 tls_getc(void)
1028 {
1029 if (ssl_xfer_buffer_lwm >= ssl_xfer_buffer_hwm)
1030 {
1031 int inbytes;
1032
1033 DEBUG(D_tls) debug_printf("Calling gnutls_record_recv(%lx, %lx, %u)\n",
1034 (long) tls_session, (long) ssl_xfer_buffer, ssl_xfer_buffer_size);
1035
1036 if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
1037 inbytes = gnutls_record_recv(tls_session, CS ssl_xfer_buffer,
1038 ssl_xfer_buffer_size);
1039 alarm(0);
1040
1041 /* A zero-byte return appears to mean that the TLS session has been
1042 closed down, not that the socket itself has been closed down. Revert to
1043 non-TLS handling. */
1044
1045 if (inbytes == 0)
1046 {
1047 DEBUG(D_tls) debug_printf("Got TLS_EOF\n");
1048
1049 receive_getc = smtp_getc;
1050 receive_ungetc = smtp_ungetc;
1051 receive_feof = smtp_feof;
1052 receive_ferror = smtp_ferror;
1053
1054 gnutls_deinit(tls_session);
1055 tls_session = NULL;
1056 tls_active = -1;
1057 tls_cipher = NULL;
1058 tls_peerdn = NULL;
1059
1060 return smtp_getc();
1061 }
1062
1063 /* Handle genuine errors */
1064
1065 else if (inbytes < 0)
1066 {
1067 record_io_error(inbytes, US"recv", NULL);
1068 ssl_xfer_error = 1;
1069 return EOF;
1070 }
1071
1072 ssl_xfer_buffer_hwm = inbytes;
1073 ssl_xfer_buffer_lwm = 0;
1074 }
1075
1076
1077 /* Something in the buffer; return next uschar */
1078
1079 return ssl_xfer_buffer[ssl_xfer_buffer_lwm++];
1080 }
1081
1082
1083
1084 /*************************************************
1085 * Read bytes from TLS channel *
1086 *************************************************/
1087
1088 /*
1089 Arguments:
1090 buff buffer of data
1091 len size of buffer
1092
1093 Returns: the number of bytes read
1094 -1 after a failed read
1095 */
1096
1097 int
1098 tls_read(uschar *buff, size_t len)
1099 {
1100 int inbytes;
1101
1102 DEBUG(D_tls) debug_printf("Calling gnutls_record_recv(%lx, %lx, %u)\n",
1103 (long) tls_session, (long) buff, len);
1104
1105 inbytes = gnutls_record_recv(tls_session, CS buff, len);
1106 if (inbytes > 0) return inbytes;
1107 if (inbytes == 0)
1108 {
1109 DEBUG(D_tls) debug_printf("Got TLS_EOF\n");
1110 }
1111 else record_io_error(inbytes, US"recv", NULL);
1112
1113 return -1;
1114 }
1115
1116
1117
1118 /*************************************************
1119 * Write bytes down TLS channel *
1120 *************************************************/
1121
1122 /*
1123 Arguments:
1124 buff buffer of data
1125 len number of bytes
1126
1127 Returns: the number of bytes after a successful write,
1128 -1 after a failed write
1129 */
1130
1131 int
1132 tls_write(const uschar *buff, size_t len)
1133 {
1134 int outbytes;
1135 int left = len;
1136
1137 DEBUG(D_tls) debug_printf("tls_do_write(%lx, %d)\n", (long) buff, left);
1138 while (left > 0)
1139 {
1140 DEBUG(D_tls) debug_printf("gnutls_record_send(SSL, %lx, %d)\n", (long)buff,
1141 left);
1142 outbytes = gnutls_record_send(tls_session, CS buff, left);
1143
1144 DEBUG(D_tls) debug_printf("outbytes=%d\n", outbytes);
1145 if (outbytes < 0)
1146 {
1147 record_io_error(outbytes, US"send", NULL);
1148 return -1;
1149 }
1150 if (outbytes == 0)
1151 {
1152 record_io_error(0, US"send", US"TLS channel closed on write");
1153 return -1;
1154 }
1155
1156 left -= outbytes;
1157 buff += outbytes;
1158 }
1159
1160 return len;
1161 }
1162
1163
1164
1165 /*************************************************
1166 * Close down a TLS session *
1167 *************************************************/
1168
1169 /* This is also called from within a delivery subprocess forked from the
1170 daemon, to shut down the TLS library, without actually doing a shutdown (which
1171 would tamper with the TLS session in the parent process).
1172
1173 Arguments: TRUE if gnutls_bye is to be called
1174 Returns: nothing
1175 */
1176
1177 void
1178 tls_close(BOOL shutdown)
1179 {
1180 if (tls_active < 0) return; /* TLS was not active */
1181
1182 if (shutdown)
1183 {
1184 DEBUG(D_tls) debug_printf("tls_close(): shutting down TLS\n");
1185 gnutls_bye(tls_session, GNUTLS_SHUT_WR);
1186 }
1187
1188 gnutls_deinit(tls_session);
1189 tls_session = NULL;
1190 gnutls_global_deinit();
1191
1192 tls_active = -1;
1193 }
1194
1195 /* End of tls-gnu.c */