bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
53dfcefa9440a49d703e49193819a79be99c9ba6Timo Sirainen#define PROXY_FAILURE_MSG "Account is temporarily unavailable."
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* If we've been waiting auth server to respond for over this many milliseconds,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen send a "waiting" message. */
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen#define AUTH_WAITING_WARNING_TIMEOUT_MSECS (10*1000)
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Boschstatic const struct client_auth_fail_code_id client_auth_fail_codes[] = {
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Boschclient_auth_fail_code_lookup(const char *fail_code)
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch const struct client_auth_fail_code_id *fail = client_auth_fail_codes;
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainenstatic void client_auth_failed(struct client *client)
d1e7425048c61d71f41f737ba947687198842dc2Timo Sirainen if (client->auth_initializing || client->destroyed)
a1852ab4cf0a942a3fcf4ca5636a7932ebcc7970Stephan Bosch client->io = io_add(client->fd, IO_READ, client_input, client);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic void client_auth_waiting_timeout(struct client *client)
b9c76fe9d9ca194816606342da1ddbd9be6bc8abTimo Sirainen client_log_warn(client, "Auth process not responding, "
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen "delayed sending initial response (greeting)");
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen client_notify_status(client, FALSE, client->master_tag == 0 ?
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen AUTH_SERVER_WAITING_MSG : AUTH_MASTER_WAITING_MSG);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid client_set_auth_waiting(struct client *client)
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainenstatic void alt_username_set(ARRAY_TYPE(const_string) *alt_usernames, pool_t pool,
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen fields = array_get(&global_alt_usernames, &count);
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen for (i = 0; i < count; i++) {
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen array_append(&global_alt_usernames, &new_key, 1);
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen /* array is NULL-terminated, so if there are unused fields in
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen the middle set them as "" */
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainenstatic void client_auth_parse_args(struct client *client, bool success,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const char *const *args,
f32d0295c90ed810889504cdfa5e1a25a415f65fStephan Bosch reply_r->fail_code = CLIENT_AUTH_FAIL_CODE_LOGIN_DISABLED;
009217abb57a24a4076092e8e4e165545747839eStephan Bosch if (net_str2port(value, &reply_r->port) < 0) {
c93aca832ee532010ead91b85fa9f614132e1be2Stephan Bosch if (str_to_uint(value, &reply_r->proxy_timeout_msecs) < 0) {
c93aca832ee532010ead91b85fa9f614132e1be2Stephan Bosch } else if (strcmp(key, "proxy_refresh") == 0) {
c93aca832ee532010ead91b85fa9f614132e1be2Stephan Bosch if (str_to_uint(value, &reply_r->proxy_refresh_secs) < 0) {
ab281fc992907b6cf6c730f672dc3aa4c6685015Timo Sirainen else if (strcmp(key, "proxy_nopipelining") == 0)
6d24551e169c0808695db35d7a228f1970a84c75Timo Sirainen else if (strcmp(key, "proxy_not_trusted") == 0)
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainen reply_r->ssl_flags |= PROXY_SSL_FLAG_ANY_CERT;
5a250816ffc4cc5db203f9410ea99b6601c7b91aTimo Sirainen reply_r->port = login_binary->default_ssl_port;
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainen reply_r->ssl_flags |= PROXY_SSL_FLAG_ANY_CERT;
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch if (reply_r->fail_code != CLIENT_AUTH_FAIL_CODE_NONE) {
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch /* code already assigned */
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch reply_r->fail_code = client_auth_fail_code_lookup(value);
8ce3071e80b9973230048ecadfcb073fb82cc69fTimo Sirainen /* already handled in sasl-server.c */
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen alt_username_set(&alt_usernames, client->pool,
998eadc15aabe598cc9301fdb28c0fef5225b3f7Aki Tuomi /* these are passed to upstream */
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk i_debug("Ignoring unknown passdb extra field: %s", key);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic void proxy_free_password(struct client *client)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen safe_memset(client->proxy_password, 0, strlen(client->proxy_password));
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid client_proxy_finish_destroy_client(struct client *client)
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainen /* input stream got closed in client_send_raw_data().
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainen In most places we don't have to check for this explicitly,
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainen but login_proxy_detach() attempts to get and use the
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainen istream's fd, which is now -1. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_printfa(str, "proxy(%s): started proxying to %s:%u",
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (strcmp(client->virtual_user, client->proxy_user) != 0) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* remote username is different, log it */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_printfa(str, " (master %s)", client->proxy_master_user);
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainenstatic void client_proxy_error(struct client *client, const char *text)
2b96880f2d789d125aff6a95eaa7b51f558a6a1cTimo Sirainenconst char *client_proxy_get_state(struct client *client)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid client_proxy_log_failure(struct client *client, const char *line)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_printfa(str, "proxy(%s): Login failed to %s:%u",
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (strcmp(client->virtual_user, client->proxy_user) != 0) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* remote username is different, log it */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_printfa(str, " (master %s)", client->proxy_master_user);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid client_proxy_failed(struct client *client, bool send_line)
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen client_proxy_error(client, PROXY_FAILURE_MSG);
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen dsasl_client_free(&client->proxy_sasl_client);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* call this last - it may destroy the client */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* we're just freeing the proxy */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen input = login_proxy_get_istream(client->login_proxy);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* we came here from client_destroy() */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* failed for some reason, probably server disconnected */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen client_log_err(client, "proxy: Remote input buffer full");
77f1da4b5e2b800197d8db548235497d5e9d6a4fTimo Sirainen "proxy: Remote %s:%u disconnected: %s "
2b96880f2d789d125aff6a95eaa7b51f558a6a1cTimo Sirainen "(state=%s, duration=%us)%s",
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen while ((line = i_stream_next_line(input)) != NULL) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (client->v.proxy_parse_line(client, line) != 0)
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen const struct dsasl_client_mech *sasl_mech = NULL;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen client_log_err(client, "proxy: password not given");
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen client_proxy_error(client, PROXY_FAILURE_MSG);
04b7dc631f33bf61f273138c679da9bd0910fb6dTimo Sirainen if (reply->host == NULL || *reply->host == '\0') {
04b7dc631f33bf61f273138c679da9bd0910fb6dTimo Sirainen client_log_err(client, "proxy: host not given");
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen client_proxy_error(client, PROXY_FAILURE_MSG);
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen sasl_mech = dsasl_client_mech_find(reply->proxy_mech);
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen "proxy: Unsupported SASL mechanism %s",
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen client_proxy_error(client, PROXY_FAILURE_MSG);
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen /* have to use PLAIN authentication with master user logins */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* connection_queue_add() decided that we were the oldest
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen connection and killed us. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (login_proxy_is_ourself(client, reply->host, reply->port,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen client_log_err(client, "Proxying loops to itself");
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen client_proxy_error(client, PROXY_FAILURE_MSG);
e7dd5065d21c569e5e6ddd713bd345dadd1cf51dTimo Sirainen net_addr2ip(reply->hostip, &proxy_set.ip) < 0)
c51644e9e04effbbc9c415cadcfbcb4d9465855cTimo Sirainen if (net_addr2ip(reply->source_ip, &proxy_set.source_ip) < 0)
c51644e9e04effbbc9c415cadcfbcb4d9465855cTimo Sirainen } else if (login_source_ips_count > 0) {
c51644e9e04effbbc9c415cadcfbcb4d9465855cTimo Sirainen /* select the next source IP with round robin. */
c51644e9e04effbbc9c415cadcfbcb4d9465855cTimo Sirainen proxy_set.source_ip = login_source_ips[login_source_ips_idx];
c51644e9e04effbbc9c415cadcfbcb4d9465855cTimo Sirainen (login_source_ips_idx + 1) % login_source_ips_count;
2598b2f36365b52d9754b9348a5be29569293e46Timo Sirainen proxy_set.connect_timeout_msecs = reply->proxy_timeout_msecs;
f0d93763f210ecdb85a115fdd0210a16cfc5ff5cTimo Sirainen proxy_set.connect_timeout_msecs = PROXY_DEFAULT_TIMEOUT_MSECS;
6303191abcb37164f435ccdc56e9dbddf1288851Timo Sirainen proxy_set.notify_refresh_secs = reply->proxy_refresh_secs;
2ef0e8ee48c9683f7bd6698798efa3328e4322d1Timo Sirainen if (login_proxy_new(client, &proxy_set, proxy_input) < 0) {
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen client_proxy_error(client, PROXY_FAILURE_MSG);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen client->proxy_user = i_strdup(reply->destuser);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen client->proxy_master_user = i_strdup(reply->master_user);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen client->proxy_password = i_strdup(reply->password);
ab281fc992907b6cf6c730f672dc3aa4c6685015Timo Sirainen client->proxy_nopipelining = reply->proxy_nopipelining;
6d24551e169c0808695db35d7a228f1970a84c75Timo Sirainen client->proxy_not_trusted = reply->proxy_not_trusted;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* disable input until authentication is finished */
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainenclient_auth_result(struct client *client, enum client_auth_result result,
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen const struct client_auth_reply *reply, const char *text)
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen client->v.auth_result(client, result, reply, text);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenclient_auth_handle_reply(struct client *client,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const struct client_auth_reply *reply, bool success)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* we want to proxy the connection to another server.
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen don't do this unless authentication succeeded. with
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen master user proxying we can get FAIL with proxy still set.
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen proxy host=.. [port=..] [destuser=..] pass=.. */
42fcc708268a89aa9640693e71d13a2bb76e19c8Timo Sirainen /* this for plugins being able th hook into auth reply
42fcc708268a89aa9640693e71d13a2bb76e19c8Timo Sirainen when proxying is used */
42fcc708268a89aa9640693e71d13a2bb76e19c8Timo Sirainen client_auth_result(client, CLIENT_AUTH_RESULT_SUCCESS,
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen reason = "Logged in, but you should use this server instead.";
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch enum client_auth_result result = CLIENT_AUTH_RESULT_AUTHFAILED;
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch const char *timestamp, *reason = reply->reason;
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch /* Either failed or user login is disabled */
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen timestamp = t_strflocaltime("%Y-%m-%d %H:%M:%S", ioloop_time);
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch reason = t_strdup_printf(AUTH_TEMP_FAILED_MSG" [%s:%s]",
04eb0abcf8f8b0c014499b5c5bae89484553613fStephan Bosch result = CLIENT_AUTH_RESULT_MECH_SSL_REQUIRED;
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch result = CLIENT_AUTH_RESULT_AUTHFAILED_REASON;
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch client_auth_result(client, result, reply, reason);
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainenvoid client_auth_respond(struct client *client, const char *response)
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen auth_client_request_continue(client->auth_request, response);
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainenvoid client_auth_fail(struct client *client, const char *text)
decb23442f9e6cd5c4845a9cb162029b8c6d5f0fTimo Sirainenint client_auth_read_line(struct client *client)
3858a7a5da361c35f1e6e50c8e3214dc0cf379d6Phil Carmody if (i_stream_read_more(client->input, &data, &size) == -1) {
a75907609d7c410c9e17beedfafbf28b4439fa8aTimo Sirainen /* see if we have a full line */
a75907609d7c410c9e17beedfafbf28b4439fa8aTimo Sirainen for (i = 0; i < size; i++) {
decb23442f9e6cd5c4845a9cb162029b8c6d5f0fTimo Sirainen client->auth_response = str_new(default_pool, I_MAX(i+1, 256));
7fa573e6ea36024f618492e7d3649a69c1b41028Timo Sirainen if (str_len(client->auth_response) + i > LOGIN_MAX_AUTH_BUF_SIZE) {
a75907609d7c410c9e17beedfafbf28b4439fa8aTimo Sirainen client_destroy(client, "Authentication response too large");
a75907609d7c410c9e17beedfafbf28b4439fa8aTimo Sirainen i_stream_skip(client->input, i == size ? size : i+1);
a75907609d7c410c9e17beedfafbf28b4439fa8aTimo Sirainen /* drop trailing \r */
a75907609d7c410c9e17beedfafbf28b4439fa8aTimo Sirainen if (len > 0 && str_c(client->auth_response)[len-1] == '\r')
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainenvoid client_auth_parse_response(struct client *client)
a75907609d7c410c9e17beedfafbf28b4439fa8aTimo Sirainen if (strcmp(str_c(client->auth_response), "*") == 0) {
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen client_auth_respond(client, str_c(client->auth_response));
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen memset(str_c_modifiable(client->auth_response), 0,
46ec792dd4ccf6c34706c4774228301fafde6aa9Timo Sirainenstatic void client_auth_input(struct client *client)
ab90f702ceedb7ba445a9a592be0b213b27cbafaStephan Bosch i_assert(client->v.auth_parse_response != NULL);
46ec792dd4ccf6c34706c4774228301fafde6aa9Timo Sirainenvoid client_auth_send_challenge(struct client *client, const char *data)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainensasl_callback(struct client *client, enum sasl_server_reply sasl_reply,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen sasl_reply == SASL_SERVER_REPLY_AUTH_ABORTED ||
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen sasl_reply == SASL_SERVER_REPLY_MASTER_FAILED);
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch client->last_auth_fail = CLIENT_AUTH_FAIL_CODE_NONE;
0d1b8b6bec79746c5d89d57dd8c1688946bd9237Josef 'Jeff' Sipek timeout_remove(&client->to_auth_waiting);
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen client_auth_parse_args(client, TRUE, args, &reply);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (client_auth_handle_reply(client, &reply, TRUE))
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen client_auth_result(client, CLIENT_AUTH_RESULT_SUCCESS,
0d1b8b6bec79746c5d89d57dd8c1688946bd9237Josef 'Jeff' Sipek timeout_remove(&client->to_auth_waiting);
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen client_auth_parse_args(client, FALSE, args, &reply);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (client_auth_handle_reply(client, &reply, FALSE))
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (sasl_reply == SASL_SERVER_REPLY_AUTH_ABORTED) {
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen client_auth_result(client, CLIENT_AUTH_RESULT_ABORTED,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* authentication itself succeeded, we just hit some
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen internal failure. */
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen client_auth_result(client, CLIENT_AUTH_RESULT_TEMPFAIL,
0348172a5278d1f5aa2440f30346c390ddc17318Timo Sirainen /* the fd may still be hanging somewhere in kernel or another
0348172a5278d1f5aa2440f30346c390ddc17318Timo Sirainen process. make sure the client gets disconnected. */
cb2c44f33d9d48f58e4c5e42ba2526a0c100218aTimo Sirainen if (shutdown(client->fd, SHUT_RDWR) < 0 && errno != ENOTCONN)
1a1159e589def1e32b7dc25397f15146672ef73eTimo Sirainen /* e.g. mail_max_userip_connections is reached */
86bca14f79caeff0830abd2315d8a0e5db4b979bTimo Sirainen /* The error should have been logged already.
86bca14f79caeff0830abd2315d8a0e5db4b979bTimo Sirainen The client will only see a generic internal error. */
86bca14f79caeff0830abd2315d8a0e5db4b979bTimo Sirainen client_notify_disconnect(client, CLIENT_DISCONNECT_INTERNAL_ERROR,
86bca14f79caeff0830abd2315d8a0e5db4b979bTimo Sirainen "Internal login failure. "
86bca14f79caeff0830abd2315d8a0e5db4b979bTimo Sirainen "Refer to server log for more information.");
86bca14f79caeff0830abd2315d8a0e5db4b979bTimo Sirainen data = t_strdup_printf("Internal login failure (pid=%s id=%u)",
ab90f702ceedb7ba445a9a592be0b213b27cbafaStephan Bosch i_assert(client->v.auth_send_challenge != NULL);
0d1b8b6bec79746c5d89d57dd8c1688946bd9237Josef 'Jeff' Sipek timeout_remove(&client->to_auth_waiting);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenint client_auth_begin(struct client *client, const char *mech_name,
f29756821a4c6b12b73e4a2a3e1c230117a43773Timo Sirainen if (!client->secured && strcmp(client->ssl_set->ssl, "required") == 0) {
d3a7d023b47d2a137f01109e7b38702dca3f11d3Timo Sirainen "SSL required for authentication");
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen client_auth_result(client, CLIENT_AUTH_RESULT_SSL_REQUIRED, NULL,
d3a7d023b47d2a137f01109e7b38702dca3f11d3Timo Sirainen "Authentication not allowed until SSL/TLS is enabled.");
5a250816ffc4cc5db203f9410ea99b6601c7b91aTimo Sirainen sasl_server_auth_begin(client, login_binary->protocol, mech_name,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* don't handle input until we get the initial auth reply */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenbool client_check_plaintext_auth(struct client *client, bool pass_sent)
04eb0abcf8f8b0c014499b5c5bae89484553613fStephan Bosch bool ssl_required = (strcmp(client->ssl_set->ssl, "required") == 0);
e2ce85866a669d1881d2d31791619d2e7c63c253Timo Sirainen if (client->secured || (!client->set->disable_plaintext_auth &&
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen "Plaintext authentication disabled");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen "Plaintext authentication not allowed "
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen "without SSL/TLS, but your client did it anyway. "
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen "If anyone was listening, the password was exposed.");
04eb0abcf8f8b0c014499b5c5bae89484553613fStephan Bosch client_auth_result(client, CLIENT_AUTH_RESULT_SSL_REQUIRED, NULL,
04eb0abcf8f8b0c014499b5c5bae89484553613fStephan Bosch client_auth_result(client, CLIENT_AUTH_RESULT_MECH_SSL_REQUIRED, NULL,
80e461e945dd4d5b0d08535413176cf1756e8523Timo Sirainen for (client = clients; client != NULL; client = next) {
0d1b8b6bec79746c5d89d57dd8c1688946bd9237Josef 'Jeff' Sipek timeout_remove(&client->to_auth_waiting);