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