Mercurial > dovecot > core-2.2
view src/imap-login/client-authenticate.c @ 12782:447bce266022
Updated copyright notices to include year 2011.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 04 Mar 2011 20:54:29 +0200 |
parents | ac31be20d279 |
children | 81fa0597b8b6 |
line wrap: on
line source
/* Copyright (c) 2002-2011 Dovecot authors, see the included COPYING file */ #include "login-common.h" #include "base64.h" #include "buffer.h" #include "ioloop.h" #include "istream.h" #include "ostream.h" #include "safe-memset.h" #include "str.h" #include "str-sanitize.h" #include "imap-resp-code.h" #include "imap-parser.h" #include "auth-client.h" #include "client.h" #include "client-authenticate.h" #include "imap-proxy.h" #include <stdlib.h> void client_authenticate_get_capabilities(struct client *client, string_t *str) { const struct auth_mech_desc *mech; unsigned int i, count; mech = sasl_server_get_advertised_mechs(client, &count); for (i = 0; i < count; i++) { str_append_c(str, ' '); str_append(str, "AUTH="); str_append(str, mech[i].name); } } bool imap_client_auth_handle_reply(struct client *client, const struct client_auth_reply *reply) { struct imap_client *imap_client = (struct imap_client *)client; string_t *str; if (reply->host != NULL) { /* IMAP referral [nologin] referral host=.. [port=..] [destuser=..] [reason=..] NO [REFERRAL imap://destuser;AUTH=..@host:port/] Can't login. OK [...] Logged in, but you should use this server instead. .. [REFERRAL ..] (Reason from auth server) */ str = t_str_new(128); str_append(str, imap_client->cmd_tag); str_append_c(str, ' '); str_append(str, reply->nologin ? "NO " : "OK "); str_printfa(str, "[REFERRAL imap://%s;AUTH=%s@%s", reply->destuser, client->auth_mech_name, reply->host); if (reply->port != 143) str_printfa(str, ":%u", reply->port); str_append(str, "/] "); if (reply->reason != NULL) str_append(str, reply->reason); else if (reply->nologin) str_append(str, "Try this server instead."); else { str_append(str, "Logged in, but you should use " "this server instead."); } str_append(str, "\r\n"); client_send_raw(client, str_c(str)); if (!reply->nologin) { client_destroy_success(client, "Login with referral"); return TRUE; } } else if (reply->nologin) { /* Authentication went ok, but for some reason user isn't allowed to log in. Shouldn't probably happen. */ if (reply->reason != NULL) { client_send_line(client, CLIENT_CMD_REPLY_AUTH_FAIL_REASON, reply->reason); } else if (reply->temp) { client_send_line(client, CLIENT_CMD_REPLY_AUTH_FAIL_TEMP, AUTH_TEMP_FAILED_MSG); } else if (reply->authz_failure) { client_send_line(client, CLIENT_CMD_REPLY_AUTHZ_FAILED, "Authorization failed"); } else { client_send_line(client, CLIENT_CMD_REPLY_AUTH_FAILED, AUTH_FAILED_MSG); } } else { /* normal login/failure */ return FALSE; } i_assert(reply->nologin); if (!client->destroyed) client_auth_failed(client); return TRUE; } static int imap_client_auth_begin(struct imap_client *imap_client, const char *mech_name, const char *init_resp) { char *prefix; prefix = i_strdup_printf("%d%s", imap_client->client_ignores_capability_resp_code, imap_client->cmd_tag); i_free(imap_client->common.master_data_prefix); imap_client->common.master_data_prefix = (void *)prefix; imap_client->common.master_data_prefix_len = strlen(prefix)+1; return client_auth_begin(&imap_client->common, mech_name, init_resp); } int cmd_authenticate(struct imap_client *imap_client, const struct imap_arg *args) { const char *mech_name, *init_resp; /* <auth mechanism name> [<initial SASL response>] */ if (!imap_arg_get_atom(&args[0], &mech_name) || *mech_name == '\0') return -1; if (imap_arg_get_atom(&args[1], &init_resp)) args++; else init_resp = NULL; if (!IMAP_ARG_IS_EOL(&args[1])) return -1; return imap_client_auth_begin(imap_client, mech_name, init_resp); } int cmd_login(struct imap_client *imap_client, const struct imap_arg *args) { struct client *client = &imap_client->common; const char *user, *pass; string_t *plain_login, *base64; /* two arguments: username and password */ if (!imap_arg_get_astring(&args[0], &user) || !imap_arg_get_astring(&args[1], &pass) || !IMAP_ARG_IS_EOL(&args[2])) return -1; if (!client_check_plaintext_auth(client, TRUE)) return 1; /* authorization ID \0 authentication ID \0 pass */ plain_login = buffer_create_dynamic(pool_datastack_create(), 64); buffer_append_c(plain_login, '\0'); buffer_append(plain_login, user, strlen(user)); buffer_append_c(plain_login, '\0'); buffer_append(plain_login, pass, strlen(pass)); base64 = buffer_create_dynamic(pool_datastack_create(), MAX_BASE64_ENCODED_SIZE(plain_login->used)); base64_encode(plain_login->data, plain_login->used, base64); return imap_client_auth_begin(imap_client, "PLAIN", str_c(base64)); }