summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEduardo Chappa <chappa@washington.edu>2020-07-18 00:53:34 -0600
committerEduardo Chappa <chappa@washington.edu>2020-07-18 00:53:34 -0600
commitef159279c142ec4f3b3a1938cfeadc74d5891070 (patch)
tree6a670c9b33666abcb81c824bb36fdc7c920d697d
parent50f4fdaa40ab3195377f22243c3ba4287389d207 (diff)
downloadalpine-ef159279c142ec4f3b3a1938cfeadc74d5891070.tar.xz
* Addition of the variables User Certs Dir and User Certs File, which allow
a user to specify the location of server certificates that the user trusts.
-rw-r--r--alpine/alpine.c2
-rw-r--r--alpine/confscroll.c2
-rwxr-xr-xconfigure10
-rw-r--r--configure.ac2
-rw-r--r--imap/src/c-client/mail.h8
-rw-r--r--imap/src/osdep/nt/env_nt.c16
-rw-r--r--imap/src/osdep/nt/ssl_libressl.c6
-rw-r--r--imap/src/osdep/unix/env_unix.c16
-rw-r--r--imap/src/osdep/unix/ssl_unix.c5
-rw-r--r--include/config.h.in6
-rw-r--r--pith/conf.c97
-rw-r--r--pith/conf.h6
-rw-r--r--pith/conftype.h2
-rw-r--r--pith/pine.hlp80
14 files changed, 249 insertions, 9 deletions
diff --git a/alpine/alpine.c b/alpine/alpine.c
index a2585af..5182e86 100644
--- a/alpine/alpine.c
+++ b/alpine/alpine.c
@@ -475,6 +475,8 @@ main(int argc, char **argv)
#if !defined(_WINDOWS) || defined(WINDOWS_UNIXSSL_CERTS)
set_system_certs_path(pine_state);
set_system_certs_container(pine_state);
+ set_user_certs_path(pine_state);
+ set_user_certs_container(pine_state);
#endif
#ifdef SMIME
diff --git a/alpine/confscroll.c b/alpine/confscroll.c
index 67b1570..4f36642 100644
--- a/alpine/confscroll.c
+++ b/alpine/confscroll.c
@@ -5782,6 +5782,8 @@ fix_side_effects(struct pine *ps, struct variable *var, int revert)
#if !defined(_WINDOWS) || defined(ENABLE_WINDOWS_UNIXSSL_CERTS)
var == &ps->vars[V_SSLCAPATH] ||
var == &ps->vars[V_SSLCAFILE] ||
+ var == &ps->vars[V_USERSSLCAPATH] ||
+ var == &ps->vars[V_USERSSLCAFILE] ||
#endif
var == &ps->vars[V_RSHPATH] ||
var == &ps->vars[V_RSHCMD] ||
diff --git a/configure b/configure
index 9d11f5e..d1b076d 100755
--- a/configure
+++ b/configure
@@ -16997,6 +16997,16 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_SSLUSERCAPATH ".alpine-certs"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_SSLUSERCAFILE ".alpine-certs/certs.pem"
+_ACEOF
+
+
# Check whether --with-passfile was given.
if test "${with_passfile+set}" = set; then :
diff --git a/configure.ac b/configure.ac
index 118f0ae..aee1a29 100644
--- a/configure.ac
+++ b/configure.ac
@@ -626,6 +626,8 @@ PINEVAR_UNQUOTED(default-printer, DF_DEFAULT_PRINTER, [ANSI_PRINTER], [Default p
AC_DEFINE_UNQUOTED([DF_PUBLIC_CONTAINER], "PublicContainer", [Name of default public container])
AC_DEFINE_UNQUOTED([DF_PRIVATE_CONTAINER], "PrivateContainer", [Name of default private container])
AC_DEFINE_UNQUOTED([DF_CA_CONTAINER], "CAContainer", [Name of default certificate authority container])
+AC_DEFINE_UNQUOTED([DEFAULT_SSLUSERCAPATH], ".alpine-certs", [Default directory for user trusted certificates])
+AC_DEFINE_UNQUOTED([DEFAULT_SSLUSERCAFILE], ".alpine-certs/certs.pem", [Name of default container for user trusted certificates])
dnl set PASSFILE?
AC_ARG_WITH(passfile,
diff --git a/imap/src/c-client/mail.h b/imap/src/c-client/mail.h
index 32df37b..adcad4d 100644
--- a/imap/src/c-client/mail.h
+++ b/imap/src/c-client/mail.h
@@ -196,8 +196,12 @@
#define SET_SSLCAPATH (long) 232
#define GET_SSLCAFILE (long) 233
#define SET_SSLCAFILE (long) 234
-#define GET_RESTRICTIONS (long) 235
-#define SET_RESTRICTIONS (long) 236
+#define GET_SSLAPPCAPATH (long) 235
+#define SET_SSLAPPCAPATH (long) 236
+#define GET_SSLAPPCAFILE (long) 237
+#define SET_SSLAPPCAFILE (long) 238
+#define GET_RESTRICTIONS (long) 239
+#define SET_RESTRICTIONS (long) 240
/* 3xx: TCP/IP */
#define GET_OPENTIMEOUT (long) 300
diff --git a/imap/src/osdep/nt/env_nt.c b/imap/src/osdep/nt/env_nt.c
index 8fc72f0..52211ea 100644
--- a/imap/src/osdep/nt/env_nt.c
+++ b/imap/src/osdep/nt/env_nt.c
@@ -45,6 +45,8 @@ static int server_nli = 0; /* server and not logged in */
static int logtry = 3; /* number of login tries */
static char *sslCApath = NIL; /* non-standard CA path */
static char *sslCAfile = NIL; /* non-standard CA container */
+static char *sslAppCApath = NIL; /* App SSL Certs CA path */
+static char *sslAppCAfile = NIL; /* App SSL CA container */
/* block notification */
static blocknotify_t mailblocknotify = mm_blocknotify;
/* callback to get username */
@@ -143,6 +145,20 @@ void *env_parameters (long function,void *value)
case GET_SSLCAFILE:
ret = (void *) sslCAfile;
break;
+ case SET_SSLAPPCAPATH: /* this can be set null */
+ if (sslAppCApath) fs_give ((void **) &sslAppCApath);
+ sslAppCApath = value ? cpystr ((char *) value) : value;
+ break;
+ case GET_SSLAPPCAPATH:
+ ret = (void *) sslAppCApath;
+ break;
+ case SET_SSLCAFILE: /* this can be set null */
+ if (sslAppCAfile) fs_give ((void **) &sslAppCAfile);
+ sslAppCAfile = value ? cpystr ((char *) value) : value;
+ break;
+ case GET_SSLAPPCAFILE:
+ ret = (void *) sslAppCAfile;
+ break;
}
return ret;
}
diff --git a/imap/src/osdep/nt/ssl_libressl.c b/imap/src/osdep/nt/ssl_libressl.c
index 5270a9f..04dfb36 100644
--- a/imap/src/osdep/nt/ssl_libressl.c
+++ b/imap/src/osdep/nt/ssl_libressl.c
@@ -8,7 +8,7 @@
*
* Author: Eduardo Chappa, based on ssl_unix.c
*
- * Last Edited: January 25, 2020
+ * Last Edited: July 17, 2020
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -413,6 +413,10 @@ static char *ssl_start_work(SSLSTREAM *stream, char *host, unsigned long flags)
SSL_CTX_load_verify_locations (stream->context, CAfile, CApath);
else /* otherwise we set default paths to CAs... */
SSL_CTX_set_default_verify_paths(stream->context);
+ CAfile = (char *) mail_parameters (NIL,GET_SSLAPPCAFILE,NIL);
+ CApath = (char *) mail_parameters (NIL,GET_SSLAPPCAPATH,NIL);
+ if (CAfile != NIL || CApath != NIL)
+ SSL_CTX_load_verify_locations (stream->context, CAfile, CApath);
/* want to send client certificate? */
if (scc && (s = (*scc) ()) && (sl = strlen(s))) {
if ((cert = PEM_read_bio_X509(bio = BIO_new_mem_buf(s, sl), NIL, NIL, NIL)) != NIL) {
diff --git a/imap/src/osdep/unix/env_unix.c b/imap/src/osdep/unix/env_unix.c
index fe1b91d..afec59b 100644
--- a/imap/src/osdep/unix/env_unix.c
+++ b/imap/src/osdep/unix/env_unix.c
@@ -74,6 +74,8 @@ static char *blackBoxDir = NIL; /* black box directory name */
static char *blackBoxDefaultHome = NIL;
static char *sslCApath = NIL; /* non-standard CA path */
static char *sslCAfile = NIL; /* non-standard CA container */
+static char *sslAppCApath = NIL; /* App SSL CA path */
+static char *sslAppCAfile = NIL; /* App SSL CA container */
static short anonymous = NIL; /* is anonymous */
static short blackBox = NIL; /* is a black box */
static short closedBox = NIL; /* is a closed box (uses chroot() jail) */
@@ -354,6 +356,20 @@ void *env_parameters (long function,void *value)
case GET_SSLCAFILE:
ret = (void *) sslCAfile;
break;
+ case SET_SSLAPPCAPATH: /* this can be set null */
+ if (sslAppCApath) fs_give ((void **) &sslAppCApath);
+ sslAppCApath = value ? cpystr ((char *) value) : value;
+ break;
+ case GET_SSLAPPCAPATH:
+ ret = (void *) sslAppCApath;
+ break;
+ case SET_SSLAPPCAFILE: /* this can be set null */
+ if (sslAppCAfile) fs_give ((void **) &sslAppCAfile);
+ sslAppCAfile = value ? cpystr ((char *) value) : value;
+ break;
+ case GET_SSLAPPCAFILE:
+ ret = (void *) sslAppCAfile;
+ break;
case SET_LISTMAXLEVEL:
list_max_level = (long) value;
case GET_LISTMAXLEVEL:
diff --git a/imap/src/osdep/unix/ssl_unix.c b/imap/src/osdep/unix/ssl_unix.c
index 4ebe1ae..1f64b57 100644
--- a/imap/src/osdep/unix/ssl_unix.c
+++ b/imap/src/osdep/unix/ssl_unix.c
@@ -421,6 +421,11 @@ static char *ssl_start_work (SSLSTREAM *stream,char *host,unsigned long flags)
SSL_CTX_load_verify_locations (stream->context, CAfile, CApath);
else /* set default paths to CAs... */
SSL_CTX_set_default_verify_paths (stream->context);
+ /* Load app certificates */
+ CAfile = (char *) mail_parameters (NIL,GET_SSLAPPCAFILE,NIL);
+ CApath = (char *) mail_parameters (NIL,GET_SSLAPPCAPATH,NIL);
+ if (CAfile != NIL || CApath != NIL)
+ SSL_CTX_load_verify_locations (stream->context, CAfile, CApath);
/* want to send client certificate? */
if (scc && (s = (*scc) ()) && (sl = strlen (s))) {
if ((cert = PEM_read_bio_X509 (bio = BIO_new_mem_buf (s,sl),NIL,NIL,NIL)) != NULL) {
diff --git a/include/config.h.in b/include/config.h.in
index 134b813..834950c 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -42,6 +42,12 @@
/* Default configuration value */
#undef DEFAULT_SAVE
+/* Name of default container for user trusted certificates */
+#undef DEFAULT_SSLUSERCAFILE
+
+/* Default directory for user trusted certificates */
+#undef DEFAULT_SSLUSERCAPATH
+
/* Default configuration value */
#undef DF_AB_SORT_RULE
diff --git a/pith/conf.c b/pith/conf.c
index f856c96..e4f64c7 100644
--- a/pith/conf.c
+++ b/pith/conf.c
@@ -381,6 +381,10 @@ CONF_TXT_T cf_text_mimetype_path[] = "Sets the search path for the mimetypes con
CONF_TXT_T cf_text_system_certs_path[] = "Sets the path for the system ssl certificates issued by a trusted\n# certificate authority. Note that this could be a list of paths, if the same\n# pinerc is used in different systems. Alpine always chooses the first one that\n# it finds. Value must be an absolute path.";
CONF_TXT_T cf_text_system_certs_file[] = "Sets the path for the system ssl file container of certificates issued by a\n# certificate authority. Note that this could be a list of container files,\n# if the same pinerc is used in different systems. Alpine always chooses the,\n# first one that it finds. Value must be an absolute path.";
+
+CONF_TXT_T cf_text_user_certs_path[] = "Sets the path for additional ssl certificates that the user trusts. Note\n#that this could be a list of paths, if the same\n# pinerc is used in different systems. Alpine always chooses the first one that\n# it finds. Value must be an absolute path.";
+
+CONF_TXT_T cf_text_user_certs_file[] = "Sets the path for a file that contains certificates that a user trusts.\nNote that this could be a list of container files,\n# if the same pinerc is used in different systems. Alpine always chooses the,\n# first one that it finds. Value must be an absolute path.";
#endif
CONF_TXT_T cf_text_newmail_fifo_path[] = "Sets the filename for the newmail fifo (named pipe). Unix only.";
@@ -670,6 +674,10 @@ static struct variable variables[] = {
"System CACerts Dir", cf_text_system_certs_path},
{"system-certs-file", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
"System CACerts File", cf_text_system_certs_file},
+{"user-certs-path", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
+ "User Certs Dir", cf_text_user_certs_file},
+{"user-certs-file", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
+ "User Certs File", cf_text_user_certs_file},
#endif
{"url-viewers", 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0,
"URL-Viewers", cf_text_browser},
@@ -1740,6 +1748,56 @@ init_vars(struct pine *ps, void (*cmds_f) (struct pine *, char **))
GLO_SSLCAFILE = parse_list(DEFAULT_SSLCAFILE, 1,
PL_REMSURRQUOT, NULL);
#endif /* DEFAULT_SSLCAFILE */
+#ifdef DEFAULT_SSLUSERCAPATH
+ { char **l, path[MAXPATH+1];
+ int i;
+ l = parse_list(DEFAULT_SSLUSERCAPATH, 1,
+ PL_REMSURRQUOT, NULL);
+ if(l && *l && **l){
+ for(i = 0; l[i] && *l[i]; i++){
+ path[0] = '\0';
+ if(ps_global->VAR_OPER_DIR){
+ if(strlen(ps_global->VAR_OPER_DIR) + strlen(l[i]) < MAXPATH)
+ build_path(path, ps_global->VAR_OPER_DIR, l[i], MAXPATH);
+ }
+ else if(ps_global->home_dir){
+ if(strlen(ps_global->home_dir) + strlen(l[i]) < MAXPATH)
+ build_path(path, ps_global->home_dir, l[i], MAXPATH);
+ }
+ if(path[0]){
+ fs_give((void **) &l[i]);
+ l[i] = cpystr(path);
+ }
+ }
+ }
+ GLO_SSLUSERCAPATH = l;
+ }
+#endif /* DEFAULT_SSLUSERCAPATH */
+#ifdef DEFAULT_SSLUSERCAFILE
+ { char **l, path[MAXPATH+1];
+ int i;
+ l = parse_list(DEFAULT_SSLUSERCAFILE, 1,
+ PL_REMSURRQUOT, NULL);
+ if(l && *l && **l){
+ for(i = 0; l[i] && *l[i]; i++){
+ path[0] = '\0';
+ if(ps_global->VAR_OPER_DIR){
+ if(strlen(ps_global->VAR_OPER_DIR) + strlen(l[i]) < MAXPATH)
+ build_path(path, ps_global->VAR_OPER_DIR, l[i], MAXPATH);
+ }
+ else if(ps_global->home_dir){
+ if(strlen(ps_global->home_dir) + strlen(l[i]) < MAXPATH)
+ build_path(path, ps_global->home_dir, l[i], MAXPATH);
+ }
+ if(path[0]){
+ fs_give((void **) &l[i]);
+ l[i] = cpystr(path);
+ }
+ }
+ }
+ GLO_SSLUSERCAFILE = l;
+ }
+#endif /* DEFAULT_SSLUSERCAFILE */
#ifdef DF_VAR_SPELLER
GLO_SPELLER = cpystr(DF_VAR_SPELLER);
#endif
@@ -2379,6 +2437,8 @@ init_vars(struct pine *ps, void (*cmds_f) (struct pine *, char **))
#if !defined(_WINDOWS) || defined(WINDOWS_UNIXSSL_CERTS)
set_current_val(&vars[V_SSLCAPATH], TRUE, TRUE);
set_current_val(&vars[V_SSLCAFILE], TRUE, TRUE);
+ set_current_val(&vars[V_USERSSLCAPATH], TRUE, TRUE);
+ set_current_val(&vars[V_USERSSLCAFILE], TRUE, TRUE);
#endif
#if !defined(DOS) && !defined(OS2) && !defined(LEAVEOUTFIFO)
set_current_val(&vars[V_FIFOPATH], TRUE, TRUE);
@@ -7088,7 +7148,7 @@ set_system_certs_container(struct pine *ps)
{
char **l;
- for (l = ps->vars[V_SSLCAPATH].current_val.l; l && *l; l++){
+ for (l = ps->vars[V_SSLCAFILE].current_val.l; l && *l; l++){
if(is_absolute_path(*l)
&& can_access(*l, ACCESS_EXISTS) == 0
&& can_access(*l, READ_ACCESS) == 0){
@@ -7097,6 +7157,37 @@ set_system_certs_container(struct pine *ps)
}
}
}
+
+void
+set_user_certs_path(struct pine *ps)
+{
+ char **l;
+
+ for (l = ps->vars[V_USERSSLCAPATH].current_val.l; l && *l; l++){
+ if(is_absolute_path(*l)
+ && can_access(*l, ACCESS_EXISTS) == 0
+ && can_access(*l, READ_ACCESS) == 0){
+ mail_parameters(NULL, SET_SSLAPPCAPATH, (void *) *l);
+ break;
+ }
+ }
+}
+
+
+void
+set_user_certs_container(struct pine *ps)
+{
+ char **l;
+
+ for (l = ps->vars[V_USERSSLCAFILE].current_val.l; l && *l; l++){
+ if(is_absolute_path(*l)
+ && can_access(*l, ACCESS_EXISTS) == 0
+ && can_access(*l, READ_ACCESS) == 0){
+ mail_parameters(NULL, SET_SSLAPPCAFILE, (void *) *l);
+ break;
+ }
+ }
+}
#endif
int
@@ -7958,6 +8049,10 @@ config_help(int var, int feature)
return(h_config_system_certs_path);
case V_SSLCAFILE :
return(h_config_system_certs_file);
+ case V_USERSSLCAPATH :
+ return(h_config_user_certs_path);
+ case V_USERSSLCAFILE :
+ return(h_config_user_certs_file);
#endif
#if !defined(DOS) && !defined(OS2) && !defined(LEAVEOUTFIFO)
case V_FIFOPATH :
diff --git a/pith/conf.h b/pith/conf.h
index 100224b..90c2325 100644
--- a/pith/conf.h
+++ b/pith/conf.h
@@ -138,6 +138,10 @@
#define GLO_SSLCAPATH vars[V_SSLCAPATH].global_val.l
#define VAR_SSLCAFILE vars[V_SSLCAFILE].current_val.l
#define GLO_SSLCAFILE vars[V_SSLCAFILE].global_val.l
+#define VAR_SSLUSERCAPATH vars[V_USERSSLCAPATH].current_val.l
+#define GLO_SSLUSERCAPATH vars[V_USERSSLCAPATH].global_val.l
+#define VAR_SSLUSERCAFILE vars[V_USERSSLCAFILE].current_val.l
+#define GLO_SSLUSERCAFILE vars[V_USERSSLCAFILE].global_val.l
#endif
#define VAR_INDEX_COLOR_STYLE vars[V_INDEX_COLOR_STYLE].current_val.p
#define GLO_INDEX_COLOR_STYLE vars[V_INDEX_COLOR_STYLE].global_val.p
@@ -919,6 +923,8 @@ void panic1(char *, char *);
#if !defined(_WINDOWS) || defined(WINDOWS_UNIXSSL_CERTS)
void set_system_certs_path(struct pine *);
void set_system_certs_container(struct pine *);
+void set_user_certs_path(struct pine *);
+void set_user_certs_container(struct pine *);
#endif
/* mandatory to implement prototypes */
diff --git a/pith/conftype.h b/pith/conftype.h
index 4ea7993..3ed5040 100644
--- a/pith/conftype.h
+++ b/pith/conftype.h
@@ -127,6 +127,8 @@ typedef enum { V_PERSONAL_NAME = 0
#if !defined(_WINDOWS) || defined(WINDOWS_UNIXSSL_CERTS)
, V_SSLCAPATH
, V_SSLCAFILE
+ , V_USERSSLCAPATH
+ , V_USERSSLCAFILE
#endif
, V_BROWSER
, V_HISTORY
diff --git a/pith/pine.hlp b/pith/pine.hlp
index c6c1a2e..b9729c7 100644
--- a/pith/pine.hlp
+++ b/pith/pine.hlp
@@ -140,7 +140,7 @@ with help text for the config screen and the composer that didn't have any
reasonable place to be called from.
Dummy change to get revision in pine.hlp
============= h_revision =================
-Alpine Commit 494 2020-07-17 01:43:03
+Alpine Commit 495 2020-07-18 00:53:30
============= h_news =================
<HTML>
<HEAD>
@@ -192,7 +192,7 @@ problems you find with this release.
<UL>
<LI> Expansion of the configuration screen for XOAUTH2 to include
- username, and tenant.
+ username, authorization flow, and tenant.
<LI> If a user has more than one client-id for a service, Alpine tries to
asks the user which client-id to use and associates that client-id to
@@ -241,6 +241,11 @@ problems you find with this release.
<LI> Experimental: Attempt to implement the Encryption Range in Windows. It works
in Windows 10, and it should work in Windows 8.1. It needs testing in
Windows 7 and Windows Vista.
+
+<LI> Addition of variables <A HREF="h_config_user_certs_path"><!--#echo var="VAR_user-certs-path"--></A>
+ and <A HREF="h_config_user_certs_file"><!--#echo var="VAR_user-certs-file"--></A>
+ which allow a user to specify locations for certificates that the user
+ trusts.
</UL>
<P>
@@ -22518,9 +22523,9 @@ allows for users to be able to use the same pinerc file in different systems.
Example of values for this option might be:
<PRE>
-System Certs Path = /etc/ssl/certs/cert.pem
- /usr/local/ssl/ca-root-nss.crt
- C:\\libressl\\ssl\\certs\\cert.pem
+System CACerts File = /etc/ssl/certs/cert.pem
+ /usr/local/ssl/ca-root-nss.crt
+ C:\\libressl\\ssl\\certs\\cert.pem
<PRE>
<P>
@@ -22536,6 +22541,71 @@ by LibreSSL developers, and this option can be used to override this default.
<P>
&lt;End of help on this topic&gt;
</BODY></HTML>
+====== h_config_user_certs_path ======
+<HTML>
+<HEAD>
+<TITLE>OPTION: <!--#echo var="VAR_user-certs-path"--></TITLE>
+</HEAD>
+<BODY>
+<H1>OPTION: <!--#echo var="VAR_user-certs-path"--></H1>
+
+(UNIX ALPINE ONLY)
+This directory is used by Alpine to store certificates that a user
+trusts. Alpine will use the first directory in this list that exists in your
+system and can be accessed. This allows for users to be able to
+use the same pinerc file in different systems. The default location
+is ~/.alpine-certs.
+
+<P>
+In addition to the certificates stored in this directory, Alpine also
+trusts certificates saved in the container file referenced in the
+configuration variable
+<A HREF="h_config_user_certs_file"><!--#echo var="VAR_user-certs-file"--></A>.
+
+<P>
+Example of values for this option might be:
+
+<PRE>
+User Certs Dir = /home/fred/.alpine-certs
+ C:\\Users\\Admin\\alpine-certs
+<PRE>
+
+<P>
+&lt;End of help on this topic&gt;
+</BODY></HTML>
+====== h_config_user_certs_file ======
+<HTML>
+<HEAD>
+<TITLE>OPTION: <!--#echo var="VAR_user-certs-file"--></TITLE>
+</HEAD>
+<BODY>
+<H1>OPTION: <!--#echo var="VAR_user-certs-file"--></H1>
+
+(UNIX ALPINE ONLY)
+This option sets the location of a container file that holds certificate
+authority (CA) certificates that the user trusts. Its value is the
+full path referencing the location of this file. Alpine will use the first
+container in this list that exists and can be accessed in your system. This
+allows for users to be able to use the same pinerc file in different
+systems. The default location is ~/.alpine-certs/certs.pem.
+
+<P>
+In addition to the certificates stored in this directory, Alpine also
+trusts certificates saved in the directory referenced in the
+configuration variable
+<A HREF="h_config_user_certs_path"><!--#echo var="VAR_user-certs-path"--></A>.
+
+<P>
+Example of values for this option might be:
+
+<PRE>
+User Certs File = /home/fred/.alpine-certs/certs.pem
+ C:\\libressl\\ssl\\certs\\cert.pem
+<PRE>
+
+<P>
+&lt;End of help on this topic&gt;
+</BODY></HTML>
====== h_config_set_att_ansi ======
<HTML><HEAD>
<TITLE>OPTION: Set printer to attached ansi printer</TITLE>