Mercurial > dovecot > core-2.2
changeset 14149:1af2a0497f3f
lmtp: Implemented Postfix-compatible XCLIENT extension for changing client's ip/port.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 23 Feb 2012 11:12:04 +0200 |
parents | ac4eed7bef23 |
children | 3144001fae84 |
files | src/lmtp/client.c src/lmtp/client.h src/lmtp/commands.c src/lmtp/commands.h src/lmtp/lmtp-settings.c src/lmtp/lmtp-settings.h |
diffstat | 6 files changed, 71 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lmtp/client.c Thu Feb 16 23:05:17 2012 +0000 +++ b/src/lmtp/client.c Thu Feb 23 11:12:04 2012 +0200 @@ -68,6 +68,8 @@ return cmd_rset(client, args); if (strcmp(cmd, "NOOP") == 0) return cmd_noop(client, args); + if (strcmp(cmd, "XCLIENT") == 0) + return cmd_xclient(client, args); client_send_line(client, "502 5.5.2 Unknown command"); return 0; @@ -342,6 +344,29 @@ va_end(args); } +bool client_is_trusted(struct client *client) +{ + const char *const *net; + struct ip_addr net_ip; + unsigned int bits; + + if (client->lmtp_set->login_trusted_networks == NULL) + return FALSE; + + net = t_strsplit_spaces(client->lmtp_set->login_trusted_networks, ", "); + for (; *net != NULL; net++) { + if (net_parse_range(*net, &net_ip, &bits) < 0) { + i_error("login_trusted_networks: " + "Invalid network '%s'", *net); + break; + } + + if (net_is_in_network(&client->remote_ip, &net_ip, bits)) + return TRUE; + } + return FALSE; +} + void clients_destroy(void) { while (clients != NULL) {
--- a/src/lmtp/client.h Thu Feb 16 23:05:17 2012 +0000 +++ b/src/lmtp/client.h Thu Feb 23 11:12:04 2012 +0200 @@ -82,6 +82,7 @@ void client_send_line(struct client *client, const char *fmt, ...) ATTR_FORMAT(2, 3); +bool client_is_trusted(struct client *client); void clients_destroy(void);
--- a/src/lmtp/commands.c Thu Feb 16 23:05:17 2012 +0000 +++ b/src/lmtp/commands.c Thu Feb 23 11:12:04 2012 +0200 @@ -68,6 +68,8 @@ client_state_reset(client); client_send_line(client, "250-%s", client->my_domain); + if (client_is_trusted(client)) + client_send_line(client, "250-XCLIENT ADDR PORT"); client_send_line(client, "250-8BITMIME"); client_send_line(client, "250-ENHANCEDSTATUSCODES"); client_send_line(client, "250 PIPELINING"); @@ -902,3 +904,41 @@ client_input_data_handle(client); return -1; } + +int cmd_xclient(struct client *client, const char *args) +{ + const char *const *tmp; + struct ip_addr remote_ip; + unsigned int remote_port = 0; + bool args_ok = TRUE; + + if (!client_is_trusted(client)) { + client_send_line(client, "550 You are not from trusted IP"); + return 0; + } + remote_ip.family = 0; + for (tmp = t_strsplit(args, " "); *tmp != NULL; tmp++) { + if (strncasecmp(*tmp, "ADDR=", 5) == 0) { + if (net_addr2ip(*tmp + 5, &remote_ip) < 0) + args_ok = FALSE; + } else if (strncasecmp(*tmp, "PORT=", 5) == 0) { + if (str_to_uint(*tmp + 5, &remote_port) < 0 || + remote_port == 0 || remote_port > 65535) + args_ok = FALSE; + } + } + if (!args_ok) { + client_send_line(client, "501 Invalid parameters"); + return 0; + } + + /* args ok, set them and reset the state */ + client_state_reset(client); + if (remote_ip.family != 0) + client->remote_ip = remote_ip; + if (remote_port != 0) + client->remote_port = remote_port; + client_send_line(client, "220 %s %s", client->my_domain, + client->lmtp_set->login_greeting); + return 0; +}
--- a/src/lmtp/commands.h Thu Feb 16 23:05:17 2012 +0000 +++ b/src/lmtp/commands.h Thu Feb 23 11:12:04 2012 +0200 @@ -11,5 +11,6 @@ int cmd_rset(struct client *client, const char *args); int cmd_noop(struct client *client, const char *args); int cmd_data(struct client *client, const char *args); +int cmd_xclient(struct client *client, const char *args); #endif
--- a/src/lmtp/lmtp-settings.c Thu Feb 16 23:05:17 2012 +0000 +++ b/src/lmtp/lmtp-settings.c Thu Feb 23 11:12:04 2012 +0200 @@ -60,6 +60,7 @@ DEF(SET_BOOL, lmtp_proxy), DEF(SET_BOOL, lmtp_save_to_detail_mailbox), DEF(SET_STR_VARS, login_greeting), + DEF(SET_STR, login_trusted_networks), SETTING_DEFINE_LIST_END }; @@ -67,7 +68,8 @@ static const struct lmtp_settings lmtp_default_settings = { .lmtp_proxy = FALSE, .lmtp_save_to_detail_mailbox = FALSE, - .login_greeting = PACKAGE_NAME" ready." + .login_greeting = PACKAGE_NAME" ready.", + .login_trusted_networks = "" }; static const struct setting_parser_info *lmtp_setting_dependencies[] = {
--- a/src/lmtp/lmtp-settings.h Thu Feb 16 23:05:17 2012 +0000 +++ b/src/lmtp/lmtp-settings.h Thu Feb 23 11:12:04 2012 +0200 @@ -8,6 +8,7 @@ bool lmtp_proxy; bool lmtp_save_to_detail_mailbox; const char *login_greeting; + const char *login_trusted_networks; }; extern const struct setting_parser_info lmtp_setting_parser_info;