summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2011-03-25 14:51:32 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2011-03-25 14:51:32 +0000
commit1edd3b2e44096e43db5b23f9352f1973c61f4432 (patch)
treeabdeab0acc889d0ca99b83d282b4ad60c3339c69
parentadc8aa11c98a2e2d88f486ce1139bfeef3f5d7a9 (diff)
Use the rdomain information returned by DIOCNATLOOK to install the
nat-to and rdr-to rules with correct rtable rule attributes. This allows to use ftp-proxy to proxy accross rdomains. Tested and OK phessler@, OK henning@
-rw-r--r--usr.sbin/ftp-proxy/filter.c32
-rw-r--r--usr.sbin/ftp-proxy/filter.h11
-rw-r--r--usr.sbin/ftp-proxy/ftp-proxy.c29
3 files changed, 42 insertions, 30 deletions
diff --git a/usr.sbin/ftp-proxy/filter.c b/usr.sbin/ftp-proxy/filter.c
index 2112822a8d8..84d69a3ca2d 100644
--- a/usr.sbin/ftp-proxy/filter.c
+++ b/usr.sbin/ftp-proxy/filter.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: filter.c,v 1.13 2010/01/13 01:07:34 claudio Exp $ */
+/* $OpenBSD: filter.c,v 1.14 2011/03/25 14:51:31 claudio Exp $ */
/*
* Copyright (c) 2004, 2005 Camiel Dobbelaar, <cd@sentia.nl>
@@ -43,9 +43,9 @@ int add_addr(struct sockaddr *, struct pf_pool *);
int prepare_rule(u_int32_t, struct sockaddr *, struct sockaddr *,
u_int16_t);
int server_lookup4(struct sockaddr_in *, struct sockaddr_in *,
- struct sockaddr_in *);
+ struct sockaddr_in *, int *);
int server_lookup6(struct sockaddr_in6 *, struct sockaddr_in6 *,
- struct sockaddr_in6 *);
+ struct sockaddr_in6 *, int *);
static struct pfioc_rule pfr;
static struct pfioc_trans pft;
@@ -70,7 +70,7 @@ add_addr(struct sockaddr *addr, struct pf_pool *pfp)
}
int
-add_nat(u_int32_t id, struct sockaddr *src, struct sockaddr *dst,
+add_nat(u_int32_t id, struct sockaddr *src, int s_rd, struct sockaddr *dst,
u_int16_t d_port, struct sockaddr *nat, u_int16_t nat_range_low,
u_int16_t nat_range_high)
{
@@ -87,6 +87,8 @@ add_nat(u_int32_t id, struct sockaddr *src, struct sockaddr *dst,
return (-1);
pfr.rule.direction = PF_OUT;
+ /* XXX limit the source routing domain */
+ pfr.rule.rtableid = -1;
pfr.rule.nat.proxy_port[0] = nat_range_low;
pfr.rule.nat.proxy_port[1] = nat_range_high;
if (ioctl(dev, DIOCADDRULE, &pfr) == -1)
@@ -96,8 +98,8 @@ add_nat(u_int32_t id, struct sockaddr *src, struct sockaddr *dst,
}
int
-add_rdr(u_int32_t id, struct sockaddr *src, struct sockaddr *dst,
- u_int16_t d_port, struct sockaddr *rdr, u_int16_t rdr_port)
+add_rdr(u_int32_t id, struct sockaddr *src, int s_rd, struct sockaddr *dst,
+ u_int16_t d_port, struct sockaddr *rdr, u_int16_t rdr_port, int d_rd)
{
if (!src || !dst || !d_port || !rdr || !rdr_port ||
(src->sa_family != rdr->sa_family)) {
@@ -112,6 +114,8 @@ add_rdr(u_int32_t id, struct sockaddr *src, struct sockaddr *dst,
return (-1);
pfr.rule.direction = PF_IN;
+ /* XXX limit the source routing domain */
+ pfr.rule.rtableid = d_rd;
pfr.rule.rdr.proxy_port[0] = rdr_port;
if (ioctl(dev, DIOCADDRULE, &pfr) == -1)
return (-1);
@@ -254,15 +258,15 @@ prepare_rule(u_int32_t id, struct sockaddr *src,
int
server_lookup(struct sockaddr *client, struct sockaddr *proxy,
- struct sockaddr *server)
+ struct sockaddr *server, int *cdomain)
{
if (client->sa_family == AF_INET)
return (server_lookup4(satosin(client), satosin(proxy),
- satosin(server)));
+ satosin(server), cdomain));
if (client->sa_family == AF_INET6)
return (server_lookup6(satosin6(client), satosin6(proxy),
- satosin6(server)));
+ satosin6(server), cdomain));
errno = EPROTONOSUPPORT;
return (-1);
@@ -270,7 +274,7 @@ server_lookup(struct sockaddr *client, struct sockaddr *proxy,
int
server_lookup4(struct sockaddr_in *client, struct sockaddr_in *proxy,
- struct sockaddr_in *server)
+ struct sockaddr_in *server, int *cdomain)
{
struct pfioc_natlook pnl;
@@ -278,6 +282,7 @@ server_lookup4(struct sockaddr_in *client, struct sockaddr_in *proxy,
pnl.direction = PF_OUT;
pnl.af = AF_INET;
pnl.proto = IPPROTO_TCP;
+ pnl.rdomain = getrtable();
memcpy(&pnl.saddr.v4, &client->sin_addr.s_addr, sizeof pnl.saddr.v4);
memcpy(&pnl.daddr.v4, &proxy->sin_addr.s_addr, sizeof pnl.daddr.v4);
pnl.sport = client->sin_port;
@@ -292,13 +297,14 @@ server_lookup4(struct sockaddr_in *client, struct sockaddr_in *proxy,
memcpy(&server->sin_addr.s_addr, &pnl.rdaddr.v4,
sizeof server->sin_addr.s_addr);
server->sin_port = pnl.rdport;
-
+ *cdomain = pnl.rrdomain;
+
return (0);
}
int
server_lookup6(struct sockaddr_in6 *client, struct sockaddr_in6 *proxy,
- struct sockaddr_in6 *server)
+ struct sockaddr_in6 *server, int *cdomain)
{
struct pfioc_natlook pnl;
@@ -306,6 +312,7 @@ server_lookup6(struct sockaddr_in6 *client, struct sockaddr_in6 *proxy,
pnl.direction = PF_OUT;
pnl.af = AF_INET6;
pnl.proto = IPPROTO_TCP;
+ pnl.rdomain = getrtable();
memcpy(&pnl.saddr.v6, &client->sin6_addr.s6_addr, sizeof pnl.saddr.v6);
memcpy(&pnl.daddr.v6, &proxy->sin6_addr.s6_addr, sizeof pnl.daddr.v6);
pnl.sport = client->sin6_port;
@@ -320,6 +327,7 @@ server_lookup6(struct sockaddr_in6 *client, struct sockaddr_in6 *proxy,
memcpy(&server->sin6_addr.s6_addr, &pnl.rdaddr.v6,
sizeof server->sin6_addr);
server->sin6_port = pnl.rdport;
+ *cdomain = pnl.rrdomain;
return (0);
}
diff --git a/usr.sbin/ftp-proxy/filter.h b/usr.sbin/ftp-proxy/filter.h
index 11ecef7b8e5..0b40a0b4cbf 100644
--- a/usr.sbin/ftp-proxy/filter.h
+++ b/usr.sbin/ftp-proxy/filter.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: filter.h,v 1.5 2009/09/01 13:46:14 claudio Exp $ */
+/* $OpenBSD: filter.h,v 1.6 2011/03/25 14:51:31 claudio Exp $ */
/*
* Copyright (c) 2004, 2005 Camiel Dobbelaar, <cd@sentia.nl>
@@ -18,12 +18,13 @@
#define FTP_PROXY_ANCHOR "ftp-proxy"
-int add_nat(u_int32_t, struct sockaddr *, struct sockaddr *, u_int16_t,
+int add_nat(u_int32_t, struct sockaddr *, int, struct sockaddr *, u_int16_t,
struct sockaddr *, u_int16_t, u_int16_t);
-int add_rdr(u_int32_t, struct sockaddr *, struct sockaddr *, u_int16_t,
- struct sockaddr *, u_int16_t);
+int add_rdr(u_int32_t, struct sockaddr *, int, struct sockaddr *, u_int16_t,
+ struct sockaddr *, u_int16_t, int);
int do_commit(void);
int do_rollback(void);
void init_filter(char *, char *, int);
int prepare_commit(u_int32_t);
-int server_lookup(struct sockaddr *, struct sockaddr *, struct sockaddr *);
+int server_lookup(struct sockaddr *, struct sockaddr *, struct sockaddr *,
+ int *);
diff --git a/usr.sbin/ftp-proxy/ftp-proxy.c b/usr.sbin/ftp-proxy/ftp-proxy.c
index fe772c59188..0b8fbede6ab 100644
--- a/usr.sbin/ftp-proxy/ftp-proxy.c
+++ b/usr.sbin/ftp-proxy/ftp-proxy.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ftp-proxy.c,v 1.20 2009/09/01 13:46:14 claudio Exp $ */
+/* $OpenBSD: ftp-proxy.c,v 1.21 2011/03/25 14:51:31 claudio Exp $ */
/*
* Copyright (c) 2004, 2005 Camiel Dobbelaar, <cd@sentia.nl>
@@ -77,6 +77,7 @@ struct session {
char sbuf[MAX_LINE];
size_t sbuf_valid;
int cmd;
+ int client_rd;
u_int16_t port;
u_int16_t proxy_port;
LIST_ENTRY(session) entry;
@@ -427,7 +428,8 @@ handle_connection(const int listen_fd, short event, void *ev)
strerror(errno));
goto fail;
}
- if (server_lookup(client_sa, client_to_proxy_sa, server_sa) != 0) {
+ if (server_lookup(client_sa, client_to_proxy_sa, server_sa,
+ &s->client_rd) != 0) {
logmsg(LOG_CRIT, "#%d server lookup failed (no rdr?)", s->id);
goto fail;
}
@@ -477,7 +479,7 @@ handle_connection(const int listen_fd, short event, void *ev)
}
logmsg(LOG_INFO, "#%d FTP session %d/%d started: client %s to server "
- "%s via proxy %s ", s->id, session_count, max_sessions,
+ "%s via proxy %s", s->id, session_count, max_sessions,
sock_ntop(client_sa), sock_ntop(server_sa),
sock_ntop(proxy_to_server_sa));
@@ -973,13 +975,14 @@ allow_data_connection(struct session *s)
/* pass in from $client to $orig_server port $proxy_port
rdr-to $server port $port */
- if (add_rdr(s->id, client_sa, orig_sa, s->proxy_port,
- server_sa, s->port) == -1)
+ if (add_rdr(s->id, client_sa, s->client_rd, orig_sa,
+ s->proxy_port, server_sa, s->port, getrtable()) == -1)
goto fail;
/* pass out from $client to $server port $port nat-to $proxy */
- if (add_nat(s->id, client_sa, server_sa, s->port, proxy_sa,
- PF_NAT_PROXY_PORT_LOW, PF_NAT_PROXY_PORT_HIGH) == -1)
+ if (add_nat(s->id, client_sa, getrtable(), server_sa,
+ s->port, proxy_sa, PF_NAT_PROXY_PORT_LOW,
+ PF_NAT_PROXY_PORT_HIGH) == -1)
goto fail;
}
@@ -994,21 +997,21 @@ allow_data_connection(struct session *s)
/* pass in from $server to $proxy port $proxy_port
rdr-to $client port $port */
- if (add_rdr(s->id, server_sa, proxy_sa, s->proxy_port,
- client_sa, s->port) == -1)
+ if (add_rdr(s->id, server_sa, getrtable(), proxy_sa,
+ s->proxy_port, client_sa, s->port, s->client_rd) == -1)
goto fail;
/* pass out from $server to $client port $port
nat-to $orig_server port $natport */
if (rfc_mode && s->cmd == CMD_PORT) {
/* Rewrite sourceport to RFC mandated 20. */
- if (add_nat(s->id, server_sa, client_sa, s->port,
- orig_sa, 20, 20) == -1)
+ if (add_nat(s->id, server_sa, s->client_rd, client_sa,
+ s->port, orig_sa, 20, 20) == -1)
goto fail;
} else {
/* Let pf pick a source port from the standard range. */
- if (add_nat(s->id, server_sa, client_sa, s->port,
- orig_sa, PF_NAT_PROXY_PORT_LOW,
+ if (add_nat(s->id, server_sa, s->client_rd, client_sa,
+ s->port, orig_sa, PF_NAT_PROXY_PORT_LOW,
PF_NAT_PROXY_PORT_HIGH) == -1)
goto fail;
}