]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-sasl: Added support for EXTERNAL SASL mechanism
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 3 Feb 2016 10:26:10 +0000 (12:26 +0200)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 3 Feb 2016 10:26:35 +0000 (12:26 +0200)
src/lib-sasl/Makefile.am
src/lib-sasl/dsasl-client-private.h
src/lib-sasl/dsasl-client.c
src/lib-sasl/mech-external.c [new file with mode: 0644]

index 98b49dd95a24208a476a1adc1866e640c509e11c..dd6d37377b53f9e847f46964d37f538e405a1fff 100644 (file)
@@ -4,6 +4,7 @@ AM_CPPFLAGS = \
        -I$(top_srcdir)/src/lib
 
 libsasl_la_SOURCES = \
+       mech-external.c \
        mech-login.c \
        mech-plain.c \
        dsasl-client.c 
index 851a11200bb2e9a61d54bcf277284ccc4dddc7fd..a7295819cc0736f6fa99a7ae41091b862ea1626e 100644 (file)
@@ -25,6 +25,7 @@ struct dsasl_client_mech {
        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);
index 44069184002d183d2aaf57a11ab55a162ea31ab1..13338991b4c9acd9956334f2161c1aedc273dad7 100644 (file)
@@ -104,6 +104,7 @@ void dsasl_clients_init(void)
                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);
 }
diff --git a/src/lib-sasl/mech-external.c b/src/lib-sasl/mech-external.c
new file mode 100644 (file)
index 0000000..faf753a
--- /dev/null
@@ -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
+};