bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen#include "lib.h"
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen#include "str.h"
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen#include "dsasl-client-private.h"
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainenenum login_state {
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen STATE_INIT = 0,
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen STATE_USER,
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen STATE_PASS
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen};
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainenstruct login_dsasl_client {
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen struct dsasl_client client;
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen enum login_state state;
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen};
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainenstatic int
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainenmech_login_input(struct dsasl_client *_client,
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen const unsigned char *input ATTR_UNUSED,
a669d351502e15802b121e1a0bd83f27d1d95f01Timo Sirainen size_t input_len ATTR_UNUSED,
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen const char **error_r)
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen{
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen struct login_dsasl_client *client =
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen (struct login_dsasl_client *)_client;
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen if (client->state == STATE_PASS) {
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen *error_r = "Server didn't finish authentication";
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen return -1;
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen }
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen client->state++;
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen return 0;
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen}
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainenstatic int
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainenmech_login_output(struct dsasl_client *_client,
a669d351502e15802b121e1a0bd83f27d1d95f01Timo Sirainen const unsigned char **output_r, size_t *output_len_r,
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen const char **error_r)
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen{
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen struct login_dsasl_client *client =
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen (struct login_dsasl_client *)_client;
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen if (_client->set.authid == NULL) {
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen *error_r = "authid not set";
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen return -1;
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen }
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen if (_client->password == NULL) {
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen *error_r = "password not set";
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen return -1;
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen }
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen switch (client->state) {
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen case STATE_INIT:
5965eaa2d972e6264cecaf54091cd43019bc7d1fTimo Sirainen *output_r = uchar_empty_ptr;
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen *output_len_r = 0;
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen return 0;
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen case STATE_USER:
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen *output_r = (const unsigned char *)_client->set.authid;
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen *output_len_r = strlen(_client->set.authid);
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen return 0;
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen case STATE_PASS:
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen *output_r = (const unsigned char *)_client->set.password;
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen *output_len_r = strlen(_client->set.password);
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen return 0;
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen }
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen i_unreached();
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen}
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainenconst struct dsasl_client_mech dsasl_client_mech_login = {
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen .name = "LOGIN",
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen .struct_size = sizeof(struct login_dsasl_client),
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen .input = mech_login_input,
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen .output = mech_login_output
78919bf7cb55e84e5f289f33526579f63c4797d7Timo Sirainen};