changeset 19701:72f2a1b6f6ae

lib-sasl: Added support for EXTERNAL SASL mechanism
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Wed, 03 Feb 2016 12:26:10 +0200
parents c3b064ddbce3
children 915be2e91a1f
files src/lib-sasl/Makefile.am src/lib-sasl/dsasl-client-private.h src/lib-sasl/dsasl-client.c src/lib-sasl/mech-external.c
diffstat 4 files changed, 67 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-sasl/Makefile.am	Tue Feb 02 22:06:38 2016 +0200
+++ b/src/lib-sasl/Makefile.am	Wed Feb 03 12:26:10 2016 +0200
@@ -4,6 +4,7 @@
 	-I$(top_srcdir)/src/lib
 
 libsasl_la_SOURCES = \
+	mech-external.c \
 	mech-login.c \
 	mech-plain.c \
 	dsasl-client.c 
--- a/src/lib-sasl/dsasl-client-private.h	Tue Feb 02 22:06:38 2016 +0200
+++ b/src/lib-sasl/dsasl-client-private.h	Wed Feb 03 12:26:10 2016 +0200
@@ -25,6 +25,7 @@
 	void (*free)(struct dsasl_client *client);
 };
 
+extern const struct dsasl_client_mech dsasl_client_mech_external;
 extern const struct dsasl_client_mech dsasl_client_mech_login;
 
 void dsasl_client_mech_register(const struct dsasl_client_mech *mech);
--- a/src/lib-sasl/dsasl-client.c	Tue Feb 02 22:06:38 2016 +0200
+++ b/src/lib-sasl/dsasl-client.c	Wed Feb 03 12:26:10 2016 +0200
@@ -104,6 +104,7 @@
 		return;
 
 	i_array_init(&dsasl_mechanisms, 8);
+	dsasl_client_mech_register(&dsasl_client_mech_external);
 	dsasl_client_mech_register(&dsasl_client_mech_plain);
 	dsasl_client_mech_register(&dsasl_client_mech_login);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-sasl/mech-external.c	Wed Feb 03 12:26:10 2016 +0200
@@ -0,0 +1,64 @@
+/* Copyright (c) 2016 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "dsasl-client-private.h"
+
+struct external_dsasl_client {
+	struct dsasl_client client;
+	bool output_sent;
+};
+
+static int
+mech_external_input(struct dsasl_client *_client,
+		    const unsigned char *input ATTR_UNUSED, unsigned int input_len,
+		    const char **error_r)
+{
+	struct external_dsasl_client *client =
+		(struct external_dsasl_client *)_client;
+
+	if (!client->output_sent) {
+		if (input_len > 0) {
+			*error_r = "Server sent non-empty initial response";
+			return -1;
+		}
+	} else {
+		*error_r = "Server didn't finish authentication";
+		return -1;
+	}
+	return 0;
+}
+
+static int
+mech_external_output(struct dsasl_client *_client,
+		     const unsigned char **output_r, unsigned int *output_len_r,
+		     const char **error_r)
+{
+	struct external_dsasl_client *client =
+		(struct external_dsasl_client *)_client;
+	const char *username;
+
+	if (_client->set.authid == NULL) {
+		*error_r = "authid not set";
+		return -1;
+	}
+
+	if (_client->set.authzid != NULL)
+		username = _client->set.authzid;
+	else if (_client->set.authid != NULL)
+		username = _client->set.authid;
+	else
+		username = "";
+
+	*output_r = (const void *)username;
+	*output_len_r = strlen(username);
+	client->output_sent = TRUE;
+	return 0;
+}
+
+const struct dsasl_client_mech dsasl_client_mech_external = {
+	.name = "EXTERNAL",
+	.struct_size = sizeof(struct external_dsasl_client),
+
+	.input = mech_external_input,
+	.output = mech_external_output
+};