sasl-server.c revision 183bea41fa640dc8117f3eb45ff935cd81377a84
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2002-2011 Dovecot authors, see the included COPYING file */
afc77c5375cdb8f2bf0ab6280d9229ac27c933c6Timo Sirainen "Maximum number of connections from user+IP exceeded " \
afc77c5375cdb8f2bf0ab6280d9229ac27c933c6Timo Sirainen "(mail_max_userip_connections=%u)"
afc77c5375cdb8f2bf0ab6280d9229ac27c933c6Timo Sirainen unsigned char cookie[MASTER_AUTH_COOKIE_SIZE];
afc77c5375cdb8f2bf0ab6280d9229ac27c933c6Timo Sirainensasl_server_get_advertised_mechs(struct client *client, unsigned int *count_r)
84a5175b9768da401404635c9b606264585739bdTimo Sirainen unsigned int i, j, count;
afc77c5375cdb8f2bf0ab6280d9229ac27c933c6Timo Sirainen mech = auth_client_get_available_mechs(auth_client, &count);
d2cf6522779802d0edeab7dcf960ffea2f2e1828Timo Sirainen ret_mech = t_new(struct auth_mech_desc, count);
5f4e547bb810403e8cfb19a49d8fe34713507ffdTimo Sirainen for (i = j = 0; i < count; i++) {
5f4e547bb810403e8cfb19a49d8fe34713507ffdTimo Sirainen /* a) transport is secured
5f4e547bb810403e8cfb19a49d8fe34713507ffdTimo Sirainen b) auth mechanism isn't plaintext
5f4e547bb810403e8cfb19a49d8fe34713507ffdTimo Sirainen c) we allow insecure authentication
5f4e547bb810403e8cfb19a49d8fe34713507ffdTimo Sirainen if ((mech[i].flags & MECH_SEC_PRIVATE) == 0 &&
d2cf6522779802d0edeab7dcf960ffea2f2e1828Timo Sirainen (client->secured || !client->set->disable_plaintext_auth ||
d2cf6522779802d0edeab7dcf960ffea2f2e1828Timo Sirainen ssl_proxy_has_valid_client_cert(client->ssl_proxy))
d2cf6522779802d0edeab7dcf960ffea2f2e1828Timo Sirainen auth_flags |= AUTH_REQUEST_FLAG_VALID_CLIENT_CERT;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen /* e.g. webmail */
fcb5f4cd72b413a5356a8db55e679403c6a1adb5Timo Sirainencall_client_callback(struct client *client, enum sasl_server_reply reply,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen i_assert(reply != SASL_SERVER_REPLY_CONTINUE);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen /* NOTE: client may be destroyed now */
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenmaster_auth_callback(const struct master_auth_reply *reply, void *context)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen enum sasl_server_reply sasl_reply = SASL_SERVER_REPLY_MASTER_FAILED;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen auth_client_send_cancel(auth_client, client->master_auth_id);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen call_client_callback(client, sasl_reply, data, NULL);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenstatic void master_send_request(struct anvil_request *anvil_request)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen struct client *client = anvil_request->client;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen const unsigned char *data;
5f8d497e88fae77fbeb625246bc18260f6775b83Timo Sirainen req.flags |= MAIL_AUTH_REQUEST_FLAG_TLS_COMPRESSION;
5f8d497e88fae77fbeb625246bc18260f6775b83Timo Sirainen memcpy(req.cookie, anvil_request->cookie, sizeof(req.cookie));
afc77c5375cdb8f2bf0ab6280d9229ac27c933c6Timo Sirainen buf = buffer_create_dynamic(pool_datastack_create(), 256);
afc77c5375cdb8f2bf0ab6280d9229ac27c933c6Timo Sirainen buffer_append(buf, client->master_data_prefix,
afc77c5375cdb8f2bf0ab6280d9229ac27c933c6Timo Sirainen data = i_stream_get_data(client->input, &size);
f2686912e0156c04296d6dc306f39d61089a1363Timo Sirainen master_auth_request(master_auth, client->fd, &req, buf->data,
afc77c5375cdb8f2bf0ab6280d9229ac27c933c6Timo Sirainen master_auth_callback, client, &client->master_tag);
afc77c5375cdb8f2bf0ab6280d9229ac27c933c6Timo Sirainenstatic void anvil_lookup_callback(const char *reply, void *context)
afc77c5375cdb8f2bf0ab6280d9229ac27c933c6Timo Sirainen const struct login_settings *set = client->set;
afc77c5375cdb8f2bf0ab6280d9229ac27c933c6Timo Sirainen strtoul(reply, NULL, 10) < set->mail_max_userip_connections)
afc77c5375cdb8f2bf0ab6280d9229ac27c933c6Timo Sirainen auth_client_send_cancel(auth_client, req->auth_id);
afc77c5375cdb8f2bf0ab6280d9229ac27c933c6Timo Sirainen errmsg = t_strdup_printf(ERR_TOO_MANY_USERIP_CONNECTIONS,
afc77c5375cdb8f2bf0ab6280d9229ac27c933c6Timo Sirainen call_client_callback(client, SASL_SERVER_REPLY_MASTER_FAILED,
afc77c5375cdb8f2bf0ab6280d9229ac27c933c6Timo Sirainenanvil_check_too_many_connections(struct client *client,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen req->auth_pid = auth_client_request_get_server_pid(request);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen req->auth_id = auth_client_request_get_id(request);
afc77c5375cdb8f2bf0ab6280d9229ac27c933c6Timo Sirainen buffer_create_data(&buf, req->cookie, sizeof(req->cookie));
afc77c5375cdb8f2bf0ab6280d9229ac27c933c6Timo Sirainen cookie = auth_client_request_get_cookie(request);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen if (strlen(cookie) == MASTER_AUTH_COOKIE_SIZE*2)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client->set->mail_max_userip_connections == 0) {
afc77c5375cdb8f2bf0ab6280d9229ac27c933c6Timo Sirainen query = t_strconcat("LOOKUP\t", login_binary.protocol, "/",
afc77c5375cdb8f2bf0ab6280d9229ac27c933c6Timo Sirainen anvil_client_query(anvil, query, anvil_lookup_callback, req);
84a5175b9768da401404635c9b606264585739bdTimo Sirainenauthenticate_callback(struct auth_client_request *request,
84a5175b9768da401404635c9b606264585739bdTimo Sirainen enum auth_request_status status, const char *data_base64,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen unsigned int i;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen /* client aborted */
0d6ae58916bee3452c91d9d81be72227761ec33dTimo Sirainen /* continue */
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client->sasl_callback(client, SASL_SERVER_REPLY_CONTINUE,
b13d76faf0c82162c29050382cd7f4a808294622Timo Sirainen /* user can't login */
0d6ae58916bee3452c91d9d81be72227761ec33dTimo Sirainen call_client_callback(client, SASL_SERVER_REPLY_SUCCESS,
60d1fdf2c17fd0c7020234590dbd73da81c3ce8fTimo Sirainen anvil_check_too_many_connections(client, request);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen /* parse our username if it's there */
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen call_client_callback(client, SASL_SERVER_REPLY_AUTH_FAILED,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenvoid sasl_server_auth_begin(struct client *client,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen i_assert(auth_client_is_connected(auth_client));
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client->auth_mech_name = str_ucase(i_strdup(mech_name));
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen mech = auth_client_find_mech(auth_client, mech_name);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen "Unsupported authentication mechanism.");
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen if (!client->secured && client->set->disable_plaintext_auth &&
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen "Plaintext authentication disabled.");
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen info.cert_username = client->ssl_proxy == NULL ? NULL :
const char *auth_name =