diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2019-08-29 14:40:30 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2019-08-29 15:09:27 +0300 |
commit | ddfa689bff19d877170add6fed3381f3d5b79a8e (patch) | |
tree | 9e2f3a0f53569afc9a67ee92bc3b885ec39e76cb | |
parent | 113e144dedbebb5bc659eadc7f329450bb374606 (diff) | |
download | mailutils-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.
-rw-r--r-- | NEWS | 20 | ||||
-rw-r--r-- | doc/texinfo/programs/pop3d.texi | 33 | ||||
-rw-r--r-- | pop3d/cmd.c | 116 | ||||
-rw-r--r-- | pop3d/pop3d.c | 31 | ||||
-rw-r--r-- | pop3d/pop3d.h | 2 |
5 files changed, 151 insertions, 51 deletions
@@ -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 93ace2fff..b508bf534 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 5ca7b7b86..1ed73c237 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 a993b9dc2..f400f2b26 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 c040a02bd..efd115644 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); |