dovecot-2.2: imapc: Added imapc_sasl_mechanisms setting

dovecot at dovecot.org dovecot at dovecot.org
Thu Jan 8 20:54:12 UTC 2015


details:   http://hg.dovecot.org/dovecot-2.2/rev/fba6355ddb8a
changeset: 18142:fba6355ddb8a
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Jan 08 22:52:11 2015 +0200
description:
imapc: Added imapc_sasl_mechanisms setting
The first supported SASL mechanism is used, otherwise the login fails
entirely.

diffstat:

 src/lib-imap-client/imapc-client.c           |   1 +
 src/lib-imap-client/imapc-client.h           |   3 +
 src/lib-imap-client/imapc-connection.c       |  61 +++++++++++++++++++++++++--
 src/lib-storage/Makefile.am                  |   1 +
 src/lib-storage/index/imapc/imapc-settings.c |   2 +
 src/lib-storage/index/imapc/imapc-settings.h |   1 +
 src/lib-storage/index/imapc/imapc-storage.c  |   1 +
 src/lib-storage/mail-storage.c               |   3 +
 8 files changed, 68 insertions(+), 5 deletions(-)

diffs (193 lines):

diff -r ee135359faa4 -r fba6355ddb8a src/lib-imap-client/imapc-client.c
--- a/src/lib-imap-client/imapc-client.c	Thu Jan 08 22:32:20 2015 +0200
+++ b/src/lib-imap-client/imapc-client.c	Thu Jan 08 22:52:11 2015 +0200
@@ -54,6 +54,7 @@
 	client->set.master_user = p_strdup_empty(pool, set->master_user);
 	client->set.username = p_strdup(pool, set->username);
 	client->set.password = p_strdup(pool, set->password);
+	client->set.sasl_mechanisms = p_strdup(pool, set->sasl_mechanisms);
 	client->set.dns_client_socket_path =
 		p_strdup(pool, set->dns_client_socket_path);
 	client->set.temp_path_prefix =
diff -r ee135359faa4 -r fba6355ddb8a src/lib-imap-client/imapc-client.h
--- a/src/lib-imap-client/imapc-client.h	Thu Jan 08 22:32:20 2015 +0200
+++ b/src/lib-imap-client/imapc-client.h	Thu Jan 08 22:52:11 2015 +0200
@@ -60,6 +60,9 @@
 	const char *master_user;
 	const char *username;
 	const char *password;
+	/* Space-separated list of SASL mechanisms to try (in the specified
+	   order). The default is to use only LOGIN command or SASL PLAIN. */
+	const char *sasl_mechanisms;
 	unsigned int max_idle_time;
 
 	const char *dns_client_socket_path;
diff -r ee135359faa4 -r fba6355ddb8a src/lib-imap-client/imapc-connection.c
--- a/src/lib-imap-client/imapc-connection.c	Thu Jan 08 22:32:20 2015 +0200
+++ b/src/lib-imap-client/imapc-connection.c	Thu Jan 08 22:52:11 2015 +0200
@@ -760,12 +760,52 @@
 	imapc_connection_disconnect(conn);
 }
 
