summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
Diffstat (limited to 'sbin')
-rw-r--r--sbin/ipsecctl/parse.y99
1 files changed, 58 insertions, 41 deletions
diff --git a/sbin/ipsecctl/parse.y b/sbin/ipsecctl/parse.y
index ff7569ccc8a..a53667f07bd 100644
--- a/sbin/ipsecctl/parse.y
+++ b/sbin/ipsecctl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.136 2008/06/14 00:57:30 bluhm Exp $ */
+/* $OpenBSD: parse.y,v 1.137 2008/07/01 14:08:39 bluhm Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -181,18 +181,18 @@ struct ipsec_rule *create_sagroup(struct ipsec_addr_wrap *, u_int8_t,
u_int32_t, struct ipsec_addr_wrap *, u_int8_t,
u_int32_t);
struct ipsec_rule *create_flow(u_int8_t, u_int8_t, struct ipsec_hosts *,
- struct ipsec_hosts *, u_int8_t, char *, char *,
- u_int8_t);
-void set_rule_peers(struct ipsec_rule *r,
+ u_int8_t, char *, char *, u_int8_t);
+int set_rule_peers(struct ipsec_rule *r,
struct ipsec_hosts *peers);
void expand_any(struct ipsec_addr_wrap *);
-int expand_rule(struct ipsec_rule *, u_int8_t, u_int32_t,
- struct ipsec_key *, struct ipsec_key *, int);
+int expand_rule(struct ipsec_rule *, struct ipsec_hosts *,
+ u_int8_t, u_int32_t, struct ipsec_key *,
+ struct ipsec_key *, int);
struct ipsec_rule *reverse_rule(struct ipsec_rule *);
struct ipsec_rule *create_ike(u_int8_t, struct ipsec_hosts *,
- struct ipsec_hosts *, struct ike_mode *,
- struct ike_mode *, u_int8_t, u_int8_t, u_int8_t,
- char *, char *, struct ike_auth *, char *);
+ struct ike_mode *, struct ike_mode *, u_int8_t,
+ u_int8_t, u_int8_t, char *, char *,
+ struct ike_auth *, char *);
int add_sagroup(struct ipsec_rule *);
int get_id_type(char *);
@@ -316,7 +316,8 @@ tcpmd5rule : TCPMD5 hosts spispec authkeyspec {
if (r == NULL)
YYERROR;
- if (expand_rule(r, 0, $3.spiin, $4.keyin, NULL, 0))
+ if (expand_rule(r, NULL, 0, $3.spiin, $4.keyin, NULL,
+ 0))
errx(1, "tcpmd5rule: expand_rule");
}
;
@@ -330,7 +331,8 @@ sarule : satype tmode hosts spispec transforms authkeyspec
if (r == NULL)
YYERROR;
- if (expand_rule(r, 0, $4.spiin, $6.keyin, $7.keyin, 1))
+ if (expand_rule(r, NULL, 0, $4.spiin, $6.keyin,
+ $7.keyin, 1))
errx(1, "sarule: expand_rule");
}
;
@@ -338,12 +340,12 @@ sarule : satype tmode hosts spispec transforms authkeyspec
flowrule : FLOW satype dir proto hosts peers ids type {
struct ipsec_rule *r;
- r = create_flow($3, $4, &$5, &$6, $2, $7.srcid,
+ r = create_flow($3, $4, &$5, $2, $7.srcid,
$7.dstid, $8);
if (r == NULL)
YYERROR;
- if (expand_rule(r, $3, 0, NULL, NULL, 0))
+ if (expand_rule(r, &$6, $3, 0, NULL, NULL, 0))
errx(1, "flowrule: expand_rule");
}
;
@@ -352,12 +354,12 @@ ikerule : IKE ikemode satype tmode proto hosts peers
phase1mode phase2mode ids ikeauth tag {
struct ipsec_rule *r;
- r = create_ike($5, &$6, &$7, $8, $9, $3, $4, $2,
+ r = create_ike($5, &$6, $8, $9, $3, $4, $2,
$10.srcid, $10.dstid, &$11, $12);
if (r == NULL)
YYERROR;
- if (expand_rule(r, 0, 0, NULL, NULL, 0))
+ if (expand_rule(r, &$7, 0, 0, NULL, NULL, 0))
errx(1, "ikerule: expand_rule");
}
;
@@ -2310,7 +2312,6 @@ create_sagroup(struct ipsec_addr_wrap *dst, u_int8_t proto, u_int32_t spi,
struct ipsec_rule *
create_flow(u_int8_t dir, u_int8_t proto, struct ipsec_hosts *hosts,
- struct ipsec_hosts *peers,
u_int8_t satype, char *srcid, char *dstid, u_int8_t type)
{
struct ipsec_rule *r;
@@ -2342,12 +2343,6 @@ create_flow(u_int8_t dir, u_int8_t proto, struct ipsec_hosts *hosts,
if (type == TYPE_DENY || type == TYPE_BYPASS)
return (r);
- set_rule_peers(r, peers);
- if (r->peer == NULL) {
- yyerror("no peer specified");
- goto errout;
- }
-
r->auth = calloc(1, sizeof(struct ipsec_auth));
if (r->auth == NULL)
err(1, "create_flow: calloc");
@@ -2398,11 +2393,15 @@ expand_any(struct ipsec_addr_wrap *ipa_in)
}
}
-void
+int
set_rule_peers(struct ipsec_rule *r, struct ipsec_hosts *peers)
{
- r->local = peers->src;
- r->peer = peers->dst;
+ if (r->type == RULE_FLOW &&
+ (r->flowtype == TYPE_DENY || r->flowtype == TYPE_BYPASS))
+ return (0);
+
+ r->local = copyhost(peers->src);
+ r->peer = copyhost(peers->dst);
if (r->peer == NULL) {
/* Set peer to remote host. Must be a host address. */
if (r->direction == IPSEC_IN) {
@@ -2417,15 +2416,23 @@ set_rule_peers(struct ipsec_rule *r, struct ipsec_hosts *peers)
r->peer = copyhost(r->dst);
}
}
+
+ if (r->type == RULE_FLOW && r->peer == NULL) {
+ yyerror("no peer specified for destination %s",
+ r->dst->name);
+ return (1);
+ }
+ return (0);
}
int
-expand_rule(struct ipsec_rule *rule, u_int8_t direction, u_int32_t spi,
- struct ipsec_key *authkey, struct ipsec_key *enckey, int group)
+expand_rule(struct ipsec_rule *rule, struct ipsec_hosts *peers,
+ u_int8_t direction, u_int32_t spi, struct ipsec_key *authkey,
+ struct ipsec_key *enckey, int group)
{
struct ipsec_rule *r, *revr;
struct ipsec_addr_wrap *src, *dst;
- int added = 0;
+ int added = 0, ret = 1;
if (validate_af(rule->src, rule->dst)) {
yyerror("source/destination address families do not match");
@@ -2433,7 +2440,6 @@ expand_rule(struct ipsec_rule *rule, u_int8_t direction, u_int32_t spi,
}
expand_any(rule->src);
expand_any(rule->dst);
- expand_any(rule->peer);
for (src = rule->src; src; src = src->next) {
for (dst = rule->dst; dst; dst = dst->next) {
if (src->af != dst->af)
@@ -2443,34 +2449,39 @@ expand_rule(struct ipsec_rule *rule, u_int8_t direction, u_int32_t spi,
r->src = copyhost(src);
r->dst = copyhost(dst);
+ if (peers && set_rule_peers(r, peers)) {
+ ipsecctl_free_rule(r);
+ goto errout;
+ }
+
r->nr = ipsec->rule_nr++;
if (ipsecctl_add_rule(ipsec, r))
- return (1);
+ goto out;
if (group && add_sagroup(r))
- return (1);
+ goto out;
if (direction == IPSEC_INOUT) {
/* Create and add reverse flow rule. */
revr = reverse_rule(r);
if (revr == NULL)
- return (1);
+ goto out;
revr->nr = ipsec->rule_nr++;
if (ipsecctl_add_rule(ipsec, revr))
- return (1);
+ goto out;
if (group && add_sagroup(revr))
- return (1);
+ goto out;
} else if (spi != 0 || authkey || enckey) {
/* Create and add reverse sa rule. */
revr = reverse_sa(r, spi, authkey, enckey);
if (revr == NULL)
- return (1);
+ goto out;
revr->nr = ipsec->rule_nr++;
if (ipsecctl_add_rule(ipsec, revr))
- return (1);
+ goto out;
if (group && add_sagroup(revr))
- return (1);
+ goto out;
}
added++;
}
@@ -2478,8 +2489,16 @@ expand_rule(struct ipsec_rule *rule, u_int8_t direction, u_int32_t spi,
if (!added)
yyerror("rule expands to no valid combination");
errout:
+ ret = 0;
ipsecctl_free_rule(rule);
- return (0);
+ out:
+ if (peers) {
+ if (peers->src)
+ free(peers->src);
+ if (peers->dst)
+ free(peers->dst);
+ }
+ return (ret);
}
struct ipsec_rule *
@@ -2530,7 +2549,7 @@ reverse_rule(struct ipsec_rule *rule)
}
struct ipsec_rule *
-create_ike(u_int8_t proto, struct ipsec_hosts *hosts, struct ipsec_hosts *peers,
+create_ike(u_int8_t proto, struct ipsec_hosts *hosts,
struct ike_mode *phase1mode, struct ike_mode *phase2mode, u_int8_t satype,
u_int8_t tmode, u_int8_t mode, char *srcid, char *dstid,
struct ike_auth *authtype, char *tag)
@@ -2575,8 +2594,6 @@ create_ike(u_int8_t proto, struct ipsec_hosts *hosts, struct ipsec_hosts *peers,
return NULL;
}
- set_rule_peers(r, peers);
-
r->satype = satype;
r->tmode = tmode;
r->ikemode = mode;