client-authenticate.c revision cd94aeaa294f7cc507206b4b2075852f00e14d61
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* Copyright (c) 2002-2008 Dovecot authors, see the included COPYING file */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteconst char *client_authenticate_get_capabilities(bool secured)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte unsigned int i, count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mech = auth_client_get_available_mechs(auth_client, &count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < count; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* a) transport is secured
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte b) auth mechanism isn't plaintext
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte c) we allow insecure authentication
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void client_auth_input(struct imap_client *client)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (i_stream_next_line(client->common.input) == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* @UNSAFE */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Authentication aborted");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte auth_client_request_continue(client->common.auth_request, line);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* clear sensitive data */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void client_auth_failed(struct imap_client *client)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* get back to normal client input. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic bool client_handle_args(struct imap_client *client,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const char *reason = NULL, *host = NULL, *destuser = NULL, *pass = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bool proxy = FALSE, temp = FALSE, nologin = !success, proxy_self;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte login_proxy_is_ourself(&client->common, host, port, destuser);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* we want to proxy the connection to another server.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte don't do this unless authentication succeeded. with
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte master user proxying we can get FAIL with proxy still set.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte proxy host=.. [port=..] [destuser=..] pass=.. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (imap_proxy_new(client, host, port, destuser, pass) < 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* IMAP referral
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte [nologin] referral host=.. [port=..] [destuser=..]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NO [REFERRAL imap://destuser;AUTH=..@host:port/] Can't login.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte OK [...] Logged in, but you should use this server instead.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte .. [REFERRAL ..] (Reason from auth server)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte str_printfa(reply, "[REFERRAL imap://%s;AUTH=%s@%s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte str_append(reply, "Logged in, but you should use "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "this server instead.");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte client_destroy_success(client, "Login with referral");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Authentication went ok, but for some reason user isn't
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte allowed to log in. Shouldn't probably happen. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Proxying loops to itself");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void sasl_callback(struct client *_client, enum sasl_server_reply reply,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct imap_client *client = (struct imap_client *)_client;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const char *msg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "OK [CAPABILITY %s] Logged in.",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte msg = reply == SASL_SERVER_REPLY_AUTH_FAILED ? "NO " : "BAD ";
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte msg = t_strconcat(msg, data != NULL ? data : AUTH_FAILED_MSG,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* authentication itself succeeded, we just hit some
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte internal failure. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* don't check return value here. it gets tricky if we try
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte to call client_destroy() in here. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int client_auth_begin(struct imap_client *client, const char *mech_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sasl_server_auth_begin(&client->common, IMAP_SERVICE_NAME, mech_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* don't handle input until we get the initial auth reply */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint cmd_authenticate(struct imap_client *client, const struct imap_arg *args)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* we want only one argument: authentication mechanism name */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (args[0].type != IMAP_ARG_ATOM && args[0].type != IMAP_ARG_STRING)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* optional SASL initial response */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return client_auth_begin(client, mech_name, init_resp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint cmd_login(struct imap_client *client, const struct imap_arg *args)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* two arguments: username and password */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (args[0].type != IMAP_ARG_ATOM && args[0].type != IMAP_ARG_STRING)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (args[1].type != IMAP_ARG_ATOM && args[1].type != IMAP_ARG_STRING)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!client->common.secured && disable_plaintext_auth) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Plaintext authentication disabled");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte client->common.auth_tried_disabled_plaintext = TRUE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "* BAD [ALERT] Plaintext authentication is disabled, "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "but your client sent password in plaintext anyway. "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "If anyone was listening, the password was exposed.");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte client_send_tagline(client, "NO "AUTH_PLAINTEXT_DISABLED_MSG);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* authorization ID \0 authentication ID \0 pass */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte plain_login = buffer_create_dynamic(pool_datastack_create(), 64);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte base64 = buffer_create_dynamic(pool_datastack_create(),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte base64_encode(plain_login->data, plain_login->used, base64);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return client_auth_begin(client, "PLAIN", str_c(base64));