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 | 98 | ||||
-rw-r--r-- | pop3d/pop3d.c | 31 | ||||
-rw-r--r-- | pop3d/pop3d.h | 2 |
5 files changed, 142 insertions, 42 deletions
@@ -1,14 +1,32 @@ -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 * Support for the new mailbox format - dotmail Dotmail is a replacement for traditional mbox format, proposed by Kurt Hackenberg. A dotmail mailbox is a single disk file, where 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 @@ -210,12 +210,40 @@ The following configuration file statements affect the behavior of @item auth @tab @xref{auth statement}. @item server @tab @xref{Server Settings}. @item acl @tab @xref{acl statement}. @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 @deffn {Pop3d Conf} expire @var{n} Automatically expire read messages after @var{n} @@ -224,17 +252,12 @@ days. @xref{Auto-expire}, for a detailed description. @deffn {Pop3d Conf} delete-expired @var{bool} 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. @end deffn @deffn {Pop3d Conf} stat-file @var{file} diff --git a/pop3d/cmd.c b/pop3d/cmd.c index 5ca7b7b86..1ed73c237 100644 --- a/pop3d/cmd.c +++ b/pop3d/cmd.c @@ -14,12 +14,14 @@ You should have received a copy of the GNU General Public License along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ #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 }, { "RETR", pop3d_retr }, { "DELE", pop3d_dele }, { "USER", pop3d_user }, @@ -46,86 +48,112 @@ pop3d_find_command (const char *name) return p->handler; } return p->handler; } int -stls_preflight (mu_m_server_t msrv) +stls_server_check (struct pop3d_srv_config *cfg, char const *srvid) { - mu_list_t srvlist; - mu_iterator_t itr; - int errors = 0; - int tls_ok = mu_init_tls_libs (); - int tls_requested = 0; - int global_conf_status = 0; + int result; - 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)) - { - mu_ip_server_t ipsrv; - struct pop3d_srv_config *cfg; - mu_iterator_current (itr, (void**) &ipsrv); - cfg = mu_ip_server_get_data (ipsrv); switch (cfg->tls_mode) { case tls_unspecified: - if (cfg->tls_conf.cert_file) - { + if (global_tls_mode != tls_unspecified) + cfg->tls_mode = global_tls_mode; + else if (cfg->tls_conf.cert_file) cfg->tls_mode = tls_ondemand; - break; - } else + { cfg->tls_mode = tls_no; - /* fall through */ + return MU_TLS_CONFIG_NULL; + } + break; + case tls_no: - continue; + return MU_TLS_CONFIG_NULL; default: break; } - switch (mu_tls_config_check (&cfg->tls_conf, 1)) + 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"), - mu_ip_server_addrstr (ipsrv)); - errors = 1; + 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"), - mu_ip_server_addrstr (ipsrv)); - errors = 1; + mu_error (_("server %s: no certificate set"), srvid); + result = MU_TLS_CONFIG_FAIL; } break; default: - mu_error (_("server %s: TLS configuration failed"), - mu_ip_server_addrstr (ipsrv)); + mu_error (_("server %s: TLS configuration failed"), srvid); + } + return result; +} + +int +stls_preflight (mu_m_server_t msrv) +{ + mu_list_t srvlist; + mu_iterator_t itr; + int errors = 0; + int tls_ok = mu_init_tls_libs (); + int tls_requested = 0; + + 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)) + { + mu_ip_server_t ipsrv; + struct pop3d_srv_config *cfg; + mu_iterator_current (itr, (void**) &ipsrv); + cfg = mu_ip_server_get_data (ipsrv); + + switch (stls_server_check (cfg, mu_ip_server_addrstr (ipsrv))) + { + case MU_TLS_CONFIG_NULL: + continue; + + case MU_TLS_CONFIG_OK: + break; + + default: errors = 1; } tls_requested = 1; } 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 " "configuration")); errors = 1; } diff --git a/pop3d/pop3d.c b/pop3d/pop3d.c index a993b9dc2..f400f2b26 100644 --- a/pop3d/pop3d.c +++ b/pop3d/pop3d.c @@ -228,12 +228,18 @@ static struct mu_cfg_param pop3d_cfg_param[] = { " linkwrdir forbid symbolic links in group or world writable directories\n" " gwrdir forbid files in group writable directories\n" " awrdir forbid files in world writable directories\n"), 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, N_("Set the minimal allowed delay between two successive logins.") }, { "stat-file", mu_c_string, &login_stat_file, 0, NULL, N_("Set the name of login statistics file (for login-delay).") }, @@ -527,13 +533,36 @@ main (int argc, char **argv) mu_m_server_destroy (&server); } else { 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); } if (status) diff --git a/pop3d/pop3d.h b/pop3d/pop3d.h index c040a02bd..efd115644 100644 --- a/pop3d/pop3d.h +++ b/pop3d/pop3d.h @@ -245,12 +245,13 @@ extern int pop3d_xlines; extern char *apop_database_name; extern int apop_database_safety; 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 */ #define DEFAULT_GROUP_DB_SAFETY \ (MU_FILE_SAFETY_WORLD_WRITABLE| \ @@ -288,12 +289,13 @@ extern void pop3d_parse_command (char *cmd, char **pcmd, char **parg); extern RETSIGTYPE pop3d_master_signal (int); 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); extern void pop3d_setio (int, int, struct mu_tls_config *); extern char *pop3d_readline (char *, size_t); extern void pop3d_flush_output (void); |