client-authenticate.c revision 62ba819bc24e7eb197684998ccd4aa1ddd130aad
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (C) 2002-2004 Timo Sirainen */
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainenconst char *client_authenticate_get_capabilities(bool secured)
8b247780e911909a9fdc47f69ce6d1478902ad98Timo Sirainen unsigned int i, count;
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainen mech = auth_client_get_available_mechs(auth_client, &count);
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainen for (i = 0; i < count; i++) {
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainen /* a) transport is secured
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainen b) auth mechanism isn't plaintext
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainen c) we allow insecure authentication
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainen if ((mech[i].flags & MECH_SEC_PRIVATE) == 0 &&
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainenstatic void client_auth_input(struct imap_client *client)
9a48c2243fe98ca8393be7908f84d20c634bcdf9Timo Sirainen if (i_stream_next_line(client->input) == NULL)
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen /* @UNSAFE */
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainen sasl_server_auth_client_error(&client->common,
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen "Authentication aborted");
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen sasl_server_auth_client_error(&client->common,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen "Don't send unrequested data");
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen auth_client_request_continue(client->common.auth_request, line);
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen /* clear sensitive data */
5a1b498b646b5c5dbd1b3f3861df766f560578c5Timo Sirainenstatic bool client_handle_args(struct imap_client *client,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen const char *reason = NULL, *host = NULL, *destuser = NULL, *pass = NULL;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen /* we want to proxy the connection to another server.
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen proxy host=.. [port=..] [destuser=..] pass=.. */
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if (imap_proxy_new(client, host, port, destuser, pass) < 0)
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen /* IMAP referral
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen [nologin] referral host=.. [port=..] [destuser=..]
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen NO [REFERRAL imap://destuser;AUTH=..@host:port/] Can't login.
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen OK [...] Logged in, but you should use this server instead.
556f95092c3bc850517d5ab2bb502024a55645f1Timo Sirainen .. [REFERRAL ..] (Reason from auth server)
556f95092c3bc850517d5ab2bb502024a55645f1Timo Sirainen str_printfa(reply, "[REFERRAL imap://%s;AUTH=%s@%s",
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen destuser, client->common.auth_mech_name, host);
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Sirainen str_append(reply, "Try this server instead.");
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen str_append(reply, "Logged in, but you should use "
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen "this server instead.");
3d77cc0d502dc69ffe2afe318605964dd40b7b20Timo Sirainen client_destroy(client, "Login with referral");
e3678f7bfba87b5aa1446a1a7b9928272b4f72a3Timo Sirainen } else if (nologin) {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* Authentication went ok, but for some reason user isn't
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen allowed to log in. Shouldn't probably happen. */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* get back to normal client input. */
d66ef20c30fee728899ee168c75fcc5ff8fbdac1Timo Sirainen client->io = io_add(client->common.fd, IO_READ,
5238111c460098d9cc8cc22527026138a278b9a4Timo Sirainenstatic void sasl_callback(struct client *_client, enum sasl_server_reply reply,
3d77cc0d502dc69ffe2afe318605964dd40b7b20Timo Sirainen struct imap_client *client = (struct imap_client *)_client;
c9bf63e9094761767a63ac6b189bcf60bcffdc44Timo Sirainen const char *msg;
d66ef20c30fee728899ee168c75fcc5ff8fbdac1Timo Sirainen msg = reply == SASL_SERVER_REPLY_AUTH_FAILED ? "NO " : "BAD ";
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen msg = t_strconcat(msg, data != NULL ? data : AUTH_FAILED_MSG,
d66ef20c30fee728899ee168c75fcc5ff8fbdac1Timo Sirainen /* get back to normal client input. */
6cc0546c058f3e6253c6f99727b28dd602712974Timo Sirainen client->io = io_add(client->common.fd, IO_READ,
9de176ef7f3d28ff486c2a8805110b84389e4f19Timo Sirainen /* don't check return value here. it gets tricky if we try
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen to call client_destroy() in here. */
0ce5f96804e81cb0f857e7df32c0272f1eed9377Timo Sirainenint cmd_authenticate(struct imap_client *client, struct imap_arg *args)
0ce5f96804e81cb0f857e7df32c0272f1eed9377Timo Sirainen /* we want only one argument: authentication mechanism name */
0ce5f96804e81cb0f857e7df32c0272f1eed9377Timo Sirainen if (args[0].type != IMAP_ARG_ATOM && args[0].type != IMAP_ARG_STRING)
6cc0546c058f3e6253c6f99727b28dd602712974Timo Sirainen /* optional SASL initial response */
9de176ef7f3d28ff486c2a8805110b84389e4f19Timo Sirainen sasl_server_auth_begin(&client->common, IMAP_SERVICE_NAME, mech_name,
9de176ef7f3d28ff486c2a8805110b84389e4f19Timo Sirainen /* following input data will go to authentication */
9de176ef7f3d28ff486c2a8805110b84389e4f19Timo Sirainen client->io = io_add(client->common.fd, IO_READ,
555ebb032f9b8f0cdb66f27ce7374734833e7cacTimo Sirainenint cmd_login(struct imap_client *client, struct imap_arg *args)
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen /* two arguments: username and password */
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen if (args[0].type != IMAP_ARG_ATOM && args[0].type != IMAP_ARG_STRING)
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen if (args[1].type != IMAP_ARG_ATOM && args[1].type != IMAP_ARG_STRING)
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen if (!client->common.secured && disable_plaintext_auth) {
9de176ef7f3d28ff486c2a8805110b84389e4f19Timo Sirainen client_syslog(&client->common, "Login failed: "
9de176ef7f3d28ff486c2a8805110b84389e4f19Timo Sirainen "Plaintext authentication disabled");
9de176ef7f3d28ff486c2a8805110b84389e4f19Timo Sirainen "* BAD [ALERT] Plaintext authentication is disabled, "
9de176ef7f3d28ff486c2a8805110b84389e4f19Timo Sirainen "but your client sent password in plaintext anyway. "
9de176ef7f3d28ff486c2a8805110b84389e4f19Timo Sirainen "If anyone was listening, the password was exposed.");
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen client_send_tagline(client, "NO "AUTH_PLAINTEXT_DISABLED_MSG);
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen /* authorization ID \0 authentication ID \0 pass */
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen plain_login = buffer_create_dynamic(pool_datastack_create(), 64);
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen buffer_append(plain_login, user, strlen(user));
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen buffer_append(plain_login, pass, strlen(pass));
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen base64 = buffer_create_dynamic(pool_datastack_create(),
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen base64_encode(plain_login->data, plain_login->used, base64);
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen sasl_server_auth_begin(&client->common, IMAP_SERVICE_NAME, "PLAIN",
9de176ef7f3d28ff486c2a8805110b84389e4f19Timo Sirainen /* don't read any input from client until login is finished */