26
29
static void client_idle_disconnect_timeout(struct client *client)
28
client_send_line(client, CLIENT_CMD_REPLY_BYE,
29
"Disconnected for inactivity.");
30
client_destroy(client, "Disconnected: Inactivity");
31
const char *user_reason, *destroy_reason;
34
if (client->master_tag != 0) {
35
secs = ioloop_time - client->auth_finished;
36
user_reason = "Timeout while finishing login.";
37
destroy_reason = t_strdup_printf(
38
"Timeout while finishing login (waited %u secs)", secs);
39
client_log_err(client, destroy_reason);
40
} else if (client->auth_request != NULL) {
42
"Disconnected for inactivity during authentication.";
44
"Disconnected: Inactivity during authentication";
45
} else if (client->login_proxy != NULL) {
46
secs = ioloop_time - client->created;
47
user_reason = "Timeout while finishing login.";
48
destroy_reason = t_strdup_printf(
49
"proxy: Logging in to %s:%u timed out "
50
"(state=%u, duration=%us)",
51
login_proxy_get_host(client->login_proxy),
52
login_proxy_get_port(client->login_proxy),
53
client->proxy_state, secs);
54
client_log_err(client, destroy_reason);
56
user_reason = "Disconnected for inactivity.";
57
destroy_reason = "Disconnected: Inactivity";
59
client_send_line(client, CLIENT_CMD_REPLY_BYE, user_reason);
60
client_destroy(client, destroy_reason);
33
63
static void client_open_streams(struct client *client)
147
183
if (client->login_proxy != NULL)
148
184
login_proxy_free(&client->login_proxy);
149
if (client->ssl_proxy != NULL)
150
ssl_proxy_free(&client->ssl_proxy);
151
185
client->v.destroy(client);
152
if (client_unref(&client) &&
153
master_service_get_service_count(master_service) == 1) {
186
if (client_unref(&client) && initial_service_count == 1) {
154
187
/* as soon as this connection is done with proxying
155
188
(or whatever), the process will die. there's no need for
156
authentication anymore, so close the connection. */
157
auth_client_disconnect(auth_client);
189
authentication anymore, so close the connection.
190
do this only with initial service_count=1, in case there
191
are other clients with pending authentications */
192
auth_client_disconnect(auth_client, "unnecessary connection");
159
194
login_client_destroyed();
160
195
login_refresh_proctitle();
236
273
client_destroy(client, "Disconnected: Connection queue full");
239
void clients_destroy_all(void)
276
void clients_destroy_all_reason(const char *reason)
241
278
struct client *client, *next;
243
280
for (client = clients; client != NULL; client = next) {
244
281
next = client->next;
245
client_destroy(client, "Disconnected: Shutting down");
282
client_destroy(client, reason);
286
void clients_destroy_all(void)
288
clients_destroy_all_reason("Disconnected: Shutting down");
249
291
static void client_start_tls(struct client *client)
336
378
return clients_count;
381
const char *client_get_session_id(struct client *client)
383
buffer_t *buf, *base64_buf;
388
if (client->session_id != NULL)
389
return client->session_id;
391
buf = buffer_create_dynamic(pool_datastack_create(), 24);
392
base64_buf = buffer_create_dynamic(pool_datastack_create(), 24*2);
394
if (gettimeofday(&tv, NULL) < 0)
395
i_fatal("gettimeofday(): %m");
396
timestamp = tv.tv_usec + (long long)tv.tv_sec * 1000ULL*1000ULL;
398
/* add lowest 48 bits of the timestamp. this gives us a bit less than
399
9 years until it wraps */
400
for (i = 0; i < 48; i += 8)
401
buffer_append_c(buf, (timestamp >> i) & 0xff);
403
buffer_append_c(buf, client->remote_port & 0xff);
404
buffer_append_c(buf, (client->remote_port >> 16) & 0xff);
406
if (IPADDR_IS_V6(&client->ip))
407
buffer_append(buf, &client->ip.u.ip6, sizeof(client->ip.u.ip6));
410
buffer_append(buf, &client->ip.u.ip4, sizeof(client->ip.u.ip4));
411
base64_encode(buf->data, buf->used, base64_buf);
412
client->session_id = p_strdup(client->pool, str_c(base64_buf));
413
return client->session_id;
416
static struct var_expand_table login_var_expand_empty_tab[] = {
417
{ 'u', NULL, "user" },
418
{ 'n', NULL, "username" },
419
{ 'd', NULL, "domain" },
420
{ 's', NULL, "service" },
421
{ 'h', NULL, "home" },
422
{ 'l', NULL, "lip" },
423
{ 'r', NULL, "rip" },
424
{ 'p', NULL, "pid" },
425
{ 'm', NULL, "mech" },
426
{ 'a', NULL, "lport" },
427
{ 'b', NULL, "rport" },
428
{ 'c', NULL, "secured" },
429
{ 'k', NULL, "ssl_security" },
430
{ 'e', NULL, "mail_pid" },
431
{ '\0', NULL, "session" },
339
435
static const struct var_expand_table *
340
436
get_var_expand_table(struct client *client)
342
static struct var_expand_table static_tab[] = {
343
{ 'u', NULL, "user" },
344
{ 'n', NULL, "username" },
345
{ 'd', NULL, "domain" },
346
{ 's', NULL, "service" },
347
{ 'h', NULL, "home" },
348
{ 'l', NULL, "lip" },
349
{ 'r', NULL, "rip" },
350
{ 'p', NULL, "pid" },
351
{ 'm', NULL, "mech" },
352
{ 'a', NULL, "lport" },
353
{ 'b', NULL, "rport" },
354
{ 'c', NULL, "secured" },
355
{ 'k', NULL, "ssl_security" },
356
{ 'e', NULL, "mail_pid" },
359
438
struct var_expand_table *tab;
362
tab = t_malloc(sizeof(static_tab));
363
memcpy(tab, static_tab, sizeof(static_tab));
441
tab = t_malloc(sizeof(login_var_expand_empty_tab));
442
memcpy(tab, login_var_expand_empty_tab,
443
sizeof(login_var_expand_empty_tab));
365
445
if (client->virtual_user != NULL) {
366
446
tab[0].value = client->virtual_user;
398
478
tab[13].value = client->mail_pid == 0 ? "" :
399
479
dec2str(client->mail_pid);
480
tab[14].value = client_get_session_id(client);
403
static bool have_key(const struct var_expand_table *table, const char *str)
484
static bool have_username_key(const char *str)
408
key = var_get_key(str);
409
for (i = 0; table[i].key != '\0'; i++) {
410
if (table[i].key == key) {
411
return table[i].value != NULL &&
412
table[i].value[0] != '\0';
488
for (; *str != '\0'; str++) {
489
if (str[0] == '%' && str[1] != '\0') {
491
key = var_get_key(str);
492
if (key == 'u' || key == 'n')
435
516
memcpy(tab, static_tab, sizeof(static_tab));
437
518
str = t_str_new(256);
519
str2 = t_str_new(128);
438
520
for (e = client->set->log_format_elements_split; *e != NULL; e++) {
439
for (p = *e; *p != '\0'; p++) {
440
if (*p != '%' || p[1] == '\0')
522
var_expand(str, *e, var_expand_table);
523
if (have_username_key(*e)) {
524
/* username is added even if it's empty */
526
str_truncate(str2, 0);
527
var_expand(str2, *e, login_var_expand_empty_tab);
528
if (strcmp(str_c(str)+pos, str_c(str2)) == 0) {
529
/* empty %variables, don't add */
530
str_truncate(str, pos);
444
if (have_key(var_expand_table, p)) {
445
if (str_len(str) > 0)
446
str_append(str, ", ");
447
var_expand(str, *e, var_expand_table);
535
if (str_len(str) > 0)
536
str_append(str, ", ");
539
if (str_len(str) > 0)
540
str_truncate(str, str_len(str)-2);
453
542
tab[0].value = t_strdup(str_c(str));
454
543
tab[1].value = msg;
455
544
str_truncate(str, 0);
505
604
return "(client didn't send a cert)";
508
if (client->auth_attempts == 0)
509
return "(no auth attempts)";
607
if (!client->greeting_sent)
608
return t_strdup_printf(
609
"(disconnected before greeting, waited %u secs)",
610
(unsigned int)(ioloop_time - client->created));
612
if (client->auth_attempts == 0) {
613
return t_strdup_printf("(no auth attempts in %u secs)",
614
(unsigned int)(ioloop_time - client->created));
511
617
/* some auth attempts without SSL/TLS */
512
618
if (client->auth_tried_disabled_plaintext)
513
return "(tried to use disabled plaintext auth)";
619
return "(tried to use disallowed plaintext auth)";
514
620
if (client->set->auth_ssl_require_client_cert &&
515
621
client->ssl_proxy == NULL)
516
622
return "(cert required, client didn't start TLS)";
517
623
if (client->auth_tried_unsupported_mech)
518
624
return "(tried to use unsupported auth mechanism)";
519
if (client->auth_request != NULL && client->auth_attempts == 1)
520
return "(disconnected while authenticating)";
625
if (client->auth_waiting && client->auth_attempts == 1) {
626
return t_strdup_printf("(client didn't finish SASL auth, "
627
"waited %u secs)", auth_secs);
629
if (client->auth_request != NULL && client->auth_attempts == 1) {
630
return t_strdup_printf("(disconnected while authenticating, "
631
"waited %u secs)", auth_secs);
633
if (client->authenticating && client->auth_attempts == 1) {
634
return t_strdup_printf("(disconnected while finishing login, "
635
"waited %u secs)", auth_secs);
521
637
if (client->auth_try_aborted && client->auth_attempts == 1)
522
638
return "(aborted authentication)";
639
if (client->auth_process_comm_fail)
640
return "(auth process communication failure)";
524
return t_strdup_printf("(auth failed, %u attempts)",
525
client->auth_attempts);
642
if (client->proxy_auth_failed)
643
return "(proxy dest auth failed)";
644
if (client->auth_successes > 0) {
645
return t_strdup_printf("(internal failure, %u succesful auths)",
646
client->auth_successes);
648
if (client->auth_user_disabled)
649
return "(user disabled)";
650
if (client->auth_pass_expired)
651
return "(password expired)";
652
return t_strdup_printf("(auth failed, %u attempts in %u secs)",
653
client->auth_attempts, auth_secs);
528
656
void client_send_line(struct client *client, enum client_cmd_reply reply,