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