summaryrefslogtreecommitdiff
path: root/imap4d/starttls.c
diff options
context:
space:
mode:
Diffstat (limited to 'imap4d/starttls.c')
-rw-r--r--imap4d/starttls.c144
1 files changed, 93 insertions, 51 deletions
diff --git a/imap4d/starttls.c b/imap4d/starttls.c
index 4c87bcd84..78be4509b 100644
--- a/imap4d/starttls.c
+++ b/imap4d/starttls.c
@@ -1,5 +1,5 @@
/* GNU Mailutils -- a suite of utilities for electronic mail
- Copyright (C) 2003-2019 Free Software Foundation, Inc.
+ Copyright (C) 2003-2024 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -15,8 +15,11 @@
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
#include "imap4d.h"
+#include <mailutils/sockaddr.h>
-struct mu_tls_config global_tls_conf;
+static int global_conf_status = -1;
+int global_tls_mode;
+struct mu_tls_config global_tls_conf = { .handshake_timeout = 10 };
/*
6.2.1. STARTTLS Command
@@ -26,11 +29,11 @@ struct mu_tls_config global_tls_conf;
Responses: no specific response for this command
Result: OK - starttls completed, begin TLS negotiation
- BAD - command unknown or arguments invalid
+ BAD - command unknown or arguments invalid
*/
int
imap4d_starttls (struct imap4d_session *session,
- struct imap4d_command *command, imap4d_tokbuf_t tok)
+ struct imap4d_command *command, imap4d_tokbuf_t tok)
{
int status;
@@ -60,13 +63,94 @@ tls_encryption_on (struct imap4d_session *session)
{
session->tls_mode = tls_no;
imap4d_capability_remove (IMAP_CAPA_STARTTLS);
-
+
login_disabled = 0;
imap4d_capability_remove (IMAP_CAPA_LOGINDISABLED);
imap4d_capability_remove (IMAP_CAPA_XTLSREQUIRED);
}
+static int
+global_tls_status (void)
+{
+ 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_OK)
+ global_tls_mode = tls_no;
+ }
+ return global_conf_status;
+}
+
+int
+starttls_server_check (struct imap4d_srv_config *cfg, char const *srvid)
+{
+ int result;
+
+ switch (cfg->tls_mode)
+ {
+ case tls_unspecified:
+ {
+ if (cfg->tls_conf.cert_file || global_tls_status () == MU_TLS_CONFIG_OK)
+ {
+ struct mu_sockaddr *sa;
+ int port = -1;
+
+ mu_ip_server_get_sockaddr (cfg->m_cfg.tcpsrv, &sa);
+ mu_sockaddr_get_port (sa, &port);
+ mu_sockaddr_free (sa);
+
+ if (port == PORT_IMAP4S)
+ cfg->tls_mode = tls_connection;
+ else if (global_tls_mode != tls_unspecified)
+ cfg->tls_mode = global_tls_mode;
+ else
+ cfg->tls_mode = tls_ondemand;
+ break;
+ }
+ }
+ /* fall through */
+ 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_tls_status () == MU_TLS_CONFIG_OK)
+ {
+ 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)
{
@@ -75,13 +159,7 @@ 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);
for (mu_iterator_first (itr); !mu_iterator_is_done (itr); mu_iterator_next (itr))
@@ -90,54 +168,18 @@ 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;
}
-
+
tls_requested = 1;
}
mu_iterator_destroy (&itr);
@@ -148,7 +190,7 @@ starttls_init (mu_m_server_t msrv)
"configuration"));
errors = 1;
}
-
+
if (errors)
return 1;

Return to:

Send suggestions and report system problems to the System administrator.