89a126810703c666309310d0f3189e9834d70b5bTimo Sirainen/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainencmd_id_x_originating_ip(struct imap_client *client,
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen const char *key ATTR_UNUSED, const char *value)
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainencmd_id_x_originating_port(struct imap_client *client,
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen const char *key ATTR_UNUSED, const char *value)
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen (void)net_str2port(value, &client->common.remote_port);
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainencmd_id_x_connected_ip(struct imap_client *client,
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen const char *key ATTR_UNUSED, const char *value)
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen (void)net_addr2ip(value, &client->common.local_ip);
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainencmd_id_x_connected_port(struct imap_client *client,
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen const char *key ATTR_UNUSED, const char *value)
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainen (void)net_str2port(value, &client->common.local_port);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen const char *key ATTR_UNUSED, const char *value)
e6d7d19c328e7043ad35d5a52c1617bde915a16fTimo Sirainen if (str_to_uint(value, &client->common.proxy_ttl) < 0) {
d7095f3a4466fbb78b2d5eb3d322bc15a5b0ab1fTimo Sirainen /* nothing */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainencmd_id_x_session_id(struct imap_client *client,
e6d7d19c328e7043ad35d5a52c1617bde915a16fTimo Sirainen const char *key ATTR_UNUSED, const char *value)
9315dd69233d554452df0c12bc57002d2042a8f4Timo Sirainen if (strlen(value) <= LOGIN_MAX_SESSION_ID_LEN) {
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen i_assert(strncasecmp(key, "x-forward-", 10) == 0);
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen client_add_forward_field(&client->common, key+10, value);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenstatic const struct imap_id_param_handler imap_login_id_params[] = {
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen { "x-originating-ip", FALSE, cmd_id_x_originating_ip },
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen { "x-originating-port", FALSE, cmd_id_x_originating_port },
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen { "x-connected-ip", FALSE, cmd_id_x_connected_ip },
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen { "x-connected-port", FALSE, cmd_id_x_connected_port },
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen { "x-session-id", FALSE, cmd_id_x_session_id },
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen { "x-session-ext-id", FALSE, cmd_id_x_session_id },
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainenstatic const struct imap_id_param_handler *
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen for (unsigned int i = 0; imap_login_id_params[i].key != NULL; i++) {
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen unsigned int prefix_len = strlen(imap_login_id_params[i].key);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (strncasecmp(imap_login_id_params[i].key, key, prefix_len) == 0 &&
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainenclient_try_update_info(struct imap_client *client,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* do not try to process NIL values as client-info,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen but store them for non-reserved keys */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (client->common.trusted && !client->id_logged && value != NULL)
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainenstatic void cmd_id_handle_keyvalue(struct imap_client *client,
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen /* length of key + length of value (NIL for NULL) and two set of
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen quotes and space */
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen client_id_str = !client_try_update_info(client, key, value);
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen if (client->set->imap_id_retain && client_id_str &&
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_len(client->common.client_id) + kvlen < LOGIN_MAX_CLIENT_ID_LEN)) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client->common.client_id = str_new(client->common.preproxy_pool, 64);
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen imap_append_quoted(client->common.client_id, key);
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen imap_append_quoted(client->common.client_id, value);
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen str_array_icase_find((void *)client->cmd_id->log_keys, key)))
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen imap_id_log_reply_append(client->cmd_id->log_reply, key, value);
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainenstatic int cmd_id_handle_args(struct imap_client *client,
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen struct imap_client_cmd_id *id = client->cmd_id;
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen /* no ID logging */
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen /* already logged the ID reply */
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen if (strcmp(client->set->imap_id_log, "*") == 0) {
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen /* log all keys */
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen /* log only specified keys */
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen id->log_keys = p_strsplit_spaces(default_pool,
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen if (i_strocpy(id->key, key, sizeof(id->key)) < 0)
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen cmd_id_handle_keyvalue(client, id->key, value);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void cmd_id_finish(struct imap_client *client)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* finished handling the parameters */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen "ID sent: %s", str_c(client->cmd_id->log_reply)));
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen imap_id_reply_generate(client->set->imap_id_send)));
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen client_send_reply(&client->common, IMAP_CMD_REPLY_OK, "ID completed.");
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenstatic void cmd_id_free(struct imap_client *client)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen struct imap_client_cmd_id *id = client->cmd_id;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen client->cmd_id = id = i_new(struct imap_client_cmd_id, 1);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen id->parser = imap_parser_create(client->common.input,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen while ((ret = imap_parser_read_args(id->parser, 1, parser_flags, &args)) > 0) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if ((ret = cmd_id_handle_args(client, args)) < 0) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen "Invalid ID parameters");
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen /* NIL parameter */
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen /* finished the line */