X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=lib-sys%2Fmutt_ssl.cpkg;h=b1816c4d5bbc04265573210fbce4d37684a54704;hp=d2663581e1e51bd96553a69dfd7611c8fcb7fcf7;hb=98f62b5fcbd680fd5214ee85e1635b84322cbdd1;hpb=3bb9d26e7eb111656d716e34d81225dfb16b6c4b diff --git a/lib-sys/mutt_ssl.cpkg b/lib-sys/mutt_ssl.cpkg index d266358..b1816c4 100644 --- a/lib-sys/mutt_ssl.cpkg +++ b/lib-sys/mutt_ssl.cpkg @@ -12,16 +12,59 @@ #include #include -#ifdef HAVE_GNUTLS_OPENSSL_H -#include -#endif -#include +#include #include #include "mutt.h" #include "mutt_socket.h" +@import "../lib-lua/base.cpkg" + +@package mod_ssl { + bool force_tls = 0; + /* + ** .pp + ** If this variable is \fIset\fP, Madmutt will require that all connections + ** to remote servers be encrypted. Furthermore it will attempt to + ** negotiate TLS even if the server does not advertise the capability, + ** since it would otherwise have to abort the connection anyway. This + ** option supersedes ``$$ssl_starttls''. + */ + bool use_sslv3 = 1; + /* + ** .pp + ** This variables specifies whether to attempt to use SSLv3 in the + ** SSL authentication process. + */ + + path_t cert_file = luaM_pathnew("~/.cache/madmutt/certificates"); + /* + ** .pp + ** This variable specifies the file where the certificates you trust + ** are saved. When an unknown certificate is encountered, you are asked + ** if you accept it or not. If you accept it, the certificate can also + ** be saved in this file and further connections are automatically + ** accepted. + ** .pp + ** You can also manually add CA certificates in this file. Any server + ** certificate that is signed with one of these CA certificates are + ** also automatically accepted. + ** .pp + ** Example: \fTset certificate_file=~/.madmutt/certificates\fP + */ + + path_t ca_certificates_file = NULL; + /* + ** .pp + ** This variable specifies a file containing trusted CA certificates. + ** Any server certificate that is signed with one of these CA + ** certificates are also automatically accepted. + ** .pp + ** Example: \fTset ssl_ca_certificates_file=/etc/ssl/certs/ca-certificates.crt\fP + */ +}; + typedef struct _tlssockdata { gnutls_session state; gnutls_certificate_credentials xcred; @@ -83,7 +126,7 @@ static int tls_socket_read (CONNECTION * conn, char *buf, ssize_t len) } ret = gnutls_record_recv (data->state, buf, len); - if (gnutls_error_is_fatal (ret) == 1) { + if (ret < 0 && gnutls_error_is_fatal (ret) == 1) { mutt_error (_("tls_socket_read (%s)"), gnutls_strerror (ret)); mutt_sleep (4); return -1; @@ -103,7 +146,7 @@ static int tls_socket_write (CONNECTION * conn, const char *buf, ssize_t len) } ret = gnutls_record_send (data->state, buf, len); - if (gnutls_error_is_fatal (ret) == 1) { + if (ret < 0 && gnutls_error_is_fatal (ret) == 1) { mutt_error (_("tls_socket_write (%s)"), gnutls_strerror (ret)); mutt_sleep (4); return -1; @@ -159,12 +202,13 @@ static int tls_negotiate (CONNECTION * conn) return -1; } - gnutls_certificate_set_x509_trust_file (data->xcred, SslCertFile, + gnutls_certificate_set_x509_trust_file (data->xcred, mod_ssl.cert_file, GNUTLS_X509_FMT_PEM); /* ignore errors, maybe file doesn't exist yet */ - if (SslCACertFile) { - gnutls_certificate_set_x509_trust_file (data->xcred, SslCACertFile, + if (mod_ssl.ca_certificates_file) { + gnutls_certificate_set_x509_trust_file (data->xcred, + mod_ssl.ca_certificates_file, GNUTLS_X509_FMT_PEM); } @@ -179,15 +223,7 @@ static int tls_negotiate (CONNECTION * conn) gnutls_transport_set_ptr (data->state, (gnutls_transport_ptr)(intptr_t)conn->fd); /* disable TLS/SSL protocols as needed */ - if (!option (OPTTLSV1) && !option (OPTSSLV3)) { - mutt_error (_("All available protocols for TLS/SSL connection disabled")); - goto fail; - } - else if (!option (OPTTLSV1)) { - protocol_priority[0] = GNUTLS_SSL3; - protocol_priority[1] = 0; - } - else if (!option (OPTSSLV3)) { + if (!mod_ssl.use_sslv3) { protocol_priority[0] = GNUTLS_TLS1; protocol_priority[1] = 0; } @@ -201,10 +237,6 @@ static int tls_negotiate (CONNECTION * conn) gnutls_set_default_priority (data->state); gnutls_protocol_set_priority (data->state, protocol_priority); - if (SslDHPrimeBits > 0) { - gnutls_dh_set_prime_bits (data->state, SslDHPrimeBits); - } - /* gnutls_set_cred (data->state, GNUTLS_ANON, NULL); */ @@ -293,7 +325,7 @@ static int tls_compare_certificates (const gnutls_datum * peercert) unsigned char *b64_data_data; struct stat filestat; - if (stat (SslCertFile, &filestat) == -1) + if (stat(mod_ssl.cert_file, &filestat) == -1) return 0; b64_data.size = filestat.st_size + 1; @@ -301,7 +333,7 @@ static int tls_compare_certificates (const gnutls_datum * peercert) b64_data_data[b64_data.size - 1] = '\0'; b64_data.data = b64_data_data; - fd1 = fopen (SslCertFile, "r"); + fd1 = fopen(mod_ssl.cert_file, "r"); if (fd1 == NULL) { return 0; } @@ -364,16 +396,18 @@ static void tls_fingerprint (gnutls_digest_algorithm algo, static char *tls_make_date (time_t t, char *s, ssize_t len) { - struct tm *l = gmtime (&t); - - if (l) - snprintf (s, len, "%s, %d %s %d %02d:%02d:%02d UTC", - Weekdays[l->tm_wday], l->tm_mday, Months[l->tm_mon], - l->tm_year + 1900, l->tm_hour, l->tm_min, l->tm_sec); - else - m_strcpy(s, len, _("[invalid date]")); + struct tm *l = gmtime(&t); + + if (l) { + const char *loc; + loc = setlocale(LC_TIME, "C"); + strftime(s, len, "%a, %d %b %Y %T UTC", l); + setlocale(LC_TIME, loc); + } else { + m_strcpy(s, len, _("[invalid date]")); + } - return (s); + return s; } static int tls_check_stored_hostname (const gnutls_datum * cert, @@ -388,7 +422,7 @@ static int tls_check_stored_hostname (const gnutls_datum * cert, regmatch_t pmatch[3]; /* try checking against names stored in stored certs file */ - if ((fp = fopen (SslCertFile, "r"))) { + if ((fp = fopen(mod_ssl.cert_file, "r"))) { if (regcomp (&preg, "^#H ([a-zA-Z0-9_\\.-]+) ([0-9A-F]{4}( [0-9A-F]{4}){7})[ \t]*$", @@ -428,8 +462,6 @@ static int tls_check_certificate (CONNECTION * conn) { tlssockdata *data = conn->sockdata; gnutls_session state = data->state; - char helpstr[STRING]; - char buf[STRING]; char fpbuf[STRING]; ssize_t buflen; char dn_common_name[STRING]; @@ -713,7 +745,7 @@ static int tls_check_certificate (CONNECTION * conn) menu->title = _("TLS/SSL Certificate check"); /* certificates with bad dates, or that are revoked, must be accepted manually each and every time */ - if (SslCertFile && !certerr_expired && !certerr_notyetvalid + if (mod_ssl.cert_file && !certerr_expired && !certerr_notyetvalid && !certerr_revoked) { menu->prompt = _("(r)eject, accept (o)nce, (a)ccept always"); menu->keys = _("roa"); @@ -723,13 +755,6 @@ static int tls_check_certificate (CONNECTION * conn) menu->keys = _("ro"); } - helpstr[0] = '\0'; - mutt_make_help (buf, sizeof (buf), _("Exit "), MENU_GENERIC, OP_EXIT); - strncat (helpstr, buf, sizeof (helpstr)); - mutt_make_help (buf, sizeof (buf), _("Help"), MENU_GENERIC, OP_HELP); - strncat (helpstr, buf, sizeof (helpstr)); - menu->help = helpstr; - done = 0; set_option (OPTUNBUFFEREDINPUT); while (!done) { @@ -741,7 +766,7 @@ static int tls_check_certificate (CONNECTION * conn) break; case OP_MAX + 3: /* accept always */ done = 0; - if ((fp = fopen (SslCertFile, "a"))) { + if ((fp = fopen(mod_ssl.cert_file, "a"))) { /* save hostname if necessary */ if (certerr_hostname) { fprintf (fp, "#H %s %s\n", conn->account.host, fpbuf); @@ -777,5 +802,7 @@ static int tls_check_certificate (CONNECTION * conn) unset_option (OPTUNBUFFEREDINPUT); mutt_menuDestroy (&menu); gnutls_x509_crt_deinit (cert); - return (done == 2); + return done == 2; } + +/* vim:set ft=c: */