diff options
-rw-r--r-- | imap4d/imap4d.c | 49 | ||||
-rw-r--r-- | imap4d/imap4d.h | 4 | ||||
-rw-r--r-- | imap4d/starttls.c | 115 |
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 @@ -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 04b9060a4..da4626fe7 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 4ac540939..2d9e03269 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 " |