diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2020-03-22 21:07:19 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2020-03-22 21:07:19 +0200 |
commit | 13a4975430ad6d0992bb18325bbc990d1bd890fe (patch) | |
tree | 003428b3661883d71da93e6fbed4b40845d6638f | |
parent | e1e7e02cf9324e542e275db890535240f75ecce3 (diff) | |
download | mailutils-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.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[] = { | |||
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; | |||
225 | extern char **imap4d_argv; | 225 | extern char **imap4d_argv; |
226 | extern jmp_buf child_jmp; | 226 | extern jmp_buf child_jmp; |
227 | extern struct mu_tls_config global_tls_conf; | 227 | extern struct mu_tls_config global_tls_conf; |
228 | 228 | extern int global_tls_mode; | |
229 | |||
229 | extern int test_mode; | 230 | extern int test_mode; |
230 | extern int silent_expunge; | 231 | extern int silent_expunge; |
231 | 232 | ||
@@ -345,6 +346,7 @@ extern int imap4d_select_status (void); | |||
345 | extern int imap4d_starttls (struct imap4d_session *, | 346 | extern int imap4d_starttls (struct imap4d_session *, |
346 | struct imap4d_command *, imap4d_tokbuf_t); | 347 | struct imap4d_command *, imap4d_tokbuf_t); |
347 | int starttls_init (mu_m_server_t msrv); | 348 | int starttls_init (mu_m_server_t msrv); |
349 | int starttls_server_check (struct imap4d_srv_config *cfg, char const *srvid); | ||
348 | void tls_encryption_on (struct imap4d_session *); | 350 | void tls_encryption_on (struct imap4d_session *); |
349 | extern int imap4d_status (struct imap4d_session *, | 351 | extern 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 | ||
19 | static int global_conf_status = -1; | ||
20 | int global_tls_mode; | ||
19 | struct mu_tls_config global_tls_conf; | 21 | struct 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 | ||
70 | int | 72 | int |
73 | starttls_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 | |||
136 | int | ||
71 | starttls_init (mu_m_server_t msrv) | 137 | starttls_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 | ||