mech-cram-md5.c revision 244fcb971a4a38b476f733bfd5ed5d18b2c831f7
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen/* Copyright (C) 2002,2003 Timo Sirainen / Joshua Goodall */
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen/* CRAM-MD5 SASL authentication, see RFC-2195
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen Joshua Goodall <joshua@roughtrade.net> */
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen /* requested: */
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen /* received: */
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen unsigned long maxbuf;
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainenstatic const char *get_cram_challenge(void)
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen return t_strdup_printf("%s.%s@%s", buf, dec2str(ioloop_time),
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainenstatic int verify_credentials(struct cram_auth_request *auth,
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen unsigned char digest[16], context_digest[32], *cdp;
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen if (hex_to_binary(credentials, context_digest_buf) <= 0)
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen (c) = (*p++); \
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen (c) += (*p++ << 8); \
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen (c) += (*p++ << 16); \
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen (c) += (*p++ << 24); \
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen md5_update(&ctxi, auth->challenge, strlen(auth->challenge));
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen if (memcmp(response_hex, auth->response, 32) != 0) {
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainenstatic int parse_cram_response(struct cram_auth_request *auth,
244fcb971a4a38b476f733bfd5ed5d18b2c831f7Timo Sirainen const char **error_r)
244fcb971a4a38b476f733bfd5ed5d18b2c831f7Timo Sirainen for (i = 0; i < size; i++) {
244fcb971a4a38b476f733bfd5ed5d18b2c831f7Timo Sirainen auth->username = p_strndup(auth->pool, data, i);
244fcb971a4a38b476f733bfd5ed5d18b2c831f7Timo Sirainen auth->response = p_strndup(auth->pool, data + i, size - i);
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainenstatic void credentials_callback(const char *result,
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen auth->username == NULL ? "" : auth->username);
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen auth->username == NULL ? "" : auth->username);
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainenmech_cram_md5_auth_continue(struct auth_request *auth_request,
244fcb971a4a38b476f733bfd5ed5d18b2c831f7Timo Sirainen struct auth_client_request_continue *request __attr_unused__,
244fcb971a4a38b476f733bfd5ed5d18b2c831f7Timo Sirainen const unsigned char *data,
244fcb971a4a38b476f733bfd5ed5d18b2c831f7Timo Sirainen if (parse_cram_response(auth, data, request->data_size, &error)) {
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen if (mech_is_valid_username(auth_request->user)) {
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen passdb->lookup_credentials(&auth->auth_request,
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen auth->username == NULL ? "" : auth->username, error);
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen mech_auth_finish(auth_request, NULL, 0, FALSE);
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainenstatic void mech_cram_md5_auth_free(struct auth_request *auth_request)
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainenmech_cram_md5_auth_new(struct auth_client_connection *conn,
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen pool = pool_alloconly_create("cram_md5_auth_request", 2048);
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen auth = p_new(pool, struct cram_auth_request, 1);
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen auth->auth_request.auth_continue = mech_cram_md5_auth_continue;
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen auth->auth_request.auth_free = mech_cram_md5_auth_free;
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen auth->challenge = p_strdup(auth->pool, get_cram_challenge());
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen /* initialize reply */
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen /* send the initial challenge */