diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2011-03-25 14:51:32 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2011-03-25 14:51:32 +0000 |
commit | 1edd3b2e44096e43db5b23f9352f1973c61f4432 (patch) | |
tree | abdeab0acc889d0ca99b83d282b4ad60c3339c69 /usr.sbin | |
parent | adc8aa11c98a2e2d88f486ce1139bfeef3f5d7a9 (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@
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/ftp-proxy/filter.c | 32 | ||||
-rw-r--r-- | usr.sbin/ftp-proxy/filter.h | 11 | ||||
-rw-r--r-- | usr.sbin/ftp-proxy/ftp-proxy.c | 29 |
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; } |