diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2009-09-01 13:46:15 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2009-09-01 13:46:15 +0000 |
commit | 97a009f0845e9714085d93131354aa564bbe8ab0 (patch) | |
tree | efee1e5dacc8a9d4a49bda8ab4bb7572dea56a4f | |
parent | c4b0c3c9bc8f557e7ade997adcd3f5e5654bb5f8 (diff) |
Bring ftp-proxy in sync with the massive pf change just commited by Henning.
This changes the way the rdr/nat rules are added to pf. Now only a single
anchor is needed (the other ones do no longer exist).
To convert your ruleset you need something like this at the start of your
ruleset:
# filter rules and anchors for ftp-proxy(8)
anchor "ftp-proxy/*"
pass in quick proto tcp to port ftp rdr-to 127.0.0.1 port 8021
This was tested by myself, sthen@, dlg@ and I think many more. OK by the same
people plus henning.
-rw-r--r-- | usr.sbin/ftp-proxy/filter.c | 162 | ||||
-rw-r--r-- | usr.sbin/ftp-proxy/filter.h | 4 | ||||
-rw-r--r-- | usr.sbin/ftp-proxy/ftp-proxy.c | 36 |
3 files changed, 57 insertions, 145 deletions
diff --git a/usr.sbin/ftp-proxy/filter.c b/usr.sbin/ftp-proxy/filter.c index 80625a6fd9c..6a771c28639 100644 --- a/usr.sbin/ftp-proxy/filter.c +++ b/usr.sbin/ftp-proxy/filter.c @@ -1,4 +1,4 @@ -/* $OpenBSD: filter.c,v 1.8 2008/06/13 07:25:26 claudio Exp $ */ +/* $OpenBSD: filter.c,v 1.9 2009/09/01 13:46:14 claudio Exp $ */ /* * Copyright (c) 2004, 2005 Camiel Dobbelaar, <cd@sentia.nl> @@ -39,8 +39,7 @@ #define satosin(sa) ((struct sockaddr_in *)(sa)) #define satosin6(sa) ((struct sockaddr_in6 *)(sa)) -enum { TRANS_FILTER = 0, TRANS_NAT, TRANS_RDR, TRANS_SIZE }; - +int add_addr(struct sockaddr *, int); int prepare_rule(u_int32_t, int, struct sockaddr *, struct sockaddr *, u_int16_t); int server_lookup4(struct sockaddr_in *, struct sockaddr_in *, @@ -51,26 +50,25 @@ int server_lookup6(struct sockaddr_in6 *, struct sockaddr_in6 *, static struct pfioc_pooladdr pfp; static struct pfioc_rule pfr; static struct pfioc_trans pft; -static struct pfioc_trans_e pfte[TRANS_SIZE]; +static struct pfioc_trans_e pfte; static int dev, rule_log; static char *qname, *tagname; int -add_filter(u_int32_t id, u_int8_t dir, struct sockaddr *src, - struct sockaddr *dst, u_int16_t d_port) +add_addr(struct sockaddr *addr, int which) { - if (!src || !dst || !d_port) { - errno = EINVAL; - return (-1); + if (addr->sa_family == AF_INET) { + memcpy(&pfp.addr.addr.v.a.addr.v4, + &satosin(addr)->sin_addr.s_addr, 4); + memset(&pfp.addr.addr.v.a.mask.addr8, 255, 4); + } else { + memcpy(&pfp.addr.addr.v.a.addr.v6, + &satosin6(addr)->sin6_addr.s6_addr, 16); + memset(&pfp.addr.addr.v.a.mask.addr8, 255, 16); } - - if (prepare_rule(id, PF_RULESET_FILTER, src, dst, d_port) == -1) - return (-1); - - pfr.rule.direction = dir; - if (ioctl(dev, DIOCADDRULE, &pfr) == -1) + pfp.which = which; + if (ioctl(dev, DIOCADDADDR, &pfp) == -1) return (-1); - return (0); } @@ -85,23 +83,15 @@ add_nat(u_int32_t id, struct sockaddr *src, struct sockaddr *dst, return (-1); } - if (prepare_rule(id, PF_RULESET_NAT, src, dst, d_port) == -1) + if (prepare_rule(id, PF_RULESET_FILTER, src, dst, d_port) == -1) return (-1); - if (nat->sa_family == AF_INET) { - memcpy(&pfp.addr.addr.v.a.addr.v4, - &satosin(nat)->sin_addr.s_addr, 4); - memset(&pfp.addr.addr.v.a.mask.addr8, 255, 4); - } else { - memcpy(&pfp.addr.addr.v.a.addr.v6, - &satosin6(nat)->sin6_addr.s6_addr, 16); - memset(&pfp.addr.addr.v.a.mask.addr8, 255, 16); - } - if (ioctl(dev, DIOCADDADDR, &pfp) == -1) + if (add_addr(nat, PF_NAT) == -1) return (-1); - pfr.rule.rpool.proxy_port[0] = nat_range_low; - pfr.rule.rpool.proxy_port[1] = nat_range_high; + pfr.rule.direction = PF_OUT; + pfr.rule.nat.proxy_port[0] = nat_range_low; + pfr.rule.nat.proxy_port[1] = nat_range_high; if (ioctl(dev, DIOCADDRULE, &pfr) == -1) return (-1); @@ -118,22 +108,14 @@ add_rdr(u_int32_t id, struct sockaddr *src, struct sockaddr *dst, return (-1); } - if (prepare_rule(id, PF_RULESET_RDR, src, dst, d_port) == -1) + if (prepare_rule(id, PF_RULESET_FILTER, src, dst, d_port) == -1) return (-1); - if (rdr->sa_family == AF_INET) { - memcpy(&pfp.addr.addr.v.a.addr.v4, - &satosin(rdr)->sin_addr.s_addr, 4); - memset(&pfp.addr.addr.v.a.mask.addr8, 255, 4); - } else { - memcpy(&pfp.addr.addr.v.a.addr.v6, - &satosin6(rdr)->sin6_addr.s6_addr, 16); - memset(&pfp.addr.addr.v.a.mask.addr8, 255, 16); - } - if (ioctl(dev, DIOCADDADDR, &pfp) == -1) + if (add_addr(rdr, PF_RDR) == -1) return (-1); - pfr.rule.rpool.proxy_port[0] = rdr_port; + pfr.rule.direction = PF_IN; + pfr.rule.rdr.proxy_port[0] = rdr_port; if (ioctl(dev, DIOCADDRULE, &pfr) == -1) return (-1); @@ -184,33 +166,17 @@ int prepare_commit(u_int32_t id) { char an[PF_ANCHOR_NAME_SIZE]; - int i; memset(&pft, 0, sizeof pft); - pft.size = TRANS_SIZE; - pft.esize = sizeof pfte[0]; - pft.array = pfte; + pft.size = 1; + pft.esize = sizeof pfte; + pft.array = &pfte; snprintf(an, PF_ANCHOR_NAME_SIZE, "%s/%d.%d", FTP_PROXY_ANCHOR, getpid(), id); - for (i = 0; i < TRANS_SIZE; i++) { - memset(&pfte[i], 0, sizeof pfte[0]); - strlcpy(pfte[i].anchor, an, PF_ANCHOR_NAME_SIZE); - switch (i) { - case TRANS_FILTER: - pfte[i].rs_num = PF_RULESET_FILTER; - break; - case TRANS_NAT: - pfte[i].rs_num = PF_RULESET_NAT; - break; - case TRANS_RDR: - pfte[i].rs_num = PF_RULESET_RDR; - break; - default: - errno = EINVAL; - return (-1); - } - } + memset(&pfte, 0, sizeof pfte); + strlcpy(pfte.anchor, an, PF_ANCHOR_NAME_SIZE); + pfte.rs_num = PF_RULESET_FILTER; if (ioctl(dev, DIOCXBEGIN, &pft) == -1) return (-1); @@ -237,20 +203,7 @@ prepare_rule(u_int32_t id, int rs_num, struct sockaddr *src, strlcpy(pfp.anchor, an, PF_ANCHOR_NAME_SIZE); strlcpy(pfr.anchor, an, PF_ANCHOR_NAME_SIZE); - switch (rs_num) { - case PF_RULESET_FILTER: - pfr.ticket = pfte[TRANS_FILTER].ticket; - break; - case PF_RULESET_NAT: - pfr.ticket = pfte[TRANS_NAT].ticket; - break; - case PF_RULESET_RDR: - pfr.ticket = pfte[TRANS_RDR].ticket; - break; - default: - errno = EINVAL; - return (-1); - } + pfr.ticket = pfte.ticket; if (ioctl(dev, DIOCBEGINADDRS, &pfp) == -1) return (-1); pfr.pool_ticket = pfp.ticket; @@ -278,43 +231,24 @@ prepare_rule(u_int32_t id, int rs_num, struct sockaddr *src, pfr.rule.dst.port_op = PF_OP_EQ; pfr.rule.dst.port[0] = htons(d_port); - switch (rs_num) { - case PF_RULESET_FILTER: - /* - * pass [quick] [log] inet[6] proto tcp \ - * from $src to $dst port = $d_port flags S/SA keep state - * (max 1) [queue qname] [tag tagname] - */ - pfr.rule.action = PF_PASS; - pfr.rule.quick = 1; - pfr.rule.log = rule_log; - pfr.rule.keep_state = 1; - pfr.rule.flags = TH_SYN; - pfr.rule.flagset = (TH_SYN|TH_ACK); - pfr.rule.max_states = 1; - if (qname != NULL) - strlcpy(pfr.rule.qname, qname, sizeof pfr.rule.qname); - if (tagname != NULL) { - pfr.rule.quick = 0; - strlcpy(pfr.rule.tagname, tagname, - sizeof pfr.rule.tagname); - } - break; - case PF_RULESET_NAT: - /* - * nat inet[6] proto tcp from $src to $dst port $d_port -> $nat - */ - pfr.rule.action = PF_NAT; - break; - case PF_RULESET_RDR: - /* - * rdr inet[6] proto tcp from $src to $dst port $d_port -> $rdr - */ - pfr.rule.action = PF_RDR; - break; - default: - errno = EINVAL; - return (-1); + /* + * pass [quick] [log] inet[6] proto tcp \ + * from $src to $dst port = $d_port flags S/SA keep state + * (max 1) [queue qname] [tag tagname] + */ + pfr.rule.action = PF_PASS; + pfr.rule.quick = 1; + pfr.rule.log = rule_log; + pfr.rule.keep_state = 1; + pfr.rule.flags = TH_SYN; + pfr.rule.flagset = (TH_SYN|TH_ACK); + pfr.rule.max_states = 1; + if (qname != NULL) + strlcpy(pfr.rule.qname, qname, sizeof pfr.rule.qname); + if (tagname != NULL) { + pfr.rule.quick = 0; + strlcpy(pfr.rule.tagname, tagname, + sizeof pfr.rule.tagname); } return (0); diff --git a/usr.sbin/ftp-proxy/filter.h b/usr.sbin/ftp-proxy/filter.h index 150bc49d3ce..11ecef7b8e5 100644 --- a/usr.sbin/ftp-proxy/filter.h +++ b/usr.sbin/ftp-proxy/filter.h @@ -1,4 +1,4 @@ -/* $OpenBSD: filter.h,v 1.4 2007/08/01 09:31:41 henning Exp $ */ +/* $OpenBSD: filter.h,v 1.5 2009/09/01 13:46:14 claudio Exp $ */ /* * Copyright (c) 2004, 2005 Camiel Dobbelaar, <cd@sentia.nl> @@ -18,8 +18,6 @@ #define FTP_PROXY_ANCHOR "ftp-proxy" -int add_filter(u_int32_t, u_int8_t, struct sockaddr *, struct sockaddr *, - u_int16_t); int add_nat(u_int32_t, struct sockaddr *, 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, diff --git a/usr.sbin/ftp-proxy/ftp-proxy.c b/usr.sbin/ftp-proxy/ftp-proxy.c index 131991a4bb8..fe772c59188 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.19 2008/06/13 07:25:26 claudio Exp $ */ +/* $OpenBSD: ftp-proxy.c,v 1.20 2009/09/01 13:46:14 claudio Exp $ */ /* * Copyright (c) 2004, 2005 Camiel Dobbelaar, <cd@sentia.nl> @@ -971,26 +971,16 @@ allow_data_connection(struct session *s) proxy_reply(s->cmd, orig_sa, s->proxy_port); logmsg(LOG_DEBUG, "#%d proxy: %s", s->id, linebuf); - /* rdr from $client to $orig_server port $proxy_port -> $server - port $port */ + /* 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) goto fail; - /* nat from $client to $server port $port -> $proxy */ + /* 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) goto fail; - - /* pass in from $client to $server port $port */ - if (add_filter(s->id, PF_IN, client_sa, server_sa, - s->port) == -1) - goto fail; - - /* pass out from $proxy to $server port $port */ - if (add_filter(s->id, PF_OUT, proxy_sa, server_sa, - s->port) == -1) - goto fail; } /* Active modes. */ @@ -1002,14 +992,14 @@ allow_data_connection(struct session *s) goto fail; prepared = 1; - /* rdr from $server to $proxy port $proxy_port -> $client port - $port */ + /* 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) goto fail; - /* nat from $server to $client port $port -> $orig_server port - $natport */ + /* 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, @@ -1022,16 +1012,6 @@ allow_data_connection(struct session *s) PF_NAT_PROXY_PORT_HIGH) == -1) goto fail; } - - /* pass in from $server to $client port $port */ - if (add_filter(s->id, PF_IN, server_sa, client_sa, s->port) == - -1) - goto fail; - - /* pass out from $orig_server to $client port $port */ - if (add_filter(s->id, PF_OUT, orig_sa, client_sa, s->port) == - -1) - goto fail; } /* Commit rules if they were prepared. */ |