client-common-auth.c revision 2ef0e8ee48c9683f7bd6698798efa3328e4322d1
5a580c3a38ced62d4bcc95b8ac7c4f2935b5d294Timo Sirainen/* Copyright (c) 2002-2010 Dovecot authors, see the included COPYING file */
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen#define PROXY_FAILURE_MSG "Account is temporarily unavailable."
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen#define LOGIN_DNS_CLIENT_SOCKET_PATH "dns-client"
0db42260be85e797aa9909a29b20296996f52e75Timo Sirainen/* If we've been waiting auth server to respond for over this many milliseconds,
0db42260be85e797aa9909a29b20296996f52e75Timo Sirainen send a "waiting" message. */
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client->io = io_add(client->fd, IO_READ, client_input, client);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenstatic void client_auth_waiting_timeout(struct client *client)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client_send_line(client, CLIENT_CMD_REPLY_STATUS,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen AUTH_SERVER_WAITING_MSG : AUTH_MASTER_WAITING_MSG);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenvoid client_set_auth_waiting(struct client *client)
16cb5d65265dd0b216542803fd80c4b999ae118eTimo Sirainenstatic void client_auth_parse_args(struct client *client,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen const char *const *args,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen reply_r->proxy_timeout_msecs = 1000*atoi(value);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen reply_r->ssl_flags |= PROXY_SSL_FLAG_STARTTLS;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen /* already handled in login-common */
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen i_debug("Ignoring unknown passdb extra field: %s", key);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenstatic void proxy_free_password(struct client *client)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen safe_memset(client->proxy_password, 0, strlen(client->proxy_password));
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenvoid client_proxy_finish_destroy_client(struct client *client)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen str_printfa(str, "proxy(%s): started proxying to %s:%u",
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen if (strcmp(client->virtual_user, client->proxy_user) != 0) {
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen /* remote username is different, log it */
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen str_printfa(str, " (master %s)", client->proxy_master_user);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenvoid client_proxy_log_failure(struct client *client, const char *line)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen str_printfa(str, "proxy(%s): Login failed to %s:%u",
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen if (strcmp(client->virtual_user, client->proxy_user) != 0) {
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen /* remote username is different, log it */
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen str_printfa(str, " (master %s)", client->proxy_master_user);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenvoid client_proxy_failed(struct client *client, bool send_line)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client_send_line(client, CLIENT_CMD_REPLY_AUTH_FAIL_TEMP,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen /* call this last - it may destroy the client */
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen /* we're just freeing the proxy */
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen input = login_proxy_get_istream(client->login_proxy);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen /* we came here from client_destroy() */
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen /* failed for some reason, probably server disconnected */
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client_log_err(client, "proxy: Remote input buffer full");
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client_log_err(client, "proxy: Remote disconnected");
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen while ((line = i_stream_next_line(input)) != NULL) {
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen if (client->v.proxy_parse_line(client, line) != 0)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client_log_err(client, "proxy: password not given");
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client_send_line(client, CLIENT_CMD_REPLY_AUTH_FAIL_TEMP,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen if (reply->host == NULL || *reply->host == '\0') {
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client_log_err(client, "proxy: host not given");
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client_send_line(client, CLIENT_CMD_REPLY_AUTH_FAIL_TEMP,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen /* connection_queue_add() decided that we were the oldest
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen connection and killed us. */
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen if (login_proxy_is_ourself(client, reply->host, reply->port,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client_log_err(client, "Proxying loops to itself");
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client_send_line(client, CLIENT_CMD_REPLY_AUTH_FAIL_TEMP,
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen proxy_set.dns_client_socket_path = LOGIN_DNS_CLIENT_SOCKET_PATH;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen proxy_set.connect_timeout_msecs = reply->proxy_timeout_msecs;
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen if (login_proxy_new(client, &proxy_set, proxy_input) < 0) {
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client_send_line(client, CLIENT_CMD_REPLY_AUTH_FAIL_TEMP,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client->proxy_user = i_strdup(reply->destuser);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client->proxy_master_user = i_strdup(reply->master_user);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen client->proxy_password = i_strdup(reply->password);
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen /* disable input until authentication is finished */
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainenclient_auth_handle_reply(struct client *client,
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen const struct client_auth_reply *reply, bool success)
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen /* we want to proxy the connection to another server.
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen don't do this unless authentication succeeded. with
01435c38e7d671d5a892c4b802cfb204881cd454Timo Sirainen master user proxying we can get FAIL with proxy still set.
if (!success)
return FALSE;
return TRUE;
const unsigned char *data;
unsigned int len;
for (i = 0; i < size; i++) {
return i < size;
int ret;
return ret;
int ret;
switch (sasl_reply) {
data);
const char *init_resp)
return TRUE;
if (pass_sent) {
return FALSE;
void clients_notify_auth_connected(void)