* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2012 */
+/* Copyright (c) University of Cambridge 1995 - 2013 */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions for handling an incoming SMTP call. */
#ifdef EXPERIMENTAL_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)
+ setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tvtmp, vslen);
+}
+
/*************************************************
* Check if host is required proxy host *
*************************************************/
const char v2sig[13] = "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A\x02";
uschar *iptype; /* To display debug info */
struct timeval tv;
+int get_ok = 0;
+socklen_t vslen = 0;
+struct timeval tvtmp;
+
+vslen = sizeof(struct timeval);
fd = fileno(smtp_in);
+/* Save current socket timeout values */
+get_ok = getsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&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;
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,
sizeof(struct timeval));
+
do
{
ret = recv(fd, &hdr, sizeof(hdr), MSG_PEEK);
while (ret == -1 && errno == EINTR);
if (ret == -1)
+ {
+ restore_socket_timeout(fd, get_ok, tvtmp, vslen);
return (errno == EAGAIN) ? 0 : ERRNO_PROXYFAIL;
+ }
if (ret >= 16 &&
memcmp(&hdr.v2, v2sig, 13) == 0)
debug_printf("Proxied src arg is not an %s address\n", iptype);
goto proxyfail;
}
- proxy_host = sender_host_address;
+ proxy_host_address = sender_host_address;
sender_host_address = p;
p = sp + 1;
if ((sp = Ustrchr(p, ' ')) == NULL)
debug_printf("Proxied src port '%s' not an integer\n", p);
goto proxyfail;
}
- proxy_port = sender_host_port;
+ proxy_host_port = sender_host_port;
sender_host_port = tmp_port;
p = sp + 1;
if ((sp = Ustrchr(p, '\0')) == NULL)
}
proxyfail:
+restore_socket_timeout(fd, get_ok, tvtmp, vslen);
/* Don't flush any potential buffer contents. Any input should cause a
synchronization failure or we just don't want to speak SMTP to them */
return FALSE;
done:
+restore_socket_timeout(fd, get_ok, tvtmp, vslen);
flush_input();
DEBUG(D_receive)
debug_printf("Valid %s sender from Proxy Protocol header\n",
}
#endif
-
-
/*************************************************
* Read one command line *
*************************************************/
+#ifdef SUPPORT_TLS
+static uschar *
+s_tlslog(uschar * s, int * sizep, int * ptrp)
+{
+ int size = sizep ? *sizep : 0;
+ int ptr = ptrp ? *ptrp : 0;
+
+ if ((log_extra_selector & LX_tls_cipher) != 0 && tls_in.cipher != NULL)
+ s = string_append(s, &size, &ptr, 2, US" X=", tls_in.cipher);
+ if ((log_extra_selector & LX_tls_certificate_verified) != 0 &&
+ tls_in.cipher != NULL)
+ s = string_append(s, &size, &ptr, 2, US" CV=",
+ tls_in.certificate_verified? "yes":"no");
+ if ((log_extra_selector & LX_tls_peerdn) != 0 && tls_in.peerdn != NULL)
+ s = string_append(s, &size, &ptr, 3, US" DN=\"",
+ string_printing(tls_in.peerdn), US"\"");
+ if ((log_extra_selector & LX_tls_sni) != 0 && tls_in.sni != NULL)
+ s = string_append(s, &size, &ptr, 3, US" SNI=\"",
+ string_printing(tls_in.sni), US"\"");
+
+ if (s)
+ {
+ s[ptr] = '\0';
+ if (sizep) *sizep = size;
+ if (ptrp) *ptrp = ptr;
+ }
+ else
+ s = US"";
+ return s;
+}
+#endif
+
/*************************************************
* Log lack of MAIL if so configured *
*************************************************/
}
#ifdef SUPPORT_TLS
-if ((log_extra_selector & LX_tls_cipher) != 0 && tls_in.cipher != NULL)
- s = string_append(s, &size, &ptr, 2, US" X=", tls_in.cipher);
-if ((log_extra_selector & LX_tls_certificate_verified) != 0 &&
- tls_in.cipher != NULL)
- s = string_append(s, &size, &ptr, 2, US" CV=",
- tls_in.certificate_verified? "yes":"no");
-if ((log_extra_selector & LX_tls_peerdn) != 0 && tls_in.peerdn != NULL)
- s = string_append(s, &size, &ptr, 3, US" DN=\"",
- string_printing(tls_in.peerdn), US"\"");
-if ((log_extra_selector & LX_tls_sni) != 0 && tls_in.sni != NULL)
- s = string_append(s, &size, &ptr, 3, US" SNI=\"",
- string_printing(tls_in.sni), US"\"");
+s = s_tlslog(s, &size, &ptr);
#endif
sep = (smtp_connection_had[SMTP_HBUFF_SIZE-1] != SCH_NONE)?
is closing if required and return 2. */
if (log_reject_target != 0)
- log_write(0, log_reject_target, "%s %s%srejected %s%s",
+ log_write(0, log_reject_target, "%s%s %s%srejected %s%s",
host_and_ident(TRUE),
+#ifdef SUPPORT_TLS
+ s_tlslog(NULL, NULL, NULL),
+#else
+ "",
+#endif
sender_info, (rc == FAIL)? US"" : US"temporarily ", what, log_msg);
if (!drop) return 0;
return done - 2; /* Convert yield values */
}
+/* vi: aw ai sw=2
+*/
/* End of smtp_in.c */