summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/doc-docbook/spec.xfpt17
-rw-r--r--doc/doc-txt/ChangeLog3
-rw-r--r--src/src/deliver.c105
-rw-r--r--src/src/expand.c10
-rw-r--r--src/src/globals.c12
-rw-r--r--src/src/globals.h10
-rw-r--r--src/src/receive.c2
-rw-r--r--src/src/smtp_in.c12
-rw-r--r--src/src/transports/smtp_socks.c14
-rw-r--r--test/confs/40204
-rw-r--r--test/log/40204
-rw-r--r--test/scripts/4020-socks/40204
-rw-r--r--test/stdout/40204
13 files changed, 117 insertions, 84 deletions
diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index 6096e1df2..418cb1a11 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -12038,7 +12038,8 @@ qualified host name. See also &$smtp_active_hostname$&.
&$proxy_target_address$& &&&
&$proxy_target_port$& &&&
&$proxy_session$&
-These variables are only available when built with Proxy Protocol support
+These variables are only available when built with Proxy Protocol
+or Socks5 support
For details see chapter &<<SECTproxyInbound>>&.
.wen
@@ -35481,7 +35482,7 @@ selection marked by asterisks:
&` queue_time_overall `& time on queue for whole message
&` pid `& Exim process id
.new
-&` proxy `& proxy address on <= lines
+&` proxy `& proxy address on <= and => lines
.wen
&` received_recipients `& recipients on <= lines
&` received_sender `& sender on <= lines
@@ -35615,7 +35616,8 @@ The latter can be disabled by turning off the &%outgoing_interface%& option.
.cindex "TCP/IP" "logging proxy address"
&%proxy%&: The internal (closest to the system running Exim) IP address
of the proxy, tagged by PRX=, on the &"<="& line for a message accepted
-on a proxied connection.
+on a proxied connection
+or the &"=>"& line for a message delivered on a proxied connection..
See &<<SECTproxyInbound>>& for more information.
.wen
.next
@@ -38087,10 +38089,6 @@ Use of a proxy is enabled by setting the &%hosts_proxy%&
main configuration option to a hostlist; connections from these
hosts will use Proxy Protocol.
-To log the IP of the proxy in the incoming logline, add &"+proxy"&
-to the &%log_selector%& option.
-This will add a component tagged with &"PRX="& to the line.
-
The following expansion variables are usable
(&"internal"& and &"external"& here refer to the interfaces
of the proxy):
@@ -38190,6 +38188,11 @@ The default value for selection bias is 1.
Proxies from the list are tried according to their priority
and weight settings until one responds. The timeout for the
overall connection applies to the set of proxied attempts.
+
+.section Logging SECTproxyLog
+To log the (local) IP of a proxy in the incoming or delivery logline,
+add &"+proxy"& to the &%log_selector%& option.
+This will add a component tagged with &"PRX="& to the line.
.wen
. ////////////////////////////////////////////////////////////////////////////
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 1fa19daad..c167f8392 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -117,7 +117,8 @@ JH/23 Move SOCKS5 support from Experimental to mainline, enabled for a build
JH/26 Move PROXY support from Experimental to mainline, enabled for a build
by defining SUPPORT_PROXY. Note that the proxy_required_hosts option
- is renamed to hosts_proxy.
+ is renamed to hosts_proxy, and the proxy_{host,target}_{address,port}.
+ variables are renamed to proxy_{local,external}_{address,port}.
Exim version 4.86
diff --git a/src/src/deliver.c b/src/src/deliver.c
index 65f148c07..53712b269 100644
--- a/src/src/deliver.c
+++ b/src/src/deliver.c
@@ -718,11 +718,24 @@ s = string_append(s, sizep, ptrp, 5, US" H=", addr->host_used->name,
if (LOGGING(outgoing_port))
s = string_append(s, sizep, ptrp, 2, US":", string_sprintf("%d",
addr->host_used->port));
+
+#ifdef SUPPORT_SOCKS
+if (LOGGING(proxy) && proxy_local_address)
+ {
+ s = string_append(s, sizep, ptrp, 3, US" PRX=[", proxy_local_address, US"]");
+ if (LOGGING(outgoing_port))
+ s = string_append(s, sizep, ptrp, 2, US":", string_sprintf("%d",
+ proxy_local_port));
+ }
+#endif
+
return d_log_interface(s, sizep, ptrp);
}
+
+
#ifdef SUPPORT_TLS
static uschar *
d_tlslog(uschar * s, int * sizep, int * ptrp, address_item * addr)
@@ -3297,6 +3310,21 @@ while (!done)
switch (subid)
{
+#ifdef SUPPORT_SOCKS
+ case '2': /* proxy information; must arrive before A0 and applies to that addr XXX oops*/
+ proxy_session = TRUE; /*XXX shouod this be cleared somewhere? */
+ if (*ptr == 0)
+ ptr++;
+ else
+ {
+ proxy_local_address = string_copy(ptr);
+ while(*ptr++);
+ memcpy(&proxy_local_port, ptr, sizeof(proxy_local_port));
+ ptr += sizeof(proxy_local_port);
+ }
+ break;
+#endif
+
#ifdef EXPERIMENTAL_DSN_INFO
case '1': /* must arrive before A0, and applies to that addr */
/* Two strings: smtp_greeting and helo_response */
@@ -4441,15 +4469,13 @@ for (delivery_count = 0; addr_remote; delivery_count++)
#ifdef SUPPORT_TLS
if (addr->cipher)
{
- ptr = big_buffer;
- sprintf(CS ptr, "%.128s", addr->cipher);
- while(*ptr++);
+ ptr = big_buffer + sprintf(CS big_buffer, "%.128s", addr->cipher) + 1;
if (!addr->peerdn)
*ptr++ = 0;
else
{
- sprintf(CS ptr, "%.512s", addr->peerdn);
- while(*ptr++);
+ ptr += sprintf(CS ptr, "%.512s", addr->peerdn);
+ ptr++;
}
rmt_dlv_checked_write(fd, 'X', '1', big_buffer, ptr - big_buffer);
@@ -4475,9 +4501,7 @@ for (delivery_count = 0; addr_remote; delivery_count++)
# ifndef DISABLE_OCSP
if (addr->ocsp > OCSP_NOT_REQ)
{
- ptr = big_buffer;
- sprintf(CS ptr, "%c", addr->ocsp + '0');
- while(*ptr++);
+ ptr = big_buffer + sprintf(CS big_buffer, "%c", addr->ocsp + '0') + 1;
rmt_dlv_checked_write(fd, 'X', '4', big_buffer, ptr - big_buffer);
}
# endif
@@ -4485,23 +4509,17 @@ for (delivery_count = 0; addr_remote; delivery_count++)
if (client_authenticator)
{
- ptr = big_buffer;
- sprintf(CS big_buffer, "%.64s", client_authenticator);
- while(*ptr++);
+ ptr = big_buffer + sprintf(CS big_buffer, "%.64s", client_authenticator) + 1;
rmt_dlv_checked_write(fd, 'C', '1', big_buffer, ptr - big_buffer);
}
if (client_authenticated_id)
{
- ptr = big_buffer;
- sprintf(CS big_buffer, "%.64s", client_authenticated_id);
- while(*ptr++);
+ ptr = big_buffer + sprintf(CS big_buffer, "%.64s", client_authenticated_id) + 1;
rmt_dlv_checked_write(fd, 'C', '2', big_buffer, ptr - big_buffer);
}
if (client_authenticated_sender)
{
- ptr = big_buffer;
- sprintf(CS big_buffer, "%.64s", client_authenticated_sender);
- while(*ptr++);
+ ptr = big_buffer + sprintf(CS big_buffer, "%.64s", client_authenticated_sender) + 1;
rmt_dlv_checked_write(fd, 'C', '3', big_buffer, ptr - big_buffer);
}
@@ -4532,19 +4550,34 @@ for (delivery_count = 0; addr_remote; delivery_count++)
rmt_dlv_checked_write(fd, 'R', '0', big_buffer, ptr - big_buffer);
}
+#ifdef SUPPORT_SOCKS
+ if (LOGGING(proxy) && proxy_session)
+ {
+ ptr = big_buffer;
+ if (proxy_local_address)
+ {
+ DEBUG(D_deliver) debug_printf("proxy_local_address '%s'\n", proxy_local_address);
+ ptr = big_buffer + sprintf(CS ptr, "%.128s", proxy_local_address) + 1;
+ DEBUG(D_deliver) debug_printf("proxy_local_port %d\n", proxy_local_port);
+ memcpy(ptr, &proxy_local_port, sizeof(proxy_local_port));
+ ptr += sizeof(proxy_local_port);
+ }
+ else
+ *ptr++ = '\0';
+ rmt_dlv_checked_write(fd, 'A', '2', big_buffer, ptr - big_buffer);
+ }
+#endif
+
#ifdef EXPERIMENTAL_DSN_INFO
/*um, are they really per-addr? Other per-conn stuff is not (auth, tls). But host_used is! */
if (addr->smtp_greeting)
{
- ptr = big_buffer;
DEBUG(D_deliver) debug_printf("smtp_greeting '%s'\n", addr->smtp_greeting);
- sprintf(CS ptr, "%.128s", addr->smtp_greeting);
- while(*ptr++);
+ ptr = big_buffer + sprintf(CS big_buffer, "%.128s", addr->smtp_greeting) + 1;
if (addr->helo_response)
{
DEBUG(D_deliver) debug_printf("helo_response '%s'\n", addr->helo_response);
- sprintf(CS ptr, "%.128s", addr->helo_response);
- while(*ptr++);
+ ptr += sprintf(CS ptr, "%.128s", addr->helo_response) + 1;
}
else
*ptr++ = '\0';
@@ -4554,8 +4587,7 @@ for (delivery_count = 0; addr_remote; delivery_count++)
/* The rest of the information goes in an 'A0' item. */
- sprintf(CS big_buffer, "%c%c", addr->transport_return,
- addr->special_action);
+ sprintf(CS big_buffer, "%c%c", addr->transport_return, addr->special_action);
ptr = big_buffer + 2;
memcpy(ptr, &(addr->basic_errno), sizeof(addr->basic_errno));
ptr += sizeof(addr->basic_errno);
@@ -4565,23 +4597,15 @@ for (delivery_count = 0; addr_remote; delivery_count++)
ptr += sizeof(addr->flags);
if (!addr->message) *ptr++ = 0; else
- {
- sprintf(CS ptr, "%.1024s", addr->message);
- while(*ptr++);
- }
+ ptr += sprintf(CS ptr, "%.1024s", addr->message) + 1;
if (!addr->user_message) *ptr++ = 0; else
- {
- sprintf(CS ptr, "%.1024s", addr->user_message);
- while(*ptr++);
- }
+ ptr += sprintf(CS ptr, "%.1024s", addr->user_message) + 1;
if (!addr->host_used) *ptr++ = 0; else
{
- sprintf(CS ptr, "%.256s", addr->host_used->name);
- while(*ptr++);
- sprintf(CS ptr, "%.64s", addr->host_used->address);
- while(*ptr++);
+ ptr += sprintf(CS ptr, "%.256s", addr->host_used->name) + 1;
+ ptr += sprintf(CS ptr, "%.64s", addr->host_used->address) + 1;
memcpy(ptr, &(addr->host_used->port), sizeof(addr->host_used->port));
ptr += sizeof(addr->host_used->port);
@@ -4600,12 +4624,9 @@ for (delivery_count = 0; addr_remote; delivery_count++)
if (LOGGING(incoming_interface) && sending_ip_address)
#endif
{
- uschar * ptr = big_buffer;
- sprintf(CS ptr, "%.128s", sending_ip_address);
- while(*ptr++);
- sprintf(CS ptr, "%d", sending_port);
- while(*ptr++);
-
+ uschar * ptr;
+ ptr = big_buffer + sprintf(CS big_buffer, "%.128s", sending_ip_address) + 1;
+ ptr += sprintf(CS ptr, "%d", sending_port) + 1;
rmt_dlv_checked_write(fd, 'I', '0', big_buffer, ptr - big_buffer);
}
diff --git a/src/src/expand.c b/src/src/expand.c
index f3baee9af..a5f14364c 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -615,12 +615,12 @@ static var_entry var_table[] = {
{ "prdr_requested", vtype_bool, &prdr_requested },
#endif
{ "primary_hostname", vtype_stringptr, &primary_hostname },
-#ifdef SUPPORT_PROXY
- { "proxy_host_address", vtype_stringptr, &proxy_host_address },
- { "proxy_host_port", vtype_int, &proxy_host_port },
+#if defined(SUPPORT_PROXY) || defined(SUPPORT_SOCKS)
+ { "proxy_external_address",vtype_stringptr, &proxy_external_address },
+ { "proxy_external_port", vtype_int, &proxy_external_port },
+ { "proxy_local_address", vtype_stringptr, &proxy_local_address },
+ { "proxy_local_port", vtype_int, &proxy_local_port },
{ "proxy_session", vtype_bool, &proxy_session },
- { "proxy_target_address",vtype_stringptr, &proxy_target_address },
- { "proxy_target_port", vtype_int, &proxy_target_port },
#endif
{ "prvscheck_address", vtype_stringptr, &prvscheck_address },
{ "prvscheck_keynum", vtype_stringptr, &prvscheck_keynum },
diff --git a/src/src/globals.c b/src/src/globals.c
index fbfb9b8a2..6bd33a1a5 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -875,7 +875,7 @@ bit_table log_options[] = { /* must be in alphabetical order */
BIT_TABLE(L, outgoing_interface),
BIT_TABLE(L, outgoing_port),
BIT_TABLE(L, pid),
-#ifdef SUPPORT_PROXY
+#if defined(SUPPORT_PROXY) || defined (SUPPORT_SOCKS)
BIT_TABLE(L, proxy),
#endif
BIT_TABLE(L, queue_run),
@@ -1001,14 +1001,14 @@ int process_info_len = 0;
uschar *process_log_path = NULL;
BOOL prod_requires_admin = TRUE;
-#ifdef SUPPORT_PROXY
+#if defined(SUPPORT_PROXY) || defined(SUPPORT_SOCKS)
uschar *hosts_proxy = US"";
-uschar *proxy_host_address = US"";
-int proxy_host_port = 0;
+uschar *proxy_external_address = US"";
+int proxy_external_port = 0;
+uschar *proxy_local_address = US"";
+int proxy_local_port = 0;
BOOL proxy_session = FALSE;
BOOL proxy_session_failed = FALSE;
-uschar *proxy_target_address = US"";
-int proxy_target_port = 0;
#endif
uschar *prvscheck_address = NULL;
diff --git a/src/src/globals.h b/src/src/globals.h
index 4263e104d..899471116 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -645,14 +645,14 @@ extern int process_info_len;
extern uschar *process_log_path; /* Alternate path */
extern BOOL prod_requires_admin; /* TRUE if prodding requires admin */
-#ifdef SUPPORT_PROXY
+#if defined(SUPPORT_PROXY) || defined(SUPPORT_SOCKS)
extern uschar *hosts_proxy; /* Hostlist which (require) use proxy protocol */
-extern uschar *proxy_host_address; /* IP of host being proxied */
-extern int proxy_host_port; /* Port of host being proxied */
+extern uschar *proxy_external_address; /* IP of remote interface of proxy */
+extern int proxy_external_port; /* Port on remote interface of proxy */
+extern uschar *proxy_local_address; /* IP of local interface of proxy */
+extern int proxy_local_port; /* Port on local interface of proxy */
extern BOOL proxy_session; /* TRUE if receiving mail from valid proxy */
extern BOOL proxy_session_failed; /* TRUE if required proxy negotiation failed */
-extern uschar *proxy_target_address; /* IP of proxy server inbound */
-extern int proxy_target_port; /* Port of proxy server inbound */
#endif
extern uschar *prvscheck_address; /* Set during prvscheck expansion item */
diff --git a/src/src/receive.c b/src/src/receive.c
index 01f461650..dc228d921 100644
--- a/src/src/receive.c
+++ b/src/src/receive.c
@@ -3777,7 +3777,7 @@ if (prdr_requested)
#ifdef SUPPORT_PROXY
if (proxy_session && LOGGING(proxy))
- s = string_append(s, &size, &sptr, 2, US" PRX=", proxy_host_address);
+ s = string_append(s, &size, &sptr, 2, US" PRX=", proxy_local_address);
#endif
sprintf(CS big_buffer, "%d", msg_size);
diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c
index d99f02e69..a5ed2f9b7 100644
--- a/src/src/smtp_in.c
+++ b/src/src/smtp_in.c
@@ -761,10 +761,10 @@ if (ret >= 16 &&
DEBUG(D_receive) debug_printf("Invalid %s source IP\n", iptype);
return ERRNO_PROXYFAIL;
}
- proxy_host_address = sender_host_address;
+ proxy_local_address = sender_host_address;
sender_host_address = string_copy(US tmpip);
tmpport = ntohs(hdr.v2.addr.ip4.src_port);
- proxy_host_port = sender_host_port;
+ proxy_local_port = sender_host_port;
sender_host_port = tmpport;
/* Save dest ip/port */
tmpaddr.sin_addr.s_addr = hdr.v2.addr.ip4.dst_addr;
@@ -787,10 +787,10 @@ if (ret >= 16 &&
DEBUG(D_receive) debug_printf("Invalid %s source IP\n", iptype);
return ERRNO_PROXYFAIL;
}
- proxy_host_address = sender_host_address;
+ proxy_local_address = sender_host_address;
sender_host_address = string_copy(US tmpip6);
tmpport = ntohs(hdr.v2.addr.ip6.src_port);
- proxy_host_port = sender_host_port;
+ proxy_local_port = sender_host_port;
sender_host_port = tmpport;
/* Save dest ip/port */
memmove(tmpaddr6.sin6_addr.s6_addr, hdr.v2.addr.ip6.dst_addr, 16);
@@ -881,7 +881,7 @@ else if (ret >= 8 &&
debug_printf("Proxied src arg is not an %s address\n", iptype);
goto proxyfail;
}
- proxy_host_address = sender_host_address;
+ proxy_local_address = sender_host_address;
sender_host_address = p;
p = sp + 1;
if ((sp = Ustrchr(p, ' ')) == NULL)
@@ -912,7 +912,7 @@ else if (ret >= 8 &&
debug_printf("Proxied src port '%s' not an integer\n", p);
goto proxyfail;
}
- proxy_host_port = sender_host_port;
+ proxy_local_port = sender_host_port;
sender_host_port = tmp_port;
p = sp + 1;
if ((sp = Ustrchr(p, '\0')) == NULL)
diff --git a/src/src/transports/smtp_socks.c b/src/src/transports/smtp_socks.c
index 30eded545..33b25d1da 100644
--- a/src/src/transports/smtp_socks.c
+++ b/src/src/transports/smtp_socks.c
@@ -290,7 +290,11 @@ for(;;)
if ((fd = smtp_sock_connect(&proxy, proxy_af, sob->port,
interface, tb, sob->timeout)) >= 0)
+ {
+ proxy_local_address = string_copy(proxy.address);
+ proxy_local_port = sob->port;
break;
+ }
log_write(0, LOG_MAIN, "%s: %s", __FUNCTION__, strerror(errno));
sob->is_failed = TRUE;
@@ -373,11 +377,13 @@ if ( buf[0] != 5
)
goto proxy_err;
-/*XXX log proxy outbound addr/port? */
+proxy_external_address = string_copy(
+ host_ntoa(buf[3] == 4 ? AF_INET6 : AF_INET, buf+4, NULL, NULL));
+proxy_external_port = ntohs(*((uint16_t *)(buf + (buf[3] == 4 ? 20 : 8))));
+proxy_session = TRUE;
+
HDEBUG(D_transport|D_acl|D_v)
- debug_printf(" proxy farside local: [%s]:%d\n",
- host_ntoa(buf[3] == 4 ? AF_INET6 : AF_INET, buf+4, NULL, NULL),
- ntohs(*((uint16_t *)(buf + (buf[3] == 4 ? 20 : 8)))));
+ debug_printf(" proxy farside: [%s]:%d\n", proxy_external_address, proxy_external_port);
return fd;
diff --git a/test/confs/4020 b/test/confs/4020
index 8e2f6b052..794272e6d 100644
--- a/test/confs/4020
+++ b/test/confs/4020
@@ -13,6 +13,8 @@ tls_advertise_hosts =
# ----- Main settings -----
+log_selector = +proxy +outgoing_port
+
domainlist local_domains = test.ex : *.test.ex
acl_smtp_rcpt = accept
@@ -38,7 +40,7 @@ my_smtp:
driver = smtp
interface = HOSTIPV4
port = PORT_S
- socks_proxy = 127.0.0.1 port=PORT_S OPT
+ socks_proxy = 127.0.0.1 port=PORT_D OPT
debug_print = transport_name <$transport_name>
diff --git a/test/log/4020 b/test/log/4020
index f289beffd..b5e1f7bef 100644
--- a/test/log/4020
+++ b/test/log/4020
@@ -1,6 +1,6 @@
1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss
-1999-03-02 09:44:33 10HmaX-0005vi-00 => userx@test.ex R=my_main_router T=my_smtp H=127.0.0.1 [127.0.0.1] C="250 accepted OK"
+1999-03-02 09:44:33 10HmaX-0005vi-00 => userx@test.ex R=my_main_router T=my_smtp H=127.0.0.1 [127.0.0.1]:1224 PRX=[127.0.0.1]:1225 C="250 accepted OK"
1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss
-1999-03-02 09:44:33 10HmaY-0005vi-00 => userx@test.ex R=my_main_router T=my_smtp H=127.0.0.1 [127.0.0.1] C="250 accepted OK"
+1999-03-02 09:44:33 10HmaY-0005vi-00 => userx@test.ex R=my_main_router T=my_smtp H=127.0.0.1 [127.0.0.1]:1224 PRX=[127.0.0.1]:1225 C="250 accepted OK"
1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
diff --git a/test/scripts/4020-socks/4020 b/test/scripts/4020-socks/4020
index 49d97c05f..44c885b8d 100644
--- a/test/scripts/4020-socks/4020
+++ b/test/scripts/4020-socks/4020
@@ -3,7 +3,7 @@
munge loopback
#
# auth: null
-server PORT_S
+server PORT_D
<<\x05\x01\x00
>>\x05\x00
<<\x05\x01\x00\x01\x7f\x00\x00\x01\x04\xc8
@@ -42,7 +42,7 @@ quit
#
#
# auth: username/password
-server PORT_S
+server PORT_D
<<\x05\x01\x02
>>\x05\x02
<<\x01\x04fred\x05fubar
diff --git a/test/stdout/4020 b/test/stdout/4020
index 720c954fd..293f5136e 100644
--- a/test/stdout/4020
+++ b/test/stdout/4020
@@ -22,7 +22,7 @@
221 myhost.test.ex closing connection
******** SERVER ********
-Listening on port 1224 ...
+Listening on port 1225 ...
Connection request from [ip4.ip4.ip4.ip4]
<<\x05\x01\x00
>>\x05\x00
@@ -43,7 +43,7 @@ R
QUIT
250 bye
End of script
-Listening on port 1224 ...
+Listening on port 1225 ...
Connection request from [ip4.ip4.ip4.ip4]
<<\x05\x01\x02
>>\x05\x02