diff options
Diffstat (limited to 'sbin/ipsecctl/parse.y')
-rw-r--r-- | sbin/ipsecctl/parse.y | 99 |
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; |