diff options
Diffstat (limited to 'src/lib-sasl/mech-plain.c')
-rw-r--r-- | src/lib-sasl/mech-plain.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/lib-sasl/mech-plain.c b/src/lib-sasl/mech-plain.c new file mode 100644 index 0000000..432fa1f --- /dev/null +++ b/src/lib-sasl/mech-plain.c @@ -0,0 +1,70 @@ +/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "str.h" +#include "dsasl-client-private.h" + +struct plain_dsasl_client { + struct dsasl_client client; + bool output_sent; +}; + +static int +mech_plain_input(struct dsasl_client *_client, + const unsigned char *input ATTR_UNUSED, size_t input_len, + const char **error_r) +{ + struct plain_dsasl_client *client = + (struct plain_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_plain_output(struct dsasl_client *_client, + const unsigned char **output_r, size_t *output_len_r, + const char **error_r) +{ + struct plain_dsasl_client *client = + (struct plain_dsasl_client *)_client; + string_t *str; + + if (_client->set.authid == NULL) { + *error_r = "authid not set"; + return -1; + } + if (_client->password == NULL) { + *error_r = "password not set"; + return -1; + } + + str = str_new(_client->pool, 64); + if (_client->set.authzid != NULL) + str_append(str, _client->set.authzid); + str_append_c(str, '\0'); + str_append(str, _client->set.authid); + str_append_c(str, '\0'); + str_append(str, _client->password); + + *output_r = str_data(str); + *output_len_r = str_len(str); + client->output_sent = TRUE; + return 0; +} + +const struct dsasl_client_mech dsasl_client_mech_plain = { + .name = "PLAIN", + .struct_size = sizeof(struct plain_dsasl_client), + + .input = mech_plain_input, + .output = mech_plain_output +}; |