summaryrefslogtreecommitdiffabout
authorSergey Poznyakoff <gray@gnu.org.ua>2019-08-29 11:40:30 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2019-08-29 12:09:27 (GMT)
commitddfa689bff19d877170add6fed3381f3d5b79a8e (patch) (side-by-side diff)
tree9e2f3a0f53569afc9a67ee92bc3b885ec39e76cb
parent113e144dedbebb5bc659eadc7f329450bb374606 (diff)
downloadmailutils-ddfa689bff19d877170add6fed3381f3d5b79a8e.tar.gz
mailutils-ddfa689bff19d877170add6fed3381f3d5b79a8e.tar.bz2
pop3d: implement TLS in inetd mode
New global configuration statement "tls-mode" configures the TLS for use in inetd mode. The certificate and key files are configured by the global "tls" compound statement. Example configuration (pop3s server): mode inetd; tls-mode connection; tls { ssl-key-file /etc/ssl/key.pem; ssl-certificate-file /etc/ssl/cert.pem; } In daemon mode, global "tls-mode" sets the type of TLS encryption to use in all server blocks that lack the "tls-mode" statement. * pop3d/cmd.c (global_tls_mode) (global_conf_status): New globals. (stls_server_check): New function. (stls_preflight): Use stls_server_check. * pop3d/pop3d.c (pop3d_cfg_param): New global statement: tls-mode (main): Set up TLS connection in inetd mode, if requested. * pop3d/pop3d.h (global_tls_mode): New global. (stls_server_check): New proto. * NEWS: Document changes. * doc/texinfo/programs/pop3d.texi: Likewise.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--NEWS20
-rw-r--r--doc/texinfo/programs/pop3d.texi33
-rw-r--r--pop3d/cmd.c116
-rw-r--r--pop3d/pop3d.c31
-rw-r--r--pop3d/pop3d.h2
5 files changed, 151 insertions, 51 deletions
diff --git a/NEWS b/NEWS
index 6b16f17..251f5a8 100644
--- a/NEWS
+++ b/NEWS
@@ -1,10 +1,28 @@
-GNU mailutils NEWS -- history of user-visible changes. 2019-06-21
+GNU mailutils NEWS -- history of user-visible changes. 2019-08-29
Copyright (C) 2002-2019 Free Software Foundation, Inc.
See the end of file for copying conditions.
Please send mailutils bug reports to <bug-mailutils@gnu.org>.
Version 3.7.90 (git)
+
+* Use of TLS in pop3d run from inetd
+
+New global configuration statement "tls-mode" configures the TLS for
+use in inetd mode.
+
+The certificate and key files are configured by the global "tls"
+compound statement.
+
+Example configuration (pop3s server):
+
+ mode inetd;
+ tls-mode connection;
+ tls {
+ ssl-key-file /etc/ssl/key.pem;
+ ssl-certificate-file /etc/ssl/cert.pem;
+ }
+
Version 3.7 - 2019-06-21
diff --git a/doc/texinfo/programs/pop3d.texi b/doc/texinfo/programs/pop3d.texi
index 93ace2f..b508bf5 100644
--- a/doc/texinfo/programs/pop3d.texi
+++ b/doc/texinfo/programs/pop3d.texi
@@ -213,6 +213,34 @@ The following configuration file statements affect the behavior of
@item tcp-wrappers @tab @xref{tcp-wrappers statement}.
@end multitable
+@deffn {Pop3d Conf} tls-mode @var{mode}
+Configure the use of TLS encryption for inetd mode.
+
+In daemon mode, this statement sets the type of TLS encryption to
+use in all server blocks that lack the @code{tls-mode} statement
+(@pxref{Server Statement}).
+
+Allowed values for @var{mode} are:
+
+@table @asis
+@item no
+TLS is not used. The @command{STLS} command won't be available even if
+the TLS configuration is otherwise complete.
+
+@item ondemand
+TLS is initiated when the user issues the appropriate command.
+This is the default when TLS is configured.
+
+@item required
+Same as above, but the use of TLS is mandatory. The authentication
+state is entered only after TLS negotiation has succeeded.
+
+@item connection
+TLS is always forced when the connection is established (POP3S
+protocol).
+@end table
+@end deffn
+
@deffn {Pop3d Conf} undelete @var{bool}
On startup, clear deletion marks from all the messages.
@end deffn
@@ -227,11 +255,6 @@ Delete expired messages upon closing the mailbox. @xref{Auto-expire},
for a detailed description.
@end deffn
-@deffn {Pop3d Conf} tls-required @var{bool}
-Always require @code{STLS} command before entering authentication
-phase.
-@end deffn
-
@deffn {Pop3d Conf} login-delay @var{duration}
Set the minimal allowed delay between two successive logins.
@xref{Login delay}, for more information.
diff --git a/pop3d/cmd.c b/pop3d/cmd.c
index 5ca7b7b..1ed73c2 100644
--- a/pop3d/cmd.c
+++ b/pop3d/cmd.c
@@ -17,6 +17,8 @@
#include "pop3d.h"
struct mu_tls_config global_tls_conf;
+int global_tls_mode;
+int global_conf_status = -1;
static struct pop3d_command command_table[] = {
{ "STLS", pop3d_stls },
@@ -49,6 +51,70 @@ pop3d_find_command (const char *name)
}
int
+stls_server_check (struct pop3d_srv_config *cfg, char const *srvid)
+{
+ int result;
+
+ switch (cfg->tls_mode)
+ {
+ case tls_unspecified:
+ if (global_tls_mode != tls_unspecified)
+ cfg->tls_mode = global_tls_mode;
+ else if (cfg->tls_conf.cert_file)
+ cfg->tls_mode = tls_ondemand;
+ else
+ {
+ cfg->tls_mode = tls_no;
+ return MU_TLS_CONFIG_NULL;
+ }
+ break;
+
+ case tls_no:
+ return MU_TLS_CONFIG_NULL;
+
+ default:
+ break;
+ }
+
+ result = mu_tls_config_check (&cfg->tls_conf, 1);
+ switch (result)
+ {
+ case MU_TLS_CONFIG_OK:
+ if (!cfg->tls_conf.cert_file)
+ {
+ mu_error (_("server %s: no certificate set"), srvid);
+ result = MU_TLS_CONFIG_FAIL;
+ }
+ break;
+
+ case MU_TLS_CONFIG_NULL:
+ if (global_conf_status == -1)
+ {
+ if (global_tls_conf.cert_file)
+ global_conf_status = mu_tls_config_check (&global_tls_conf, 1);
+ else
+ global_conf_status = MU_TLS_CONFIG_NULL;
+ }
+
+ if (global_conf_status != MU_TLS_CONFIG_NULL)
+ {
+ cfg->tls_conf = global_tls_conf;
+ result = MU_TLS_CONFIG_OK;
+ }
+ else
+ {
+ mu_error (_("server %s: no certificate set"), srvid);
+ result = MU_TLS_CONFIG_FAIL;
+ }
+ break;
+
+ default:
+ mu_error (_("server %s: TLS configuration failed"), srvid);
+ }
+ return result;
+}
+
+int
stls_preflight (mu_m_server_t msrv)
{
mu_list_t srvlist;
@@ -56,13 +122,7 @@ stls_preflight (mu_m_server_t msrv)
int errors = 0;
int tls_ok = mu_init_tls_libs ();
int tls_requested = 0;
- int global_conf_status = 0;
- if (global_tls_conf.cert_file)
- global_conf_status = mu_tls_config_check (&global_tls_conf, 1);
- else
- global_conf_status = MU_TLS_CONFIG_NULL;
-
mu_m_server_get_srvlist (msrv, &srvlist);
mu_list_get_iterator (srvlist, &itr);
for (mu_iterator_first (itr); !mu_iterator_is_done (itr); mu_iterator_next (itr))
@@ -71,51 +131,16 @@ stls_preflight (mu_m_server_t msrv)
struct pop3d_srv_config *cfg;
mu_iterator_current (itr, (void**) &ipsrv);
cfg = mu_ip_server_get_data (ipsrv);
- switch (cfg->tls_mode)
+
+ switch (stls_server_check (cfg, mu_ip_server_addrstr (ipsrv)))
{
- case tls_unspecified:
- if (cfg->tls_conf.cert_file)
- {
- cfg->tls_mode = tls_ondemand;
- break;
- }
- else
- cfg->tls_mode = tls_no;
- /* fall through */
- case tls_no:
+ case MU_TLS_CONFIG_NULL:
continue;
-
- default:
- break;
- }
- switch (mu_tls_config_check (&cfg->tls_conf, 1))
- {
case MU_TLS_CONFIG_OK:
- if (!cfg->tls_conf.cert_file)
- {
- mu_error (_("server %s: no certificate set"),
- mu_ip_server_addrstr (ipsrv));
- errors = 1;
- }
- break;
-
- case MU_TLS_CONFIG_NULL:
- if (global_conf_status != MU_TLS_CONFIG_NULL)
- {
- cfg->tls_conf = global_tls_conf;
- }
- else
- {
- mu_error (_("server %s: no certificate set"),
- mu_ip_server_addrstr (ipsrv));
- errors = 1;
- }
break;
default:
- mu_error (_("server %s: TLS configuration failed"),
- mu_ip_server_addrstr (ipsrv));
errors = 1;
}
@@ -123,6 +148,9 @@ stls_preflight (mu_m_server_t msrv)
}
mu_iterator_destroy (&itr);
+ if (global_tls_mode == tls_unspecified)
+ global_tls_mode = tls_no;
+
if (tls_requested && !tls_ok)
{
mu_error (_("TLS is not configured, but requested in the "
diff --git a/pop3d/pop3d.c b/pop3d/pop3d.c
index a993b9d..f400f2b 100644
--- a/pop3d/pop3d.c
+++ b/pop3d/pop3d.c
@@ -231,6 +231,12 @@ static struct mu_cfg_param pop3d_cfg_param[] = {
N_("arg: list") },
{ "tls", mu_cfg_section, &global_tls_conf },
+ { "tls-mode", mu_cfg_callback,
+ &global_tls_mode, 0, cb_tls,
+ N_("Kind of TLS encryption to use for the inetd server"
+ " and all server blocks that lack the tls-mode statement."),
+ /* TRANSLATORS: words to the right of : are keywords - do not translate */
+ N_("arg: false|true|ondemand|stls|requred|connection") },
#ifdef ENABLE_LOGIN_DELAY
{ "login-delay", mu_c_time, &login_delay, 0, NULL,
@@ -530,7 +536,30 @@ main (int argc, char **argv)
{
struct pop3d_srv_config cfg;
memset (&cfg, 0, sizeof cfg);
- cfg.tls_mode = tls_no;
+
+ switch (stls_server_check (&cfg, "<inetd>"))
+ {
+ case MU_TLS_CONFIG_OK:
+ if (mu_init_tls_libs ())
+ status = EX_OK;
+ else
+ {
+ mu_error (_("TLS is not configured, but requested in the "
+ "configuration"));
+ exit (EX_CONFIG);
+ }
+ break;
+
+ case MU_TLS_CONFIG_NULL:
+ break;
+
+ case MU_TLS_CONFIG_UNSAFE:
+ exit (EX_CONFIG);
+
+ default:
+ exit (EX_UNAVAILABLE);
+ }
+
/* Make sure we are in the root directory. */
chdir ("/");
status = pop3d_mainloop (MU_STDIN_FD, MU_STDOUT_FD, &cfg);
diff --git a/pop3d/pop3d.h b/pop3d/pop3d.h
index c040a02..efd1156 100644
--- a/pop3d/pop3d.h
+++ b/pop3d/pop3d.h
@@ -248,6 +248,7 @@ extern uid_t apop_database_owner;
extern int apop_database_owner_set;
extern struct mu_tls_config global_tls_conf;
+extern int global_tls_mode;
/* Safety checks for group-rw database files, such as stat and bulletin
databases */
@@ -291,6 +292,7 @@ extern RETSIGTYPE pop3d_child_signal (int);
extern int pop3d_stls (char *, struct pop3d_session *);
int stls_preflight (mu_m_server_t msrv);
+int stls_server_check (struct pop3d_srv_config *cfg, char const *srvid);
extern void pop3d_outf (const char *fmt, ...) MU_PRINTFLIKE(1,2);

Return to:

Send suggestions and report system problems to the System administrator.