summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2020-03-22 21:07:19 +0200
committerSergey Poznyakoff <gray@gnu.org>2020-03-22 21:07:19 +0200
commit13a4975430ad6d0992bb18325bbc990d1bd890fe (patch)
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.
-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 2e0c14d4f..435be73de 100644
--- a/imap4d/imap4d.c
+++ b/imap4d/imap4d.c
@@ -535,2 +535,8 @@ static struct mu_cfg_param imap4d_cfg_param[] = {
{ "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,
@@ -938,8 +944,2 @@ main (int argc, char **argv)
- if (mu_gsasl_enabled ())
- {
- auth_gssapi_init ();
- auth_gsasl_init ();
- }
-
#ifdef USE_LIBPAM
@@ -1011,2 +1011,8 @@ main (int argc, char **argv)
{
+ if (mu_gsasl_enabled ())
+ {
+ auth_gssapi_init ();
+ auth_gsasl_init ();
+ }
+
mu_m_server_begin (server);
@@ -1020,3 +1026,32 @@ main (int argc, char **argv)
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. */
diff --git a/imap4d/imap4d.h b/imap4d/imap4d.h
index 04b9060a4..da4626fe7 100644
--- a/imap4d/imap4d.h
+++ b/imap4d/imap4d.h
@@ -227,3 +227,4 @@ extern jmp_buf child_jmp;
extern struct mu_tls_config global_tls_conf;
-
+extern int global_tls_mode;
+
extern int test_mode;
@@ -347,2 +348,3 @@ extern int imap4d_starttls (struct imap4d_session *,
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 *);
diff --git a/imap4d/starttls.c b/imap4d/starttls.c
index 4ac540939..2d9e03269 100644
--- a/imap4d/starttls.c
+++ b/imap4d/starttls.c
@@ -18,2 +18,4 @@
+static int global_conf_status = -1;
+int global_tls_mode;
struct mu_tls_config global_tls_conf;
@@ -70,2 +72,66 @@ 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)
@@ -77,8 +143,2 @@ starttls_init (mu_m_server_t msrv)
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;
@@ -92,42 +152,8 @@ starttls_init (mu_m_server_t msrv)
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;
@@ -135,4 +161,2 @@ starttls_init (mu_m_server_t msrv)
default:
- mu_error (_("server %s: TLS configuration failed"),
- mu_ip_server_addrstr (ipsrv));
errors = 1;
@@ -144,2 +168,5 @@ starttls_init (mu_m_server_t msrv)
+ if (global_tls_mode == tls_unspecified)
+ global_tls_mode = tls_no;
+
if (tls_requested && !tls_ok)

Return to:

Send suggestions and report system problems to the System administrator.