client-authenticate.c revision 0442399c3ad313d6f5267c182ddb9012e525941d
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (C) 2002-2004 Timo Sirainen */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenconst char *client_authenticate_get_capabilities(int secured)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int i, count;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mech = auth_client_get_available_mechs(auth_client, &count);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen for (i = 0; i < count; i++) {
9955f6cba7652469b1d600a3674e8d27dd4e61bdTimo Sirainen /* a) transport is secured
9955f6cba7652469b1d600a3674e8d27dd4e61bdTimo Sirainen b) auth mechanism isn't plaintext
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen c) we allow insecure authentication
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if ((mech[i].flags & MECH_SEC_PRIVATE) == 0 &&
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (i_stream_next_line(client->input) == NULL)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* @UNSAFE */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen "Authentication aborted");
73a87c2ff65c6116cde6fb158dfddb8ef7346901Timo Sirainen "Don't send unrequested data");
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen auth_client_request_continue(client->common.auth_request, line);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* clear sensitive data */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic int client_handle_success_args(struct imap_client *client,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen str_printfa(reply, "[REFERRAL %s] ", referral);
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen str_append(reply, "Try this server instead.");
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen "Login: ", client->common.virtual_user, NULL));
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen /* get back to normal client input. */
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen client->io = io_add(client->common.fd, IO_READ,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic void sasl_callback(struct client *_client, enum sasl_server_reply reply,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct imap_client *client = (struct imap_client *)_client;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (client_handle_success_args(client, args, FALSE))
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen "Login: ", client->common.virtual_user, NULL));
d22301419109ed4a38351715e6760011421dadecTimo Sirainen if (client_handle_success_args(client, args, TRUE))
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen client_send_tagline(client, "Authentication failed");
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* get back to normal client input. */
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen client->io = io_add(client->common.fd, IO_READ,
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen client_send_line(client, "* BYE Internal login failure. "
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen "Refer to server log for more information.");
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen client_destroy(client, t_strconcat("Internal login failure: ",
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen client_destroy(client, "Transmit buffer full");
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen /* continue */
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainenint cmd_authenticate(struct imap_client *client, struct imap_arg *args)
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen /* we want only one argument: authentication mechanism name */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (args[0].type != IMAP_ARG_ATOM && args[0].type != IMAP_ARG_STRING)
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen sasl_server_auth_begin(&client->common, "IMAP", mech_name, NULL,
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen /* following input data will go to authentication */
d22301419109ed4a38351715e6760011421dadecTimo Sirainen client->io = io_add(client->common.fd, IO_READ,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenint cmd_login(struct imap_client *client, struct imap_arg *args)
dd4f30895ebbddd77e000472fbadcb3128ae2883Timo Sirainen /* two arguments: username and password */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (args[0].type != IMAP_ARG_ATOM && args[0].type != IMAP_ARG_STRING)
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen if (args[1].type != IMAP_ARG_ATOM && args[1].type != IMAP_ARG_STRING)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (!client->common.secured && disable_plaintext_auth) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen client_syslog(&client->common, "Login failed: "
3f91e60401495a4046c73992fabaa5e77200a451Timo Sirainen "Plaintext authentication disabled");
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen "* BAD [ALERT] Plaintext authentication is disabled, "
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen "but your client sent password in plaintext anyway. "
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen "If anyone was listening, the password was exposed.");
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen "NO Plaintext authentication disabled.");
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen /* authorization ID \0 authentication ID \0 pass */
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen plain_login = buffer_create_dynamic(pool_datastack_create(), 64);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen buffer_append(plain_login, user, strlen(user));
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen buffer_append(plain_login, pass, strlen(pass));
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen base64 = buffer_create_dynamic(pool_datastack_create(),
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen base64_encode(plain_login->data, plain_login->used, base64);
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen sasl_server_auth_begin(&client->common, "IMAP", "PLAIN",
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* don't read any input from client until login is finished */