mutt stable branch with some hacks
1/*
2 * Copyright (C) 1999-2001 Tommi Komulainen <Tommi.Komulainen@iki.fi>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19#if HAVE_CONFIG_H
20# include "config.h"
21#endif
22
23#include <openssl/ssl.h>
24#include <openssl/x509.h>
25#include <openssl/x509v3.h>
26#include <openssl/x509_vfy.h>
27#include <openssl/err.h>
28#include <openssl/rand.h>
29#include <openssl/evp.h>
30
31/* LibreSSL defines OPENSSL_VERSION_NUMBER but sets it to 0x20000000L.
32 * So technically we don't need the defined(OPENSSL_VERSION_NUMBER) check.
33 */
34#if (defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L) || \
35 (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
36#define X509_get0_notBefore X509_get_notBefore
37#define X509_get0_notAfter X509_get_notAfter
38#define X509_getm_notBefore X509_get_notBefore
39#define X509_getm_notAfter X509_get_notAfter
40#define X509_STORE_CTX_get0_chain X509_STORE_CTX_get_chain
41#define SSL_has_pending SSL_pending
42#endif
43
44/* Unimplemented OpenSSL 1.1 api calls */
45#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x2070000fL)
46#define SSL_has_pending SSL_pending
47#endif
48
49#undef _
50
51#include <string.h>
52
53#include "mutt.h"
54#include "mutt_socket.h"
55#include "mutt_menu.h"
56#include "mutt_curses.h"
57#include "mutt_ssl.h"
58#include "mutt_idna.h"
59
60/* Just in case OpenSSL doesn't define DEVRANDOM */
61#ifndef DEVRANDOM
62#define DEVRANDOM "/dev/urandom"
63#endif
64
65/* This is ugly, but as RAND_status came in on OpenSSL version 0.9.5
66 * and the code has to support older versions too, this is seemed to
67 * be cleaner way compared to having even uglier #ifdefs all around.
68 */
69#ifdef HAVE_RAND_STATUS
70#define HAVE_ENTROPY() (RAND_status() == 1)
71#else
72static int entropy_byte_count = 0;
73/* OpenSSL fills the entropy pool from /dev/urandom if it exists */
74#define HAVE_ENTROPY() (!access(DEVRANDOM, R_OK) || entropy_byte_count >= 16)
75#endif
76
77/* index for storing hostname as application specific data in SSL structure */
78static int HostExDataIndex = -1;
79
80/* Index for storing the "skip mode" state in SSL structure. When the
81 * user skips a certificate in the chain, the stored value will be
82 * non-null. */
83static int SkipModeExDataIndex = -1;
84
85/* keep a handle on accepted certificates in case we want to
86 * open up another connection to the same server in this session */
87static STACK_OF(X509) *SslSessionCerts = NULL;
88
89typedef struct
90{
91 SSL_CTX *ctx;
92 SSL *ssl;
93 X509 *cert;
94 unsigned char isopen;
95}
96sslsockdata;
97
98/* local prototypes */
99static int ssl_init (void);
100static int add_entropy (const char *file);
101static int ssl_socket_read (CONNECTION* conn, char* buf, size_t len);
102static int ssl_socket_write (CONNECTION* conn, const char* buf, size_t len);
103static int ssl_socket_poll (CONNECTION* conn, time_t wait_secs);
104static int ssl_socket_open (CONNECTION * conn);
105static int ssl_socket_close (CONNECTION * conn);
106static int tls_close (CONNECTION* conn);
107static void ssl_err (sslsockdata *data, int err);
108static void ssl_dprint_err_stack (void);
109static int ssl_cache_trusted_cert (X509 *cert);
110static int ssl_verify_callback (int preverify_ok, X509_STORE_CTX *ctx);
111static int interactive_check_cert (X509 *cert, int idx, int len, SSL *ssl, int allow_always);
112static void ssl_get_client_cert(sslsockdata *ssldata, CONNECTION *conn);
113static int ssl_passwd_cb(char *buf, int size, int rwflag, void *userdata);
114static int ssl_negotiate (CONNECTION *conn, sslsockdata*);
115
116/* ssl certificate verification can behave strangely if there are expired
117 * certs loaded into the trusted store. This function filters out expired
118 * certs.
119 * Previously the code used this form:
120 * SSL_CTX_load_verify_locations (ssldata->ctx, SslCertFile, NULL);
121 */
122static int ssl_load_certificates (SSL_CTX *ctx)
123{
124 FILE *fp;
125 X509 *cert = NULL;
126 X509_STORE *store;
127 char buf[STRING];
128 int rv = 1;
129
130 dprint (2, (debugfile, "ssl_load_certificates: loading trusted certificates\n"));
131 store = SSL_CTX_get_cert_store (ctx);
132 if (!store)
133 {
134 store = X509_STORE_new ();
135 SSL_CTX_set_cert_store (ctx, store);
136 }
137
138 if ((fp = fopen (SslCertFile, "rt")) == NULL)
139 return 0;
140
141 while (NULL != PEM_read_X509 (fp, &cert, NULL, NULL))
142 {
143 if ((X509_cmp_current_time (X509_get0_notBefore (cert)) >= 0) ||
144 (X509_cmp_current_time (X509_get0_notAfter (cert)) <= 0))
145 {
146 dprint (2, (debugfile, "ssl_load_certificates: filtering expired cert: %s\n",
147 X509_NAME_oneline (X509_get_subject_name (cert), buf, sizeof (buf))));
148 }
149 else
150 {
151 X509_STORE_add_cert (store, cert);
152 }
153 }
154 /* PEM_read_X509 sets the error NO_START_LINE on eof */
155 if (ERR_GET_REASON(ERR_peek_last_error()) != PEM_R_NO_START_LINE)
156 rv = 0;
157 ERR_clear_error();
158
159 X509_free (cert);
160 safe_fclose (&fp);
161
162 return rv;
163}
164
165static int ssl_set_verify_partial (SSL_CTX *ctx)
166{
167 int rv = 0;
168#ifdef HAVE_SSL_PARTIAL_CHAIN
169 X509_VERIFY_PARAM *param;
170
171 if (option (OPTSSLVERIFYPARTIAL))
172 {
173 param = X509_VERIFY_PARAM_new();
174 if (param)
175 {
176 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_PARTIAL_CHAIN);
177 if (0 == SSL_CTX_set1_param(ctx, param))
178 {
179 dprint (2, (debugfile, "ssl_set_verify_partial: SSL_CTX_set1_param() failed."));
180 rv = -1;
181 }
182 X509_VERIFY_PARAM_free(param);
183 }
184 else
185 {
186 dprint (2, (debugfile, "ssl_set_verify_partial: X509_VERIFY_PARAM_new() failed."));
187 rv = -1;
188 }
189 }
190#endif
191 return rv;
192}
193
194/* mutt_ssl_starttls: Negotiate TLS over an already opened connection.
195 * TODO: Merge this code better with ssl_socket_open. */
196int mutt_ssl_starttls (CONNECTION* conn)
197{
198 sslsockdata* ssldata;
199 int maxbits;
200 long ssl_options = 0;
201
202 if (ssl_init())
203 goto bail;
204
205 ssldata = (sslsockdata*) safe_calloc (1, sizeof (sslsockdata));
206 /* the ssl_use_xxx protocol options don't apply. We must use TLS in TLS.
207 *
208 * However, we need to be able to negotiate amongst various TLS versions,
209 * which at present can only be done with the SSLv23_client_method;
210 * TLSv1_client_method gives us explicitly TLSv1.0, not 1.1 or 1.2 (True as
211 * of OpenSSL 1.0.1c)
212 */
213 if (! (ssldata->ctx = SSL_CTX_new (SSLv23_client_method())))
214 {
215 dprint (1, (debugfile, "mutt_ssl_starttls: Error allocating SSL_CTX\n"));
216 goto bail_ssldata;
217 }
218#ifdef SSL_OP_NO_TLSv1_3
219 if (!option(OPTTLSV1_3))
220 ssl_options |= SSL_OP_NO_TLSv1_3;
221#endif
222#ifdef SSL_OP_NO_TLSv1_2
223 if (!option(OPTTLSV1_2))
224 ssl_options |= SSL_OP_NO_TLSv1_2;
225#endif
226#ifdef SSL_OP_NO_TLSv1_1
227 if (!option(OPTTLSV1_1))
228 ssl_options |= SSL_OP_NO_TLSv1_1;
229#endif
230#ifdef SSL_OP_NO_TLSv1
231 if (!option(OPTTLSV1))
232 ssl_options |= SSL_OP_NO_TLSv1;
233#endif
234 /* these are always set */
235#ifdef SSL_OP_NO_SSLv3
236 ssl_options |= SSL_OP_NO_SSLv3;
237#endif
238#ifdef SSL_OP_NO_SSLv2
239 ssl_options |= SSL_OP_NO_SSLv2;
240#endif
241 if (! SSL_CTX_set_options(ssldata->ctx, ssl_options))
242 {
243 dprint(1, (debugfile, "mutt_ssl_starttls: Error setting options to %ld\n", ssl_options));
244 goto bail_ctx;
245 }
246
247 if (option (OPTSSLSYSTEMCERTS))
248 {
249 if (! SSL_CTX_set_default_verify_paths (ssldata->ctx))
250 {
251 dprint (1, (debugfile, "mutt_ssl_starttls: Error setting default verify paths\n"));
252 goto bail_ctx;
253 }
254 }
255
256 if (SslCertFile && !ssl_load_certificates (ssldata->ctx))
257 dprint (1, (debugfile, "mutt_ssl_starttls: Error loading trusted certificates\n"));
258
259 ssl_get_client_cert(ssldata, conn);
260
261 if (SslCiphers)
262 {
263 if (!SSL_CTX_set_cipher_list (ssldata->ctx, SslCiphers))
264 {
265 dprint (1, (debugfile, "mutt_ssl_starttls: Could not select preferred ciphers\n"));
266 goto bail_ctx;
267 }
268 }
269
270 if (ssl_set_verify_partial (ssldata->ctx))
271 {
272 mutt_error (_("Warning: error enabling ssl_verify_partial_chains"));
273 mutt_sleep (2);
274 }
275
276 if (! (ssldata->ssl = SSL_new (ssldata->ctx)))
277 {
278 dprint (1, (debugfile, "mutt_ssl_starttls: Error allocating SSL\n"));
279 goto bail_ctx;
280 }
281
282 if (SSL_set_fd (ssldata->ssl, conn->fd) != 1)
283 {
284 dprint (1, (debugfile, "mutt_ssl_starttls: Error setting fd\n"));
285 goto bail_ssl;
286 }
287
288 if (ssl_negotiate (conn, ssldata))
289 goto bail_ssl;
290
291 ssldata->isopen = 1;
292
293 /* hmm. watch out if we're starting TLS over any method other than raw. */
294 conn->sockdata = ssldata;
295 conn->conn_read = ssl_socket_read;
296 conn->conn_write = ssl_socket_write;
297 conn->conn_close = tls_close;
298 conn->conn_poll = ssl_socket_poll;
299
300 conn->ssf = SSL_CIPHER_get_bits (SSL_get_current_cipher (ssldata->ssl),
301 &maxbits);
302
303 return 0;
304
305bail_ssl:
306 SSL_free (ssldata->ssl);
307 ssldata->ssl = 0;
308bail_ctx:
309 SSL_CTX_free (ssldata->ctx);
310 ssldata->ctx = 0;
311bail_ssldata:
312 FREE (&ssldata);
313bail:
314 return -1;
315}
316
317/*
318 * OpenSSL library needs to be fed with sufficient entropy. On systems
319 * with /dev/urandom, this is done transparently by the library itself,
320 * on other systems we need to fill the entropy pool ourselves.
321 *
322 * Even though only OpenSSL 0.9.5 and later will complain about the
323 * lack of entropy, we try to our best and fill the pool with older
324 * versions also. (That's the reason for the ugly #ifdefs and macros,
325 * otherwise I could have simply #ifdef'd the whole ssl_init function)
326 */
327static int ssl_init (void)
328{
329 BUFFER *path = NULL;
330 static unsigned char init_complete = 0;
331
332 if (init_complete)
333 return 0;
334
335 if (! HAVE_ENTROPY())
336 {
337 /* load entropy from files */
338 add_entropy (SslEntropyFile);
339
340 path = mutt_buffer_pool_get ();
341 add_entropy (RAND_file_name (path->data, path->dsize));
342
343 /* load entropy from egd sockets */
344#ifdef HAVE_RAND_EGD
345 add_entropy (getenv ("EGDSOCKET"));
346 mutt_buffer_printf (path, "%s/.entropy", NONULL(Homedir));
347 add_entropy (mutt_b2s (path));
348 add_entropy ("/tmp/entropy");
349#endif
350
351 /* shuffle $RANDFILE (or ~/.rnd if unset) */
352 RAND_write_file (RAND_file_name (path->data, path->dsize));
353 mutt_buffer_pool_release (&path);
354
355 mutt_clear_error ();
356 if (! HAVE_ENTROPY())
357 {
358 mutt_error (_("Failed to find enough entropy on your system"));
359 mutt_sleep (2);
360 return -1;
361 }
362 }
363
364/* OpenSSL performs automatic initialization as of 1.1.
365 * However LibreSSL does not (as of 2.8.3). */
366#if (defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L) || \
367 (defined(LIBRESSL_VERSION_NUMBER))
368 /* I don't think you can do this just before reading the error. The call
369 * itself might clobber the last SSL error. */
370 SSL_load_error_strings();
371 SSL_library_init();
372#endif
373 init_complete = 1;
374 return 0;
375}
376
377static int add_entropy (const char *file)
378{
379 struct stat st;
380 int n = -1;
381
382 if (!file) return 0;
383
384 if (stat (file, &st) == -1)
385 return errno == ENOENT ? 0 : -1;
386
387 mutt_message (_("Filling entropy pool: %s...\n"),
388 file);
389
390 /* check that the file permissions are secure */
391 if (st.st_uid != getuid () ||
392 ((st.st_mode & (S_IWGRP | S_IRGRP)) != 0) ||
393 ((st.st_mode & (S_IWOTH | S_IROTH)) != 0))
394 {
395 mutt_error (_("%s has insecure permissions!"), file);
396 mutt_sleep (2);
397 return -1;
398 }
399
400#ifdef HAVE_RAND_EGD
401 n = RAND_egd (file);
402#endif
403 if (n <= 0)
404 n = RAND_load_file (file, -1);
405
406#ifndef HAVE_RAND_STATUS
407 if (n > 0) entropy_byte_count += n;
408#endif
409 return n;
410}
411
412static int ssl_socket_open_err (CONNECTION *conn)
413{
414 mutt_error (_("SSL disabled due to the lack of entropy"));
415 mutt_sleep (2);
416 return -1;
417}
418
419
420int mutt_ssl_socket_setup (CONNECTION * conn)
421{
422 if (ssl_init() < 0)
423 {
424 conn->conn_open = ssl_socket_open_err;
425 return -1;
426 }
427
428 conn->conn_open = ssl_socket_open;
429 conn->conn_read = ssl_socket_read;
430 conn->conn_write = ssl_socket_write;
431 conn->conn_close = ssl_socket_close;
432 conn->conn_poll = ssl_socket_poll;
433
434 return 0;
435}
436
437static int ssl_socket_read (CONNECTION* conn, char* buf, size_t len)
438{
439 sslsockdata *data = conn->sockdata;
440 int rc;
441
442 rc = SSL_read (data->ssl, buf, len);
443 if (rc <= 0)
444 {
445 data->isopen = 0;
446 ssl_err (data, rc);
447 }
448
449 return rc;
450}
451
452static int ssl_socket_write (CONNECTION* conn, const char* buf, size_t len)
453{
454 sslsockdata *data = conn->sockdata;
455 int rc;
456
457 rc = SSL_write (data->ssl, buf, len);
458 if (rc <= 0)
459 ssl_err (data, rc);
460
461 return rc;
462}
463
464static int ssl_socket_poll (CONNECTION* conn, time_t wait_secs)
465{
466 sslsockdata *data = conn->sockdata;
467
468 if (!data)
469 return -1;
470
471 if (SSL_has_pending (data->ssl))
472 return 1;
473 else
474 return raw_socket_poll (conn, wait_secs);
475}
476
477static int ssl_socket_open (CONNECTION * conn)
478{
479 sslsockdata *data;
480 int maxbits;
481
482 if (raw_socket_open (conn) < 0)
483 return -1;
484
485 data = (sslsockdata *) safe_calloc (1, sizeof (sslsockdata));
486 conn->sockdata = data;
487
488 if (! (data->ctx = SSL_CTX_new (SSLv23_client_method ())))
489 {
490 /* L10N: an SSL context is a data structure returned by the OpenSSL
491 * function SSL_CTX_new(). In this case it returned NULL: an
492 * error condition.
493 */
494 mutt_error (_("Unable to create SSL context"));
495 ssl_dprint_err_stack ();
496 mutt_socket_close (conn);
497 return -1;
498 }
499
500 /* disable SSL protocols as needed */
501 if (!option(OPTTLSV1))
502 {
503 SSL_CTX_set_options(data->ctx, SSL_OP_NO_TLSv1);
504 }
505 /* TLSv1.1/1.2 support was added in OpenSSL 1.0.1, but some OS distros such
506 * as Fedora 17 are on OpenSSL 1.0.0.
507 */
508#ifdef SSL_OP_NO_TLSv1_1
509 if (!option(OPTTLSV1_1))
510 {
511 SSL_CTX_set_options(data->ctx, SSL_OP_NO_TLSv1_1);
512 }
513#endif
514#ifdef SSL_OP_NO_TLSv1_2
515 if (!option(OPTTLSV1_2))
516 {
517 SSL_CTX_set_options(data->ctx, SSL_OP_NO_TLSv1_2);
518 }
519#endif
520#ifdef SSL_OP_NO_TLSv1_3
521 if (!option(OPTTLSV1_3))
522 {
523 SSL_CTX_set_options(data->ctx, SSL_OP_NO_TLSv1_3);
524 }
525#endif
526 if (!option(OPTSSLV2))
527 {
528 SSL_CTX_set_options(data->ctx, SSL_OP_NO_SSLv2);
529 }
530 if (!option(OPTSSLV3))
531 {
532 SSL_CTX_set_options(data->ctx, SSL_OP_NO_SSLv3);
533 }
534
535 if (option (OPTSSLSYSTEMCERTS))
536 {
537 if (! SSL_CTX_set_default_verify_paths (data->ctx))
538 {
539 dprint (1, (debugfile, "ssl_socket_open: Error setting default verify paths\n"));
540 mutt_socket_close (conn);
541 return -1;
542 }
543 }
544
545 if (SslCertFile && !ssl_load_certificates (data->ctx))
546 dprint (1, (debugfile, "ssl_socket_open: Error loading trusted certificates\n"));
547
548 ssl_get_client_cert(data, conn);
549
550 if (SslCiphers)
551 {
552 SSL_CTX_set_cipher_list (data->ctx, SslCiphers);
553 }
554
555 if (ssl_set_verify_partial (data->ctx))
556 {
557 mutt_error (_("Warning: error enabling ssl_verify_partial_chains"));
558 mutt_sleep (2);
559 }
560
561 data->ssl = SSL_new (data->ctx);
562 SSL_set_fd (data->ssl, conn->fd);
563
564 if (ssl_negotiate(conn, data))
565 {
566 mutt_socket_close (conn);
567 return -1;
568 }
569
570 data->isopen = 1;
571
572 conn->ssf = SSL_CIPHER_get_bits (SSL_get_current_cipher (data->ssl),
573 &maxbits);
574
575 return 0;
576}
577
578/* ssl_negotiate: After SSL state has been initialized, attempt to negotiate
579 * SSL over the wire, including certificate checks. */
580static int ssl_negotiate (CONNECTION *conn, sslsockdata* ssldata)
581{
582 int err;
583 const char* errmsg;
584
585 if ((HostExDataIndex = SSL_get_ex_new_index (0, "host", NULL, NULL, NULL)) == -1)
586 {
587 dprint (1, (debugfile, "failed to get index for application specific data\n"));
588 return -1;
589 }
590
591 if (! SSL_set_ex_data (ssldata->ssl, HostExDataIndex, conn->account.host))
592 {
593 dprint (1, (debugfile, "failed to save hostname in SSL structure\n"));
594 return -1;
595 }
596
597 if ((SkipModeExDataIndex = SSL_get_ex_new_index (0, "skip", NULL, NULL, NULL)) == -1)
598 {
599 dprint (1, (debugfile, "failed to get index for application specific data\n"));
600 return -1;
601 }
602
603 if (! SSL_set_ex_data (ssldata->ssl, SkipModeExDataIndex, NULL))
604 {
605 dprint (1, (debugfile, "failed to save skip mode in SSL structure\n"));
606 return -1;
607 }
608
609 SSL_set_verify (ssldata->ssl, SSL_VERIFY_PEER, ssl_verify_callback);
610 SSL_set_mode (ssldata->ssl, SSL_MODE_AUTO_RETRY);
611
612 if (!SSL_set_tlsext_host_name (ssldata->ssl, conn->account.host))
613 {
614 /* L10N: This is a warning when trying to set the host name for
615 * TLS Server Name Indication (SNI). This allows the server to present
616 * the correct certificate if it supports multiple hosts. */
617 mutt_error _("Warning: unable to set TLS SNI host name");
618 mutt_sleep (1);
619 }
620
621 ERR_clear_error ();
622
623 if ((err = SSL_connect (ssldata->ssl)) != 1)
624 {
625 switch (SSL_get_error (ssldata->ssl, err))
626 {
627 case SSL_ERROR_SYSCALL:
628 errmsg = _("I/O error");
629 break;
630 case SSL_ERROR_SSL:
631 errmsg = ERR_error_string (ERR_get_error (), NULL);
632 break;
633 default:
634 errmsg = _("unknown error");
635 }
636
637 mutt_error (_("SSL failed: %s"), errmsg);
638 mutt_sleep (1);
639
640 return -1;
641 }
642
643 /* L10N:
644 %1$s is version (e.g. "TLSv1.2")
645 %2$s is cipher_version (e.g. "TLSv1/SSLv3")
646 %3$s is cipher_name (e.g. "ECDHE-RSA-AES128-GCM-SHA256") */
647 mutt_message (_("%s connection using %s (%s)"),
648 SSL_get_version(ssldata->ssl),
649 SSL_get_cipher_version (ssldata->ssl),
650 SSL_get_cipher_name (ssldata->ssl));
651
652 return 0;
653}
654
655static int ssl_socket_close (CONNECTION * conn)
656{
657 sslsockdata *data = conn->sockdata;
658 if (data)
659 {
660 if (data->isopen)
661 SSL_shutdown (data->ssl);
662
663 /* hold onto this for the life of mutt, in case we want to reconnect.
664 * The purist in me wants a mutt_exit hook. */
665#if 0
666 X509_free (data->cert);
667#endif
668 SSL_free (data->ssl);
669 SSL_CTX_free (data->ctx);
670 FREE (&conn->sockdata);
671 }
672
673 return raw_socket_close (conn);
674}
675
676static int tls_close (CONNECTION* conn)
677{
678 int rc;
679
680 rc = ssl_socket_close (conn);
681 conn->conn_read = raw_socket_read;
682 conn->conn_write = raw_socket_write;
683 conn->conn_close = raw_socket_close;
684 conn->conn_poll = raw_socket_poll;
685
686 return rc;
687}
688
689static void ssl_err (sslsockdata *data, int err)
690{
691 const char* errmsg;
692 unsigned long sslerr;
693
694 switch (SSL_get_error (data->ssl, err))
695 {
696 case SSL_ERROR_NONE:
697 return;
698 case SSL_ERROR_ZERO_RETURN:
699 errmsg = "SSL connection closed";
700 data->isopen = 0;
701 break;
702 case SSL_ERROR_WANT_READ:
703 errmsg = "retry read";
704 break;
705 case SSL_ERROR_WANT_WRITE:
706 errmsg = "retry write";
707 break;
708 case SSL_ERROR_WANT_CONNECT:
709 errmsg = "retry connect";
710 break;
711 case SSL_ERROR_WANT_ACCEPT:
712 errmsg = "retry accept";
713 break;
714 case SSL_ERROR_WANT_X509_LOOKUP:
715 errmsg = "retry x509 lookup";
716 break;
717 case SSL_ERROR_SYSCALL:
718 errmsg = "I/O error";
719 data->isopen = 0;
720 break;
721 case SSL_ERROR_SSL:
722 sslerr = ERR_get_error ();
723 switch (sslerr)
724 {
725 case 0:
726 switch (err)
727 {
728 case 0:
729 errmsg = "EOF";
730 break;
731 default:
732 errmsg = strerror(errno);
733 }
734 break;
735 default:
736 errmsg = ERR_error_string (sslerr, NULL);
737 }
738 break;
739 default:
740 errmsg = "unknown error";
741 }
742
743 dprint (1, (debugfile, "SSL error: %s\n", errmsg));
744}
745
746static void ssl_dprint_err_stack (void)
747{
748#ifdef DEBUG
749 BIO *bio;
750 char *buf = NULL;
751 long buflen;
752 char *output;
753
754 if (! (bio = BIO_new (BIO_s_mem ())))
755 return;
756 ERR_print_errors (bio);
757 if ((buflen = BIO_get_mem_data (bio, &buf)) > 0)
758 {
759 output = safe_malloc (buflen + 1);
760 memcpy (output, buf, buflen);
761 output[buflen] = '\0';
762 dprint (1, (debugfile, "SSL error stack: %s\n", output));
763 FREE (&output);
764 }
765 BIO_free (bio);
766#endif
767}
768
769
770static char *x509_get_part (X509_NAME *name, int nid)
771{
772 static char ret[SHORT_STRING];
773
774 if (!name ||
775 X509_NAME_get_text_by_NID (name, nid, ret, sizeof (ret)) < 0)
776 strfcpy (ret, _("Unknown"), sizeof (ret));
777
778 return ret;
779}
780
781static void x509_fingerprint (char *s, int l, X509 * cert, const EVP_MD *(*hashfunc)(void))
782{
783 unsigned char md[EVP_MAX_MD_SIZE];
784 unsigned int n;
785 int j;
786
787 if (!X509_digest (cert, hashfunc(), md, &n))
788 {
789 snprintf (s, l, "%s", _("[unable to calculate]"));
790 }
791 else
792 {
793 for (j = 0; j < (int) n; j++)
794 {
795 char ch[8];
796 snprintf (ch, 8, "%02X%s", md[j], (j % 2 ? " " : ""));
797 safe_strcat (s, l, ch);
798 }
799 }
800}
801
802static char *asn1time_to_string (ASN1_UTCTIME *tm)
803{
804 static char buf[64];
805 BIO *bio;
806
807 strfcpy (buf, _("[invalid date]"), sizeof (buf));
808
809 bio = BIO_new (BIO_s_mem());
810 if (bio)
811 {
812 if (ASN1_TIME_print (bio, tm))
813 (void) BIO_read (bio, buf, sizeof (buf));
814 BIO_free (bio);
815 }
816
817 return buf;
818}
819
820static int compare_certificates (X509 *cert, X509 *peercert,
821 unsigned char *peermd, unsigned int peermdlen)
822{
823 unsigned char md[EVP_MAX_MD_SIZE];
824 unsigned int mdlen;
825
826 /* Avoid CPU-intensive digest calculation if the certificates are
827 * not even remotely equal.
828 */
829 if (X509_subject_name_cmp (cert, peercert) != 0 ||
830 X509_issuer_name_cmp (cert, peercert) != 0)
831 return -1;
832
833 if (!X509_digest (cert, EVP_sha256(), md, &mdlen) || peermdlen != mdlen)
834 return -1;
835
836 if (memcmp(peermd, md, mdlen) != 0)
837 return -1;
838
839 return 0;
840}
841
842static int check_certificate_cache (X509 *peercert)
843{
844 unsigned char peermd[EVP_MAX_MD_SIZE];
845 unsigned int peermdlen;
846 X509 *cert;
847 int i;
848
849 if (!X509_digest (peercert, EVP_sha256(), peermd, &peermdlen)
850 || !SslSessionCerts)
851 {
852 return 0;
853 }
854
855 for (i = sk_X509_num (SslSessionCerts); i-- > 0;)
856 {
857 cert = sk_X509_value (SslSessionCerts, i);
858 if (!compare_certificates (cert, peercert, peermd, peermdlen))
859 {
860 return 1;
861 }
862 }
863
864 return 0;
865}
866
867static int check_certificate_expiration (X509 *peercert, int silent)
868{
869 if (option (OPTSSLVERIFYDATES) != MUTT_NO)
870 {
871 if (X509_cmp_current_time (X509_get0_notBefore (peercert)) >= 0)
872 {
873 if (!silent)
874 {
875 dprint (2, (debugfile, "Server certificate is not yet valid\n"));
876 mutt_error (_("Server certificate is not yet valid"));
877 mutt_sleep (2);
878 }
879 return 0;
880 }
881 if (X509_cmp_current_time (X509_get0_notAfter (peercert)) <= 0)
882 {
883 if (!silent)
884 {
885 dprint (2, (debugfile, "Server certificate has expired\n"));
886 mutt_error (_("Server certificate has expired"));
887 mutt_sleep (2);
888 }
889 return 0;
890 }
891 }
892
893 return 1;
894}
895
896static int check_certificate_file (X509 *peercert)
897{
898 unsigned char peermd[EVP_MAX_MD_SIZE];
899 unsigned int peermdlen;
900 X509 *cert = NULL;
901 int pass = 0;
902 FILE *fp;
903
904 if (!SslCertFile)
905 return 0;
906
907 if ((fp = fopen (SslCertFile, "rt")) == NULL)
908 return 0;
909
910 if (!X509_digest (peercert, EVP_sha256(), peermd, &peermdlen))
911 {
912 safe_fclose (&fp);
913 return 0;
914 }
915
916 while (PEM_read_X509 (fp, &cert, NULL, NULL) != NULL)
917 {
918 if ((compare_certificates (cert, peercert, peermd, peermdlen) == 0) &&
919 check_certificate_expiration (cert, 1))
920 {
921 pass = 1;
922 break;
923 }
924 }
925 /* PEM_read_X509 sets an error on eof */
926 if (!pass)
927 ERR_clear_error();
928 X509_free (cert);
929 safe_fclose (&fp);
930
931 return pass;
932}
933
934static int check_certificate_by_digest (X509 *peercert)
935{
936 return check_certificate_expiration (peercert, 0) &&
937 check_certificate_file (peercert);
938}
939
940/* port to mutt from msmtp's tls.c */
941static int hostname_match (const char *hostname, const char *certname)
942{
943 const char *cmp1, *cmp2;
944
945 if (strncmp(certname, "*.", 2) == 0)
946 {
947 cmp1 = certname + 2;
948 cmp2 = strchr(hostname, '.');
949 if (!cmp2)
950 {
951 return 0;
952 }
953 else
954 {
955 cmp2++;
956 }
957 }
958 else
959 {
960 cmp1 = certname;
961 cmp2 = hostname;
962 }
963
964 if (*cmp1 == '\0' || *cmp2 == '\0')
965 {
966 return 0;
967 }
968
969 if (strcasecmp(cmp1, cmp2) != 0)
970 {
971 return 0;
972 }
973
974 return 1;
975}
976
977/* port to mutt from msmtp's tls.c */
978static int check_host (X509 *x509cert, const char *hostname, char *err, size_t errlen)
979{
980 int i, rc = 0;
981 /* hostname in ASCII format: */
982 char *hostname_ascii = NULL;
983 /* needed to get the common name: */
984 X509_NAME *x509_subject;
985 char *buf = NULL;
986 int bufsize;
987 /* needed to get the DNS subjectAltNames: */
988 STACK_OF(GENERAL_NAME) *subj_alt_names;
989 int subj_alt_names_count;
990 GENERAL_NAME *subj_alt_name;
991 /* did we find a name matching hostname? */
992 int match_found;
993
994 /* Check if 'hostname' matches the one of the subjectAltName extensions of
995 * type DNS or the Common Name (CN). */
996
997#if defined(HAVE_LIBIDN) || defined(HAVE_LIBIDN2)
998 if (idna_to_ascii_lz(hostname, &hostname_ascii, 0) != IDNA_SUCCESS)
999 {
1000 hostname_ascii = safe_strdup(hostname);
1001 }
1002#else
1003 hostname_ascii = safe_strdup(hostname);
1004#endif
1005
1006 /* Try the DNS subjectAltNames. */
1007 match_found = 0;
1008 if ((subj_alt_names = X509_get_ext_d2i(x509cert, NID_subject_alt_name,
1009 NULL, NULL)))
1010 {
1011 subj_alt_names_count = sk_GENERAL_NAME_num(subj_alt_names);
1012 for (i = 0; i < subj_alt_names_count; i++)
1013 {
1014 subj_alt_name = sk_GENERAL_NAME_value(subj_alt_names, i);
1015 if (subj_alt_name->type == GEN_DNS)
1016 {
1017 if (subj_alt_name->d.ia5->length >= 0 &&
1018 mutt_strlen((char *)subj_alt_name->d.ia5->data) == (size_t)subj_alt_name->d.ia5->length &&
1019 (match_found = hostname_match(hostname_ascii,
1020 (char *)(subj_alt_name->d.ia5->data))))
1021 {
1022 break;
1023 }
1024 }
1025 }
1026 GENERAL_NAMES_free(subj_alt_names);
1027 }
1028
1029 if (!match_found)
1030 {
1031 /* Try the common name */
1032 if (!(x509_subject = X509_get_subject_name(x509cert)))
1033 {
1034 if (err && errlen)
1035 strfcpy (err, _("cannot get certificate subject"), errlen);
1036 goto out;
1037 }
1038
1039 /* first get the space requirements */
1040 bufsize = X509_NAME_get_text_by_NID(x509_subject, NID_commonName,
1041 NULL, 0);
1042 if (bufsize == -1)
1043 {
1044 if (err && errlen)
1045 strfcpy (err, _("cannot get certificate common name"), errlen);
1046 goto out;
1047 }
1048 bufsize++; /* space for the terminal nul char */
1049 buf = safe_malloc((size_t)bufsize);
1050 if (X509_NAME_get_text_by_NID(x509_subject, NID_commonName,
1051 buf, bufsize) == -1)
1052 {
1053 if (err && errlen)
1054 strfcpy (err, _("cannot get certificate common name"), errlen);
1055 goto out;
1056 }
1057 /* cast is safe since bufsize is incremented above, so bufsize-1 is always
1058 * zero or greater.
1059 */
1060 if (mutt_strlen(buf) == (size_t)bufsize - 1)
1061 {
1062 match_found = hostname_match(hostname_ascii, buf);
1063 }
1064 }
1065
1066 if (!match_found)
1067 {
1068 if (err && errlen)
1069 snprintf (err, errlen, _("certificate owner does not match hostname %s"),
1070 hostname);
1071 goto out;
1072 }
1073
1074 rc = 1;
1075
1076out:
1077 FREE(&buf);
1078 FREE(&hostname_ascii);
1079
1080 return rc;
1081}
1082
1083static int ssl_cache_trusted_cert (X509 *c)
1084{
1085 dprint (1, (debugfile, "ssl_cache_trusted_cert: trusted\n"));
1086 if (!SslSessionCerts)
1087 SslSessionCerts = sk_X509_new_null();
1088 return (sk_X509_push (SslSessionCerts, X509_dup(c)));
1089}
1090
1091/* certificate verification callback, called for each certificate in the chain
1092 * sent by the peer, starting from the root; returning 1 means that the given
1093 * certificate is trusted, returning 0 immediately aborts the SSL connection */
1094static int ssl_verify_callback (int preverify_ok, X509_STORE_CTX *ctx)
1095{
1096 char buf[STRING];
1097 const char *host;
1098 int len, pos;
1099 X509 *cert;
1100 SSL *ssl;
1101 int skip_mode;
1102#ifdef HAVE_SSL_PARTIAL_CHAIN
1103 static int last_pos = 0;
1104 static X509 *last_cert = NULL;
1105 unsigned char last_cert_md[EVP_MAX_MD_SIZE];
1106 unsigned int last_cert_mdlen;
1107#endif
1108
1109 if (! (ssl = X509_STORE_CTX_get_ex_data (ctx, SSL_get_ex_data_X509_STORE_CTX_idx ())))
1110 {
1111 dprint (1, (debugfile, "ssl_verify_callback: failed to retrieve SSL structure from X509_STORE_CTX\n"));
1112 return 0;
1113 }
1114 if (! (host = SSL_get_ex_data (ssl, HostExDataIndex)))
1115 {
1116 dprint (1, (debugfile, "ssl_verify_callback: failed to retrieve hostname from SSL structure\n"));
1117 return 0;
1118 }
1119
1120 /* This is true when a previous entry in the certificate chain did
1121 * not verify and the user manually chose to skip it via the
1122 * $ssl_verify_partial_chains option.
1123 * In this case, all following certificates need to be treated as non-verified
1124 * until one is actually verified.
1125 */
1126 skip_mode = (SSL_get_ex_data (ssl, SkipModeExDataIndex) != NULL);
1127
1128 cert = X509_STORE_CTX_get_current_cert (ctx);
1129 pos = X509_STORE_CTX_get_error_depth (ctx);
1130 len = sk_X509_num (X509_STORE_CTX_get0_chain (ctx));
1131
1132 dprint (1, (debugfile,
1133 "ssl_verify_callback: checking cert chain entry %s (preverify: %d skipmode: %d)\n",
1134 X509_NAME_oneline (X509_get_subject_name (cert), buf, sizeof (buf)),
1135 preverify_ok, skip_mode));
1136
1137#ifdef HAVE_SSL_PARTIAL_CHAIN
1138 /* Sometimes, when a certificate is (s)kipped, OpenSSL will pass it
1139 * a second time with preverify_ok = 1. Don't show it or the user
1140 * will think their "s" key is broken.
1141 */
1142 if (option (OPTSSLVERIFYPARTIAL))
1143 {
1144 if (skip_mode && preverify_ok && (pos == last_pos) && last_cert)
1145 {
1146 if (X509_digest (last_cert, EVP_sha256(), last_cert_md, &last_cert_mdlen) &&
1147 !compare_certificates (cert, last_cert, last_cert_md, last_cert_mdlen))
1148 {
1149 dprint (2, (debugfile,
1150 "ssl_verify_callback: ignoring duplicate skipped certificate.\n"));
1151 return 1;
1152 }
1153 }
1154
1155 last_pos = pos;
1156 if (last_cert)
1157 X509_free (last_cert);
1158 last_cert = X509_dup (cert);
1159 }
1160#endif
1161
1162 /* check session cache first */
1163 if (check_certificate_cache (cert))
1164 {
1165 dprint (2, (debugfile, "ssl_verify_callback: using cached certificate\n"));
1166 SSL_set_ex_data (ssl, SkipModeExDataIndex, NULL);
1167 return 1;
1168 }
1169
1170 /* check hostname only for the leaf certificate */
1171 buf[0] = 0;
1172 if (pos == 0 && option (OPTSSLVERIFYHOST) != MUTT_NO)
1173 {
1174 if (!check_host (cert, host, buf, sizeof (buf)))
1175 {
1176 mutt_error (_("Certificate host check failed: %s"), buf);
1177 mutt_sleep (2);
1178 /* we disallow (a)ccept always in the prompt, because it will have no effect
1179 * for hostname mismatches. */
1180 return interactive_check_cert (cert, pos, len, ssl, 0);
1181 }
1182 dprint (2, (debugfile, "ssl_verify_callback: hostname check passed\n"));
1183 }
1184
1185 if (!preverify_ok || skip_mode)
1186 {
1187 /* automatic check from user's database */
1188 if (SslCertFile && check_certificate_by_digest (cert))
1189 {
1190 dprint (2, (debugfile, "ssl_verify_callback: digest check passed\n"));
1191 SSL_set_ex_data (ssl, SkipModeExDataIndex, NULL);
1192 return 1;
1193 }
1194
1195#ifdef DEBUG
1196 /* log verification error */
1197 {
1198 int err = X509_STORE_CTX_get_error (ctx);
1199 snprintf (buf, sizeof (buf), "%s (%d)",
1200 X509_verify_cert_error_string (err), err);
1201 dprint (2, (debugfile, "X509_verify_cert: %s\n", buf));
1202 }
1203#endif
1204
1205 /* prompt user */
1206 return interactive_check_cert (cert, pos, len, ssl, 1);
1207 }
1208
1209 return 1;
1210}
1211
1212static int interactive_check_cert (X509 *cert, int idx, int len, SSL *ssl, int allow_always)
1213{
1214 static const int part[] =
1215 { NID_commonName, /* CN */
1216 NID_pkcs9_emailAddress, /* Email */
1217 NID_organizationName, /* O */
1218 NID_organizationalUnitName, /* OU */
1219 NID_localityName, /* L */
1220 NID_stateOrProvinceName, /* ST */
1221 NID_countryName /* C */ };
1222 X509_NAME *x509_subject;
1223 X509_NAME *x509_issuer;
1224 char helpstr[LONG_STRING];
1225 char buf[STRING];
1226 char title[STRING];
1227 MUTTMENU *menu = mutt_new_menu (MENU_GENERIC);
1228 int done;
1229 BUFFER *drow = NULL;
1230 unsigned u;
1231 FILE *fp;
1232 int allow_skip = 0, reset_ignoremacro = 0;
1233
1234 mutt_push_current_menu (menu);
1235
1236 drow = mutt_buffer_pool_get ();
1237
1238 mutt_menu_add_dialog_row (menu, _("This certificate belongs to:"));
1239 x509_subject = X509_get_subject_name (cert);
1240 for (u = 0; u < mutt_array_size (part); u++)
1241 {
1242 mutt_buffer_printf (drow, " %s", x509_get_part (x509_subject, part[u]));
1243 mutt_menu_add_dialog_row (menu, mutt_b2s (drow));
1244 }
1245
1246 mutt_menu_add_dialog_row (menu, "");
1247 mutt_menu_add_dialog_row (menu, _("This certificate was issued by:"));
1248 x509_issuer = X509_get_issuer_name (cert);
1249 for (u = 0; u < mutt_array_size (part); u++)
1250 {
1251 mutt_buffer_printf (drow, " %s", x509_get_part (x509_issuer, part[u]));
1252 mutt_menu_add_dialog_row (menu, mutt_b2s (drow));
1253 }
1254
1255 mutt_menu_add_dialog_row (menu, "");
1256 mutt_menu_add_dialog_row (menu, _("This certificate is valid"));
1257 mutt_buffer_printf (drow, _(" from %s"),
1258 asn1time_to_string (X509_getm_notBefore (cert)));
1259 mutt_menu_add_dialog_row (menu, mutt_b2s (drow));
1260 mutt_buffer_printf (drow, _(" to %s"),
1261 asn1time_to_string (X509_getm_notAfter (cert)));
1262 mutt_menu_add_dialog_row (menu, mutt_b2s (drow));
1263
1264 mutt_menu_add_dialog_row (menu, "");
1265 buf[0] = '\0';
1266 x509_fingerprint (buf, sizeof (buf), cert, EVP_sha1);
1267 mutt_buffer_printf (drow, _("SHA1 Fingerprint: %s"), buf);
1268 mutt_menu_add_dialog_row (menu, mutt_b2s (drow));
1269 buf[0] = '\0';
1270 buf[40] = '\0'; /* Ensure the second printed line is null terminated */
1271 x509_fingerprint (buf, sizeof (buf), cert, EVP_sha256);
1272 buf[39] = '\0'; /* Divide into two lines of output */
1273 mutt_buffer_printf (drow, "%s%s", _("SHA256 Fingerprint: "), buf);
1274 mutt_menu_add_dialog_row (menu, mutt_b2s (drow));
1275 mutt_buffer_printf (drow, "%*s%s",
1276 (int)mutt_strlen (_("SHA256 Fingerprint: ")), "", buf + 40);
1277 mutt_menu_add_dialog_row (menu, mutt_b2s (drow));
1278
1279 snprintf (title, sizeof (title),
1280 _("SSL Certificate check (certificate %d of %d in chain)"),
1281 len - idx, len);
1282 menu->title = title;
1283
1284 /* The leaf/host certificate can't be skipped. */
1285#ifdef HAVE_SSL_PARTIAL_CHAIN
1286 if ((idx != 0) &&
1287 (option (OPTSSLVERIFYPARTIAL)))
1288 allow_skip = 1;
1289#endif
1290
1291 /* Inside ssl_verify_callback(), this function is guarded by a call to
1292 * check_certificate_by_digest(). This means if check_certificate_expiration() is
1293 * true, then check_certificate_file() must be false. Therefore we don't need
1294 * to also scan the certificate file here.
1295 */
1296 allow_always = allow_always &&
1297 SslCertFile &&
1298 check_certificate_expiration (cert, 1);
1299
1300 /* L10N:
1301 * These four letters correspond to the choices in the next four strings:
1302 * (r)eject, accept (o)nce, (a)ccept always, (s)kip.
1303 * These prompts are the interactive certificate confirmation prompts for
1304 * an OpenSSL connection.
1305 */
1306 menu->keys = _("roas");
1307 if (allow_always)
1308 {
1309 if (allow_skip)
1310 menu->prompt = _("(r)eject, accept (o)nce, (a)ccept always, (s)kip");
1311 else
1312 menu->prompt = _("(r)eject, accept (o)nce, (a)ccept always");
1313 }
1314 else
1315 {
1316 if (allow_skip)
1317 menu->prompt = _("(r)eject, accept (o)nce, (s)kip");
1318 else
1319 menu->prompt = _("(r)eject, accept (o)nce");
1320 }
1321
1322 helpstr[0] = '\0';
1323 mutt_make_help (buf, sizeof (buf), _("Exit "), MENU_GENERIC, OP_EXIT);
1324 safe_strcat (helpstr, sizeof (helpstr), buf);
1325 mutt_make_help (buf, sizeof (buf), _("Help"), MENU_GENERIC, OP_HELP);
1326 safe_strcat (helpstr, sizeof (helpstr), buf);
1327 menu->help = helpstr;
1328
1329 done = 0;
1330
1331 if (!option (OPTIGNOREMACROEVENTS))
1332 {
1333 set_option (OPTIGNOREMACROEVENTS);
1334 reset_ignoremacro = 1;
1335 }
1336 while (!done)
1337 {
1338 switch (mutt_menuLoop (menu))
1339 {
1340 case -1: /* abort */
1341 case OP_MAX + 1: /* reject */
1342 case OP_EXIT:
1343 done = 1;
1344 break;
1345 case OP_MAX + 3: /* accept always */
1346 if (!allow_always)
1347 break;
1348 done = 0;
1349 if ((fp = fopen (SslCertFile, "a")))
1350 {
1351 if (PEM_write_X509 (fp, cert))
1352 done = 1;
1353 safe_fclose (&fp);
1354 }
1355 if (!done)
1356 {
1357 mutt_error (_("Warning: Couldn't save certificate"));
1358 mutt_sleep (2);
1359 }
1360 else
1361 {
1362 mutt_message (_("Certificate saved"));
1363 mutt_sleep (0);
1364 }
1365 /* fall through */
1366 case OP_MAX + 2: /* accept once */
1367 done = 2;
1368 SSL_set_ex_data (ssl, SkipModeExDataIndex, NULL);
1369 ssl_cache_trusted_cert (cert);
1370 break;
1371 case OP_MAX + 4: /* skip */
1372 if (!allow_skip)
1373 break;
1374 done = 2;
1375 SSL_set_ex_data (ssl, SkipModeExDataIndex, &SkipModeExDataIndex);
1376 break;
1377 }
1378 }
1379 if (reset_ignoremacro)
1380 unset_option (OPTIGNOREMACROEVENTS);
1381
1382 mutt_buffer_pool_release (&drow);
1383 mutt_pop_current_menu (menu);
1384 mutt_menuDestroy (&menu);
1385 dprint (2, (debugfile, "ssl interactive_check_cert: done=%d\n", done));
1386 return (done == 2);
1387}
1388
1389static void ssl_get_client_cert(sslsockdata *ssldata, CONNECTION *conn)
1390{
1391 if (SslClientCert)
1392 {
1393 dprint (2, (debugfile, "Using client certificate %s\n", SslClientCert));
1394 SSL_CTX_set_default_passwd_cb_userdata(ssldata->ctx, &conn->account);
1395 SSL_CTX_set_default_passwd_cb(ssldata->ctx, ssl_passwd_cb);
1396 SSL_CTX_use_certificate_file(ssldata->ctx, SslClientCert, SSL_FILETYPE_PEM);
1397 SSL_CTX_use_PrivateKey_file(ssldata->ctx, SslClientCert, SSL_FILETYPE_PEM);
1398
1399 /* if we are using a client cert, SASL may expect an external auth name */
1400 mutt_account_getuser (&conn->account);
1401 }
1402}
1403
1404static int ssl_passwd_cb(char *buf, int size, int rwflag, void *userdata)
1405{
1406 ACCOUNT *account = (ACCOUNT*)userdata;
1407
1408 if (mutt_account_getuser (account))
1409 return 0;
1410
1411 dprint (2, (debugfile, "ssl_passwd_cb: getting password for %s@%s:%u\n",
1412 account->user, account->host, account->port));
1413
1414 if (mutt_account_getpass (account))
1415 return 0;
1416
1417 return snprintf(buf, size, "%s", account->pass);
1418}