client-common-auth.c revision b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch/* Copyright (c) 2002-2011 Dovecot authors, see the included COPYING file */
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch#define PROXY_FAILURE_MSG "Account is temporarily unavailable."
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch#define LOGIN_DNS_CLIENT_SOCKET_PATH "dns-client"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch/* If we've been waiting auth server to respond for over this many milliseconds,
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch send a "waiting" message. */
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch if (client->auth_initializing || client->destroyed)
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch client->io = io_add(client->fd, IO_READ, client_input, client);
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Boschstatic void client_auth_waiting_timeout(struct client *client)
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch client_send_line(client, CLIENT_CMD_REPLY_STATUS,
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch AUTH_SERVER_WAITING_MSG : AUTH_MASTER_WAITING_MSG);
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Boschvoid client_set_auth_waiting(struct client *client)
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Boschstatic void client_auth_parse_args(struct client *client,
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch const char *const *args,
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch reply_r->proxy_timeout_msecs = 1000*atoi(value);
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch reply_r->ssl_flags |= PROXY_SSL_FLAG_ANY_CERT;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch reply_r->port = login_binary.default_ssl_port;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch reply_r->ssl_flags |= PROXY_SSL_FLAG_ANY_CERT;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch /* already handled in login-common */
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch i_debug("Ignoring unknown passdb extra field: %s", key);
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Boschstatic void proxy_free_password(struct client *client)
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch safe_memset(client->proxy_password, 0, strlen(client->proxy_password));
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Boschvoid client_proxy_finish_destroy_client(struct client *client)
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch /* input stream got closed in client_send_raw_data().
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch In most places we don't have to check for this explicitly,
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch but login_proxy_detach() attempts to get and use the
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch istream's fd, which is now -1. */
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch str_printfa(str, "proxy(%s): started proxying to %s:%u",
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch if (strcmp(client->virtual_user, client->proxy_user) != 0) {
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch /* remote username is different, log it */
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch str_printfa(str, " (master %s)", client->proxy_master_user);
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Boschvoid client_proxy_log_failure(struct client *client, const char *line)
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch str_printfa(str, "proxy(%s): Login failed to %s:%u",
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch if (strcmp(client->virtual_user, client->proxy_user) != 0) {
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch /* remote username is different, log it */
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch str_printfa(str, " (master %s)", client->proxy_master_user);
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Boschvoid client_proxy_failed(struct client *client, bool send_line)
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch client_send_line(client, CLIENT_CMD_REPLY_AUTH_FAIL_TEMP,
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch /* call this last - it may destroy the client */
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Boschstatic const char *get_disconnect_reason(struct istream *input)
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch return errno == 0 || errno == EPIPE ? "Connection closed" :
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch /* we're just freeing the proxy */
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch input = login_proxy_get_istream(client->login_proxy);
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch /* we came here from client_destroy() */
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch /* failed for some reason, probably server disconnected */
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch client_log_err(client, "proxy: Remote input buffer full");
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;
switch (sasl_reply) {
data);
const char *init_resp)
return TRUE;
if (pass_sent) {
return FALSE;
void clients_notify_auth_connected(void)