summaryrefslogtreecommitdiffabout
authorSergey Poznyakoff <gray@gnu.org>2020-03-22 19:07:19 (GMT)
committer Sergey Poznyakoff <gray@gnu.org>2020-03-22 19:07:19 (GMT)
commit13a4975430ad6d0992bb18325bbc990d1bd890fe (patch) (side-by-side diff)
tree003428b3661883d71da93e6fbed4b40845d6638f
parente1e7e02cf9324e542e275db890535240f75ecce3 (diff)
downloadmailutils-13a4975430ad6d0992bb18325bbc990d1bd890fe.tar.gz
mailutils-13a4975430ad6d0992bb18325bbc990d1bd890fe.tar.bz2
imap4d: implement TLS in inetd mode
This is a follow-up to commit ddfa689bff. It also fixes possible bug in daemon mode: calls to auth_gssapi_init and auth_gsasl_init should appear after eventual demonization (mu_m_server_begin), since the latter may close file descriptors opened by them.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--imap4d/imap4d.c49
-rw-r--r--imap4d/imap4d.h4
-rw-r--r--imap4d/starttls.c115
3 files changed, 116 insertions, 52 deletions
diff --git a/imap4d/imap4d.c b/imap4d/imap4d.c
index 2e0c14d..435be73 100644
--- a/imap4d/imap4d.c
+++ b/imap4d/imap4d.c
@@ -533,6 +533,12 @@ static struct mu_cfg_param imap4d_cfg_param[] = {
N_("Retain these supplementary groups when switching to user privileges"),
N_("groups: list of string") },
{ "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") },
{ "preauth", mu_cfg_callback, NULL, 0, cb_preauth,
N_("Configure PREAUTH mode. <value> is one of:\n"
" prog:///<full-program-name: string>\n"
@@ -936,12 +942,6 @@ main (int argc, char **argv)
if (login_disabled)
imap4d_capability_add (IMAP_CAPA_LOGINDISABLED);
- if (mu_gsasl_enabled ())
- {
- auth_gssapi_init ();
- auth_gsasl_init ();
- }
-
#ifdef USE_LIBPAM
if (!mu_pam_service)
mu_pam_service = "gnu-imap4d";
@@ -1009,6 +1009,12 @@ main (int argc, char **argv)
/* Actually run the daemon. */
if (mu_m_server_mode (server) == MODE_DAEMON)
{
+ if (mu_gsasl_enabled ())
+ {
+ auth_gssapi_init ();
+ auth_gsasl_init ();
+ }
+
mu_m_server_begin (server);
status = mu_m_server_run (server);
mu_m_server_end (server);
@@ -1018,7 +1024,36 @@ main (int argc, char **argv)
{
struct imap4d_srv_config cfg;
memset (&cfg, 0, sizeof cfg);
- cfg.tls_mode = tls_no;
+
+ if (mu_gsasl_enabled ())
+ {
+ auth_gssapi_init ();
+ auth_gsasl_init ();
+ }
+
+ switch (starttls_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 = imap4d_mainloop (MU_STDIN_FD, MU_STDOUT_FD, &cfg);
diff --git a/imap4d/imap4d.h b/imap4d/imap4d.h
index 04b9060..da4626f 100644
--- a/imap4d/imap4d.h
+++ b/imap4d/imap4d.h
@@ -225,7 +225,8 @@ extern int imap4d_argc;
extern char **imap4d_argv;
extern jmp_buf child_jmp;
extern struct mu_tls_config global_tls_conf;
-
+extern int global_tls_mode;
+
extern int test_mode;
extern int silent_expunge;
@@ -345,6 +346,7 @@ extern int imap4d_select_status (void);
extern int imap4d_starttls (struct imap4d_session *,
struct imap4d_command *, imap4d_tokbuf_t);
int starttls_init (mu_m_server_t msrv);
+int starttls_server_check (struct imap4d_srv_config *cfg, char const *srvid);
void tls_encryption_on (struct imap4d_session *);
extern int imap4d_status (struct imap4d_session *,
struct imap4d_command *, imap4d_tokbuf_t);
diff --git a/imap4d/starttls.c b/imap4d/starttls.c
index 4ac5409..2d9e032 100644
--- a/imap4d/starttls.c
+++ b/imap4d/starttls.c
@@ -16,6 +16,8 @@
#include "imap4d.h"
+static int global_conf_status = -1;
+int global_tls_mode;
struct mu_tls_config global_tls_conf;
/*
@@ -68,6 +70,70 @@ tls_encryption_on (struct imap4d_session *session)
}
int
+starttls_server_check (struct imap4d_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
starttls_init (mu_m_server_t msrv)
{
mu_list_t srvlist;
@@ -75,12 +141,6 @@ starttls_init (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);
@@ -90,51 +150,15 @@ starttls_init (mu_m_server_t msrv)
struct imap4d_srv_config *cfg;
mu_iterator_current (itr, (void**) &ipsrv);
cfg = mu_ip_server_get_data (ipsrv);
- switch (cfg->tls_mode)
+ switch (starttls_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;
}
@@ -142,6 +166,9 @@ starttls_init (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 "

Return to:

Send suggestions and report system problems to the System administrator.