"ADDR", addr);
}
+ /* DESTPORT */
+ if (xclient->dest_port != 0 &&
+ str_array_icase_find(xclient_args, "DESTPORT")) {
+ smtp_client_connection_xclient_addf(conn, str, offset,
+ "DESTPORT", "%u",
+ xclient->dest_port);
+ }
+
+ /* DESTADDR */
+ if (xclient->dest_ip.family != 0 &&
+ str_array_icase_find(xclient_args, "DESTADDR")) {
+ const char *addr = net_ip2addr(&xclient->dest_ip);
+
+ /* Older versions of Dovecot LMTP don't quite follow Postfix'
+ specification of the XCLIENT command regarding IPv6
+ addresses: the "IPV6:" prefix is omitted. For now, we
+ maintain this deviation for LMTP. Newer versions of Dovecot
+ LMTP can work with or without the prefix. */
+ if (conn->protocol != SMTP_PROTOCOL_LMTP &&
+ xclient->dest_ip.family == AF_INET6)
+ addr = t_strconcat("IPV6:", addr, NULL);
+ smtp_client_connection_xclient_add(conn, str, offset,
+ "DESTADDR", addr);
+ }
+
/* final XCLIENT command */
if (str_len(str) > offset)
smtp_client_connection_xclient_submit(conn, str_c(str));
if (src->source_port != 0)
dst->source_port = src->source_port;
}
+ if (src->dest_ip.family != 0) {
+ dst->dest_ip = src->dest_ip;
+ if (src->dest_port != 0)
+ dst->dest_port = src->dest_port;
+ }
if (src->helo != NULL && *src->helo != '\0')
dst->helo = p_strdup(pool, src->helo);
if (src->login != NULL && *src->login != '\0')
struct ip_addr source_ip;
/* PORT */
in_port_t source_port;
+ /* DESTADDR */
+ struct ip_addr dest_ip;
+ /* DESTPORT */
+ in_port_t dest_port;
/* HELO, LOGIN */
const char *helo, *login;
/* SESSION */
"Invalid ADDR parameter");
return;
}
+ } else if (strcmp(param.keyword, "DESTADDR") == 0) {
+ bool ipv6 = FALSE;
+ if (strcasecmp(param.value, "[UNAVAILABLE]") == 0)
+ continue;
+ if (str_begins_icase(param.value, "IPV6:", ¶m.value))
+ ipv6 = TRUE;
+ if (net_addr2ip(param.value, &proxy_data->dest_ip) < 0 ||
+ (ipv6 && proxy_data->dest_ip.family != AF_INET6)) {
+ smtp_server_reply(cmd, 501, "5.5.4",
+ "Invalid DESTADDR parameter");
+ return;
+ }
} else if (strcmp(param.keyword, "HELO") == 0) {
if (strcasecmp(param.value, "[UNAVAILABLE]") == 0)
continue;
"Invalid PORT parameter");
return;
}
+ } else if (strcmp(param.keyword, "DESTPORT") == 0) {
+ if (strcasecmp(param.value, "[UNAVAILABLE]") == 0)
+ continue;
+ if (net_str2port(param.value, &proxy_data->dest_port) < 0) {
+ smtp_server_reply(cmd, 501, "5.5.4",
+ "Invalid DESTPORT parameter");
+ return;
+ }
} else if (strcmp(param.keyword, "PROTO") == 0) {
param.value = t_str_ucase(param.value);
if (strcmp(param.value, "SMTP") == 0)
i_zero(proxy_data);
proxy_data->source_ip = conn->conn.remote_ip;
proxy_data->source_port = conn->conn.remote_port;
+ proxy_data->dest_ip = conn->conn.local_ip;
+ proxy_data->dest_port = conn->conn.local_port;
if (conn->proxy_helo != NULL)
proxy_data->helo = conn->proxy_helo;
else if (conn->helo.domain_valid)
{
static const char *base_fields =
"ADDR PORT PROTO HELO LOGIN SESSION CLIENT-TRANSPORT TTL TIMEOUT "
- "DESTNAME";
+ "DESTNAME DESTADDR DESTPORT";
struct smtp_server_cmd_ctx *cmd = &reply->command->context;
struct smtp_server_connection *conn = cmd->conn;