diff options
author | Genadijus Paleckis <rwx () openbsd ! lt> | 2012-01-02 14:55:43 +0100 |
---|---|---|
committer | Stef Walter <stefw@collabora.co.uk> | 2012-01-02 14:55:43 +0100 |
commit | 7f91436fead9673d99b74d0e0f797f7c45223248 (patch) | |
tree | 498e75e489c78362c9872f1e706e5b96f94ceb69 | |
parent | 4d7afff20d11a931846298a6e5be40c43a1dfbb5 (diff) |
* In particular use /dev/pf for transparent client lookups
-rw-r--r-- | common/smtppass.c | 47 | ||||
-rw-r--r-- | configure.in | 4 |
2 files changed, 51 insertions, 0 deletions
diff --git a/common/smtppass.c b/common/smtppass.c index 45ad0b7..0d0bc33 100644 --- a/common/smtppass.c +++ b/common/smtppass.c @@ -73,6 +73,14 @@ #include <sys/prctl.h> #endif +#ifdef USE_PF_NATLOOKUP +#include <sys/ioctl.h> + +#include <net/if.h> +#include <netinet/in.h> +#include <net/pfvar.h> +#endif /* USE_PF_NATLOOKUP */ + #include "compat.h" #include "sock_any.h" #include "stringx.h" @@ -801,6 +809,11 @@ static int make_connections(spctx_t* ctx, int client) const char* dstname; const char* srcname; +#ifdef USE_PF_NATLOOKUP + struct pfioc_natlook nl; + int dev; +#endif /* USE_PF_NATLOOKUP */ + ASSERT(client != -1); /* Setup the incoming connection. This also fills in peeraddr for us */ @@ -829,6 +842,40 @@ static int make_connections(spctx_t* ctx, int client) return -1; } +#ifdef USE_PF_NATLOOKUP + dev = open("/dev/pf", O_RDWR); + if (dev == -1) { + sp_message(ctx, LOG_ERR, "open(\"/dev/pf\") failed"); + return -1; + } + + memset(&nl, 0, sizeof(struct pfioc_natlook)); + + memcpy(&nl.saddr.v4.s_addr, &(peeraddr.s.in.sin_addr), sizeof(struct in_addr)); + nl.sport = peeraddr.s.in.sin_port; + + memcpy(&nl.daddr.v4.s_addr, &(addr.s.in.sin_addr), sizeof(struct in_addr)); + nl.dport = addr.s.in.sin_port; + + nl.af = AF_INET; + nl.proto = IPPROTO_TCP; + + if (ioctl(dev, DIOCNATLOOK, &nl)) { + sp_message(ctx, LOG_ERR, "DIOCNATLOOK"); + return -1; + } + + if (close(dev) != 0) { + sp_message(ctx, LOG_ERR, "close(\"/dev/pf\") failed"); + return -1; + } + + memcpy(&(addr.s.in.sin_addr), &nl.rdaddr.v4.s_addr, + sizeof(struct in_addr)); + addr.s.in.sin_port = nl.rdport; + addr.s.in.sin_family = AF_INET; +#endif /* USE_PF_NATLOOKUP */ + /* Check address types */ if(sock_any_cmp(&addr, &peeraddr, SANY_OPT_NOPORT) == 0) { diff --git a/configure.in b/configure.in index 1b2b485..0f69b88 100644 --- a/configure.in +++ b/configure.in @@ -88,6 +88,10 @@ AC_CHECK_HEADERS([linux/types.h linux/netfilter_ipv4.h], ]] ) +# Check for OpenBSD type transparent proxy support +AC_CHECK_HEADERS([net/pfvar.h], + AC_DEFINE(USE_PF_NATLOOKUP, 1, [Whether the system supports OpenBSD packet filter for transparent proxy]),,) + # Checks for typedefs, structures, and compiler characteristics. AC_TYPE_SIZE_T |