summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEduardo Chappa <chappa@washington.edu>2019-02-17 19:17:46 -0700
committerEduardo Chappa <chappa@washington.edu>2019-02-17 19:17:46 -0700
commit08fcd1b86979b422eb586e56459d6fe15333e500 (patch)
tree27247d07d9c1063e2a2fc376155d675f54a4d4e4
parent35f3426203172af028df5a6e39bc6dea2514020d (diff)
downloadalpine-08fcd1b86979b422eb586e56459d6fe15333e500.tar.xz
* Rewrite support for specific SSL encryption protocols, including
a. Add a new variable: encryption-protocol-range, which can be used to specify the minimum and maximum versions of the TLS protocol that Alpine will attempt to use to encrypt its communication with the server. b. Add support for the Server Name Identification (SNI) extension needed for TLSv1.3. c. Remove the DTLS code. It was not being used.
-rw-r--r--alpine/alpine.c65
-rw-r--r--alpine/confscroll.c2
-rwxr-xr-xconfigure99
-rw-r--r--configure.ac64
-rw-r--r--imap/src/c-client/imap4r1.c6
-rw-r--r--imap/src/c-client/mail.c38
-rw-r--r--imap/src/c-client/mail.h12
-rw-r--r--imap/src/c-client/nntp.c8
-rw-r--r--imap/src/c-client/pop3.c2
-rw-r--r--imap/src/osdep/unix/ssl_unix.c168
-rw-r--r--include/config.h.in3
-rw-r--r--include/config.wnt.h3
-rw-r--r--pith/conf.c84
-rw-r--r--pith/conf.h3
-rw-r--r--pith/conftype.h1
-rw-r--r--pith/pine.hlp135
16 files changed, 520 insertions, 173 deletions
diff --git a/alpine/alpine.c b/alpine/alpine.c
index bbccb793..11f3354e 100644
--- a/alpine/alpine.c
+++ b/alpine/alpine.c
@@ -646,6 +646,71 @@ main(int argc, char **argv)
}
}
+ if(ps_global->VAR_ENCRYPTION_RANGE
+ && ps_global->VAR_ENCRYPTION_RANGE[0]){
+ char *min_s, *max_s, *s;
+ int min_v, max_v;
+
+ if((s = strchr(ps_global->VAR_ENCRYPTION_RANGE, ',')) == NULL){
+ snprintf(tmp_20k_buf, SIZEOF_20KBUF,
+ _("Bad encryption range: \"%s\": resetting to default"),
+ ps_global->VAR_ENCRYPTION_RANGE);
+ tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
+ init_error(ps_global, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
+ fs_give((void **) &ps_global->VAR_ENCRYPTION_RANGE);
+ ps_global->VAR_ENCRYPTION_RANGE = cpystr(DF_ENCRYPTION_RANGE);
+ s = strchr(ps_global->VAR_ENCRYPTION_RANGE, ','); /* try again */
+ }
+
+ if(s == NULL){
+ snprintf(tmp_20k_buf, SIZEOF_20KBUF,
+ _("Bad default encryption range: \"%s\""),
+ ps_global->VAR_ENCRYPTION_RANGE);
+ tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
+ init_error(ps_global, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
+ }
+ else {
+ *s = ' ';
+ get_pair(ps_global->VAR_ENCRYPTION_RANGE, &min_s, &max_s, 1, 0);
+ *s = ',';
+
+ min_v = pith_ssl_encryption_version(min_s);
+ max_v = pith_ssl_encryption_version(max_s);
+
+ if(min_v < 0 || max_v < 0){
+ snprintf(tmp_20k_buf, SIZEOF_20KBUF,
+ _("Bad encryption range: \"%s\": resetting to default"),
+ ps_global->VAR_ENCRYPTION_RANGE);
+ tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
+ init_error(ps_global, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
+ min_v = max_v = 0;
+ }
+
+ if(min_v > max_v){
+ int bubble;
+ snprintf(tmp_20k_buf, SIZEOF_20KBUF,
+ _("Minimum encryption protocol (%s) bigger than maximum value (%s). Reversing..."),
+ min_s, max_s);
+ tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
+ init_error(ps_global, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
+ bubble = min_v;
+ min_v = max_v;
+ max_v = bubble;
+ }
+
+ if(max_v > 0 && max_v < (long) pith_ssl_encryption_version("tls1")){
+ snprintf(tmp_20k_buf, SIZEOF_20KBUF,
+ _("Security alert: SSL maximum encryption version was set to SSLv3."),
+ ps_global->VAR_ENCRYPTION_RANGE);
+ tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';
+ init_error(ps_global, SM_ORDER | SM_DING, 3, 5, tmp_20k_buf);
+ }
+
+ mail_parameters(NULL, SET_ENCRYPTION_RANGE_MIN, (void *) &min_v);
+ mail_parameters(NULL, SET_ENCRYPTION_RANGE_MAX, (void *) &max_v);
+ }
+ }
+
/*
* setup alternative authentication driver preference for IMAP opens
*/
diff --git a/alpine/confscroll.c b/alpine/confscroll.c
index ff8841fe..98e5768b 100644
--- a/alpine/confscroll.c
+++ b/alpine/confscroll.c
@@ -341,6 +341,7 @@ exclude_config_var(struct pine *ps, struct variable *var, int allow_hard_to_conf
case V_GLOB_ADDRBOOK :
case V_DISABLE_DRIVERS :
case V_DISABLE_AUTHS :
+ case V_ENCRYPTION_RANGE :
case V_REMOTE_ABOOK_METADATA :
case V_REMOTE_ABOOK_HISTORY :
case V_REMOTE_ABOOK_VALIDITY :
@@ -5767,6 +5768,7 @@ fix_side_effects(struct pine *ps, struct variable *var, int revert)
var == &ps->vars[V_NEWS_SPEC] ||
var == &ps->vars[V_DISABLE_DRIVERS] ||
var == &ps->vars[V_DISABLE_AUTHS] ||
+ var == &ps->vars[V_ENCRYPTION_RANGE] ||
var == &ps->vars[V_RSHPATH] ||
var == &ps->vars[V_RSHCMD] ||
var == &ps->vars[V_SSHCMD] ||
diff --git a/configure b/configure
index 238a2ee9..0f34f07b 100755
--- a/configure
+++ b/configure
@@ -914,6 +914,9 @@ with_ssl_dir
with_ssl_certs_dir
with_ssl_include_dir
with_ssl_lib_dir
+with_encryption_minimum_version
+with_encryption_maximum_version
+with_encryption_range
with_krb5
with_krb5_dir
with_krb5_include_dir
@@ -1756,6 +1759,12 @@ Optional Packages:
--with-ssl-include-dir=DIR
SSL include file path
--with-ssl-lib-dir=DIR SSL library path
+ --encryption-minimum-version=VERSION
+ Minimum SSL encryption version. Default: no_min
+ --encryption-maximum-version=VERSION
+ Maximum SSL encryption version. Default: no_max
+ --with-encryption-range=VALUE
+ Default Encryption Range ($alpine_RANGE )
--without-krb5 Disable Kerberos support
--with-krb5-dir=DIR Root of Kerberos lib/include path
--with-krb5-include-dir=DIR
@@ -18213,6 +18222,96 @@ fi
fi
fi
+if test "x$alpine_SSLTYPE" != "xnone" ; then
+ alpine_default_SSLMIN="no_min"
+ alpine_default_SSLMAX="no_max"
+ alpine_default_RANGE="${alpine_default_SSLMIN},${alpine_default_SSLMAX}"
+ alpine_ENCRYPTION="$alpine_default_SSLMIN ssl3 tls1 tls1_1 tls1_2 tls1_3 $alpine_default_SSLMAX"
+ alpine_SSLMIN="$alpine_default_SSLMIN"
+ alpine_SSLMAX="$alpine_default_SSLMAX"
+ alpine_RANGE="$alpine_default_RANGE"
+
+# Check whether --with-encryption-minimum-version was given.
+if test "${with_encryption_minimum_version+set}" = set; then :
+ withval=$with_encryption_minimum_version;
+ if test "x$withval" != "xno" ; then
+ alpine_SSLMIN=$withval
+ fi
+
+fi
+
+
+# Check whether --with-encryption-maximum-version was given.
+if test "${with_encryption_maximum_version+set}" = set; then :
+ withval=$with_encryption_maximum_version;
+ if test "x$withval" != "xno" ; then
+ alpine_SSLMAX=$withval
+ fi
+
+fi
+
+ alpine_RANGE="$alpine_SSLMIN $alpine_SSLMAX"
+ for range in ${alpine_RANGE} ; do
+ for encryption in ${alpine_ENCRYPTION} ; do
+ if test "x$range" = "x$encryption" ; then
+ if test -z $alpine_min ; then
+ alpine_min="yes"
+ else
+ alpine_max="yes"
+ fi
+ fi
+ done
+ done
+
+ if test -z $alpine_max ; then
+ as_fn_error $? "Unrecognized maximum encryption version: $alpine_max" "$LINENO" 5
+ fi
+
+ if test -z $alpine_min ; then
+ as_fn_error $? "Unrecognized minimum encryption version: $alpine_min" "$LINENO" 5
+ fi
+
+ if test "x$alpine_SSLMIN" != "x$alpine_SSLMAX" ; then
+ alpine_RANGE_FEASIBLE=`echo "$alpine_ENCRYPTION" | sed "s/^.*$alpine_SSLMIN//" | grep "$alpine_SSLMAX"`
+ if test -n "$alpine_RANGE_FEASIBLE" ; then
+ alpine_RANGE="${alpine_SSLMIN},${alpine_SSLMAX}"
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Reversing order of minimum and maximum encryption" >&5
+$as_echo "$as_me: WARNING: Reversing order of minimum and maximum encryption" >&2;}
+ alpine_RANGE="${alpine_SSLMAX},${alpine_SSLMIN}"
+ fi
+ else
+ if test "x$alpine_SSLMIN" = "x$alpine_default_SSLMIN" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Overriding maximum encryption to default" >&5
+$as_echo "$as_me: WARNING: Overriding maximum encryption to default" >&2;}
+ alpine_SSLMAX="$alpine_default_SSLMAX"
+ fi
+ if test "x$alpine_SSLMAX" = "x$alpine_default_SSLMAX" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Overriding minimum encryption to default" >&5
+$as_echo "$as_me: WARNING: Overriding minimum encryption to default" >&2;}
+ alpine_SSLMIN="$alpine_default_SSLMIN"
+ fi
+ alpine_RANGE="${alpine_SSLMIN},${alpine_SSLMAX}"
+ fi
+
+ dpv=$alpine_RANGE
+
+# Check whether --with-encryption-range was given.
+if test "${with_encryption_range+set}" = set; then :
+ withval=$with_encryption_range;
+ if test "x$withval" != "xno" ; then
+ dpv=$withval
+ fi
+
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define DF_ENCRYPTION_RANGE "$dpv"
+_ACEOF
+
+
+fi
# Check whether --with-krb5 was given.
diff --git a/configure.ac b/configure.ac
index f9e149c4..0a67d012 100644
--- a/configure.ac
+++ b/configure.ac
@@ -951,6 +951,70 @@ if test "x$alpine_SSLTYPE" != "xnone" ; then
fi
fi
+if test "x$alpine_SSLTYPE" != "xnone" ; then
+ alpine_default_SSLMIN="no_min"
+ alpine_default_SSLMAX="no_max"
+ alpine_default_RANGE="${alpine_default_SSLMIN},${alpine_default_SSLMAX}"
+ alpine_ENCRYPTION="$alpine_default_SSLMIN ssl3 tls1 tls1_1 tls1_2 tls1_3 $alpine_default_SSLMAX"
+ alpine_SSLMIN="$alpine_default_SSLMIN"
+ alpine_SSLMAX="$alpine_default_SSLMAX"
+ alpine_RANGE="$alpine_default_RANGE"
+ AC_ARG_WITH(encryption-minimum-version,
+ AS_HELP_STRING([--encryption-minimum-version=VERSION],[Minimum SSL encryption version. Default: no_min]),
+ [
+ if test "x$withval" != "xno" ; then
+ alpine_SSLMIN=$withval
+ fi
+ ])
+ AC_ARG_WITH(encryption-maximum-version,
+ AS_HELP_STRING([--encryption-maximum-version=VERSION],[Maximum SSL encryption version. Default: no_max]),
+ [
+ if test "x$withval" != "xno" ; then
+ alpine_SSLMAX=$withval
+ fi
+ ])
+ alpine_RANGE="$alpine_SSLMIN $alpine_SSLMAX"
+ for range in ${alpine_RANGE} ; do
+ for encryption in ${alpine_ENCRYPTION} ; do
+ if test "x$range" = "x$encryption" ; then
+ if test -z $alpine_min ; then
+ alpine_min="yes"
+ else
+ alpine_max="yes"
+ fi
+ fi
+ done
+ done
+
+ if test -z $alpine_max ; then
+ AC_MSG_ERROR(Unrecognized maximum encryption version: $alpine_max)
+ fi
+
+ if test -z $alpine_min ; then
+ AC_MSG_ERROR(Unrecognized minimum encryption version: $alpine_min)
+ fi
+
+ if test "x$alpine_SSLMIN" != "x$alpine_SSLMAX" ; then
+ alpine_RANGE_FEASIBLE=`echo "$alpine_ENCRYPTION" | sed "s/^.*$alpine_SSLMIN//" | grep "$alpine_SSLMAX"`
+ if test -n "$alpine_RANGE_FEASIBLE" ; then
+ alpine_RANGE="${alpine_SSLMIN},${alpine_SSLMAX}"
+ else
+ AC_MSG_WARN(Reversing order of minimum and maximum encryption)
+ alpine_RANGE="${alpine_SSLMAX},${alpine_SSLMIN}"
+ fi
+ else
+ if test "x$alpine_SSLMIN" = "x$alpine_default_SSLMIN" ; then
+ AC_MSG_WARN(Overriding maximum encryption to default)
+ alpine_SSLMAX="$alpine_default_SSLMAX"
+ fi
+ if test "x$alpine_SSLMAX" = "x$alpine_default_SSLMAX" ; then
+ AC_MSG_WARN(Overriding minimum encryption to default)
+ alpine_SSLMIN="$alpine_default_SSLMIN"
+ fi
+ alpine_RANGE="${alpine_SSLMIN},${alpine_SSLMAX}"
+ fi
+PINEVAR(encryption-range, DF_ENCRYPTION_RANGE, [$alpine_RANGE] , [Default Encryption Range])
+fi
dnl Include Kerberos?
dnl Set GSSDIR for c-client make
diff --git a/imap/src/c-client/imap4r1.c b/imap/src/c-client/imap4r1.c
index f443cb9b..b7423056 100644
--- a/imap/src/c-client/imap4r1.c
+++ b/imap/src/c-client/imap4r1.c
@@ -88,7 +88,7 @@ typedef struct imap_local {
unsigned int tls1 : 1; /* using TLSv1 over SSL */
unsigned int tls1_1 : 1; /* using TLSv1_1 over SSL */
unsigned int tls1_2 : 1; /* using TLSv1_2 over SSL */
- unsigned int dtls1 : 1; /* using DTLSv1 over SSL */
+ unsigned int tls1_3 : 1; /* using TLSv1_3 over SSL */
unsigned int novalidate : 1; /* certificate not validated */
unsigned int filter : 1; /* filter SEARCH/SORT/THREAD results */
unsigned int loser : 1; /* server is a loser */
@@ -955,9 +955,9 @@ MAILSTREAM *imap_open (MAILSTREAM *stream)
/* save state for future recycling */
if (mb.tlsflag) LOCAL->tlsflag = T;
if (mb.tls1) LOCAL->tls1 = T;
- if (mb.dtls1) LOCAL->dtls1 = T;
if (mb.tls1_1) LOCAL->tls1_1 = T;
if (mb.tls1_2) LOCAL->tls1_2 = T;
+ if (mb.tls1_3) LOCAL->tls1_3 = T;
if (mb.tlssslv23) LOCAL->tlssslv23 = T;
if (mb.notlsflag) LOCAL->notlsflag = T;
if (mb.sslflag) LOCAL->sslflag = T;
@@ -979,7 +979,7 @@ MAILSTREAM *imap_open (MAILSTREAM *stream)
if (LOCAL->tls1) strcat (tmp,"/tls1");
if (LOCAL->tls1_1) strcat (tmp,"/tls1_1");
if (LOCAL->tls1_2) strcat (tmp,"/tls1_2");
- if (LOCAL->dtls1) strcat (tmp,"/dtls1");
+ if (LOCAL->tls1_3) strcat (tmp,"/tls1_3");
if (LOCAL->tlssslv23) strcat (tmp,"/tls-sslv23");
if (LOCAL->notlsflag) strcat (tmp,"/notls");
if (LOCAL->sslflag) strcat (tmp,"/ssl");
diff --git a/imap/src/c-client/mail.c b/imap/src/c-client/mail.c
index ae828751..8f0373ed 100644
--- a/imap/src/c-client/mail.c
+++ b/imap/src/c-client/mail.c
@@ -36,6 +36,10 @@ char *UW_copyright = "Copyright 1988-2008 University of Washington\n\nLicensed u
/* c-client global data */
/* version of this library */
static char *mailcclientversion = CCLIENTVERSION;
+ /* Minimum in range of encryption supported */
+static int encryption_range_min = 0;
+ /* Maximum in range of encryption supported */
+static int encryption_range_max = 0;
/* app identity */
static IDLIST *idapp = NIL;
/* list of mail drivers */
@@ -541,6 +545,16 @@ void *mail_parameters (MAILSTREAM *stream,long function,void *value)
case GET_SSLFAILURE:
ret = (void *) mailsslfailure;
break;
+ case SET_ENCRYPTION_RANGE_MIN:
+ encryption_range_min = *(int *) value;
+ case GET_ENCRYPTION_RANGE_MIN:
+ ret = (void *) &encryption_range_min;
+ break;
+ case SET_ENCRYPTION_RANGE_MAX:
+ encryption_range_max = *(int *) value;
+ case GET_ENCRYPTION_RANGE_MAX:
+ ret = (void *) &encryption_range_max;
+ break;
case SET_KINIT:
mailkinit = (kinit_t) value;
case GET_KINIT:
@@ -829,29 +843,17 @@ long mail_valid_net_parse_work (char *name,NETMBX *mb,char *service)
else if (mailssldriver && !compare_cstring (s,"ssl") && !mb->tlsflag)
mb->sslflag = mb->notlsflag = T;
else if (!compare_cstring(s, "tls1")
- && !mb->tls1_1 && !mb->tls1_2 && !mb->tls1_3
- && !mb->dtls1 && !mb->dtls1_2)
+ && !mb->tls1_1 && !mb->tls1_2 && !mb->tls1_3)
mb->sslflag = mb->notlsflag = mb->tls1 = T;
else if (!compare_cstring(s, "tls1_1")
- && !mb->tls1 && !mb->tls1_2 && !mb->tls1_3
- && !mb->dtls1 && !mb->dtls1_2)
+ && !mb->tls1 && !mb->tls1_2 && !mb->tls1_3)
mb->sslflag = mb->notlsflag = mb->tls1_1 = T;
else if (!compare_cstring(s, "tls1_2")
- && !mb->tls1 && !mb->tls1_1 && !mb->tls1_3
- && !mb->dtls1 && !mb->dtls1_2)
+ && !mb->tls1 && !mb->tls1_1 && !mb->tls1_3)
mb->sslflag = mb->notlsflag = mb->tls1_2 = T;
else if (!compare_cstring(s, "tls1_3")
- && !mb->tls1 && !mb->tls1_1 && !mb->tls1_2
- && !mb->dtls1 && !mb->dtls1_2)
+ && !mb->tls1 && !mb->tls1_1 && !mb->tls1_2)
mb->sslflag = mb->notlsflag = mb->tls1_3 = T;
- else if (!compare_cstring(s, "dtls1")
- && !mb->tls1 && !mb->tls1_1 && !mb->tls1_2
- && !mb->tls1_3 && !mb->dtls1_2)
- mb->sslflag = mb->notlsflag = mb->dtls1 = T;
- else if (!compare_cstring(s, "dtls1_2")
- && !mb->tls1 && !mb->tls1_1 && !mb->tls1_2
- && !mb->tls1_3 && !mb->dtls1)
- mb->sslflag = mb->notlsflag = mb->dtls1_2 = T;
else if (mailssldriver && !compare_cstring (s,"novalidate-cert"))
mb->novalidate = T;
/* hack for compatibility with the past */
@@ -1263,7 +1265,7 @@ MAILSTREAM *mail_open (MAILSTREAM *stream,char *name,long options)
if (mb.tls1) strcat (tmp,"/tls1");
if (mb.tls1_1) strcat (tmp,"/tls1_1");
if (mb.tls1_2) strcat (tmp,"/tls1_2");
- if (mb.dtls1) strcat (tmp,"/dtls1");
+ if (mb.tls1_3) strcat (tmp,"/tls1_3");
if (mb.trysslflag) strcat (tmp,"/tryssl");
if (mb.novalidate) strcat (tmp,"/novalidate-cert");
strcat (tmp,"/pop3/loser}");
@@ -6233,8 +6235,6 @@ NETSTREAM *net_open (NETMBX *mb,NETDRIVER *dv,unsigned long port,
flags |= mb->tls1_1 ? NET_TRYTLS1_1 : 0;
flags |= mb->tls1_2 ? NET_TRYTLS1_2 : 0;
flags |= mb->tls1_3 ? NET_TRYTLS1_3 : 0;
- flags |= mb->dtls1 ? NET_TRYDTLS1 : 0;
- flags |= mb->dtls1_2 ? NET_TRYDTLS1_2 : 0;
if (strlen (mb->host) >= NETMAXHOST) {
sprintf (tmp,"Invalid host name: %.80s",mb->host);
MM_LOG (tmp,ERROR);
diff --git a/imap/src/c-client/mail.h b/imap/src/c-client/mail.h
index 73f6521c..58d2979c 100644
--- a/imap/src/c-client/mail.h
+++ b/imap/src/c-client/mail.h
@@ -230,6 +230,10 @@
#define SET_SSLCLIENTKEY (long) 335
#define GET_KERBEROS_CP_SVR_NAME (long) 336
#define SET_KERBEROS_CP_SVR_NAME (long) 337
+#define GET_ENCRYPTION_RANGE_MIN (long) 338
+#define SET_ENCRYPTION_RANGE_MIN (long) 339
+#define GET_ENCRYPTION_RANGE_MAX (long) 340
+#define SET_ENCRYPTION_RANGE_MAX (long) 341
/* 4xx: network drivers */
#define GET_MAXLOGINTRIALS (long) 400
@@ -449,10 +453,6 @@
#define NET_TRYTLS1_2 ((unsigned long) 0x1000000)
/* try TLS1_3 mode */
#define NET_TRYTLS1_3 ((unsigned long) 0x800000)
- /* try DTLS1 mode */
-#define NET_TRYDTLS1 ((unsigned long) 0x400000)
- /* try DTLS1_2 mode */
-#define NET_TRYDTLS1_2 ((unsigned long) 0x200000)
/* Close options */
@@ -698,8 +698,6 @@ typedef struct net_mailbox {
unsigned int tls1_1 : 1; /* Use TLSv1.1 */
unsigned int tls1_2 : 1; /* Use TLSV1.2 */
unsigned int tls1_3 : 1; /* Use TLSV1.3 */
- unsigned int dtls1 : 1; /* Use DTLSv1 */
- unsigned int dtls1_2 : 1; /* Use DTLSv1.2 */
unsigned int trysslflag : 1; /* try SSL driver first flag */
unsigned int novalidate : 1; /* don't validate certificates */
unsigned int tlsflag : 1; /* TLS flag */
@@ -714,7 +712,7 @@ typedef struct net_mailbox {
: (M).tls1 ? NET_TRYTLS1 \
: (M).tls1_1 ? NET_TRYTLS1_1 \
: (M).tls1_2 ? NET_TRYTLS1_2 \
- : (M).dtls1 ? NET_TRYDTLS1 \
+ : (M).tls1_3 ? NET_TRYTLS1_3 \
: NET_TLSCLIENT)
diff --git a/imap/src/c-client/nntp.c b/imap/src/c-client/nntp.c
index 8fa32df1..b1d08024 100644
--- a/imap/src/c-client/nntp.c
+++ b/imap/src/c-client/nntp.c
@@ -70,9 +70,9 @@ typedef struct nntp_local {
unsigned int notlsflag : 1; /* TLS not used in session */
unsigned int sslflag : 1; /* SSL session */
unsigned int tls1 : 1; /* TLSv1 on SSL port */
- unsigned int dtls1 : 1; /* DTLSv1 on SSL port */
unsigned int tls1_1 : 1; /* TLSv1_1 on SSL port */
unsigned int tls1_2 : 1; /* TLSv1_2 on SSL port */
+ unsigned int tls1_3 : 1; /* TLSv1_3 on SSL port */
unsigned int novalidate : 1; /* certificate not validated */
unsigned int xover : 1; /* supports XOVER */
unsigned int xhdr : 1; /* supports XHDR */
@@ -667,9 +667,9 @@ MAILSTREAM *nntp_mopen (MAILSTREAM *stream)
if (LOCAL->notlsflag) mb.notlsflag = T;
if (LOCAL->sslflag) mb.sslflag = T;
if (LOCAL->tls1) mb.tls1 = T;
- if (LOCAL->dtls1) mb.dtls1 = T;
if (LOCAL->tls1_1) mb.tls1_1 = T;
if (LOCAL->tls1_2) mb.tls1_2 = T;
+ if (LOCAL->tls1_3) mb.tls1_3 = T;
if (LOCAL->novalidate) mb.novalidate = T;
if (LOCAL->nntpstream->loser) mb.loser = T;
if (stream->secure) mb.secflag = T;
@@ -694,7 +694,7 @@ MAILSTREAM *nntp_mopen (MAILSTREAM *stream)
if (mb.tls1) strcat (tmp,"/tls1");
if (mb.tls1_1) strcat (tmp,"/tls1_1");
if (mb.tls1_2) strcat (tmp,"/tls1_2");
- if (mb.dtls1) strcat (tmp,"/dtls1");
+ if (mb.tls1_3) strcat (tmp,"/tls1_3");
if (mb.novalidate) strcat (tmp,"/novalidate-cert");
if (mb.loser) strcat (tmp,"/loser");
if (mb.secflag) strcat (tmp,"/secure");
@@ -765,9 +765,9 @@ MAILSTREAM *nntp_mopen (MAILSTREAM *stream)
if (LOCAL->notlsflag) strcat (tmp,"/notls");
if (LOCAL->sslflag) strcat (tmp,"/ssl");
if (LOCAL->tls1) strcat (tmp,"/tls1");
- if (LOCAL->dtls1) strcat (tmp,"/dtls1");
if (LOCAL->tls1_1) strcat (tmp,"/tls1_1");
if (LOCAL->tls1_2) strcat (tmp,"/tls1_2");
+ if (LOCAL->tls1_3) strcat (tmp,"/tls1_3");
if (LOCAL->novalidate) strcat (tmp,"/novalidate-cert");
if (LOCAL->nntpstream->loser) strcat (tmp,"/loser");
if (stream->secure) strcat (tmp,"/secure");
diff --git a/imap/src/c-client/pop3.c b/imap/src/c-client/pop3.c
index 80f1858d..dfc4f925 100644
--- a/imap/src/c-client/pop3.c
+++ b/imap/src/c-client/pop3.c
@@ -424,7 +424,7 @@ MAILSTREAM *pop3_open (MAILSTREAM *stream)
if (mb.tls1) strcat (tmp,"/tls1");
if (mb.tls1_1) strcat (tmp,"/tls1_1");
if (mb.tls1_2) strcat (tmp,"/tls1_2");
- if (mb.dtls1) strcat (tmp,"/dtls1");
+ if (mb.tls1_3) strcat (tmp,"/tls1_3");
if (mb.notlsflag) strcat (tmp,"/notls");
if (mb.sslflag) strcat (tmp,"/ssl");
if (mb.novalidate) strcat (tmp,"/novalidate-cert");
diff --git a/imap/src/osdep/unix/ssl_unix.c b/imap/src/osdep/unix/ssl_unix.c
index efbe8392..11454cbd 100644
--- a/imap/src/osdep/unix/ssl_unix.c
+++ b/imap/src/osdep/unix/ssl_unix.c
@@ -33,42 +33,10 @@
#include <bio.h>
#include <crypto.h>
#include <rand.h>
-#ifndef TLS_client_method
-#ifdef TLSv1_2_client_method
-#define TLS_client_method TLSv1_2_client_method
-#elif defined(TLSv1_1_client_method)
-#define TLS_client_method TLSv1_1_client_method
-#else
-#define TLS_client_method TLSv1_client_method
-#endif /* TLSv1_2_client_method */
-#endif /* TLS_client_method */
#ifdef OPENSSL_1_1_0
#include <rsa.h>
#include <bn.h>
-#ifdef TLSv1_client_method
-#undef TLSv1_client_method
-#endif /* TLSv1_client_method */
-#ifdef TLSv1_1_client_method
-#undef TLSv1_1_client_method
-#endif /* TLSv1_1_client_method */
-#ifdef TLSv1_2_client_method
-#undef TLSv1_2_client_method
-#endif /* TLSv1_2_client_method */
-#ifdef DTLSv1_client_method
-#undef DTLSv1_client_method
-#endif /* DTLSv1_client_method */
-#ifdef DTLSv1_2_client_method
-#undef DTLSv1_2_client_method
-#endif /* DTLSv1_2_client_method */
-#define TLSv1_client_method TLS_client_method
-#define TLSv1_1_client_method TLS_client_method
-#define TLSv1_2_client_method TLS_client_method
-#define DTLSv1_client_method DTLS_client_method
-#define DTLSv1_2_client_method DTLS_client_method
#endif /* OPENSSL_1_1_0 */
-#ifndef DTLSv1_2_client_method
-#define DTLSv1_2_client_method DTLSv1_client_method
-#endif /* DTLSv1_2_client_method */
#undef STRING
#undef crypt
@@ -105,7 +73,8 @@ typedef struct ssl_stream {
#include "sslio.h"
/* Function prototypes */
-const SSL_METHOD *ssl_connect_mthd(int flag);
+int ssl_disable_mask(int ssl_version, int direction);
+const SSL_METHOD *ssl_connect_mthd(int flag, int *min, int *max);
static SSLSTREAM *ssl_start(TCPSTREAM *tstream,char *host,unsigned long flags);
static char *ssl_start_work (SSLSTREAM *stream,char *host,unsigned long flags);
static int ssl_open_verify (int ok,X509_STORE_CTX *ctx);
@@ -205,50 +174,95 @@ SSLSTREAM *ssl_aopen (NETMBX *mb,char *service,char *usrbuf)
return NIL; /* don't use this mechanism with SSL */
}
+typedef struct ssl_disable_s {
+ int version;
+ int disable_code;
+} SSL_DISABLE_S;
+
+SSL_DISABLE_S ssl_disable[] = {
+ {SSL2_VERSION, SSL_OP_NO_SSLv2},
+ {SSL3_VERSION, SSL_OP_NO_SSLv3},
+ {TLS1_VERSION, SSL_OP_NO_TLSv1},
+ {TLS1_1_VERSION, SSL_OP_NO_TLSv1_1},
+ {TLS1_2_VERSION, SSL_OP_NO_TLSv1_2},
+#ifdef TLS1_3_VERSION
+ {TLS1_3_VERSION, SSL_OP_NO_TLSv1_3},
+#endif /* TLS1_3_VERSION */
+ {0, 0}
+};
+
+#define NUMBER_SSL_VERSIONS (sizeof(ssl_disable)/sizeof(ssl_disable[0]) - 1)
+
+/* returns the mask to disable a specific version.
+ * If version not found, returns 0.
+ *
+ * Arguments: version, and direction.
+ * If direction is -1, returns mask to disable versions less than given version.
+ * If direction is +1, returns mask to disable versions bigger than given version.
+ */
+int ssl_disable_mask(int ssl_version, int direction)
+{
+ int rv = 0;
+ int i;
+ for(i = 0; ssl_disable[i].version != 0
+ && ssl_disable[i].version != ssl_version; i++);
+ if(i == 0
+ || i == NUMBER_SSL_VERSIONS - 1
+ || ssl_disable[i].version == 0)
+ return rv;
+ i += direction; /* move in the direction */
+ for(; i >= 0 && i <= NUMBER_SSL_VERSIONS - 1; i += direction)
+ rv |= ssl_disable[i].disable_code;
+ return rv;
+}
+
+
/* ssl_connect_mthd: returns a context pointer to the connection to
* a ssl server
*/
-const SSL_METHOD *ssl_connect_mthd(int flag)
+const SSL_METHOD *ssl_connect_mthd(int flag, int *min, int *max)
{
- if (flag & NET_TRYTLS1)
-#ifndef OPENSSL_NO_TLS1_METHOD
- return TLSv1_client_method();
+ char tmp[10000];
+ int client_request;
+ client_request = (flag & NET_TRYTLS1) ? TLS1_VERSION
+ : (flag & NET_TRYTLS1_1) ? TLS1_1_VERSION
+ : (flag & NET_TRYTLS1_2) ? TLS1_2_VERSION
+#ifdef TLS1_3_VERSION
+ : (flag & NET_TRYTLS1_3) ? TLS1_3_VERSION
#else
- return TLS_client_method();
-#endif /* OPENSSL_NO_TLS1_METHOD */
-
- else if(flag & NET_TRYTLS1_1)
-#ifndef OPENSSL_NO_TLS1_1_METHOD
+ : (flag & NET_TRYTLS1_3) ? INT_MAX
+#endif
+ : 0L;
+
+ *min = *(int *) mail_parameters(NULL, GET_ENCRYPTION_RANGE_MIN, NULL);
+ *max = *(int *) mail_parameters(NULL, GET_ENCRYPTION_RANGE_MAX, NULL);
+
+ /*
+ * if no special request, negotiate the maximum the client is configured
+ * to negotiate
+ */
+ if(client_request == 0)
+ client_request = *max;
+
+ if(client_request < *min || client_request > *max)
+ return NIL; /* out of range? bail out */
+
+#ifndef OPENSSL_1_1_0
+ if(client_request == SSL3_VERSION)
+ return SSLv3_client_method();
+ if(client_request == TLS1_VERSION)
+ return TLSv1_client_method();
+ else if(client_request == TLS1_1_VERSION)
return TLSv1_1_client_method();
-#else
- return TLS_client_method();
-#endif /* OPENSSL_NO_TLS1_1_METHOD */
-
- else if(flag & NET_TRYTLS1_2)
-#ifndef OPENSSL_NO_TLS1_2_METHOD
+ else if(client_request == TLS1_2_VERSION)
return TLSv1_2_client_method();
-#else
- return TLS_client_method();
-#endif /* OPENSSL_NO_TLS1_2_METHOD */
-
- else if(flag & NET_TRYTLS1_3)
+#ifdef TLS1_3_VERSION /* this is only reachable if TLS1_3 support exists */
+ else if(client_request == TLS1_3_VERSION)
return TLS_client_method();
+#endif /* TLS1_3_VERSION */
+#endif /* ifndef OPENSSL_1_1_0 */
- else if(flag & NET_TRYDTLS1)
-#ifndef OPENSSL_NO_DTLS1_METHOD
- return DTLSv1_client_method();
-#else
- return DTLS_client_method();
-#endif /* OPENSSL_NO_DTLS1_METHOD */
-
- else if(flag & NET_TRYDTLS1_2)
-#ifndef OPENSSL_NO_DTLS1_METHOD
- return DTLSv1_2_client_method();
-#else
- return DTLS_client_method();
-#endif /* OPENSSL_NO_DTLS1_METHOD */
-
- else return SSLv23_client_method();
+ return SSLv23_client_method();
}
/* Start SSL/TLS negotiations
@@ -317,6 +331,7 @@ static char *ssl_start_work (SSLSTREAM *stream,char *host,unsigned long flags)
BIO *bio;
X509 *cert;
unsigned long sl,tl;
+ int min, max;
char *s,*t,*err,tmp[MAILTMPLEN], buf[256];
sslcertificatequery_t scq =
(sslcertificatequery_t) mail_parameters (NIL,GET_SSLCERTIFICATEQUERY,NIL);
@@ -326,9 +341,21 @@ static char *ssl_start_work (SSLSTREAM *stream,char *host,unsigned long flags)
(sslclientkey_t) mail_parameters (NIL,GET_SSLCLIENTKEY,NIL);
if (ssl_last_error) fs_give ((void **) &ssl_last_error);
ssl_last_host = host;
- if (!(stream->context = SSL_CTX_new (ssl_connect_mthd(flags))))
+ if (!(stream->context = SSL_CTX_new (ssl_connect_mthd(flags, &min, &max))))
return "SSL context failed";
SSL_CTX_set_options (stream->context,0);
+#ifdef OPENSSL_1_1_0
+ if(stream->context != NIL &&
+ ((min != 0 && SSL_CTX_set_min_proto_version(stream->context, min) == 0) ||
+ (max != 0 && SSL_CTX_set_max_proto_version(stream->context, max) == 0)))
+ return "SSL set protocol version Failed";
+#else
+ { int masklow, maskhigh;
+ masklow = ssl_disable_mask(min, -1);
+ maskhigh = ssl_disable_mask(max, 1);
+ SSL_CTX_set_options(stream->context, masklow|maskhigh);
+ }
+#endif /* OPENSSL_1_1_0 */
/* disable certificate validation? */
if (flags & NET_NOVALIDATECERT)
SSL_CTX_set_verify (stream->context,SSL_VERIFY_NONE,NIL);
@@ -363,6 +390,9 @@ static char *ssl_start_work (SSLSTREAM *stream,char *host,unsigned long flags)
/* create connection */
if (!(stream->con = (SSL *) SSL_new (stream->context)))
return "SSL connection failed";
+ if (host && !SSL_set_tlsext_host_name(stream->con, host)){
+ return "Server Name Identification (SNI) failed";
+ }
bio = BIO_new_socket (stream->tcpstream->tcpsi,BIO_NOCLOSE);
SSL_set_bio (stream->con,bio,bio);
SSL_set_connect_state (stream->con);
diff --git a/include/config.h.in b/include/config.h.in
index 0779f336..453a2c12 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -64,6 +64,9 @@
#undef DF_ELM_STYLE_SAVE
/* Default configuration value */
+#undef DF_ENCRYPTION_RANGE
+
+/* Default configuration value */
#undef DF_FCC_RULE
/* Default configuration value */
diff --git a/include/config.wnt.h b/include/config.wnt.h
index ca2f58f3..6e22f38e 100644
--- a/include/config.wnt.h
+++ b/include/config.wnt.h
@@ -57,6 +57,9 @@
#define DF_ELM_STYLE_SAVE "no"
/* Default configuration value */
+#define DF_ENCRYPTION_RANGE "no_min,no_max"
+
+/* Default configuration value */
#define DF_FCC_RULE "default-fcc"
/* Default configuration value */
diff --git a/pith/conf.c b/pith/conf.c
index 607c9f82..c7c24dbe 100644
--- a/pith/conf.c
+++ b/pith/conf.c
@@ -281,6 +281,8 @@ CONF_TXT_T cf_text_disable_drivers[] = "List of mail drivers to disable.";
CONF_TXT_T cf_text_disable_auths[] = "List of SASL authenticators to disable.";
+CONF_TXT_T cf_text_encryption_range[] = "A range in the form min,max that sets the minimum amd maximum versions of the\n# SSL protocol that Alpine will use when connecting to a secure server.";
+
CONF_TXT_T cf_text_remote_abook_metafile[] = "Set by Alpine; contains data for caching remote address books.";
CONF_TXT_T cf_text_old_patterns[] = "Patterns is obsolete, use patterns-xxx";
@@ -744,6 +746,8 @@ static struct variable variables[] = {
NULL, cf_text_disable_drivers},
{"disable-these-authenticators", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0,
NULL, cf_text_disable_auths},
+{"encryption-protocol-range", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
+ NULL, cf_text_encryption_range},
{"remote-abook-metafile", 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0,
NULL, cf_text_remote_abook_metafile},
{"remote-abook-history", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0,
@@ -1601,6 +1605,7 @@ init_vars(struct pine *ps, void (*cmds_f) (struct pine *, char **))
GLO_PRINTER = cpystr(DF_DEFAULT_PRINTER);
GLO_ELM_STYLE_SAVE = cpystr(DF_ELM_STYLE_SAVE);
+ GLO_ENCRYPTION_RANGE = cpystr(DF_ENCRYPTION_RANGE);
GLO_SAVE_BY_SENDER = cpystr(DF_SAVE_BY_SENDER);
GLO_HEADER_IN_REPLY = cpystr(DF_HEADER_IN_REPLY);
GLO_INBOX_PATH = cpystr("inbox");
@@ -2328,6 +2333,7 @@ init_vars(struct pine *ps, void (*cmds_f) (struct pine *, char **))
set_current_val(&vars[V_FORCED_ABOOK_ENTRY], TRUE, TRUE);
set_current_val(&vars[V_DISABLE_DRIVERS], TRUE, TRUE);
set_current_val(&vars[V_DISABLE_AUTHS], TRUE, TRUE);
+ set_current_val(&vars[V_ENCRYPTION_RANGE], TRUE, TRUE);
set_current_val(&vars[V_VIEW_HEADERS], TRUE, TRUE);
/* strip spaces and colons */
@@ -7825,6 +7831,8 @@ config_help(int var, int feature)
return(h_config_disable_drivers);
case V_DISABLE_AUTHS :
return(h_config_disable_auths);
+ case V_ENCRYPTION_RANGE :
+ return(h_config_encryption_range);
case V_REMOTE_ABOOK_METADATA :
return(h_config_abook_metafile);
case V_REPLY_STRING :
@@ -8187,36 +8195,26 @@ get_supported_options(void)
/* TRANSLATORS: headings */
config[cnt] = cpystr(_("Encryption:"));
- if(++cnt < alcnt && mail_parameters(NIL, GET_SSLDRIVER, NIL))
+ if(++cnt < alcnt && mail_parameters(NIL, GET_SSLDRIVER, NIL)){
config[cnt] = cpystr(_(" TLS and SSL"));
- else
- config[cnt] = cpystr(_(" None (no TLS or SSL)"));
-
- tmp[0] = tmp[1] = ' ';
- tmp[2] = '\0';
-#ifndef OPENSSL_NO_TLS1_METHOD
- strcat(tmp, "TLSv1, ");
-#endif /* OPENSSL_NO_TLS1_METHOD */
-#ifdef TLS1_1_VERSION
- strcat(tmp, "TLSv1.1, ");
-#endif /* TLS1_1_VERSION */
-#ifdef TLS1_2_VERSION
- strcat(tmp, "TLSv1.2. ");
-#endif /* TLS1_2_VERSION */
+ tmp[0] = tmp[1] = ' ';
+ tmp[2] = '\0';
+ strcat(tmp, "TLSv1, ");
+ strcat(tmp, "TLSv1.1, ");
+ strcat(tmp, "TLSv1.2, ");
#ifdef TLS1_3_VERSION
- strcat(tmp, "TLSv1.3, ");
+ strcat(tmp, "TLSv1.3, ");
#endif /* TLS1_3_VERSION */
-#ifdef DTLS1_VERSION
- strcat(tmp, "DTLSv1, ");
-#endif /* DTLS1_VERSION */
-#ifdef DTLS1_2_VERSION
- strcat(tmp, "DTLSv1.2, ");
-#endif /* DTLS1_2_VERSION */
- if(tmp[2] != '\0'){
- tmp[strlen(tmp)-2] = '\0';
- if(++cnt < alcnt)
- config[cnt] = cpystr(tmp);
+ strcat(tmp, "DTLSv1, ");
+ strcat(tmp, "DTLSv1.2, ");
+ tmp[strlen(tmp)-2] = '.';
+ tmp[strlen(tmp)-1] = '\0';
}
+ else
+ config[cnt] = cpystr(_(" None (no TLS or SSL)"));
+
+ if(++cnt < alcnt)
+ config[cnt] = cpystr(tmp);
#ifdef SMIME
if(++cnt < alcnt)
config[cnt] = cpystr(" S/MIME");
@@ -8452,3 +8450,37 @@ pcpine_general_help(titlebuf)
#endif /* _WINDOWS */
+typedef struct ssl_versions_s {
+ char *name;
+ int version;
+} SSL_VERSIONS_S;
+
+int
+pith_ssl_encryption_version(char *s)
+{
+ SSL_VERSIONS_S ssl_versions[] = {
+ {"no_min", 0},
+ {"ssl3", SSL3_VERSION},
+ {"tls1", TLS1_VERSION},
+ {"tls1_1", TLS1_1_VERSION },
+ {"tls1_2", TLS1_2_VERSION},
+#ifdef TLS1_3_VERSION
+ {"tls1_3", TLS1_3_VERSION},
+#endif /* TLS1_3_VERSION */
+ {"no_max", 0}, /* set this last in the list */
+ { NULL, 0},
+ };
+ int i;
+
+ if(s == NULL || *s == '\0')
+ return -1;
+
+ for(i = 0; ssl_versions[i].name != NULL; i++)
+ if(strcmp(ssl_versions[i].name, s) == 0)
+ break;
+
+ if(strcmp(s, "no_max") == 0) i--;
+
+ return ssl_versions[i].name != NULL ? ssl_versions[i].version : -1;
+}
+
diff --git a/pith/conf.h b/pith/conf.h
index 7648e355..474e9d5f 100644
--- a/pith/conf.h
+++ b/pith/conf.h
@@ -263,6 +263,8 @@
#define GLO_REMOTE_ABOOK_HISTORY vars[V_REMOTE_ABOOK_HISTORY].global_val.p
#define VAR_REMOTE_ABOOK_VALIDITY vars[V_REMOTE_ABOOK_VALIDITY].current_val.p
#define GLO_REMOTE_ABOOK_VALIDITY vars[V_REMOTE_ABOOK_VALIDITY].global_val.p
+#define GLO_ENCRYPTION_RANGE vars[V_ENCRYPTION_RANGE].global_val.p
+#define VAR_ENCRYPTION_RANGE vars[V_ENCRYPTION_RANGE].current_val.p
/* Elm style save is obsolete in Pine 3.81 (see saved msg name rule) */
#define VAR_ELM_STYLE_SAVE vars[V_ELM_STYLE_SAVE].current_val.p
#define GLO_ELM_STYLE_SAVE vars[V_ELM_STYLE_SAVE].global_val.p
@@ -912,6 +914,7 @@ char **get_supported_options(void);
unsigned reset_startup_rule(MAILSTREAM *);
void free_pinerc_lines(PINERC_LINE **);
void panic1(char *, char *);
+int pith_ssl_encryption_version(char *);
/* mandatory to implement prototypes */
int set_input_timeout(int);
diff --git a/pith/conftype.h b/pith/conftype.h
index e70c5276..bfb337c9 100644
--- a/pith/conftype.h
+++ b/pith/conftype.h
@@ -171,6 +171,7 @@ typedef enum { V_PERSONAL_NAME = 0
, V_NEW_VER_QUELL
, V_DISABLE_DRIVERS
, V_DISABLE_AUTHS
+ , V_ENCRYPTION_RANGE
, V_REMOTE_ABOOK_METADATA
, V_REMOTE_ABOOK_HISTORY
, V_REMOTE_ABOOK_VALIDITY
diff --git a/pith/pine.hlp b/pith/pine.hlp
index 03aa9363..99670197 100644
--- a/pith/pine.hlp
+++ b/pith/pine.hlp
@@ -188,6 +188,12 @@ Based on code provided by Maciej W. Rozycki.
<LI> Add /tls1_3 flag for servers that support it. Read more information
in the secure protocols <A HREF="h_network_encryption_security">help</A>.
+<LI> New variable
+<A HREF="h_config_encryption_range"><!--#echo var="VAR_encryption-protocol-range"--></A>
+that allows users to configure versions of the SSL/TLS protocol that Alpine is
+restricted to try when establishing a secure connection SSL/TLS to a remote
+server. The default can be set at compilation time.
+
<LI> Add -dict option to PC-Pico, which allows users to choose a dictionary
when spelling. Sample usage: -dict "en_US, de_DE, fr_FR".
@@ -218,6 +224,10 @@ Suggested by Barry Landy.
<LI> S/MIME: Some clients do not transform messages to canonical form when
signing first and encrypting second, which makes Alpine fail to parse the
signed data after encryption. Reported by Holger Trapp.
+
+<LI> Add /auth=XYZ to the way to define a server. This allows users to
+select the method to authenticate to an IMAP, SMTP or POP3 server.
+Examples are /auth=plain, or /auth=gssapi, etc.
</UL>
<P>
@@ -304,9 +314,13 @@ Bugs that have been addressed include:
by David Woodhouse to the RedHat bugzilla system.
<LI> When there are time changes in the clock, Alpine might go to sleep
- for big amounts of time while displaying messages in the screen.
- Reset sleep time to 5 seconds in case it finds it needs to sleep
+ for big amounts of time while displaying messages in the screen.
+ Reset sleep time to 5 seconds in case it finds it needs to sleep
more than 5 seconds or a negative amount of time.
+
+ <LI> Restore recognition of empty directories. It was deleted by mistake
+ when added support for internationalization in folders. Based on a
+ report by Michael Rutter.
</UL>
<P>
@@ -3356,6 +3370,7 @@ if the connection is encrypted.
<LI> <A HREF="h_config_disable_password_file_saving"><!--#echo var="FEAT_disable-password-file-saving"--></A> Disable password file saving</LI>
<LI> <A HREF="h_config_mailcap_params"><!--#echo var="FEAT_enable-mailcap-param-substitution"--></A> feature </LI>
<LI> <A HREF="h_config_disable_auths"><!--#echo var="VAR_disable-these-authenticators"--></A> option </LI>
+<LI> <A HREF="h_config_encryption_range"><!--#echo var="VAR_encryption-protocol-range"--></A> option </LI>
</UL>
<P>
&lt;End of help on this topic&gt;
@@ -4324,6 +4339,7 @@ There are also additional details on
<li><a href="h_config_default_fcc">OPTION: <!--#echo var="VAR_default-fcc"--></a>
<li><a href="h_config_def_save_folder">OPTION: <!--#echo var="VAR_default-saved-msg-folder"--></a>
<li><a href="h_config_disable_auths">OPTION: <!--#echo var="VAR_disable-these-authenticators"--></a>
+<li><a href="h_config_encryption_range">OPTION: <!--#echo var="VAR_encryption-protocol-range"--></a>
<li><a href="h_config_disable_drivers">OPTION: <!--#echo var="VAR_disable-these-drivers"--></a>
<li><a href="h_config_char_set">OPTION: Display Character Set</a>
<li><a href="h_config_display_filters">OPTION: <!--#echo var="VAR_display-filters"--></a>
@@ -20710,6 +20726,9 @@ take place over a Secure Socket Layer connection. The server must support
this method, and be prepared to accept connections on the appropriate
port (993 by default).
Alpine must be linked with an SSL library for this option to be operational.
+Using this option will make Alpine try to connect to the server using the
+most secure encrypted SSL connection that both your version of Alpine and the
+server support.
<P>
<CENTER><SAMP>/ssl</SAMP></CENTER>
@@ -20727,79 +20746,50 @@ Alpine must be linked with an SSL library for this option to be operational.
<P>
<CENTER><SAMP>/tls1</SAMP></CENTER>
<P>
-
-</DD>
-
-<DT>DTLS1</DT>
-<DD>
-This parameter indicates that the connection to the server will be made
-over the SSL port, but using the DTLSv1 protocol, instead of the usual
-SSLv3 or SSLv2 protocols.
-Alpine must be linked with an SSL library for this option to be operational.
-
-<P>
-<CENTER><SAMP>/dtls1</SAMP></CENTER>
-<P>
-
-</DD>
-
-<DT>DTLS1_2</DT>
-<DD>
-This parameter indicates that the connection to the server will be made
-over the SSL port, but using the DTLSv1.2 protocol, instead of the usual
-SSLv3 or SSLv2 protocols.
-Alpine must be linked with an SSL library for this option to be operational.
-
-<P>
-<CENTER><SAMP>/dtls1_2</SAMP></CENTER>
-<P>
-
</DD>
<DT>TLS1_1</DT>
<DD>
This parameter indicates that the connection to the server will be made
-over the SSL port, but using the TLSv1.1 protocol, instead of the usual
-SSLv3 or SSLv2 protocols.
-Alpine must be linked with an SSL library for this option to be operational.
+over the SSL port, but using the TLSv1.1 protocol.
+Alpine must be linked with an SSL library that supports this encryption
+protocol for this option to be operational.
<P>
<CENTER><SAMP>/tls1_1</SAMP></CENTER>
<P>
-
</DD>
<DT>TLS1_2</DT>
<DD>
This parameter indicates that the connection to the server will be made
-over the SSL port, but using the TLSv1.2 protocol, instead of the usual
-SSLv3 or SSLv2 protocols.
-Alpine must be linked with an SSL library for this option to be operational.
+over the SSL port, but using the TLSv1.2 protocol.
+Alpine must be linked with an SSL library that supports this encryption
+protocol for this option to be operational.
<P>
<CENTER><SAMP>/tls1_2</SAMP></CENTER>
<P>
-
</DD>
<DT>TLS1_3</DT>
<DD>
This parameter indicates that the connection to the server will be made
-over the SSL port, but using the TLSv1.3 protocol, instead of the usual
-SSLv3 or SSLv2 protocols.
-Alpine must be linked with an SSL library for this option to be operational.
+over the SSL port, but using the TLSv1.3 protocol.
+Alpine must be linked with an SSL library that supports this encryption
+protocol for this option to be operational.
<P>
-<CENTER><SAMP>/tls1_2</SAMP></CENTER>
+<CENTER><SAMP>/tls1_3</SAMP></CENTER>
<P>
-
</DD>
-
<DT>NoValidate-Cert</DT>
<DD>Do not validate certificates (for TLS or SSL connections) from the server.
This is needed if the server uses self-signed certificates or if Alpine
-cannot validate the certificate for some other known reason.
+cannot validate the certificate for some other known reason. You should avoid
+using this option, and instead install the certificate of the server, so you
+are not a victim of a cracker-in-the-middle attack.
<P>
</DD>
@@ -25704,6 +25694,63 @@ However, disabling the relevant authenticator avoids annoying error messages.
&lt;End of help on this topic&gt;
</BODY>
</HTML>
+====== h_config_encryption_range =====
+<HTML>
+<HEAD>
+<TITLE>OPTION: <!--#echo var="VAR_encryption-protocol-range"--></TITLE>
+</HEAD>
+<BODY>
+<H1>OPTION: <!--#echo var="VAR_encryption-protocol-range"--></H1>
+
+This option sets a range of encryption protocols that can be attempted when
+Alpine will try to establish a secure connection using the SSL or TLS
+protocols.
+
+<P>
+Before a secure connection to an external server is established, Alpine and the
+server will attempt to negotiate a secure connection. This part is known as the
+&quot;ClientHello&quot;. At that time Alpine will announce the version of
+encryption that it would like to establish. The server can reject that, and announce
+a different version of encryption. Once both the server and Alpine have found
+a version of encryption that they both agree on, they will both use it to start
+a secure connection.
+
+<P>
+The use of the /ssl parameter in the definition of the server will make Alpine
+attempt the highest encryption protocol that it can use, in agreement with the
+server. However, using this option, you will set limits to the versions of
+the protocols that are used. This would, for example, allow you to disable the use
+of ssl3, in favor of more modern protocols.
+
+<P>
+For purposes of this option, the protocols are sorted
+as follows
+
+<P>
+<CENTER>
+no_min < ssl3 < tls1 < tls1_1 < tls1_2 < tls1_3 < no_max
+</CENTER>
+
+<P>
+For example, if you want to disable ssl3, all you have to do is to set the minimum
+version to tls1, or any higher protocol.
+
+<P>The name of the parameters used to configure this option is the same as the
+parameters that are added to the definition of a server to make it a secure
+connection, and they are listed above for your reference.
+
+<P>
+The special values &quot;no_min&quot; and &quot;no_max&quot; do not set values
+for the minimum and maximum protocol versions, and Alpine will use the maximum
+and minimum values of encryption protocols built into your SSL library.
+
+<P>
+<UL>
+<LI><A HREF="h_finding_help">Finding more information and requesting help</A>
+</UL><P>
+&lt;End of help on this topic&gt;
+</BODY>
+</HTML>
====== h_config_abook_metafile =====
<HTML>
<HEAD>