sasl-server.c revision b55f914c0ade77252cfd798ea8eb9a84bda56315
76b43e4417bab52e913da39b5f5bc2a130d3f149Timo Sirainen/* Copyright (c) 2002-2012 Dovecot authors, see the included COPYING file */
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen "Maximum number of connections from user+IP exceeded " \
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen "(mail_max_userip_connections=%u)"
39afc7584d935b2dc7332c21966a7b20da03f1ecTimo Sirainen unsigned char cookie[MASTER_AUTH_COOKIE_SIZE];
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainensasl_server_get_advertised_mechs(struct client *client, unsigned int *count_r)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen unsigned int i, j, count;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen mech = auth_client_get_available_mechs(auth_client, &count);
1f6c210c30992e95b806d2f517e2b3625ed941c5Timo Sirainen ret_mech = t_new(struct auth_mech_desc, count);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen for (i = j = 0; i < count; i++) {
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen /* a) transport is secured
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen b) auth mechanism isn't plaintext
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen c) we allow insecure authentication
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if ((mech[i].flags & MECH_SEC_PRIVATE) == 0 &&
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen (client->secured || !client->set->disable_plaintext_auth ||
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen ssl_proxy_has_valid_client_cert(client->ssl_proxy))
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen auth_flags |= AUTH_REQUEST_FLAG_VALID_CLIENT_CERT;
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen /* e.g. webmail */
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen auth_flags |= AUTH_REQUEST_FLAG_SUPPORT_FINAL_RESP;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainencall_client_callback(struct client *client, enum sasl_server_reply reply,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen i_assert(reply != SASL_SERVER_REPLY_CONTINUE);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen /* NOTE: client may be destroyed now */
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenmaster_auth_callback(const struct master_auth_reply *reply, void *context)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen enum sasl_server_reply sasl_reply = SASL_SERVER_REPLY_MASTER_FAILED;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen auth_client_send_cancel(auth_client, client->master_auth_id);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen call_client_callback(client, sasl_reply, data, NULL);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenstatic void master_send_request(struct anvil_request *anvil_request)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen struct client *client = anvil_request->client;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen const unsigned char *data;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen const char *session_id = client_get_session_id(client);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen req.flags |= MAIL_AUTH_REQUEST_FLAG_TLS_COMPRESSION;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen memcpy(req.cookie, anvil_request->cookie, sizeof(req.cookie));
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen buf = buffer_create_dynamic(pool_datastack_create(), 256);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen /* session ID */
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen buffer_append(buf, session_id, strlen(session_id)+1);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen /* protocol specific data (e.g. IMAP tag) */
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen buffer_append(buf, client->master_data_prefix,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen /* buffered client input */
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen data = i_stream_get_data(client->input, &size);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen master_auth_request(master_auth, client->fd, &req, buf->data,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen master_auth_callback, client, &client->master_tag);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenstatic void anvil_lookup_callback(const char *reply, void *context)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen const struct login_settings *set = client->set;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen strtoul(reply, NULL, 10) < set->mail_max_userip_connections)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen auth_client_send_cancel(auth_client, req->auth_id);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen errmsg = t_strdup_printf(ERR_TOO_MANY_USERIP_CONNECTIONS,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen call_client_callback(client, SASL_SERVER_REPLY_MASTER_FAILED,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenanvil_check_too_many_connections(struct client *client,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen req->auth_pid = auth_client_request_get_server_pid(request);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen req->auth_id = auth_client_request_get_id(request);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen buffer_create_data(&buf, req->cookie, sizeof(req->cookie));
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen cookie = auth_client_request_get_cookie(request);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen if (strlen(cookie) == MASTER_AUTH_COOKIE_SIZE*2)
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen client->set->mail_max_userip_connections == 0) {
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen query = t_strconcat("LOOKUP\t", login_binary->protocol, "/",
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen anvil_client_query(anvil, query, anvil_lookup_callback, req);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenauthenticate_callback(struct auth_client_request *request,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen enum auth_request_status status, const char *data_base64,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen unsigned int i;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen /* client aborted */
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen /* continue */
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen client->sasl_callback(client, SASL_SERVER_REPLY_CONTINUE,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen /* user can't login */
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen } else if (strncmp(args[i], "resp=", 5) == 0 &&
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen call_client_callback(client, SASL_SERVER_REPLY_SUCCESS,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen anvil_check_too_many_connections(client, request);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen /* fall through */
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen /* parse our username if it's there */
39afc7584d935b2dc7332c21966a7b20da03f1ecTimo Sirainen call_client_callback(client, SASL_SERVER_REPLY_AUTH_FAILED,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenvoid sasl_server_auth_begin(struct client *client,
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen i_assert(auth_client_is_connected(auth_client));
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen client->auth_mech_name = str_ucase(i_strdup(mech_name));
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen mech = auth_client_find_mech(auth_client, mech_name);
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen "Unsupported authentication mechanism.");
3320f4770d1f6c2cdd10f3c4ca5a324beb335339Timo Sirainen if (!client->secured && client->set->disable_plaintext_auth &&
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen "Plaintext authentication disabled.");
39afc7584d935b2dc7332c21966a7b20da03f1ecTimo Sirainen info.cert_username = client->ssl_proxy == NULL ? NULL :
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainen info.initial_resp_base64 = initial_resp_base64;
cb1fd563e6000153d1be76fd8722a096bd144b77Timo Sirainenstatic void sasl_server_auth_cancel(struct client *client, const char *reason,
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen if (client->set->auth_verbose && reason != NULL) {
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen str_sanitize(client->auth_mech_name, MAX_MECH_NAME);
19e8adccba16ff419f5675b1575358c2956dce83Timo Sirainen "Authenticate %s failed: %s", auth_name, reason));
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainen auth_client_request_abort(&client->auth_request);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen call_client_callback(client, reply, reason, NULL);
df02611c44e9432e7961223bf9bfa3fb233b1789Timo Sirainenvoid sasl_server_auth_failed(struct client *client, const char *reason)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen sasl_server_auth_cancel(client, reason, SASL_SERVER_REPLY_AUTH_FAILED);
15780ce9a9aaf06b585f43850a60b89bf1ea3e1fTimo Sirainenvoid sasl_server_auth_abort(struct client *client)