mech-cram-md5.c revision 73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0fae
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)
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen return t_strdup_printf("<%s.%s@%s>", (const char *)buf,
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainenstatic int verify_credentials(struct cram_auth_request *request,
4b058f90f9e8a2c6b2eed275de4eb8cc5195a71dTimo Sirainen if (hex_to_binary(credentials, context_digest_buf) < 0)
edf7428147facc11ddb43b9a874a99b96486d42dTimo Sirainen hmac_md5_set_cram_context(&ctx, context_digest);
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen hmac_md5_update(&ctx, request->challenge, strlen(request->challenge));
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen if (memcmp(response_hex, request->response, 32) != 0) {
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainenstatic int parse_cram_response(struct cram_auth_request *request,
244fcb971a4a38b476f733bfd5ed5d18b2c831f7Timo Sirainen const char **error_r)
3a734c9c3efd87864d1ad860826fd4e787457bedTimo Sirainen /* <username> SPACE <response>. Username may contain spaces, so assume
3a734c9c3efd87864d1ad860826fd4e787457bedTimo Sirainen the rightmost space is the response separator. */
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen request->username = p_strndup(request->pool, data, space);
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen p_strndup(request->pool, data + space, size - space);
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainenstatic void credentials_callback(const char *result,
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen mech_auth_finish(auth_request, NULL, 0, TRUE);
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen mech_auth_finish(auth_request, NULL, 0, FALSE);
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainenmech_cram_md5_auth_continue(struct auth_request *auth_request,
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen if (parse_cram_response(request, data, data_size, &error)) {
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen p_strdup(auth_request->pool, request->username);
9abfe876fa81576f130f3f82f622ae936c21a716Timo Sirainen if (mech_fix_username(auth_request->user, &error)) {
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen i_info("cram-md5(%s): %s", get_log_prefix(auth_request), error);
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen mech_auth_finish(auth_request, NULL, 0, FALSE);
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainenmech_cram_md5_auth_initial(struct auth_request *auth_request,
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen request->challenge = p_strdup(request->pool, get_cram_challenge());
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen callback(auth_request, AUTH_CLIENT_RESULT_CONTINUE,
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen request->challenge, strlen(request->challenge));
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainenstatic void mech_cram_md5_auth_free(struct auth_request *request)
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainenstatic struct auth_request *mech_cram_md5_auth_new(void)
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen pool = pool_alloconly_create("cram_md5_auth_request", 2048);
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen request = p_new(pool, struct cram_auth_request, 1);