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
@@ -533,6 +533,12 @@ static struct mu_cfg_param imap4d_cfg_param[] = {
533 N_("Retain these supplementary groups when switching to user privileges"), 533 N_("Retain these supplementary groups when switching to user privileges"),
534 N_("groups: list of string") }, 534 N_("groups: list of string") },
535 { "tls", mu_cfg_section, &global_tls_conf }, 535 { "tls", mu_cfg_section, &global_tls_conf },
536 { "tls-mode", mu_cfg_callback,
537 &global_tls_mode, 0, cb_tls,
538 N_("Kind of TLS encryption to use for the inetd server"
539 " and all server blocks that lack the tls-mode statement."),
540 /* TRANSLATORS: words to the right of : are keywords - do not translate */
541 N_("arg: false|true|ondemand|stls|requred|connection") },
536 { "preauth", mu_cfg_callback, NULL, 0, cb_preauth, 542 { "preauth", mu_cfg_callback, NULL, 0, cb_preauth,
537 N_("Configure PREAUTH mode. <value> is one of:\n" 543 N_("Configure PREAUTH mode. <value> is one of:\n"
538 " prog:///<full-program-name: string>\n" 544 " prog:///<full-program-name: string>\n"
@@ -936,12 +942,6 @@ main (int argc, char **argv)
936 if (login_disabled) 942 if (login_disabled)
937 imap4d_capability_add (IMAP_CAPA_LOGINDISABLED); 943 imap4d_capability_add (IMAP_CAPA_LOGINDISABLED);
938 944
939 if (mu_gsasl_enabled ())
940 {
941 auth_gssapi_init ();
942 auth_gsasl_init ();
943 }
944
945#ifdef USE_LIBPAM 945#ifdef USE_LIBPAM
946 if (!mu_pam_service) 946 if (!mu_pam_service)
947 mu_pam_service = "gnu-imap4d"; 947 mu_pam_service = "gnu-imap4d";
@@ -1009,6 +1009,12 @@ main (int argc, char **argv)
1009 /* Actually run the daemon. */ 1009 /* Actually run the daemon. */
1010 if (mu_m_server_mode (server) == MODE_DAEMON) 1010 if (mu_m_server_mode (server) == MODE_DAEMON)
1011 { 1011 {
1012 if (mu_gsasl_enabled ())
1013 {
1014 auth_gssapi_init ();
1015 auth_gsasl_init ();
1016 }
1017
1012 mu_m_server_begin (server); 1018 mu_m_server_begin (server);
1013 status = mu_m_server_run (server); 1019 status = mu_m_server_run (server);
1014 mu_m_server_end (server); 1020 mu_m_server_end (server);
@@ -1018,7 +1024,36 @@ main (int argc, char **argv)
1018 { 1024 {
1019 struct imap4d_srv_config cfg; 1025 struct imap4d_srv_config cfg;
1020 memset (&cfg, 0, sizeof cfg); 1026 memset (&cfg, 0, sizeof cfg);
1021 cfg.tls_mode = tls_no; 1027
1028 if (mu_gsasl_enabled ())
1029 {
1030 auth_gssapi_init ();
1031 auth_gsasl_init ();
1032 }
1033
1034 switch (starttls_server_check (&cfg, "<inetd>"))
1035 {
1036 case MU_TLS_CONFIG_OK:
1037 if (mu_init_tls_libs ())
1038 status = EX_OK;
1039 else
1040 {
1041 mu_error (_("TLS is not configured, but requested in the "
1042 "configuration"));
1043 exit (EX_CONFIG);
1044 }
1045 break;
1046
1047 case MU_TLS_CONFIG_NULL:
1048 break;
1049
1050 case MU_TLS_CONFIG_UNSAFE:
1051 exit (EX_CONFIG);
1052
1053 default:
1054 exit (EX_UNAVAILABLE);
1055 }
1056
1022 /* Make sure we are in the root directory. */ 1057 /* Make sure we are in the root directory. */
1023 chdir ("/"); 1058 chdir ("/");
1024 status = imap4d_mainloop (MU_STDIN_FD, MU_STDOUT_FD, &cfg); 1059 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;
225extern char **imap4d_argv; 225extern char **imap4d_argv;
226extern jmp_buf child_jmp; 226extern jmp_buf child_jmp;
227extern struct mu_tls_config global_tls_conf; 227extern struct mu_tls_config global_tls_conf;
228 228extern int global_tls_mode;
229
229extern int test_mode; 230extern int test_mode;
230extern int silent_expunge; 231extern int silent_expunge;
231 232
@@ -345,6 +346,7 @@ extern int imap4d_select_status (void);
345extern int imap4d_starttls (struct imap4d_session *, 346extern int imap4d_starttls (struct imap4d_session *,
346 struct imap4d_command *, imap4d_tokbuf_t); 347 struct imap4d_command *, imap4d_tokbuf_t);
347int starttls_init (mu_m_server_t msrv); 348int starttls_init (mu_m_server_t msrv);
349int starttls_server_check (struct imap4d_srv_config *cfg, char const *srvid);
348void tls_encryption_on (struct imap4d_session *); 350void tls_encryption_on (struct imap4d_session *);
349extern int imap4d_status (struct imap4d_session *, 351extern int imap4d_status (struct imap4d_session *,
350 struct imap4d_command *, imap4d_tokbuf_t); 352 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 @@
16 16
17#include "imap4d.h" 17#include "imap4d.h"
18 18
19static int global_conf_status = -1;
20int global_tls_mode;
19struct mu_tls_config global_tls_conf; 21struct mu_tls_config global_tls_conf;
20 22
21/* 23/*
@@ -68,6 +70,70 @@ tls_encryption_on (struct imap4d_session *session)
68} 70}
69 71
70int 72int
73starttls_server_check (struct imap4d_srv_config *cfg, char const *srvid)
74{
75 int result;
76
77 switch (cfg->tls_mode)
78 {
79 case tls_unspecified:
80 if (global_tls_mode != tls_unspecified)
81 cfg->tls_mode = global_tls_mode;
82 else if (cfg->tls_conf.cert_file)
83 cfg->tls_mode = tls_ondemand;
84 else
85 {
86 cfg->tls_mode = tls_no;
87 return MU_TLS_CONFIG_NULL;
88 }
89 break;
90
91 case tls_no:
92 return MU_TLS_CONFIG_NULL;
93
94 default:
95 break;
96 }
97
98 result = mu_tls_config_check (&cfg->tls_conf, 1);
99 switch (result)
100 {
101 case MU_TLS_CONFIG_OK:
102 if (!cfg->tls_conf.cert_file)
103 {
104 mu_error (_("server %s: no certificate set"), srvid);
105 result = MU_TLS_CONFIG_FAIL;
106 }
107 break;
108
109 case MU_TLS_CONFIG_NULL:
110 if (global_conf_status == -1)
111 {
112 if (global_tls_conf.cert_file)
113 global_conf_status = mu_tls_config_check (&global_tls_conf, 1);
114 else
115 global_conf_status = MU_TLS_CONFIG_NULL;
116 }
117
118 if (global_conf_status != MU_TLS_CONFIG_NULL)
119 {
120 cfg->tls_conf = global_tls_conf;
121 result = MU_TLS_CONFIG_OK;
122 }
123 else
124 {
125 mu_error (_("server %s: no certificate set"), srvid);
126 result = MU_TLS_CONFIG_FAIL;
127 }
128 break;
129
130 default:
131 mu_error (_("server %s: TLS configuration failed"), srvid);
132 }
133 return result;
134}
135
136int
71starttls_init (mu_m_server_t msrv) 137starttls_init (mu_m_server_t msrv)
72{ 138{
73 mu_list_t srvlist; 139 mu_list_t srvlist;
@@ -75,12 +141,6 @@ starttls_init (mu_m_server_t msrv)
75 int errors = 0; 141 int errors = 0;
76 int tls_ok = mu_init_tls_libs (); 142 int tls_ok = mu_init_tls_libs ();
77 int tls_requested = 0; 143 int tls_requested = 0;
78 int global_conf_status = 0;
79
80 if (global_tls_conf.cert_file)
81 global_conf_status = mu_tls_config_check (&global_tls_conf, 1);
82 else
83 global_conf_status = MU_TLS_CONFIG_NULL;
84 144
85 mu_m_server_get_srvlist (msrv, &srvlist); 145 mu_m_server_get_srvlist (msrv, &srvlist);
86 mu_list_get_iterator (srvlist, &itr); 146 mu_list_get_iterator (srvlist, &itr);
@@ -90,51 +150,15 @@ starttls_init (mu_m_server_t msrv)
90 struct imap4d_srv_config *cfg; 150 struct imap4d_srv_config *cfg;
91 mu_iterator_current (itr, (void**) &ipsrv); 151 mu_iterator_current (itr, (void**) &ipsrv);
92 cfg = mu_ip_server_get_data (ipsrv); 152 cfg = mu_ip_server_get_data (ipsrv);
93 switch (cfg->tls_mode) 153 switch (starttls_server_check (cfg, mu_ip_server_addrstr (ipsrv)))
94 { 154 {
95 case tls_unspecified: 155 case MU_TLS_CONFIG_NULL:
96 if (cfg->tls_conf.cert_file)
97 {
98 cfg->tls_mode = tls_ondemand;
99 break;
100 }
101 else