diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/src/deliver.c | 105 | ||||
-rw-r--r-- | src/src/expand.c | 10 | ||||
-rw-r--r-- | src/src/globals.c | 12 | ||||
-rw-r--r-- | src/src/globals.h | 10 | ||||
-rw-r--r-- | src/src/receive.c | 2 | ||||
-rw-r--r-- | src/src/smtp_in.c | 12 | ||||
-rw-r--r-- | src/src/transports/smtp_socks.c | 14 |
7 files changed, 96 insertions, 69 deletions
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; |