changeset: 6971:37209157e33c user: Kevin McCarthy <ke...@8t8.us> date: Sat Mar 18 13:48:02 2017 -0700 link: http://dev.mutt.org/hg/mutt/rev/37209157e33c
Pass envlist to filter children too. (closes #3922) The new setenv patch neglected to pass the envlist for filters too. Unfortunately, the filter code was already set up to pass COLUMNS to children, so it needed to be changed to add this to the envlist instead. Factor out mutt_envlist_set() from the parse_setenv() function, which the filter code can then use to set COLUMNS after forking. changeset: 6972:2b9c40f13e13 user: Kevin McCarthy <ke...@8t8.us> date: Sat Mar 18 14:39:12 2017 -0700 link: http://dev.mutt.org/hg/mutt/rev/2b9c40f13e13 Fix mutt_envlist_set() for the case that envlist is null. (see #3922) changeset: 6973:741865dfc052 user: Kevin McCarthy <ke...@8t8.us> date: Sat Mar 18 14:47:42 2017 -0700 link: http://dev.mutt.org/hg/mutt/rev/741865dfc052 merge stable diffs (truncated from 1102 to 950 lines): diff -r f0e3b2875065 -r 741865dfc052 browser.c --- a/browser.c Sun Mar 05 15:24:45 2017 -0800 +++ b/browser.c Sat Mar 18 14:47:42 2017 -0700 @@ -492,17 +492,20 @@ tmp->msg_unread = Context->unread; } + strfcpy (buffer, NONULL (tmp->path), sizeof (buffer)); + mutt_pretty_mailbox (buffer, sizeof (buffer)); + #ifdef USE_IMAP if (mx_is_imap (tmp->path)) { - add_folder (menu, state, tmp->path, NULL, tmp); + add_folder (menu, state, buffer, NULL, tmp); continue; } #endif #ifdef USE_POP if (mx_is_pop (tmp->path)) { - add_folder (menu, state, tmp->path, NULL, tmp); + add_folder (menu, state, buffer, NULL, tmp); continue; } #endif @@ -528,9 +531,6 @@ s.st_mtime = st2.st_mtime; } - strfcpy (buffer, NONULL(tmp->path), sizeof (buffer)); - mutt_pretty_mailbox (buffer, sizeof (buffer)); - add_folder (menu, state, buffer, &s, tmp); } while ((tmp = tmp->next)); diff -r f0e3b2875065 -r 741865dfc052 configure.ac --- a/configure.ac Sun Mar 05 15:24:45 2017 -0800 +++ b/configure.ac Sat Mar 18 14:47:42 2017 -0700 @@ -710,6 +710,11 @@ AC_CHECK_DECLS([SSL_set_mode, SSL_MODE_AUTO_RETRY],, AC_MSG_ERROR([Unable to find decent SSL header]), [[#include <openssl/ssl.h>]]) + AC_CHECK_DECL([X509_V_FLAG_PARTIAL_CHAIN], + AC_DEFINE(HAVE_SSL_PARTIAL_CHAIN,1,[ Define if OpenSSL supports partial chains. ]), + , + [[#include <openssl/x509_vfy.h>]]) + AC_DEFINE(USE_SSL,1,[ Define if you want support for SSL. ]) AC_DEFINE(USE_SSL_OPENSSL,1,[ Define if you want support for SSL via OpenSSL. ]) LIBS="$saved_LIBS" diff -r f0e3b2875065 -r 741865dfc052 doc/makedoc-defs.h --- a/doc/makedoc-defs.h Sun Mar 05 15:24:45 2017 -0800 +++ b/doc/makedoc-defs.h Sat Mar 18 14:47:42 2017 -0700 @@ -19,6 +19,9 @@ # ifndef USE_SSL_OPENSSL # define USE_SSL_OPENSSL # endif +# ifndef HAVE_SSL_PARTIAL_CHAIN +# define HAVE_SSL_PARTIAL_CHAIN +# endif # ifndef USE_SSL_GNUTLS # define USE_SSL_GNUTLS # endif diff -r f0e3b2875065 -r 741865dfc052 filter.c --- a/filter.c Sun Mar 05 15:24:45 2017 -0800 +++ b/filter.c Sat Mar 18 14:47:42 2017 -0700 @@ -122,10 +122,10 @@ if (MuttIndexWindow && (MuttIndexWindow->cols > 0)) { snprintf (columns, sizeof (columns), "%d", MuttIndexWindow->cols); - setenv ("COLUMNS", columns, 1); + mutt_envlist_set ("COLUMNS", columns); } - execl (EXECSHELL, "sh", "-c", cmd, NULL); + execle (EXECSHELL, "sh", "-c", cmd, NULL, mutt_envlist ()); _exit (127); } else if (thepid == -1) diff -r f0e3b2875065 -r 741865dfc052 init.c --- a/init.c Sun Mar 05 15:24:45 2017 -0800 +++ b/init.c Sat Mar 18 14:47:42 2017 -0700 @@ -1845,11 +1845,56 @@ return rc; } +char **mutt_envlist (void) +{ + return envlist; +} + +/* Helper function for parse_setenv(). + * It's broken out because some other parts of mutt (filter.c) need + * to set/overwrite environment variables in envlist before execing. + */ +void mutt_envlist_set (const char *name, const char *value) +{ + char **envp = envlist; + char work[LONG_STRING]; + int count, len; + + len = mutt_strlen (name); + + /* Look for current slot to overwrite */ + count = 0; + while (envp && *envp) + { + if (!mutt_strncmp (name, *envp, len) && (*envp)[len] == '=') + { + FREE (envp); /* __FREE_CHECKED__ */ + break; + } + envp++; + count++; + } + + /* Format var=value string */ + snprintf (work, sizeof(work), "%s=%s", NONULL (name), NONULL (value)); + + /* If slot found, overwrite */ + if (envp && *envp) + *envp = safe_strdup (work); + + /* If not found, add new slot */ + else + { + safe_realloc (&envlist, sizeof(char *) * (count + 2)); + envlist[count] = safe_strdup (work); + envlist[count + 1] = NULL; + } +} + static int parse_setenv(BUFFER *tmp, BUFFER *s, unsigned long data, BUFFER *err) { int query, unset, len; - char work[LONG_STRING]; - char **save, **envp = envlist; + char *name, **save, **envp = envlist; int count = 0; query = 0; @@ -1924,6 +1969,8 @@ return -1; } + /* set variable */ + if (*s->dptr == '=') { s->dptr++; @@ -1936,38 +1983,10 @@ return -1; } - /* Look for current slot to overwrite */ - count = 0; - while (envp && *envp) - { - if (!mutt_strncmp (tmp->data, *envp, len) && (*envp)[len] == '=') - { - FREE (envp); /* __FREE_CHECKED__ */ - break; - } - envp++; - count++; - } - - /* Format var=value string */ - strfcpy (work, tmp->data, sizeof(work)); - len = strlen (work); - work[len++] = '='; + name = safe_strdup (tmp->data); mutt_extract_token (tmp, s, 0); - strfcpy (&work[len], tmp->data, sizeof(work)-len); - - /* If slot found, overwrite */ - if (*envp) - *envp = safe_strdup (work); - - /* If not found, add new slot */ - else - { - *envp = safe_strdup (work); - count++; - safe_realloc (&envlist, sizeof(char *) * (count + 1)); - envlist[count] = NULL; - } + mutt_envlist_set (name, tmp->data); + FREE (&name); return 0; } diff -r f0e3b2875065 -r 741865dfc052 init.h --- a/init.h Sun Mar 05 15:24:45 2017 -0800 +++ b/init.h Sat Mar 18 14:47:42 2017 -0700 @@ -78,7 +78,6 @@ }; #define UL (unsigned long) - #endif /* _MAKEDOC */ #ifndef ISPELL @@ -3377,6 +3376,24 @@ ** URL. You should only unset this for particular known hosts, using ** the \fC$<account-hook>\fP function. */ +# ifdef USE_SSL_OPENSSL +# ifdef HAVE_SSL_PARTIAL_CHAIN + { "ssl_verify_partial_chains", DT_BOOL, R_NONE, OPTSSLVERIFYPARTIAL, 0 }, + /* + ** .pp + ** This option should not be changed from the default unless you understand + ** what you are doing. + ** .pp + ** Setting this variable to \fIyes\fP will permit verifying partial + ** certification chains, i. e. a certificate chain where not the root, + ** but an intermediate certificate CA, or the host certificate, are + ** marked trusted (in $$certificate_file), without marking the root + ** signing CA as trusted. + ** .pp + ** (OpenSSL 1.0.2b and newer only). + */ +# endif /* defined HAVE_SSL_PARTIAL_CHAIN */ +# endif /* defined USE_SSL_OPENSSL */ { "ssl_ciphers", DT_STR, R_NONE, UL &SslCiphers, UL 0 }, /* ** .pp diff -r f0e3b2875065 -r 741865dfc052 main.c --- a/main.c Sun Mar 05 15:24:45 2017 -0800 +++ b/main.c Sat Mar 18 14:47:42 2017 -0700 @@ -163,9 +163,9 @@ exit (0); } -extern const char cc_version[]; -extern const char cc_cflags[]; -extern const char configure_options[]; +extern unsigned char cc_version[]; +extern unsigned char cc_cflags[]; +extern unsigned char configure_options[]; static char * rstrip_in_place(char *s) @@ -222,13 +222,13 @@ puts ("\n\nCompiler:"); rstrip_in_place((char *)cc_version); - puts (cc_version); + puts ((char *)cc_version); rstrip_in_place((char *)configure_options); - printf ("\nConfigure options: %s\n", configure_options); + printf ("\nConfigure options: %s\n", (char *)configure_options); rstrip_in_place((char *)cc_cflags); - printf ("\nCompilation CFLAGS: %s\n", cc_cflags); + printf ("\nCompilation CFLAGS: %s\n", (char *)cc_cflags); puts (_("\nCompile options:")); diff -r f0e3b2875065 -r 741865dfc052 mutt.h --- a/mutt.h Sun Mar 05 15:24:45 2017 -0800 +++ b/mutt.h Sat Mar 18 14:47:42 2017 -0700 @@ -396,6 +396,9 @@ OPTSSLFORCETLS, OPTSSLVERIFYDATES, OPTSSLVERIFYHOST, +# if defined(USE_SSL_OPENSSL) && defined(HAVE_SSL_PARTIAL_CHAIN) + OPTSSLVERIFYPARTIAL, +# endif /* USE_SSL_OPENSSL */ #endif /* defined(USE_SSL) */ OPTIMPLICITAUTOVIEW, OPTINCLUDEONLYFIRST, diff -r f0e3b2875065 -r 741865dfc052 mutt_ssl.c --- a/mutt_ssl.c Sun Mar 05 15:24:45 2017 -0800 +++ b/mutt_ssl.c Sat Mar 18 14:47:42 2017 -0700 @@ -23,6 +23,7 @@ #include <openssl/ssl.h> #include <openssl/x509.h> #include <openssl/x509v3.h> +#include <openssl/x509_vfy.h> #include <openssl/err.h> #include <openssl/rand.h> #include <openssl/evp.h> @@ -57,6 +58,12 @@ /* index for storing hostname as application specific data in SSL structure */ static int HostExDataIndex = -1; + +/* Index for storing the "skip mode" state in SSL structure. When the + * user skips a certificate in the chain, the stored value will be + * non-null. */ +static int SkipModeExDataIndex = -1; + /* keep a handle on accepted certificates in case we want to * open up another connection to the same server in this session */ static STACK_OF(X509) *SslSessionCerts = NULL; @@ -82,7 +89,7 @@ static void ssl_dprint_err_stack (void); static int ssl_cache_trusted_cert (X509 *cert); static int ssl_verify_callback (int preverify_ok, X509_STORE_CTX *ctx); -static int interactive_check_cert (X509 *cert, int idx, int len); +static int interactive_check_cert (X509 *cert, int idx, int len, SSL *ssl, int allow_always); static void ssl_get_client_cert(sslsockdata *ssldata, CONNECTION *conn); static int ssl_passwd_cb(char *buf, int size, int rwflag, void *userdata); static int ssl_negotiate (CONNECTION *conn, sslsockdata*); @@ -136,6 +143,35 @@ return rv; } +static int ssl_set_verify_partial (SSL_CTX *ctx) +{ + int rv = 0; +#ifdef HAVE_SSL_PARTIAL_CHAIN + X509_VERIFY_PARAM *param; + + if (option (OPTSSLVERIFYPARTIAL)) + { + param = X509_VERIFY_PARAM_new(); + if (param) + { + X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_PARTIAL_CHAIN); + if (0 == SSL_CTX_set1_param(ctx, param)) + { + dprint (2, (debugfile, "ssl_set_verify_partial: SSL_CTX_set1_param() failed.")); + rv = -1; + } + X509_VERIFY_PARAM_free(param); + } + else + { + dprint (2, (debugfile, "ssl_set_verify_partial: X509_VERIFY_PARAM_new() failed.")); + rv = -1; + } + } +#endif + return rv; +} + /* mutt_ssl_starttls: Negotiate TLS over an already opened connection. * TODO: Merge this code better with ssl_socket_open. */ int mutt_ssl_starttls (CONNECTION* conn) @@ -206,6 +242,12 @@ } } + if (ssl_set_verify_partial (ssldata->ctx)) + { + mutt_error (_("Warning: error enabling ssl_verify_partial_chains")); + mutt_sleep (2); + } + if (! (ssldata->ssl = SSL_new (ssldata->ctx))) { dprint (1, (debugfile, "mutt_ssl_starttls: Error allocating SSL\n")); @@ -453,6 +495,12 @@ SSL_CTX_set_cipher_list (data->ctx, SslCiphers); } + if (ssl_set_verify_partial (data->ctx)) + { + mutt_error (_("Warning: error enabling ssl_verify_partial_chains")); + mutt_sleep (2); + } + data->ssl = SSL_new (data->ctx); SSL_set_fd (data->ssl, conn->fd); @@ -489,8 +537,30 @@ return -1; } + if ((SkipModeExDataIndex = SSL_get_ex_new_index (0, "skip", NULL, NULL, NULL)) == -1) + { + dprint (1, (debugfile, "failed to get index for application specific data\n")); + return -1; + } + + if (! SSL_set_ex_data (ssldata->ssl, SkipModeExDataIndex, NULL)) + { + dprint (1, (debugfile, "failed to save skip mode in SSL structure\n")); + return -1; + } + SSL_set_verify (ssldata->ssl, SSL_VERIFY_PEER, ssl_verify_callback); SSL_set_mode (ssldata->ssl, SSL_MODE_AUTO_RETRY); + + if (!SSL_set_tlsext_host_name (ssldata->ssl, conn->account.host)) + { + /* L10N: This is a warning when trying to set the host name for + * TLS Server Name Indication (SNI). This allows the server to present + * the correct certificate if it supports multiple hosts. */ + mutt_error _("Warning: unable to set TLS SNI host name"); + mutt_sleep (1); + } + ERR_clear_error (); if ((err = SSL_connect (ssldata->ssl)) != 1) @@ -701,7 +771,7 @@ X509_issuer_name_cmp (cert, peercert) != 0) return -1; - if (!X509_digest (cert, EVP_sha1(), md, &mdlen) || peermdlen != mdlen) + if (!X509_digest (cert, EVP_sha256(), md, &mdlen) || peermdlen != mdlen) return -1; if (memcmp(peermd, md, mdlen) != 0) @@ -717,7 +787,7 @@ X509 *cert; int i; - if (!X509_digest (peercert, EVP_sha1(), peermd, &peermdlen) + if (!X509_digest (peercert, EVP_sha256(), peermd, &peermdlen) || !SslSessionCerts) { return 0; @@ -735,7 +805,36 @@ return 0; } -static int check_certificate_by_digest (X509 *peercert) +static int check_certificate_expiration (X509 *peercert, int silent) +{ + if (option (OPTSSLVERIFYDATES) != MUTT_NO) + { + if (X509_cmp_current_time (X509_get_notBefore (peercert)) >= 0) + { + if (!silent) + { + dprint (2, (debugfile, "Server certificate is not yet valid\n")); + mutt_error (_("Server certificate is not yet valid")); + mutt_sleep (2); + } + return 0; + } + if (X509_cmp_current_time (X509_get_notAfter (peercert)) <= 0) + { + if (!silent) + { + dprint (2, (debugfile, "Server certificate has expired\n")); + mutt_error (_("Server certificate has expired")); + mutt_sleep (2); + } + return 0; + } + } + + return 1; +} + +static int check_certificate_file (X509 *peercert) { unsigned char peermd[EVP_MAX_MD_SIZE]; unsigned int peermdlen; @@ -743,29 +842,13 @@ int pass = 0; FILE *fp; - /* expiration check */ - if (option (OPTSSLVERIFYDATES) != MUTT_NO) - { - if (X509_cmp_current_time (X509_get_notBefore (peercert)) >= 0) - { - dprint (2, (debugfile, "Server certificate is not yet valid\n")); - mutt_error (_("Server certificate is not yet valid")); - mutt_sleep (2); - return 0; - } - if (X509_cmp_current_time (X509_get_notAfter (peercert)) <= 0) - { - dprint (2, (debugfile, "Server certificate has expired\n")); - mutt_error (_("Server certificate has expired")); - mutt_sleep (2); - return 0; - } - } + if (!SslCertFile) + return 0; if ((fp = fopen (SslCertFile, "rt")) == NULL) return 0; - if (!X509_digest (peercert, EVP_sha1(), peermd, &peermdlen)) + if (!X509_digest (peercert, EVP_sha256(), peermd, &peermdlen)) { safe_fclose (&fp); return 0; @@ -773,10 +856,12 @@ while (PEM_read_X509 (fp, &cert, NULL, NULL) != NULL) { - pass = compare_certificates (cert, peercert, peermd, peermdlen) ? 0 : 1; - - if (pass) + if ((compare_certificates (cert, peercert, peermd, peermdlen) == 0) && + check_certificate_expiration (cert, 1)) + { + pass = 1; break; + } } /* PEM_read_X509 sets an error on eof */ if (!pass) @@ -787,6 +872,12 @@ return pass; } +static int check_certificate_by_digest (X509 *peercert) +{ + return check_certificate_expiration (peercert, 0) && + check_certificate_file (peercert); +} + /* port to mutt from msmtp's tls.c */ static int hostname_match (const char *hostname, const char *certname) { @@ -947,6 +1038,13 @@ int len, pos; X509 *cert; SSL *ssl; + int skip_mode; +#ifdef HAVE_SSL_PARTIAL_CHAIN + static int last_pos = 0; + static X509 *last_cert = NULL; + unsigned char last_cert_md[EVP_MAX_MD_SIZE]; + unsigned int last_cert_mdlen; +#endif if (! (ssl = X509_STORE_CTX_get_ex_data (ctx, SSL_get_ex_data_X509_STORE_CTX_idx ()))) { @@ -959,18 +1057,53 @@ return 0; } + /* This is true when a previous entry in the certificate chain did + * not verify and the user manually chose to skip it via the + * $ssl_verify_partial_chains option. + * In this case, all following certificates need to be treated as non-verified + * until one is actually verified. + */ + skip_mode = (SSL_get_ex_data (ssl, SkipModeExDataIndex) != NULL); + cert = X509_STORE_CTX_get_current_cert (ctx); pos = X509_STORE_CTX_get_error_depth (ctx); len = sk_X509_num (X509_STORE_CTX_get_chain (ctx)); - dprint (1, (debugfile, "ssl_verify_callback: checking cert chain entry %s (preverify: %d)\n", - X509_NAME_oneline (X509_get_subject_name (cert), - buf, sizeof (buf)), preverify_ok)); + dprint (1, (debugfile, + "ssl_verify_callback: checking cert chain entry %s (preverify: %d skipmode: %d)\n", + X509_NAME_oneline (X509_get_subject_name (cert), buf, sizeof (buf)), + preverify_ok, skip_mode)); + +#ifdef HAVE_SSL_PARTIAL_CHAIN + /* Sometimes, when a certificate is (s)kipped, OpenSSL will pass it + * a second time with preverify_ok = 1. Don't show it or the user + * will think their "s" key is broken. + */ + if (option (OPTSSLVERIFYPARTIAL)) + { + if (skip_mode && preverify_ok && (pos == last_pos) && last_cert) + { + if (X509_digest (last_cert, EVP_sha256(), last_cert_md, &last_cert_mdlen) && + !compare_certificates (cert, last_cert, last_cert_md, last_cert_mdlen)) + { + dprint (2, (debugfile, + "ssl_verify_callback: ignoring duplicate skipped certificate.\n")); + return 1; + } + } + + last_pos = pos; + if (last_cert) + X509_free (last_cert); + last_cert = X509_dup (cert); + } +#endif /* check session cache first */ if (check_certificate_cache (cert)) { dprint (2, (debugfile, "ssl_verify_callback: using cached certificate\n")); + SSL_set_ex_data (ssl, SkipModeExDataIndex, NULL); return 1; } @@ -982,17 +1115,20 @@ { mutt_error (_("Certificate host check failed: %s"), buf); mutt_sleep (2); - return interactive_check_cert (cert, pos, len); + /* we disallow (a)ccept always in the prompt, because it will have no effect + * for hostname mismatches. */ + return interactive_check_cert (cert, pos, len, ssl, 0); } dprint (2, (debugfile, "ssl_verify_callback: hostname check passed\n")); } - if (!preverify_ok) + if (!preverify_ok || skip_mode) { /* automatic check from user's database */ if (SslCertFile && check_certificate_by_digest (cert)) { dprint (2, (debugfile, "ssl_verify_callback: digest check passed\n")); + SSL_set_ex_data (ssl, SkipModeExDataIndex, NULL); return 1; } @@ -1006,14 +1142,14 @@ } #endif - /* prompt user */ - return interactive_check_cert (cert, pos, len); + /* prompt user */ + return interactive_check_cert (cert, pos, len, ssl, 1); } return 1; } -static int interactive_check_cert (X509 *cert, int idx, int len) +static int interactive_check_cert (X509 *cert, int idx, int len, SSL *ssl, int allow_always) { static const int part[] = { NID_commonName, /* CN */ @@ -1032,6 +1168,7 @@ int done, row, i; unsigned u; FILE *fp; + int allow_skip = 0; menu->max = mutt_array_size (part) * 2 + 10; menu->dialog = (char **) safe_calloc (1, menu->max * sizeof (char *)); @@ -1073,18 +1210,43 @@ _("SSL Certificate check (certificate %d of %d in chain)"), len - idx, len); menu->title = title; - if (SslCertFile - && (option (OPTSSLVERIFYDATES) == MUTT_NO - || (X509_cmp_current_time (X509_get_notAfter (cert)) >= 0 - && X509_cmp_current_time (X509_get_notBefore (cert)) < 0))) + + /* The leaf/host certificate can't be skipped. */ +#ifdef HAVE_SSL_PARTIAL_CHAIN + if ((idx != 0) && + (option (OPTSSLVERIFYPARTIAL))) + allow_skip = 1; +#endif + + /* Inside ssl_verify_callback(), this function is guarded by a call to + * check_certificate_by_digest(). This means if check_certificate_expiration() is + * true, then check_certificate_file() must be false. Therefore we don't need + * to also scan the certificate file here. + */ + allow_always = allow_always && + SslCertFile && + check_certificate_expiration (cert, 1); + + /* L10N: + * These four letters correspond to the choices in the next four strings: + * (r)eject, accept (o)nce, (a)ccept always, (s)kip. + * These prompts are the interactive certificate confirmation prompts for + * an OpenSSL connection. + */ + menu->keys = _("roas"); + if (allow_always) { - menu->prompt = _("(r)eject, accept (o)nce, (a)ccept always"); - menu->keys = _("roa"); + if (allow_skip) + menu->prompt = _("(r)eject, accept (o)nce, (a)ccept always, (s)kip"); + else + menu->prompt = _("(r)eject, accept (o)nce, (a)ccept always"); } else { - menu->prompt = _("(r)eject, accept (o)nce"); - menu->keys = _("ro"); + if (allow_skip) + menu->prompt = _("(r)eject, accept (o)nce, (s)kip"); + else + menu->prompt = _("(r)eject, accept (o)nce"); } helpstr[0] = '\0'; @@ -1106,6 +1268,8 @@ done = 1; break; case OP_MAX + 3: /* accept always */ + if (!allow_always) + break; done = 0; if ((fp = fopen (SslCertFile, "a"))) { @@ -1126,8 +1290,15 @@ /* fall through */ case OP_MAX + 2: /* accept once */ done = 2; + SSL_set_ex_data (ssl, SkipModeExDataIndex, NULL); ssl_cache_trusted_cert (cert); break; + case OP_MAX + 4: /* skip */ + if (!allow_skip) + break; + done = 2; + SSL_set_ex_data (ssl, SkipModeExDataIndex, &SkipModeExDataIndex); + break; } } unset_option(OPTIGNOREMACROEVENTS); diff -r f0e3b2875065 -r 741865dfc052 mutt_ssl_gnutls.c --- a/mutt_ssl_gnutls.c Sun Mar 05 15:24:45 2017 -0800 +++ b/mutt_ssl_gnutls.c Sat Mar 18 14:47:42 2017 -0700 @@ -417,6 +417,13 @@ /* set socket */ gnutls_transport_set_ptr (data->state, (gnutls_transport_ptr_t)(long)conn->fd); + if (gnutls_server_name_set (data->state, GNUTLS_NAME_DNS, conn->account.host, + mutt_strlen (conn->account.host))) + { + mutt_error _("Warning: unable to set TLS SNI host name"); + mutt_sleep (1); + } + if (tls_set_priority(data) < 0) { goto fail; } diff -r f0e3b2875065 -r 741865dfc052 po/fr.po --- a/po/fr.po Sun Mar 05 15:24:45 2017 -0800 +++ b/po/fr.po Sat Mar 18 14:47:42 2017 -0700 @@ -1,6 +1,6 @@ # French messages for Mutt. -# Copyright (C) 1998-2016 Marc Baudoin <baba...@babafou.eu.org>, Vincent Lefevre <vinc...@vinc17.net> -# Marc Baudoin <baba...@babafou.eu.org>, Vincent Lefevre <vinc...@vinc17.net>, 1998-2016 +# Copyright (C) 1998-2017 Marc Baudoin <baba...@babafou.eu.org>, Vincent Lefevre <vinc...@vinc17.net> +# Marc Baudoin <baba...@babafou.eu.org>, Vincent Lefevre <vinc...@vinc17.net>, 1998-2017 # # Note [VL]. In case you need it, you may find the latest temporary version # at this URL: https://www.vinc17.net/mutt/fr.po @@ -19,10 +19,10 @@ # , fuzzy msgid "" msgstr "" -"Project-Id-Version: Mutt 1.7.1\n" +"Project-Id-Version: Mutt 1.8.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-02-24 10:48-0800\n" -"PO-Revision-Date: 2017-02-10 12:46+0100\n" +"POT-Creation-Date: 2017-03-13 01:22+0100\n" +"PO-Revision-Date: 2017-03-13 01:36+0100\n" "Last-Translator: Vincent Lefevre <vinc...@vinc17.net>\n" "Language-Team: Vincent Lefevre <vinc...@vinc17.net>\n" "Language: fr\n" @@ -59,7 +59,7 @@ msgstr "Sélectionner" #: addrbook.c:41 browser.c:49 compose.c:96 crypt-gpgme.c:4026 curs_main.c:493 -#: mutt_ssl.c:1082 mutt_ssl_gnutls.c:1003 pager.c:1663 pgpkey.c:522 +#: mutt_ssl.c:1255 mutt_ssl_gnutls.c:1010 pager.c:1663 pgpkey.c:522 #: postpone.c:44 query.c:53 recvattach.c:57 smime.c:440 msgid "Help" msgstr "Aide" @@ -1361,7 +1361,7 @@ msgid "All matching keys are marked expired/revoked." msgstr "Toutes les clés correspondantes sont marquées expirées/révoquées." -#: crypt-gpgme.c:4018 mutt_ssl.c:1080 mutt_ssl_gnutls.c:1001 pgpkey.c:515 +#: crypt-gpgme.c:4018 mutt_ssl.c:1253 mutt_ssl_gnutls.c:1008 pgpkey.c:515 #: smime.c:435 msgid "Exit " msgstr "Quitter " @@ -1664,7 +1664,7 @@ msgid "Exit Mutt?" msgstr "Quitter Mutt ?" -#: curs_lib.c:676 mutt_socket.c:577 mutt_ssl.c:500 +#: curs_lib.c:676 mutt_socket.c:577 mutt_ssl.c:577 msgid "unknown error" msgstr "erreur inconnue" @@ -3336,21 +3336,25 @@ msgid "Could not connect to %s (%s)." msgstr "Impossible de se connecter à %s (%s)." -#: mutt_ssl.c:278 +#: mutt_ssl.c:247 mutt_ssl.c:500 +msgid "Warning: error enabling ssl_verify_partial_chains" +msgstr "Attention : erreur lors de l'activation de ssl_verify_partial_chains" + +#: mutt_ssl.c:326 msgid "Failed to find enough entropy on your system" msgstr "Impossible de trouver assez d'entropie sur votre système" -#: mutt_ssl.c:302 +#: mutt_ssl.c:350 #, c-format msgid "Filling entropy pool: %s...\n" msgstr "Remplissage du tas d'entropie : %s...\n" -#: mutt_ssl.c:310 +#: mutt_ssl.c:358 #, c-format msgid "%s has insecure permissions!" msgstr "%s a des droits d'accès peu sûrs !" -#: mutt_ssl.c:329 +#: mutt_ssl.c:377 msgid "SSL disabled due to the lack of entropy" msgstr "SSL désactivé par manque d'entropie" @@ -3358,15 +3362,22 @@ #. * function SSL_CTX_new(). In this case it returned NULL: an #. * error condition. #. -#: mutt_ssl.c:396 +#: mutt_ssl.c:444 msgid "Unable to create SSL context" msgstr "Impossible de créer le contexte SSL" -#: mutt_ssl.c:494 +#. L10N: This is a warning when trying to set the host name for +#. * TLS Server Name Indication (SNI). This allows the server to present +#. * the correct certificate if it supports multiple hosts. +#: mutt_ssl.c:560 mutt_ssl_gnutls.c:423 +msgid "Warning: unable to set TLS SNI host name" +msgstr "Attention : impossible de fixer le nom d'hôte TLS SNI" + +#: mutt_ssl.c:571 msgid "I/O error" msgstr "erreur d'E/S" -#: mutt_ssl.c:503 +#: mutt_ssl.c:580 #, c-format msgid "SSL failed: %s" msgstr "SSL a échoué : %s" @@ -3376,111 +3387,121 @@ #. %1$s is version (e.g. "TLSv1.2") #. %2$s is cipher_version (e.g. "TLSv1/SSLv3") #. %3$s is cipher_name (e.g. "ECDHE-RSA-AES128-GCM-SHA256") -#: mutt_ssl.c:513 +#: mutt_ssl.c:590 #, c-format msgid "%s connection using %s (%s)" msgstr "Connexion %s utilisant %s (%s)" -#: mutt_ssl.c:640 +#: mutt_ssl.c:717 msgid "Unknown" msgstr "Inconnu" # , c-format -#: mutt_ssl.c:653 mutt_ssl_gnutls.c:598 +#: mutt_ssl.c:730 mutt_ssl_gnutls.c:605 #, c-format msgid "[unable to calculate]" msgstr "[impossible de calculer]" # , c-format -#: mutt_ssl.c:671 mutt_ssl_gnutls.c:621 +#: mutt_ssl.c:748 mutt_ssl_gnutls.c:628 msgid "[invalid date]" msgstr "[date invalide]" -#: mutt_ssl.c:745 +#: mutt_ssl.c:817 msgid "Server certificate is not yet valid" msgstr "Le certificat du serveur n'est pas encore valide" -#: mutt_ssl.c:752 +#: mutt_ssl.c:827 msgid "Server certificate has expired" msgstr "Le certificat du serveur a expiré" -#: mutt_ssl.c:874 +#: mutt_ssl.c:976 msgid "cannot get certificate subject" msgstr "impossible d'obtenir le détenteur du certificat (subject)" -#: mutt_ssl.c:884 mutt_ssl.c:893 +#: mutt_ssl.c:986 mutt_ssl.c:995 msgid "cannot get certificate common name" msgstr "impossible d'obtenir le nom du détenteur du certificat (CN)" -#: mutt_ssl.c:907 +#: mutt_ssl.c:1009 #, c-format msgid "certificate owner does not match hostname %s" msgstr "le propriétaire du certificat ne correspond pas au nom %s" -#: mutt_ssl.c:972 +#: mutt_ssl.c:1116 #, c-format msgid "Certificate host check failed: %s" msgstr "Échec de vérification de machine : %s" -#: mutt_ssl.c:1031 mutt_ssl_gnutls.c:860 +#: mutt_ssl.c:1179 mutt_ssl_gnutls.c:867 msgid "This certificate belongs to:" msgstr "Ce certificat appartient à :" -#: mutt_ssl.c:1039 mutt_ssl_gnutls.c:899 +#: mutt_ssl.c:1187 mutt_ssl_gnutls.c:906 msgid "This certificate was issued by:" msgstr "Ce certificat a été émis par :" -#: mutt_ssl.c:1047 mutt_ssl_gnutls.c:938 +#: mutt_ssl.c:1195 mutt_ssl_gnutls.c:945 #, c-format msgid "This certificate is valid" msgstr "Ce certificat est valide" -#: mutt_ssl.c:1048 mutt_ssl_gnutls.c:941 +#: mutt_ssl.c:1196 mutt_ssl_gnutls.c:948 #, c-format msgid " from %s" msgstr " de %s" -#: mutt_ssl.c:1050 mutt_ssl_gnutls.c:945 +#: mutt_ssl.c:1198 mutt_ssl_gnutls.c:952 #, c-format msgid " to %s" msgstr " à %s" -#: mutt_ssl.c:1056 mutt_ssl_gnutls.c:950 +#: mutt_ssl.c:1204 mutt_ssl_gnutls.c:957 #, c-format msgid "SHA1 Fingerprint: %s" msgstr "Empreinte SHA1 : %s" -#: mutt_ssl.c:1059 mutt_ssl_gnutls.c:953 +#: mutt_ssl.c:1207 mutt_ssl_gnutls.c:960 #, c-format msgid "MD5 Fingerprint: %s" msgstr "Empreinte MD5 : %s" -#: mutt_ssl.c:1062 mutt_ssl_gnutls.c:982 +#: mutt_ssl.c:1210 mutt_ssl_gnutls.c:989 #, c-format msgid "SSL Certificate check (certificate %d of %d in chain)" msgstr "Vérification du certificat SSL (certificat %d sur %d dans la chaîne)" -#: mutt_ssl.c:1070 mutt_ssl_gnutls.c:991 +#. L10N: