summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2019-08-29 14:40:30 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2019-08-29 15:09:27 +0300
commitddfa689bff19d877170add6fed3381f3d5b79a8e (patch)
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.
-rw-r--r--NEWS20
-rw-r--r--doc/texinfo/programs/pop3d.texi33
-rw-r--r--pop3d/cmd.c98
-rw-r--r--pop3d/pop3d.c31
-rw-r--r--pop3d/pop3d.h2
5 files changed, 142 insertions, 42 deletions
diff --git a/NEWS b/NEWS
index 6b16f1706..251f5a80b 100644
--- a/NEWS
+++ b/NEWS
@@ -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);

Return to:

Send suggestions and report system problems to the System administrator.