summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/src/macros.h1
-rw-r--r--src/src/smtp_in.c52
l---------test/confs/40311
-rw-r--r--test/scripts/4030-proxy-protocol/403140
-rw-r--r--test/stderr/4031102
-rw-r--r--test/stdout/403153
6 files changed, 210 insertions, 39 deletions
diff --git a/src/src/macros.h b/src/src/macros.h
index 82e50b5fe..c3f1c5d43 100644
--- a/src/src/macros.h
+++ b/src/src/macros.h
@@ -201,7 +201,6 @@ host isn't speaking the protocol, and so is disallowed. Can be moved to
runtime configuration if per site settings become needed. */
#ifdef SUPPORT_PROXY
#define PROXY_NEGOTIATION_TIMEOUT_SEC 3
-#define PROXY_NEGOTIATION_TIMEOUT_USEC 0
#endif
/* Fixed option values for all PCRE functions */
diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c
index c0b6b2ac1..69eae3cb4 100644
--- a/src/src/smtp_in.c
+++ b/src/src/smtp_in.c
@@ -1034,25 +1034,6 @@ had_command_sigterm = sig;
#ifdef SUPPORT_PROXY
/*************************************************
-* Restore socket timeout to previous value *
-*************************************************/
-/* If the previous value was successfully retrieved, restore
-it before returning control to the non-proxy routines
-
-Arguments: fd - File descriptor for input
- get_ok - Successfully retrieved previous values
- tvtmp - Time struct with previous values
- vslen - Length of time struct
-Returns: none
-*/
-static void
-restore_socket_timeout(int fd, int get_ok, struct timeval * tvtmp, socklen_t vslen)
-{
-if (get_ok == 0)
- (void) setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, CS tvtmp, vslen);
-}
-
-/*************************************************
* Check if host is required proxy host *
*************************************************/
/* The function determines if inbound host will be a regular smtp host
@@ -1128,7 +1109,7 @@ if (cr != NULL)
while (capacity > 0)
{
- do { ret = recv(fd, to, 1, 0); } while (ret == -1 && errno == EINTR);
+ do { ret = read(fd, to, 1); } while (ret == -1 && errno == EINTR && !had_command_timeout);
if (ret == -1)
return -1;
have++;
@@ -1237,15 +1218,8 @@ struct timeval tvtmp;
socklen_t vslen = sizeof(struct timeval);
BOOL yield = FALSE;
-/* Save current socket timeout values */
-get_ok = getsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, CS &tvtmp, &vslen);
-
-/* Proxy Protocol host must send header within a short time
-(default 3 seconds) or it's considered invalid */
-tv.tv_sec = PROXY_NEGOTIATION_TIMEOUT_SEC;
-tv.tv_usec = PROXY_NEGOTIATION_TIMEOUT_USEC;
-if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, CS &tv, sizeof(tv)) < 0)
- goto bad;
+os_non_restarting_signal(SIGALRM, command_timeout_handler);
+ALARM(PROXY_NEGOTIATION_TIMEOUT_SEC);
do
{
@@ -1253,9 +1227,9 @@ do
don't do a PEEK into the data, actually slurp up enough to be
"safe". Can't take it all because TLS-on-connect clients follow
immediately with TLS handshake. */
- ret = recv(fd, &hdr, PROXY_INITIAL_READ, 0);
+ ret = read(fd, &hdr, PROXY_INITIAL_READ);
}
- while (ret == -1 && errno == EINTR);
+ while (ret == -1 && errno == EINTR && !had_command_timeout);
if (ret == -1)
goto proxyfail;
@@ -1269,8 +1243,8 @@ if ((ret == PROXY_INITIAL_READ) && (memcmp(&hdr.v2, v2sig, sizeof(v2sig)) == 0))
/* First get the length fields. */
do
{
- retmore = recv(fd, (uschar*)&hdr + ret, PROXY_V2_HEADER_SIZE - PROXY_INITIAL_READ, 0);
- } while (retmore == -1 && errno == EINTR);
+ retmore = read(fd, (uschar*)&hdr + ret, PROXY_V2_HEADER_SIZE - PROXY_INITIAL_READ);
+ } while (retmore == -1 && errno == EINTR && !had_command_timeout);
if (retmore == -1)
goto proxyfail;
ret += retmore;
@@ -1306,8 +1280,8 @@ if ((ret == PROXY_INITIAL_READ) && (memcmp(&hdr.v2, v2sig, sizeof(v2sig)) == 0))
{
do
{
- retmore = recv(fd, (uschar*)&hdr + ret, size-ret, 0);
- } while (retmore == -1 && errno == EINTR);
+ retmore = read(fd, (uschar*)&hdr + ret, size-ret);
+ } while (retmore == -1 && errno == EINTR && !had_command_timeout);
if (retmore == -1)
goto proxyfail;
ret += retmore;
@@ -1535,7 +1509,8 @@ done:
should cause a synchronization failure */
proxyfail:
- restore_socket_timeout(fd, get_ok, &tvtmp, vslen);
+ DEBUG(D_receive) if (had_command_timeout)
+ debug_printf("Timeout while reading proxy header\n");
bad:
if (yield)
@@ -1551,6 +1526,7 @@ bad:
debug_printf("Failure to extract proxied host, only QUIT allowed\n");
}
+ALARM(0);
return;
}
#endif
@@ -2412,7 +2388,7 @@ TCP_SYN_RCV (as of 12.1) so no idea about data-use. */
if (getsockopt(fileno(smtp_out), IPPROTO_TCP, TCP_FASTOPEN, &is_fastopen, &len) == 0)
{
- if (is_fastopen)
+ if (is_fastopen)
{
DEBUG(D_receive)
debug_printf("TFO mode connection (TCP_FASTOPEN getsockopt)\n");
@@ -5769,7 +5745,7 @@ while (done <= 0)
/* If not serializing, do the exec right away. Otherwise, fork down
into another process. */
- if ( !smtp_etrn_serialize
+ if ( !smtp_etrn_serialize
|| (pid = exim_fork(US"etrn-serialised-command")) == 0)
{
DEBUG(D_exec) debug_print_argv(argv);
diff --git a/test/confs/4031 b/test/confs/4031
new file mode 120000
index 000000000..b6e26c8b8
--- /dev/null
+++ b/test/confs/4031
@@ -0,0 +1 @@
+4030 \ No newline at end of file
diff --git a/test/scripts/4030-proxy-protocol/4031 b/test/scripts/4030-proxy-protocol/4031
new file mode 100644
index 000000000..ecf3e827b
--- /dev/null
+++ b/test/scripts/4030-proxy-protocol/4031
@@ -0,0 +1,40 @@
+# proxy-protocol proxy on inbound -bh
+#
+### non-prox plain receive
+exim -bh 127.0.0.2
+HELO clientname
+MAIL FROM: <a@test.ex>
+RCPT TO:<b@test.ex>
+DATA
+Subject: test non-prox
+
+body non-prox
+.
+QUIT
+****
+### protocol v1 receive
+exim -bh HOSTIPV4
+>>> PROXY TCP4 127.0.0.2 127.42.42.42 64000 25\r\n
+HELO clientname
+MAIL FROM: <a@test.ex>
+RCPT TO:<b@test.ex>
+DATA
+Subject: test v1
+
+body v1
+.
+QUIT
+****
+### protocol v2 receive
+exim -bh HOSTIPV4
+>>> \x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A\x21\x11\x00\x0c\x7f\x00\x00\x02\x7f\x2a\x2a\x2a\xc2\x95\x04\x01
+HELO clientname
+MAIL FROM: <a@test.ex>
+RCPT TO:<b@test.ex>
+DATA
+Subject: test v2
+
+body v2
+.
+QUIT
+****
diff --git a/test/stderr/4031 b/test/stderr/4031
new file mode 100644
index 000000000..c5336cb25
--- /dev/null
+++ b/test/stderr/4031
@@ -0,0 +1,102 @@
+### non-prox plain receive
+>>> host in hosts_connection_nolog? no (option unset)
+>>> host in host_lookup? no (option unset)
+>>> host in host_reject_connection? no (option unset)
+>>> host in sender_unqualified_hosts? no (option unset)
+>>> host in recipient_unqualified_hosts? no (option unset)
+>>> host in helo_verify_hosts? no (option unset)
+>>> host in helo_try_verify_hosts? no (option unset)
+>>> host in helo_accept_junk_hosts? no (option unset)
+>>> clientname in helo_lookup_domains? no (end of list)
+>>> using ACL "r_acl"
+>>> processing "accept" (TESTSUITE/test-config 20)
+>>> check logwrite = proxy session: $proxy_session
+>>> = proxy session: no
+LOG: proxy session: no
+>>> check logwrite = local [$received_ip_address]:$received_port
+>>> = local []:-1
+LOG: local []:-1
+>>> check logwrite = proxy internal [$proxy_local_address]:$proxy_local_port
+>>> = proxy internal []:0
+LOG: proxy internal []:0
+>>> check logwrite = proxy external [$proxy_external_address]:$proxy_external_port
+>>> = proxy external []:0
+LOG: proxy external []:0
+>>> check logwrite = remote [$sender_host_address]:$sender_host_port
+>>> = remote [127.0.0.2]:1111
+LOG: remote [127.0.0.2]:1111
+>>> accept: condition test succeeded in ACL "r_acl"
+>>> end of ACL "r_acl": ACCEPT
+>>> host in ignore_fromline_hosts? no (option unset)
+LOG: 10HmaX-0005vi-00 <= a@test.ex H=(clientname) [127.0.0.2] P=smtp S=sss
+### protocol v1 receive
+>>> host in hosts_connection_nolog? no (option unset)
+>>> host in host_lookup? no (option unset)
+>>> host in host_reject_connection? no (option unset)
+>>> host in sender_unqualified_hosts? no (option unset)
+>>> host in recipient_unqualified_hosts? no (option unset)
+>>> host in helo_verify_hosts? no (option unset)
+>>> host in helo_try_verify_hosts? no (option unset)
+>>> host in helo_accept_junk_hosts? no (option unset)
+>>> looking up host name for 127.0.0.2
+LOG: no host name found for IP address 127.0.0.2
+>>> clientname in helo_lookup_domains? no (end of list)
+>>> using ACL "r_acl"
+>>> processing "accept" (TESTSUITE/test-config 20)
+>>> check logwrite = proxy session: $proxy_session
+>>> = proxy session: yes
+LOG: proxy session: yes
+>>> check logwrite = local [$received_ip_address]:$received_port
+>>> = local []:-1
+LOG: local []:-1
+>>> check logwrite = proxy internal [$proxy_local_address]:$proxy_local_port
+>>> = proxy internal [ip4.ip4.ip4.ip4]:1111
+LOG: proxy internal [ip4.ip4.ip4.ip4]:1111
+>>> check logwrite = proxy external [$proxy_external_address]:$proxy_external_port
+>>> = proxy external [127.42.42.42]:1112
+LOG: proxy external [127.42.42.42]:1112
+>>> check logwrite = remote [$sender_host_address]:$sender_host_port
+>>> = remote [127.0.0.2]:1113
+LOG: remote [127.0.0.2]:1113
+>>> accept: condition test succeeded in ACL "r_acl"
+>>> end of ACL "r_acl": ACCEPT
+>>> host in ignore_fromline_hosts? no (option unset)
+LOG: 10HmaY-0005vi-00 <= a@test.ex H=(clientname) [127.0.0.2]:1113 P=smtp PRX=ip4.ip4.ip4.ip4 S=sss
+### protocol v2 receive
+>>> host in hosts_connection_nolog? no (option unset)
+>>> host in host_lookup? no (option unset)
+>>> host in host_reject_connection? no (option unset)
+>>> host in sender_unqualified_hosts? no (option unset)
+>>> host in recipient_unqualified_hosts? no (option unset)
+>>> host in helo_verify_hosts? no (option unset)
+>>> host in helo_try_verify_hosts? no (option unset)
+>>> host in helo_accept_junk_hosts? no (option unset)
+>>> looking up host name for 127.0.0.2
+LOG: no host name found for IP address 127.0.0.2
+>>> clientname in helo_lookup_domains? no (end of list)
+>>> using ACL "r_acl"
+>>> processing "accept" (TESTSUITE/test-config 20)
+>>> check logwrite = proxy session: $proxy_session
+>>> = proxy session: yes
+LOG: proxy session: yes
+>>> check logwrite = local [$received_ip_address]:$received_port
+>>> = local []:-1
+LOG: local []:-1
+>>> check logwrite = proxy internal [$proxy_local_address]:$proxy_local_port
+>>> = proxy internal [ip4.ip4.ip4.ip4]:1111
+LOG: proxy internal [ip4.ip4.ip4.ip4]:1111
+>>> check logwrite = proxy external [$proxy_external_address]:$proxy_external_port
+>>> = proxy external [127.42.42.42]:1114
+LOG: proxy external [127.42.42.42]:1114
+>>> check logwrite = remote [$sender_host_address]:$sender_host_port
+>>> = remote [127.0.0.2]:1115
+LOG: remote [127.0.0.2]:1115
+>>> accept: condition test succeeded in ACL "r_acl"
+>>> end of ACL "r_acl": ACCEPT
+>>> host in ignore_fromline_hosts? no (option unset)
+LOG: 10HmaZ-0005vi-00 <= a@test.ex H=(clientname) [127.0.0.2]:1115 P=smtp PRX=ip4.ip4.ip4.ip4 S=sss
+
+******** SERVER ********
+### non-prox plain receive
+### protocol v1 receive
+### protocol v2 receive
diff --git a/test/stdout/4031 b/test/stdout/4031
new file mode 100644
index 000000000..a0cddc62d
--- /dev/null
+++ b/test/stdout/4031
@@ -0,0 +1,53 @@
+### non-prox plain receive
+
+**** SMTP testing session as if from host 127.0.0.2
+**** but without any ident (RFC 1413) callback.
+**** This is not for real!
+
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+250 myhost.test.ex Hello clientname [127.0.0.2]
+250 OK
+250 Accepted
+354 Enter message, ending with "." on a line by itself
+250 OK id=10HmaX-0005vi-00
+
+**** SMTP testing: that is not a real message id!
+
+221 myhost.test.ex closing connection
+### protocol v1 receive
+
+**** SMTP testing session as if from host ip4.ip4.ip4.ip4
+**** but without any ident (RFC 1413) callback.
+**** This is not for real!
+
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+250 myhost.test.ex Hello clientname [127.0.0.2]
+250 OK
+250 Accepted
+354 Enter message, ending with "." on a line by itself
+250 OK id=10HmaY-0005vi-00
+
+**** SMTP testing: that is not a real message id!
+
+221 myhost.test.ex closing connection
+### protocol v2 receive
+
+**** SMTP testing session as if from host ip4.ip4.ip4.ip4
+**** but without any ident (RFC 1413) callback.
+**** This is not for real!
+
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+250 myhost.test.ex Hello clientname [127.0.0.2]
+250 OK
+250 Accepted
+354 Enter message, ending with "." on a line by itself
+250 OK id=10HmaZ-0005vi-00
+
+**** SMTP testing: that is not a real message id!
+
+221 myhost.test.ex closing connection
+
+******** SERVER ********
+### non-prox plain receive
+### protocol v1 receive
+### protocol v2 receive