+static bool imapc_connection_have_auth(struct imapc_connection *conn,
+				       const char *mech_name)
+{
+	char *const *capa;
+
+	for (capa = conn->capabilities_list; *capa != NULL; capa++) {
+		if (strncasecmp(*capa, "AUTH=", 5) == 0 &&
+		    strcasecmp((*capa)+5, mech_name) == 0)
+			return TRUE;
+	}
+	return FALSE;
+}
+
+static int
+imapc_connection_get_sasl_mech(struct imapc_connection *conn,
+			       const struct dsasl_client_mech **mech_r,
+			       const char **error_r)
+{
+	const struct imapc_client_settings *set = &conn->client->set;
+	const char *const *mechanisms =
+		t_strsplit_spaces(set->sasl_mechanisms, ", ");
+
+	/* find one of the specified SASL mechanisms */
+	for (; *mechanisms != NULL; mechanisms++) {
+		if (imapc_connection_have_auth(conn, *mechanisms)) {
+			*mech_r = dsasl_client_mech_find(*mechanisms);
+			if (*mech_r != NULL)
+				return 0;
+
+			*error_r = t_strdup_printf(
+				"Support for SASL method '%s' is missing", *mechanisms);
+			return -1;
+		}
+	}
+	*error_r = t_strdup_printf("IMAP server doesn't support any of the requested SASL mechanisms: %s",
+				   set->sasl_mechanisms);
+	return -1;
+}
+
 static void imapc_connection_authenticate(struct imapc_connection *conn)
 {
 	const struct imapc_client_settings *set = &conn->client->set;
 	struct imapc_command *cmd;
 	struct dsasl_client_settings sasl_set;
-	const struct dsasl_client_mech *sasl_mech;
+	const struct dsasl_client_mech *sasl_mech = NULL;
+	const char *error;
 
 	if (conn->client->set.debug) {
 		if (set->master_user == NULL) {
@@ -777,9 +817,19 @@
 		}
 	}
 
-	if ((set->master_user == NULL &&
-	     !need_literal(set->username) && !need_literal(set->password)) ||
-	    (conn->capabilities & IMAPC_CAPABILITY_AUTH_PLAIN) == 0) {
+	if (set->sasl_mechanisms != NULL && set->sasl_mechanisms[0] != '\0') {
+		if (imapc_connection_get_sasl_mech(conn, &sasl_mech, &error) < 0) {
+			i_error("imapc(%s): Authentication failed: %s",
+				conn->name, error);
+			imapc_connection_disconnect(conn);
+			return;
+		}
+	}
+
+	if (sasl_mech == NULL &&
+	    ((set->master_user == NULL &&
+	      !need_literal(set->username) && !need_literal(set->password)) ||
+	     (conn->capabilities & IMAPC_CAPABILITY_AUTH_PLAIN) == 0)) {
 		/* We can use LOGIN command */
 		cmd = imapc_connection_cmd(conn, imapc_connection_login_cb,
 					   conn);
@@ -798,7 +848,8 @@
 	}
 	sasl_set.password = set->password;
 
-	sasl_mech = &dsasl_client_mech_plain;
+	if (sasl_mech == NULL)
+		sasl_mech = &dsasl_client_mech_plain;
 	conn->sasl_client = dsasl_client_new(sasl_mech, &sasl_set);
 
 	cmd = imapc_connection_cmd(conn, imapc_connection_authenticate_cb, conn);
diff -r ee135359faa4 -r fba6355ddb8a src/lib-storage/Makefile.am
--- a/src/lib-storage/Makefile.am	Thu Jan 08 22:32:20 2015 +0200
+++ b/src/lib-storage/Makefile.am	Thu Jan 08 22:52:11 2015 +0200
@@ -7,6 +7,7 @@
 	-I$(top_srcdir)/src/lib-test \
 	-I$(top_srcdir)/src/lib-auth \
 	-I$(top_srcdir)/src/lib-dict \
+	-I$(top_srcdir)/src/lib-sasl \
 	-I$(top_srcdir)/src/lib-ssl-iostream \
 	-I$(top_srcdir)/src/lib-fs \
 	-I$(top_srcdir)/src/lib-master \
diff -r ee135359faa4 -r fba6355ddb8a src/lib-storage/index/imapc/imapc-settings.c
--- a/src/lib-storage/index/imapc/imapc-settings.c	Thu Jan 08 22:32:20 2015 +0200
+++ b/src/lib-storage/index/imapc/imapc-settings.c	Thu Jan 08 22:52:11 2015 +0200
@@ -20,6 +20,7 @@
 	DEF(SET_STR_VARS, imapc_user),
 	DEF(SET_STR_VARS, imapc_master_user),
 	DEF(SET_STR, imapc_password),
+	DEF(SET_STR, imapc_sasl_mechanisms),
 
 	DEF(SET_ENUM, imapc_ssl),
 	DEF(SET_BOOL, imapc_ssl_verify),
@@ -39,6 +40,7 @@
 	.imapc_user = "",
 	.imapc_master_user = "",
 	.imapc_password = "",
+	.imapc_sasl_mechanisms = "",
 
 	.imapc_ssl = "no:imaps:starttls",
 	.imapc_ssl_verify = TRUE,
diff -r ee135359faa4 -r fba6355ddb8a src/lib-storage/index/imapc/imapc-settings.h
--- a/src/lib-storage/index/imapc/imapc-settings.h	Thu Jan 08 22:32:20 2015 +0200
+++ b/src/lib-storage/index/imapc/imapc-settings.h	Thu Jan 08 22:52:11 2015 +0200
@@ -16,6 +16,7 @@
 	const char *imapc_user;
 	const char *imapc_master_user;
 	const char *imapc_password;
+	const char *imapc_sasl_mechanisms;
 
 	const char *imapc_ssl;
 	bool imapc_ssl_verify;
diff -r ee135359faa4 -r fba6355ddb8a src/lib-storage/index/imapc/imapc-storage.c
--- a/src/lib-storage/index/imapc/imapc-storage.c	Thu Jan 08 22:32:20 2015 +0200
+++ b/src/lib-storage/index/imapc/imapc-storage.c	Thu Jan 08 22:52:11 2015 +0200
@@ -221,6 +221,7 @@
 		*error_r = "missing imapc_password";
 		return -1;
 	}
+	set.sasl_mechanisms = imapc_set->imapc_sasl_mechanisms;
 	set.max_idle_time = imapc_set->imapc_max_idle_time;
 	set.dns_client_socket_path = *ns->user->set->base_dir == '\0' ? "" :
 		t_strconcat(ns->user->set->base_dir, "/",
diff -r ee135359faa4 -r fba6355ddb8a src/lib-storage/mail-storage.c
--- a/src/lib-storage/mail-storage.c	Thu Jan 08 22:32:20 2015 +0200
+++ b/src/lib-storage/mail-storage.c	Thu Jan 08 22:52:11 2015 +0200
@@ -11,6 +11,7 @@
 #include "mkdir-parents.h"
 #include "time-util.h"
 #include "var-expand.h"
+#include "dsasl-client.h"
 #include "mail-index-private.h"
 #include "mail-index-alloc-cache.h"
 #include "mailbox-tree.h"
@@ -40,6 +41,7 @@
 
 void mail_storage_init(void)
 {
+	dsasl_clients_init();
 	mailbox_lists_init();
 	mail_storage_hooks_init();
 	i_array_init(&mail_storage_classes, 8);
@@ -55,6 +57,7 @@
 		array_free(&mail_storage_classes);
 	mail_storage_hooks_deinit();
 	mailbox_lists_deinit();
+	dsasl_clients_deinit();
 }
 
 void mail_storage_class_register(struct mail_storage *storage_class)


More information about the dovecot-cvs mailing list