78
static void client_auth_failed(struct imap_client *client)
81
static void client_authfail_delay_timeout(struct imap_client *client)
80
if (client->auth_initializing)
83
timeout_remove(&client->to_authfail_delay);
83
85
/* get back to normal client input. */
84
if (client->io != NULL)
85
io_remove(&client->io);
86
client->io = io_add(client->common.fd, IO_READ,
87
client_input, client);
86
i_assert(client->io == NULL);
87
client->io = io_add(client->common.fd, IO_READ, client_input, client);
88
88
client_input(client);
91
void client_auth_failed(struct imap_client *client, bool nodelay)
93
unsigned int delay_msecs;
95
client->common.auth_command_tag = NULL;
97
if (client->auth_initializing)
100
if (client->io != NULL)
101
io_remove(&client->io);
103
client->io = io_add(client->common.fd, IO_READ,
104
client_input, client);
105
client_input(client);
109
/* increase the timeout after each unsuccessful attempt, but don't
110
increase it so high that the idle timeout would be triggered */
111
delay_msecs = client->common.auth_attempts *
112
AUTH_FAILURE_DELAY_INCREASE_MSECS;
113
if (delay_msecs > CLIENT_LOGIN_IDLE_TIMEOUT_MSECS)
114
delay_msecs = CLIENT_LOGIN_IDLE_TIMEOUT_MSECS - 1000;
116
i_assert(client->to_authfail_delay == NULL);
117
client->to_authfail_delay =
118
timeout_add(delay_msecs, client_authfail_delay_timeout, client);
91
121
static bool client_handle_args(struct imap_client *client,
92
const char *const *args, bool success)
122
const char *const *args, bool success,
94
125
const char *reason = NULL, *host = NULL, *destuser = NULL, *pass = NULL;
126
const char *master_user = NULL;
127
const char *key, *value, *p;
128
enum login_proxy_ssl_flags ssl_flags = 0;
96
130
unsigned int port = 143;
97
bool proxy = FALSE, temp = FALSE, nologin = !success, proxy_self;
131
unsigned int proxy_timeout_msecs = 0;
132
bool proxy = FALSE, temp = FALSE, nologin = !success;
133
bool authz_failure = FALSE;
99
136
for (; *args != NULL; args++) {
100
if (strcmp(*args, "nologin") == 0)
137
p = strchr(*args, '=');
142
key = t_strdup_until(*args, p);
145
if (strcmp(key, "nologin") == 0)
102
else if (strcmp(*args, "proxy") == 0)
147
else if (strcmp(key, "nodelay") == 0)
149
else if (strcmp(key, "proxy") == 0)
104
else if (strcmp(*args, "temp") == 0)
151
else if (strcmp(key, "temp") == 0)
106
else if (strncmp(*args, "reason=", 7) == 0)
108
else if (strncmp(*args, "host=", 5) == 0)
110
else if (strncmp(*args, "port=", 5) == 0)
111
port = atoi(*args + 5);
112
else if (strncmp(*args, "destuser=", 9) == 0)
113
destuser = *args + 9;
114
else if (strncmp(*args, "pass=", 5) == 0)
116
else if (strncmp(*args, "user=", 5) == 0) {
153
else if (strcmp(key, "authz") == 0)
154
authz_failure = TRUE;
155
else if (strcmp(key, "reason") == 0)
157
else if (strcmp(key, "host") == 0)
159
else if (strcmp(key, "port") == 0)
161
else if (strcmp(key, "destuser") == 0)
163
else if (strcmp(key, "pass") == 0)
165
else if (strcmp(key, "proxy_timeout") == 0)
166
proxy_timeout_msecs = 1000*atoi(value);
167
else if (strcmp(key, "master") == 0)
169
else if (strcmp(key, "ssl") == 0) {
170
if (strcmp(value, "yes") == 0)
171
ssl_flags |= PROXY_SSL_FLAG_YES;
172
else if (strcmp(value, "any-cert") == 0) {
173
ssl_flags |= PROXY_SSL_FLAG_YES |
174
PROXY_SSL_FLAG_ANY_CERT;
176
} else if (strcmp(key, "starttls") == 0) {
177
ssl_flags |= PROXY_SSL_FLAG_STARTTLS;
178
} else if (strcmp(key, "user") == 0) {
117
179
/* already handled in login-common */
118
180
} else if (auth_debug) {
119
i_info("Ignoring unknown passdb extra field: %s",
181
i_info("Ignoring unknown passdb extra field: %s", key);
124
185
if (destuser == NULL)
125
186
destuser = client->common.virtual_user;
127
proxy_self = proxy &&
128
login_proxy_is_ourself(&client->common, host, port, destuser);
129
if (proxy && !proxy_self) {
130
189
/* we want to proxy the connection to another server.
131
190
don't do this unless authentication succeeded. with
132
191
master user proxying we can get FAIL with proxy still set.
169
229
client_destroy_success(client, "Login with referral");
172
} else if (nologin || proxy_self) {
232
} else if (nologin) {
173
233
/* Authentication went ok, but for some reason user isn't
174
234
allowed to log in. Shouldn't probably happen. */
176
client_syslog(&client->common,
177
"Proxying loops to itself");
180
235
reply = t_str_new(128);
181
236
if (reason != NULL)
182
str_printfa(reply, "NO %s", reason);
183
else if (temp || proxy_self)
184
str_append(reply, "NO "AUTH_TEMP_FAILED_MSG);
186
str_append(reply, "NO "AUTH_FAILED_MSG);
237
str_printfa(reply, "NO [ALERT] %s", reason);
239
str_append(reply, "NO ["IMAP_RESP_CODE_UNAVAILABLE"] "
240
AUTH_TEMP_FAILED_MSG);
241
} else if (authz_failure) {
242
str_append(reply, "NO "IMAP_AUTHZ_FAILED_MSG);
244
str_append(reply, "NO "IMAP_AUTH_FAILED_MSG);
187
246
client_send_tagline(client, str_c(reply));
189
248
/* normal login/failure */
193
i_assert(nologin || proxy_self);
195
254
if (!client->destroyed)
196
client_auth_failed(client);
255
client_auth_failed(client, *nodelay_r);
214
274
if (client->to_auth_waiting != NULL)
215
275
timeout_remove(&client->to_auth_waiting);
216
276
if (args != NULL) {
217
if (client_handle_args(client, args, TRUE))
277
if (client_handle_args(client, args, TRUE, &nodelay))
221
client_send_tagline(client, "OK Logged in.");
222
280
client_destroy_success(client, "Login");
224
282
case SASL_SERVER_REPLY_AUTH_FAILED:
225
case SASL_SERVER_REPLY_CLIENT_ERROR:
283
case SASL_SERVER_REPLY_AUTH_ABORTED:
226
284
if (client->to_auth_waiting != NULL)
227
285
timeout_remove(&client->to_auth_waiting);
228
286
if (args != NULL) {
229
if (client_handle_args(client, args, FALSE))
287
if (client_handle_args(client, args, FALSE, &nodelay))
233
msg = reply == SASL_SERVER_REPLY_AUTH_FAILED ? "NO " : "BAD ";
234
msg = t_strconcat(msg, data != NULL ? data : AUTH_FAILED_MSG,
291
if (reply == SASL_SERVER_REPLY_AUTH_ABORTED)
292
msg = "BAD Authentication aborted by client.";
293
else if (data == NULL)
294
msg = "NO "IMAP_AUTH_FAILED_MSG;
296
msg = t_strconcat("NO [ALERT] ", data, NULL);
236
297
client_send_tagline(client, msg);
238
299
if (!client->destroyed)
239
client_auth_failed(client);
300
client_auth_failed(client, nodelay);
241
302
case SASL_SERVER_REPLY_MASTER_FAILED:
242
303
if (data == NULL)