parse.y revision 1.125
1/*	$OpenBSD: parse.y,v 1.125 2007/08/10 12:32:12 markus Exp $	*/
2
3/*
4 * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
5 * Copyright (c) 2001 Markus Friedl.  All rights reserved.
6 * Copyright (c) 2001 Daniel Hartmeier.  All rights reserved.
7 * Copyright (c) 2001 Theo de Raadt.  All rights reserved.
8 * Copyright (c) 2004, 2005 Hans-Joerg Hoexer <hshoexer@openbsd.org>
9 *
10 * Permission to use, copy, modify, and distribute this software for any
11 * purpose with or without fee is hereby granted, provided that the above
12 * copyright notice and this permission notice appear in all copies.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 */
22
23%{
24#include <sys/types.h>
25#include <sys/ioctl.h>
26#include <sys/queue.h>
27#include <sys/socket.h>
28#include <sys/stat.h>
29#include <net/if.h>
30#include <netinet/in.h>
31#include <netinet/ip_ipsp.h>
32#include <arpa/inet.h>
33
34#include <ctype.h>
35#include <err.h>
36#include <errno.h>
37#include <fcntl.h>
38#include <ifaddrs.h>
39#include <limits.h>
40#include <netdb.h>
41#include <stdarg.h>
42#include <stdio.h>
43#include <string.h>
44#include <syslog.h>
45#include <unistd.h>
46#include <netdb.h>
47
48#include "ipsecctl.h"
49
50#define KEYSIZE_LIMIT	1024
51
52static struct ipsecctl	*ipsec = NULL;
53static FILE		*fin = NULL;
54static int		 lineno = 1;
55static int		 errors = 0;
56static int		 debug = 0;
57
58const struct ipsec_xf authxfs[] = {
59	{ "unknown",		AUTHXF_UNKNOWN,		0,	0 },
60	{ "none",		AUTHXF_NONE,		0,	0 },
61	{ "hmac-md5",		AUTHXF_HMAC_MD5,	16,	0 },
62	{ "hmac-ripemd160",	AUTHXF_HMAC_RIPEMD160,	20,	0 },
63	{ "hmac-sha1",		AUTHXF_HMAC_SHA1,	20,	0 },
64	{ "hmac-sha2-256",	AUTHXF_HMAC_SHA2_256,	32,	0 },
65	{ "hmac-sha2-384",	AUTHXF_HMAC_SHA2_384,	48,	0 },
66	{ "hmac-sha2-512",	AUTHXF_HMAC_SHA2_512,	64,	0 },
67	{ NULL,			0,			0,	0 },
68};
69
70const struct ipsec_xf encxfs[] = {
71	{ "unknown",		ENCXF_UNKNOWN,		0,	0 },
72	{ "none",		ENCXF_NONE,		0,	0 },
73	{ "3des-cbc",		ENCXF_3DES_CBC,		24,	24 },
74	{ "des-cbc",		ENCXF_DES_CBC,		8,	8 },
75	{ "aes",		ENCXF_AES,		16,	32 },
76	{ "aesctr",		ENCXF_AESCTR,		16+4,	32+4 },
77	{ "blowfish",		ENCXF_BLOWFISH,		5,	56 },
78	{ "cast128",		ENCXF_CAST128,		5,	16 },
79	{ "null",		ENCXF_NULL,		0,	0 },
80	{ "skipjack",		ENCXF_SKIPJACK,		10,	10 },
81	{ NULL,			0,			0,	0 },
82};
83
84const struct ipsec_xf compxfs[] = {
85	{ "unknown",		COMPXF_UNKNOWN,		0,	0 },
86	{ "deflate",		COMPXF_DEFLATE,		0,	0 },
87	{ "lzs",		COMPXF_LZS,		0,	0 },
88	{ NULL,			0,			0,	0 },
89};
90
91const struct ipsec_xf groupxfs[] = {
92	{ "unknown",		GROUPXF_UNKNOWN,	0,	0 },
93	{ "none",		GROUPXF_NONE,		0,	0 },
94	{ "modp768",		GROUPXF_768,		768,	0 },
95	{ "grp1",		GROUPXF_768,		768,	0 },
96	{ "modp1024",		GROUPXF_1024,		1024,	0 },
97	{ "grp2",		GROUPXF_1024,		1024,	0 },
98	{ "modp1536",		GROUPXF_1536,		1536,	0 },
99	{ "grp5",		GROUPXF_1536,		1536,	0 },
100	{ "modp2048",		GROUPXF_2048,		2048,	0 },
101	{ "grp14",		GROUPXF_2048,		2048,	0 },
102	{ "modp3072",		GROUPXF_3072,		3072,	0 },
103	{ "grp15",		GROUPXF_3072,		3072,	0 },
104	{ "modp4096",		GROUPXF_4096,		4096,	0 },
105	{ "grp16",		GROUPXF_4096,		4096,	0 },
106	{ "modp6144",		GROUPXF_6144,		6144,	0 },
107	{ "grp17",		GROUPXF_6144,		6144,	0 },
108	{ "modp8192",		GROUPXF_8192,		8192,	0 },
109	{ "grp18",		GROUPXF_8192,		8192,	0 },
110	{ NULL,			0,			0,	0 },
111};
112
113int			 yyerror(const char *, ...);
114int			 yyparse(void);
115int			 kw_cmp(const void *, const void *);
116int			 lookup(char *);
117int			 lgetc(FILE *);
118int			 lungetc(int);
119int			 findeol(void);
120int			 yylex(void);
121
122TAILQ_HEAD(symhead, sym)	 symhead = TAILQ_HEAD_INITIALIZER(symhead);
123struct sym {
124	TAILQ_ENTRY(sym)	 entries;
125	int		 used;
126	int		 persist;
127	char		*nam;
128	char		*val;
129};
130
131int			 symset(const char *, const char *, int);
132int			 cmdline_symset(char *);
133char			*symget(const char *);
134int			 atoul(char *, u_long *);
135int			 atospi(char *, u_int32_t *);
136u_int8_t		 x2i(unsigned char *);
137struct ipsec_key	*parsekey(unsigned char *, size_t);
138struct ipsec_key	*parsekeyfile(char *);
139struct ipsec_addr_wrap	*host(const char *);
140struct ipsec_addr_wrap	*host_v6(const char *, int);
141struct ipsec_addr_wrap	*host_v4(const char *, int);
142struct ipsec_addr_wrap	*host_dns(const char *, int);
143struct ipsec_addr_wrap	*host_if(const char *, int);
144void			 ifa_load(void);
145int			 ifa_exists(const char *);
146struct ipsec_addr_wrap	*ifa_lookup(const char *ifa_name);
147struct ipsec_addr_wrap	*ifa_grouplookup(const char *);
148void			 set_ipmask(struct ipsec_addr_wrap *, u_int8_t);
149const struct ipsec_xf	*parse_xf(const char *, const struct ipsec_xf *);
150struct ipsec_life	*parse_life(int);
151struct ipsec_transforms *copytransforms(const struct ipsec_transforms *);
152struct ipsec_life	*copylife(const struct ipsec_life *);
153struct ipsec_auth	*copyipsecauth(const struct ipsec_auth *);
154struct ike_auth		*copyikeauth(const struct ike_auth *);
155struct ipsec_key	*copykey(struct ipsec_key *);
156struct ipsec_addr_wrap	*copyhost(const struct ipsec_addr_wrap *);
157char			*copytag(const char *);
158struct ipsec_rule	*copyrule(struct ipsec_rule *);
159int			 validate_af(struct ipsec_addr_wrap *,
160			    struct ipsec_addr_wrap *);
161int			 validate_sa(u_int32_t, u_int8_t,
162			     struct ipsec_transforms *, struct ipsec_key *,
163			     struct ipsec_key *, u_int8_t);
164struct ipsec_rule	*create_sa(u_int8_t, u_int8_t, struct ipsec_hosts *,
165			     u_int32_t, struct ipsec_transforms *,
166			     struct ipsec_key *, struct ipsec_key *);
167struct ipsec_rule	*reverse_sa(struct ipsec_rule *, u_int32_t,
168			     struct ipsec_key *, struct ipsec_key *);
169struct ipsec_rule	*create_sagroup(struct ipsec_addr_wrap *, u_int8_t,
170			     u_int32_t, struct ipsec_addr_wrap *, u_int8_t,
171			     u_int32_t);
172struct ipsec_rule	*create_flow(u_int8_t, u_int8_t, struct ipsec_hosts *,
173			     struct ipsec_hosts *, u_int8_t, char *, char *,
174			     u_int8_t);
175void			 expand_any(struct ipsec_addr_wrap *);
176int			 expand_rule(struct ipsec_rule *, u_int8_t, u_int32_t,
177			     struct ipsec_key *, struct ipsec_key *, int);
178struct ipsec_rule	*reverse_rule(struct ipsec_rule *);
179struct ipsec_rule	*create_ike(u_int8_t, struct ipsec_hosts *,
180			     struct ipsec_hosts *, struct ike_mode *,
181			     struct ike_mode *, u_int8_t, u_int8_t, u_int8_t,
182			     char *, char *, struct ike_auth *, char *);
183int			 add_sagroup(struct ipsec_rule *);
184int			 get_id_type(char *);
185
186struct ipsec_transforms *ipsec_transforms;
187
188typedef struct {
189	union {
190		u_int32_t	 number;
191		u_int8_t	 ikemode;
192		u_int8_t	 dir;
193		u_int8_t	 satype;	/* encapsulating prococol */
194		u_int8_t	 proto;		/* encapsulated protocol */
195		u_int8_t	 tmode;
196		char		*string;
197		u_int16_t	 port;
198		struct ipsec_hosts hosts;
199		struct ipsec_hosts peers;
200		struct ipsec_addr_wrap *singlehost;
201		struct ipsec_addr_wrap *host;
202		struct {
203			char *srcid;
204			char *dstid;
205		} ids;
206		char		*id;
207		u_int8_t	 type;
208		struct ike_auth	 ikeauth;
209		struct {
210			u_int32_t	spiout;
211			u_int32_t	spiin;
212		} spis;
213		struct {
214			struct ipsec_key *keyout;
215			struct ipsec_key *keyin;
216		} authkeys;
217		struct {
218			struct ipsec_key *keyout;
219			struct ipsec_key *keyin;
220		} enckeys;
221		struct {
222			struct ipsec_key *keyout;
223			struct ipsec_key *keyin;
224		} keys;
225		struct ipsec_transforms *transforms;
226		struct ipsec_life	*life;
227		struct ike_mode		*mode;
228	} v;
229	int lineno;
230} YYSTYPE;
231
232%}
233
234%token	FLOW FROM ESP AH IN PEER ON OUT TO SRCID DSTID RSA PSK TCPMD5 SPI
235%token	AUTHKEY ENCKEY FILENAME AUTHXF ENCXF ERROR IKE MAIN QUICK AGGRESSIVE
236%token	PASSIVE ACTIVE ANY IPIP IPCOMP COMPXF TUNNEL TRANSPORT DYNAMIC LIFE
237%token	TYPE DENY BYPASS LOCAL PROTO USE ACQUIRE REQUIRE DONTACQ GROUP PORT TAG
238%token	<v.string>		STRING
239%type	<v.string>		string
240%type	<v.dir>			dir
241%type	<v.satype>		satype
242%type	<v.proto>		proto
243%type	<v.tmode>		tmode
244%type	<v.number>		number
245%type	<v.hosts>		hosts
246%type	<v.port>		port
247%type	<v.peers>		peers
248%type	<v.singlehost>		singlehost
249%type	<v.host>		host host_list
250%type	<v.ids>			ids
251%type	<v.id>			id
252%type	<v.spis>		spispec
253%type	<v.authkeys>		authkeyspec
254%type	<v.enckeys>		enckeyspec
255%type	<v.keys>		keyspec
256%type	<v.transforms>		transforms
257%type	<v.ikemode>		ikemode
258%type	<v.ikeauth>		ikeauth
259%type	<v.type>		type
260%type	<v.life>		life
261%type	<v.mode>		phase1mode phase2mode
262%type	<v.string>		tag
263%%
264
265grammar		: /* empty */
266		| grammar '\n'
267		| grammar ikerule '\n'
268		| grammar flowrule '\n'
269		| grammar sarule '\n'
270		| grammar tcpmd5rule '\n'
271		| grammar varset '\n'
272		| grammar error '\n'		{ errors++; }
273		;
274
275number		: STRING			{
276			unsigned long	ulval;
277
278			if (atoul($1, &ulval) == -1) {
279				yyerror("%s is not a number", $1);
280				free($1);
281				YYERROR;
282			}
283			if (ulval > UINT_MAX) {
284				yyerror("0x%lx out of range", ulval);
285				free($1);
286				YYERROR;
287			}
288			$$ = (u_int32_t)ulval;
289			free($1);
290		}
291		;
292
293comma		: ','
294		| /* empty */
295		;
296
297tcpmd5rule	: TCPMD5 hosts spispec authkeyspec	{
298			struct ipsec_rule	*r;
299
300			r = create_sa(IPSEC_TCPMD5, IPSEC_TRANSPORT, &$2,
301			    $3.spiout, NULL, $4.keyout, NULL);
302			if (r == NULL)
303				YYERROR;
304
305			if (expand_rule(r, 0, $3.spiin, $4.keyin, NULL, 0))
306				errx(1, "tcpmd5rule: expand_rule");
307		}
308		;
309
310sarule		: satype tmode hosts spispec transforms authkeyspec
311		    enckeyspec {
312			struct ipsec_rule	*r;
313
314			r = create_sa($1, $2, &$3, $4.spiout, $5, $6.keyout,
315			    $7.keyout);
316			if (r == NULL)
317				YYERROR;
318
319			if (expand_rule(r, 0, $4.spiin, $6.keyin, $7.keyin, 1))
320				errx(1, "sarule: expand_rule");
321		}
322		;
323
324flowrule	: FLOW satype dir proto hosts peers ids type {
325			struct ipsec_rule	*r;
326
327			r = create_flow($3, $4, &$5, &$6, $2, $7.srcid,
328			    $7.dstid, $8);
329			if (r == NULL)
330				YYERROR;
331
332			if (expand_rule(r, $3, 0, NULL, NULL, 0))
333				errx(1, "flowrule: expand_rule");
334		}
335		;
336
337ikerule		: IKE ikemode satype tmode proto hosts peers
338		    phase1mode phase2mode ids ikeauth tag {
339			struct ipsec_rule	*r;
340
341			r = create_ike($5, &$6, &$7, $8, $9, $3, $4, $2,
342			    $10.srcid, $10.dstid, &$11, $12);
343			if (r == NULL)
344				YYERROR;
345
346			if (expand_rule(r, 0, 0, NULL, NULL, 0))
347				errx(1, "ikerule: expand_rule");
348		}
349		;
350
351satype		: /* empty */			{ $$ = IPSEC_ESP; }
352		| ESP				{ $$ = IPSEC_ESP; }
353		| AH				{ $$ = IPSEC_AH; }
354		| IPCOMP			{ $$ = IPSEC_IPCOMP; }
355		| IPIP				{ $$ = IPSEC_IPIP; }
356		;
357
358proto		: /* empty */			{ $$ = 0; }
359		| PROTO STRING			{
360			struct protoent *p;
361			const char *errstr;
362			int proto;
363
364			if ((p = getprotobyname($2)) != NULL) {
365				$$ = p->p_proto;
366			} else {
367				errstr = NULL;
368				proto = strtonum($2, 0, 255, &errstr);
369				if (errstr)
370					errx(1, "unknown protocol: %s", $2);
371				$$ = proto;
372			}
373
374		}
375		| PROTO ESP 			{ $$ = IPPROTO_ESP; }
376		| PROTO AH			{ $$ = IPPROTO_AH; }
377		;
378
379tmode		: /* empty */			{ $$ = IPSEC_TUNNEL; }
380		| TUNNEL			{ $$ = IPSEC_TUNNEL; }
381		| TRANSPORT			{ $$ = IPSEC_TRANSPORT; }
382		;
383
384dir		: /* empty */			{ $$ = IPSEC_INOUT; }
385		| IN				{ $$ = IPSEC_IN; }
386		| OUT				{ $$ = IPSEC_OUT; }
387		;
388
389hosts		: FROM host port TO host port		{
390			$$.src = $2;
391			$$.sport = $3;
392			$$.dst = $5;
393			$$.dport = $6;
394		}
395		| TO host port FROM host port		{
396			$$.src = $5;
397			$$.sport = $6;
398			$$.dst = $2;
399			$$.dport = $3;
400		}
401		;
402
403port		: /* empty */				{ $$ = 0; }
404		| PORT STRING				{
405			struct servent *s;
406			const char *errstr;
407			int port;
408
409			if ((s = getservbyname($2, "tcp")) != NULL ||
410			    (s = getservbyname($2, "udp")) != NULL) {
411				$$ = s->s_port;
412			} else {
413				errstr = NULL;
414				port = strtonum($2, 0, USHRT_MAX, &errstr);
415				if (errstr) {
416					yyerror("unknown port: %s", $2);
417					YYERROR;
418				}
419				$$ = htons(port);
420			}
421		}
422		;
423
424peers		: /* empty */				{
425			$$.dst = NULL;
426			$$.src = NULL;
427		}
428		| PEER singlehost LOCAL singlehost	{
429			$$.dst = $2;
430			$$.src = $4;
431		}
432		| LOCAL singlehost PEER singlehost	{
433			$$.dst = $4;
434			$$.src = $2;
435		}
436		| PEER singlehost			{
437			$$.dst = $2;
438			$$.src = NULL;
439		}
440		| LOCAL singlehost			{
441			$$.dst = NULL;
442			$$.src = $2;
443		}
444		;
445
446singlehost	: /* empty */			{ $$ = NULL; }
447		| STRING			{
448			if (($$ = host($1)) == NULL) {
449				free($1);
450				yyerror("could not parse host specification");
451				YYERROR;
452			}
453			free($1);
454		}
455		;
456
457host_list	: host				{ $$ = $1; }
458		| host_list comma host		{
459			if ($3 == NULL)
460				$$ = $1;
461			else if ($1 == NULL)
462				$$ = $3;
463			else {
464				$1->tail->next = $3;
465				$1->tail = $3->tail;
466				$$ = $1;
467			}
468		}
469		;
470
471host		: STRING			{
472			if (($$ = host($1)) == NULL) {
473				free($1);
474				yyerror("could not parse host specification");
475				YYERROR;
476			}
477			free($1);
478		}
479		| STRING '/' number		{
480			char	*buf;
481
482			if (asprintf(&buf, "%s/%u", $1, $3) == -1)
483				err(1, "host: asprintf");
484			free($1);
485			if (($$ = host(buf)) == NULL)	{
486				free(buf);
487				yyerror("could not parse host specification");
488				YYERROR;
489			}
490			free(buf);
491		}
492		| ANY				{
493			struct ipsec_addr_wrap	*ipa;
494
495			ipa = calloc(1, sizeof(struct ipsec_addr_wrap));
496			if (ipa == NULL)
497				err(1, "host: calloc");
498			ipa->af = AF_UNSPEC;
499			ipa->netaddress = 1;
500			ipa->tail = ipa;
501			$$ = ipa;
502		}
503		| '{' host_list '}'		{ $$ = $2; }
504		;
505
506ids		: /* empty */			{
507			$$.srcid = NULL;
508			$$.dstid = NULL;
509		}
510		| SRCID id DSTID id		{
511			$$.srcid = $2;
512			$$.dstid = $4;
513		}
514		| SRCID id			{
515			$$.srcid = $2;
516			$$.dstid = NULL;
517		}
518		| DSTID id			{
519			$$.srcid = NULL;
520			$$.dstid = $2;
521		}
522		;
523
524type		: /* empty */			{
525			$$ = TYPE_REQUIRE;
526		}
527		| TYPE USE			{
528			$$ = TYPE_USE;
529		}
530		| TYPE ACQUIRE			{
531			$$ = TYPE_ACQUIRE;
532		}
533		| TYPE REQUIRE			{
534			$$ = TYPE_REQUIRE;
535		}
536		| TYPE DENY			{
537			$$ = TYPE_DENY;
538		}
539		| TYPE BYPASS			{
540			$$ = TYPE_BYPASS;
541		}
542		| TYPE DONTACQ			{
543			$$ = TYPE_DONTACQ;
544		}
545		;
546
547id		: STRING			{ $$ = $1; }
548		;
549
550spispec		: SPI STRING			{
551			u_int32_t	 spi;
552			char		*p = strchr($2, ':');
553
554			if (p != NULL) {
555				*p++ = 0;
556
557				if (atospi(p, &spi) == -1) {
558					yyerror("%s is not a valid spi", p);
559					free($2);
560					YYERROR;
561				}
562				$$.spiin = spi;
563			} else
564				$$.spiin = 0;
565
566			if (atospi($2, &spi) == -1) {
567				yyerror("%s is not a valid spi", $2);
568				free($2);
569				YYERROR;
570			}
571			$$.spiout = spi;
572
573
574			free($2);
575		}
576		;
577
578transforms	:					{
579			if ((ipsec_transforms = calloc(1,
580			    sizeof(struct ipsec_transforms))) == NULL)
581				err(1, "transforms: calloc");
582		}
583		    transforms_l
584			{ $$ = ipsec_transforms; }
585		| /* empty */				{
586			if (($$ = calloc(1,
587			    sizeof(struct ipsec_transforms))) == NULL)
588				err(1, "transforms: calloc");
589		}
590		;
591
592transforms_l	: transforms_l transform
593		| transform
594		;
595
596transform	: AUTHXF STRING			{
597			if (ipsec_transforms->authxf)
598				yyerror("auth already set");
599			else {
600				ipsec_transforms->authxf = parse_xf($2,
601				    authxfs);
602				if (!ipsec_transforms->authxf)
603					yyerror("%s not a valid transform", $2);
604			}
605		}
606		| ENCXF STRING			{
607			if (ipsec_transforms->encxf)
608				yyerror("enc already set");
609			else {
610				ipsec_transforms->encxf = parse_xf($2, encxfs);
611				if (!ipsec_transforms->encxf)
612					yyerror("%s not a valid transform", $2);
613			}
614		}
615		| COMPXF STRING			{
616			if (ipsec_transforms->compxf)
617				yyerror("comp already set");
618			else {
619				ipsec_transforms->compxf = parse_xf($2,
620				    compxfs);
621				if (!ipsec_transforms->compxf)
622					yyerror("%s not a valid transform", $2);
623			}
624		}
625		| GROUP STRING			{
626			if (ipsec_transforms->groupxf)
627				yyerror("group already set");
628			else {
629				ipsec_transforms->groupxf = parse_xf($2,
630				    groupxfs);
631				if (!ipsec_transforms->groupxf)
632					yyerror("%s not a valid transform", $2);
633			}
634		}
635		;
636
637phase1mode	: /* empty */	{
638			struct ike_mode		*p1;
639
640			/* We create just an empty main mode */
641			if ((p1 = calloc(1, sizeof(struct ike_mode))) == NULL)
642				err(1, "phase1mode: calloc");
643			p1->ike_exch = IKE_MM;
644			$$ = p1;
645		}
646		| MAIN transforms life		{
647			struct ike_mode	*p1;
648
649			if ((p1 = calloc(1, sizeof(struct ike_mode))) == NULL)
650				err(1, "phase1mode: calloc");
651			p1->xfs = $2;
652			p1->life = $3;
653			p1->ike_exch = IKE_MM;
654			$$ = p1;
655		}
656		| AGGRESSIVE transforms life		{
657			struct ike_mode	*p1;
658
659			if ((p1 = calloc(1, sizeof(struct ike_mode))) == NULL)
660				err(1, "phase1mode: calloc");
661			p1->xfs = $2;
662			p1->life = $3;
663			p1->ike_exch = IKE_AM;
664			$$ = p1;
665		}
666		;
667
668phase2mode	: /* empty */	{
669			struct ike_mode		*p2;
670
671			/* We create just an empty quick mode */
672			if ((p2 = calloc(1, sizeof(struct ike_mode))) == NULL)
673				err(1, "phase1mode: calloc");
674			p2->ike_exch = IKE_QM;
675			$$ = p2;
676		}
677		| QUICK transforms life		{
678			struct ike_mode	*p2;
679
680			if ((p2 = calloc(1, sizeof(struct ike_mode))) == NULL)
681				err(1, "phase1mode: calloc");
682			p2->xfs = $2;
683			p2->life = $3;
684			p2->ike_exch = IKE_QM;
685			$$ = p2;
686		}
687		;
688
689life		: /* empty */			{
690			struct ipsec_life *life;
691
692			/* We create just an empty transform */
693			if ((life = calloc(1, sizeof(struct ipsec_life)))
694			    == NULL)
695				err(1, "life: calloc");
696			life->lifetime = -1;
697			life->lifevolume = -1;
698			$$ = life;
699		}
700		| LIFE number			{
701			struct ipsec_life *life;
702
703			life = parse_life($2);
704			if (life == NULL)
705				yyerror("%s not a valid lifetime", $2);
706			$$ = life;
707		}
708		;
709
710authkeyspec	: /* empty */			{
711			$$.keyout = NULL;
712			$$.keyin = NULL;
713		}
714		| AUTHKEY keyspec		{
715			$$.keyout = $2.keyout;
716			$$.keyin = $2.keyin;
717		}
718		;
719
720enckeyspec	: /* empty */			{
721			$$.keyout = NULL;
722			$$.keyin = NULL;
723		}
724		| ENCKEY keyspec		{
725			$$.keyout = $2.keyout;
726			$$.keyin = $2.keyin;
727		}
728		;
729
730keyspec		: STRING			{
731			unsigned char	*hex;
732			unsigned char	*p = strchr($1, ':');
733
734			if (p != NULL ) {
735				*p++ = 0;
736
737				if (!strncmp(p, "0x", 2))
738					p += 2;
739				$$.keyin = parsekey(p, strlen(p));
740			} else
741				$$.keyin = NULL;
742
743			hex = $1;
744			if (!strncmp(hex, "0x", 2))
745				hex += 2;
746			$$.keyout = parsekey(hex, strlen(hex));
747
748			free($1);
749		}
750		| FILENAME STRING		{
751			unsigned char	*p = strchr($2, ':');
752
753			if (p != NULL) {
754				*p++ = 0;
755				$$.keyin = parsekeyfile(p);
756			}
757			$$.keyout = parsekeyfile($2);
758			free($2);
759		}
760		;
761
762ikemode		: /* empty */			{ $$ = IKE_ACTIVE; }
763		| PASSIVE			{ $$ = IKE_PASSIVE; }
764		| DYNAMIC			{ $$ = IKE_DYNAMIC; }
765		| ACTIVE			{ $$ = IKE_ACTIVE; }
766		;
767
768ikeauth		: /* empty */			{
769			$$.type = IKE_AUTH_RSA;
770			$$.string = NULL;
771		}
772		| RSA				{
773			$$.type = IKE_AUTH_RSA;
774			$$.string = NULL;
775		}
776		| PSK STRING			{
777			$$.type = IKE_AUTH_PSK;
778			if (($$.string = strdup($2)) == NULL)
779				err(1, "ikeauth: strdup");
780		}
781		;
782
783tag		: /* empty */
784		{
785			$$ = NULL;
786		}
787		| TAG STRING
788		{
789			$$ = $2;
790		}
791		;
792
793string		: string STRING
794		{
795			if (asprintf(&$$, "%s %s", $1, $2) == -1)
796				err(1, "string: asprintf");
797			free($1);
798			free($2);
799		}
800		| STRING
801		;
802
803varset		: STRING '=' string
804		{
805			if (ipsec->opts & IPSECCTL_OPT_VERBOSE)
806				printf("%s = \"%s\"\n", $1, $3);
807			if (symset($1, $3, 0) == -1)
808				err(1, "cannot store variable");
809			free($1);
810			free($3);
811		}
812		;
813
814%%
815
816struct keywords {
817	const char	*k_name;
818	int		 k_val;
819};
820
821int
822yyerror(const char *fmt, ...)
823{
824	va_list		 ap;
825	extern const char *infile;
826
827	errors = 1;
828	va_start(ap, fmt);
829	fprintf(stderr, "%s: %d: ", infile, yylval.lineno);
830	vfprintf(stderr, fmt, ap);
831	fprintf(stderr, "\n");
832	va_end(ap);
833	return (0);
834}
835
836int
837kw_cmp(const void *k, const void *e)
838{
839	return (strcmp(k, ((const struct keywords *)e)->k_name));
840}
841
842int
843lookup(char *s)
844{
845	/* this has to be sorted always */
846	static const struct keywords keywords[] = {
847		{ "acquire",		ACQUIRE },
848		{ "active",		ACTIVE },
849		{ "aggressive",		AGGRESSIVE },
850		{ "ah",			AH },
851		{ "any",		ANY },
852		{ "auth",		AUTHXF },
853		{ "authkey",		AUTHKEY },
854		{ "bypass",		BYPASS },
855		{ "comp",		COMPXF },
856		{ "deny",		DENY },
857		{ "dontacq",		DONTACQ },
858		{ "dstid",		DSTID },
859		{ "dynamic",		DYNAMIC },
860		{ "enc",		ENCXF },
861		{ "enckey",		ENCKEY },
862		{ "esp",		ESP },
863		{ "file",		FILENAME },
864		{ "flow",		FLOW },
865		{ "from",		FROM },
866		{ "group",		GROUP },
867		{ "ike",		IKE },
868		{ "in",			IN },
869		{ "ipcomp",		IPCOMP },
870		{ "ipip",		IPIP },
871		{ "life",		LIFE },
872		{ "local",		LOCAL },
873		{ "main",		MAIN },
874		{ "out",		OUT },
875		{ "passive",		PASSIVE },
876		{ "peer",		PEER },
877		{ "port",		PORT },
878		{ "proto",		PROTO },
879		{ "psk",		PSK },
880		{ "quick",		QUICK },
881		{ "require",		REQUIRE },
882		{ "rsa",		RSA },
883		{ "spi",		SPI },
884		{ "srcid",		SRCID },
885		{ "tag",		TAG },
886		{ "tcpmd5",		TCPMD5 },
887		{ "to",			TO },
888		{ "transport",		TRANSPORT },
889		{ "tunnel",		TUNNEL },
890		{ "type",		TYPE },
891		{ "use",		USE }
892	};
893	const struct keywords	*p;
894
895	p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
896	    sizeof(keywords[0]), kw_cmp);
897
898	if (p) {
899		if (debug > 1)
900			fprintf(stderr, "%s: %d\n", s, p->k_val);
901		return (p->k_val);
902	} else {
903		if (debug > 1)
904			fprintf(stderr, "string: %s\n", s);
905		return (STRING);
906	}
907}
908
909#define MAXPUSHBACK	128
910
911char	*parsebuf;
912int	 parseindex;
913char	 pushback_buffer[MAXPUSHBACK];
914int	 pushback_index = 0;
915
916int
917lgetc(FILE *f)
918{
919	int	c, next;
920
921	if (parsebuf) {
922		/* Read character from the parsebuffer instead of input. */
923		if (parseindex >= 0) {
924			c = parsebuf[parseindex++];
925			if (c != '\0')
926				return (c);
927			parsebuf = NULL;
928		} else
929			parseindex++;
930	}
931
932	if (pushback_index)
933		return (pushback_buffer[--pushback_index]);
934
935	while ((c = getc(f)) == '\\') {
936		next = getc(f);
937		if (next != '\n') {
938			c = next;
939			break;
940		}
941		yylval.lineno = lineno;
942		lineno++;
943	}
944	if (c == '\t' || c == ' ') {
945		/* Compress blanks to a single space. */
946		do {
947			c = getc(f);
948		} while (c == '\t' || c == ' ');
949		ungetc(c, f);
950		c = ' ';
951	}
952
953	return (c);
954}
955
956int
957lungetc(int c)
958{
959	if (c == EOF)
960		return (EOF);
961	if (parsebuf) {
962		parseindex--;
963		if (parseindex >= 0)
964			return (c);
965	}
966	if (pushback_index < MAXPUSHBACK-1)
967		return (pushback_buffer[pushback_index++] = c);
968	else
969		return (EOF);
970}
971
972int
973findeol(void)
974{
975	int	c;
976
977	parsebuf = NULL;
978	pushback_index = 0;
979
980	/* skip to either EOF or the first real EOL */
981	while (1) {
982		c = lgetc(fin);
983		if (c == '\n') {
984			lineno++;
985			break;
986		}
987		if (c == EOF)
988			break;
989	}
990	return (ERROR);
991}
992
993int
994yylex(void)
995{
996	char	 buf[8096];
997	char	*p, *val;
998	int	 endc, c;
999	int	 token;
1000
1001top:
1002	p = buf;
1003	while ((c = lgetc(fin)) == ' ')
1004		; /* nothing */
1005
1006	yylval.lineno = lineno;
1007	if (c == '#')
1008		while ((c = lgetc(fin)) != '\n' && c != EOF)
1009			; /* nothing */
1010	if (c == '$' && parsebuf == NULL) {
1011		while (1) {
1012			if ((c = lgetc(fin)) == EOF)
1013				return (0);
1014
1015			if (p + 1 >= buf + sizeof(buf) - 1) {
1016				yyerror("string too long");
1017				return (findeol());
1018			}
1019			if (isalnum(c) || c == '_') {
1020				*p++ = (char)c;
1021				continue;
1022			}
1023			*p = '\0';
1024			lungetc(c);
1025			break;
1026		}
1027		val = symget(buf);
1028		if (val == NULL) {
1029			yyerror("macro \"%s\" not defined", buf);
1030			return (findeol());
1031		}
1032		parsebuf = val;
1033		parseindex = 0;
1034		goto top;
1035	}
1036
1037	switch (c) {
1038	case '\'':
1039	case '"':
1040		endc = c;
1041		while (1) {
1042			if ((c = lgetc(fin)) == EOF)
1043				return (0);
1044			if (c == endc) {
1045				*p = '\0';
1046				break;
1047			}
1048			if (c == '\n') {
1049				lineno++;
1050				continue;
1051			}
1052			if (p + 1 >= buf + sizeof(buf) - 1) {
1053				yyerror("string too long");
1054				return (findeol());
1055			}
1056			*p++ = (char)c;
1057		}
1058		yylval.v.string = strdup(buf);
1059		if (yylval.v.string == NULL)
1060			err(1, "yylex: strdup");
1061		return (STRING);
1062	}
1063
1064#define allowed_in_string(x) \
1065	(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
1066	x != '{' && x != '}' && x != '<' && x != '>' && \
1067	x != '!' && x != '=' && x != '/' && x != '#' && \
1068	x != ','))
1069
1070	if (isalnum(c) || c == ':' || c == '_' || c == '*') {
1071		do {
1072			*p++ = c;
1073			if ((unsigned)(p-buf) >= sizeof(buf)) {
1074				yyerror("string too long");
1075				return (findeol());
1076			}
1077		} while ((c = lgetc(fin)) != EOF && (allowed_in_string(c)));
1078		lungetc(c);
1079		*p = '\0';
1080		if ((token = lookup(buf)) == STRING)
1081			if ((yylval.v.string = strdup(buf)) == NULL)
1082				err(1, "yylex: strdup");
1083		return (token);
1084	}
1085	if (c == '\n') {
1086		yylval.lineno = lineno;
1087		lineno++;
1088	}
1089	if (c == EOF)
1090		return (0);
1091	return (c);
1092}
1093
1094int
1095parse_rules(FILE *input, struct ipsecctl *ipsecx)
1096{
1097	struct sym	*sym;
1098
1099	ipsec = ipsecx;
1100	fin = input;
1101	lineno = 1;
1102	errors = 0;
1103
1104	yyparse();
1105
1106	/* Free macros and check which have not been used. */
1107	while ((sym = TAILQ_FIRST(&symhead))) {
1108		if ((ipsec->opts & IPSECCTL_OPT_VERBOSE2) && !sym->used)
1109			fprintf(stderr, "warning: macro '%s' not "
1110			    "used\n", sym->nam);
1111		TAILQ_REMOVE(&symhead, sym, entries);
1112		free(sym->nam);
1113		free(sym->val);
1114		free(sym);
1115	}
1116
1117	return (errors ? -1 : 0);
1118}
1119
1120int
1121symset(const char *nam, const char *val, int persist)
1122{
1123	struct sym	*sym;
1124
1125	for (sym = TAILQ_FIRST(&symhead); sym && strcmp(nam, sym->nam);
1126	    sym = TAILQ_NEXT(sym, entries))
1127		;	/* nothing */
1128
1129	if (sym != NULL) {
1130		if (sym->persist == 1)
1131			return (0);
1132		else {
1133			TAILQ_REMOVE(&symhead, sym, entries);
1134			free(sym->nam);
1135			free(sym->val);
1136			free(sym);
1137		}
1138	}
1139	if ((sym = calloc(1, sizeof(*sym))) == NULL)
1140		return (-1);
1141
1142	sym->nam = strdup(nam);
1143	if (sym->nam == NULL) {
1144		free(sym);
1145		return (-1);
1146	}
1147	sym->val = strdup(val);
1148	if (sym->val == NULL) {
1149		free(sym->nam);
1150		free(sym);
1151		return (-1);
1152	}
1153	sym->used = 0;
1154	sym->persist = persist;
1155	TAILQ_INSERT_TAIL(&symhead, sym, entries);
1156	return (0);
1157}
1158
1159int
1160cmdline_symset(char *s)
1161{
1162	char	*sym, *val;
1163	int	ret;
1164	size_t	len;
1165
1166	if ((val = strrchr(s, '=')) == NULL)
1167		return (-1);
1168
1169	len = strlen(s) - strlen(val) + 1;
1170	if ((sym = malloc(len)) == NULL)
1171		err(1, "cmdline_symset: malloc");
1172
1173	strlcpy(sym, s, len);
1174
1175	ret = symset(sym, val + 1, 1);
1176	free(sym);
1177
1178	return (ret);
1179}
1180
1181char *
1182symget(const char *nam)
1183{
1184	struct sym	*sym;
1185
1186	TAILQ_FOREACH(sym, &symhead, entries)
1187		if (strcmp(nam, sym->nam) == 0) {
1188			sym->used = 1;
1189			return (sym->val);
1190		}
1191	return (NULL);
1192}
1193
1194int
1195atoul(char *s, u_long *ulvalp)
1196{
1197	u_long	 ulval;
1198	char	*ep;
1199
1200	errno = 0;
1201	ulval = strtoul(s, &ep, 0);
1202	if (s[0] == '\0' || *ep != '\0')
1203		return (-1);
1204	if (errno == ERANGE && ulval == ULONG_MAX)
1205		return (-1);
1206	*ulvalp = ulval;
1207	return (0);
1208}
1209
1210int
1211atospi(char *s, u_int32_t *spivalp)
1212{
1213	unsigned long	ulval;
1214
1215	if (atoul(s, &ulval) == -1)
1216		return (-1);
1217	if (ulval >= SPI_RESERVED_MIN && ulval <= SPI_RESERVED_MAX) {
1218		yyerror("illegal SPI value");
1219		return (-1);
1220	}
1221	*spivalp = ulval;
1222	return (0);
1223}
1224
1225u_int8_t
1226x2i(unsigned char *s)
1227{
1228	char	ss[3];
1229
1230	ss[0] = s[0];
1231	ss[1] = s[1];
1232	ss[2] = 0;
1233
1234	if (!isxdigit(s[0]) || !isxdigit(s[1])) {
1235		yyerror("keys need to be specified in hex digits");
1236		return (-1);
1237	}
1238	return ((u_int8_t)strtoul(ss, NULL, 16));
1239}
1240
1241struct ipsec_key *
1242parsekey(unsigned char *hexkey, size_t len)
1243{
1244	struct ipsec_key *key;
1245	int		  i;
1246
1247	key = calloc(1, sizeof(struct ipsec_key));
1248	if (key == NULL)
1249		err(1, "parsekey: calloc");
1250
1251	key->len = len / 2;
1252	key->data = calloc(key->len, sizeof(u_int8_t));
1253	if (key->data == NULL)
1254		err(1, "parsekey: calloc");
1255
1256	for (i = 0; i < (int)key->len; i++)
1257		key->data[i] = x2i(hexkey + 2 * i);
1258
1259	return (key);
1260}
1261
1262struct ipsec_key *
1263parsekeyfile(char *filename)
1264{
1265	struct stat	 sb;
1266	int		 fd;
1267	unsigned char	*hex;
1268
1269	if ((fd = open(filename, O_RDONLY)) < 0)
1270		err(1, "open %s", filename);
1271	if (fstat(fd, &sb) < 0)
1272		err(1, "parsekeyfile: stat %s", filename);
1273	if ((sb.st_size > KEYSIZE_LIMIT) || (sb.st_size == 0))
1274		errx(1, "%s: key too %s", filename, sb.st_size ? "large" :
1275		    "small");
1276	if ((hex = calloc(sb.st_size, sizeof(unsigned char))) == NULL)
1277		err(1, "parsekeyfile: calloc");
1278	if (read(fd, hex, sb.st_size) < sb.st_size)
1279		err(1, "parsekeyfile: read");
1280	close(fd);
1281	return (parsekey(hex, sb.st_size));
1282}
1283
1284int
1285get_id_type(char *string)
1286{
1287	if (string && strchr(string, '@'))
1288		return (ID_UFQDN);
1289	return (ID_FQDN);
1290}
1291
1292struct ipsec_addr_wrap *
1293host(const char *s)
1294{
1295	struct ipsec_addr_wrap	*ipa = NULL;
1296	int			 mask, cont = 1;
1297	char			*p, *q, *ps;
1298
1299	if ((p = strrchr(s, '/')) != NULL) {
1300		errno = 0;
1301		mask = strtol(p + 1, &q, 0);
1302		if (errno == ERANGE || !q || *q || mask > 128 || q == (p + 1))
1303			errx(1, "host: invalid netmask '%s'", p);
1304		if ((ps = malloc(strlen(s) - strlen(p) + 1)) == NULL)
1305			err(1, "host: calloc");
1306		strlcpy(ps, s, strlen(s) - strlen(p) + 1);
1307	} else {
1308		if ((ps = strdup(s)) == NULL)
1309			err(1, "host: strdup");
1310		mask = -1;
1311	}
1312
1313	/* Does interface with this name exist? */
1314	if (cont && (ipa = host_if(ps, mask)) != NULL)
1315		cont = 0;
1316
1317	/* IPv4 address? */
1318	if (cont && (ipa = host_v4(s, mask == -1 ? 32 : mask)) != NULL)
1319		cont = 0;
1320
1321	/* IPv6 address? */
1322	if (cont && (ipa = host_v6(ps, mask == -1 ? 128 : mask)) != NULL)
1323		cont = 0;
1324
1325	/* dns lookup */
1326	if (cont && mask == -1 && (ipa = host_dns(s, mask)) != NULL)
1327		cont = 0;
1328	free(ps);
1329
1330	if (ipa == NULL || cont == 1) {
1331		fprintf(stderr, "no IP address found for %s\n", s);
1332		return (NULL);
1333	}
1334	return (ipa);
1335}
1336
1337struct ipsec_addr_wrap *
1338host_v6(const char *s, int prefixlen)
1339{
1340	struct ipsec_addr_wrap	*ipa = NULL;
1341	struct addrinfo		 hints, *res;
1342	char			 hbuf[NI_MAXHOST];
1343
1344	bzero(&hints, sizeof(struct addrinfo));
1345	hints.ai_family = AF_INET6;
1346	hints.ai_socktype = SOCK_STREAM;
1347	hints.ai_flags = AI_NUMERICHOST;
1348	if (getaddrinfo(s, NULL, &hints, &res))
1349		return (NULL);
1350	if (res->ai_next)
1351		err(1, "host_v6: numeric hostname expanded to multiple item");
1352
1353	ipa = calloc(1, sizeof(struct ipsec_addr_wrap));
1354	if (ipa == NULL)
1355		err(1, "host_v6: calloc");
1356	ipa->af = res->ai_family;
1357	memcpy(&ipa->address.v6,
1358	    &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
1359	    sizeof(struct in6_addr));
1360	if (prefixlen > 128)
1361		prefixlen = 128;
1362	ipa->next = NULL;
1363	ipa->tail = ipa;
1364
1365	set_ipmask(ipa, prefixlen);
1366	if (getnameinfo(res->ai_addr, res->ai_addrlen,
1367	    hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST)) {
1368		errx(1, "could not get a numeric hostname");
1369	}
1370
1371	if (prefixlen != 128) {
1372		ipa->netaddress = 1;
1373		asprintf(&ipa->name, "%s/%d", hbuf, prefixlen);
1374	} else
1375		ipa->name = strdup(hbuf);
1376	if (ipa->name == NULL)
1377		err(1, "host_v6: strdup");
1378
1379	freeaddrinfo(res);
1380
1381	return (ipa);
1382}
1383
1384struct ipsec_addr_wrap *
1385host_v4(const char *s, int mask)
1386{
1387	struct ipsec_addr_wrap	*ipa = NULL;
1388	struct in_addr		 ina;
1389	int			 bits = 32;
1390
1391	bzero(&ina, sizeof(struct in_addr));
1392	if (strrchr(s, '/') != NULL) {
1393		if ((bits = inet_net_pton(AF_INET, s, &ina, sizeof(ina))) == -1)
1394			return (NULL);
1395	} else {
1396		if (inet_pton(AF_INET, s, &ina) != 1)
1397			return (NULL);
1398	}
1399
1400	ipa = calloc(1, sizeof(struct ipsec_addr_wrap));
1401	if (ipa == NULL)
1402		err(1, "host_v4: calloc");
1403
1404	ipa->address.v4 = ina;
1405	ipa->name = strdup(s);
1406	if (ipa->name == NULL)
1407		err(1, "host_v4: strdup");
1408	ipa->af = AF_INET;
1409	ipa->next = NULL;
1410	ipa->tail = ipa;
1411
1412	set_ipmask(ipa, bits);
1413	if (bits != (ipa->af == AF_INET ? 32 : 128))
1414		ipa->netaddress = 1;
1415
1416	return (ipa);
1417}
1418
1419struct ipsec_addr_wrap *
1420host_dns(const char *s, int mask)
1421{
1422	struct ipsec_addr_wrap	*ipa = NULL;
1423	struct addrinfo		 hints, *res0, *res;
1424	int			 error;
1425	char			 hbuf[NI_MAXHOST];
1426
1427	bzero(&hints, sizeof(struct addrinfo));
1428	hints.ai_family = PF_UNSPEC;
1429	hints.ai_socktype = SOCK_STREAM;
1430	error = getaddrinfo(s, NULL, &hints, &res0);
1431	if (error)
1432		return (NULL);
1433
1434	for (res = res0; res; res = res->ai_next) {
1435		if (res->ai_family != AF_INET && res->ai_family != AF_INET6)
1436			continue;
1437
1438		ipa = calloc(1, sizeof(struct ipsec_addr_wrap));
1439		if (ipa == NULL)
1440			err(1, "host_dns: calloc");
1441		switch (res->ai_family) {
1442		case AF_INET:
1443			memcpy(&ipa->address.v4,
1444			    &((struct sockaddr_in *)res->ai_addr)->sin_addr,
1445			    sizeof(struct in_addr));
1446			break;
1447		case AF_INET6:
1448			/* XXX we do not support scoped IPv6 address yet */
1449			if (((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id) {
1450				free(ipa);
1451				continue;
1452			}
1453			memcpy(&ipa->address.v6,
1454			    &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
1455			    sizeof(struct in6_addr));
1456			break;
1457		}
1458		error = getnameinfo(res->ai_addr, res->ai_addrlen, hbuf,
1459		    sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
1460		if (error)
1461			err(1, "host_dns: getnameinfo");
1462		ipa->name = strdup(hbuf);
1463		if (ipa->name == NULL)
1464			err(1, "host_dns: strdup");
1465		ipa->af = res->ai_family;
1466		ipa->next = NULL;
1467		ipa->tail = ipa;
1468
1469		/*
1470		 * XXX for now, no netmask support for IPv6.
1471		 * but since there's no way to specify address family, once you
1472		 * have IPv6 address on a host, you cannot use dns/netmask
1473		 * syntax.
1474		 */
1475		if (ipa->af == AF_INET)
1476			set_ipmask(ipa, mask == -1 ? 32 : mask);
1477		else
1478			if (mask != -1)
1479				err(1, "host_dns: cannot apply netmask "
1480				    "on non-IPv4 address");
1481		break;
1482	}
1483	freeaddrinfo(res0);
1484
1485	return (ipa);
1486}
1487
1488struct ipsec_addr_wrap *
1489host_if(const char *s, int mask)
1490{
1491	struct ipsec_addr_wrap *ipa = NULL;
1492
1493	if (ifa_exists(s))
1494		ipa = ifa_lookup(s);
1495
1496	return (ipa);
1497}
1498
1499/* interface lookup routintes */
1500
1501struct ipsec_addr_wrap	*iftab;
1502
1503void
1504ifa_load(void)
1505{
1506	struct ifaddrs		*ifap, *ifa;
1507	struct ipsec_addr_wrap	*n = NULL, *h = NULL;
1508
1509	if (getifaddrs(&ifap) < 0)
1510		err(1, "ifa_load: getifaddrs");
1511
1512	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
1513		if (!(ifa->ifa_addr->sa_family == AF_INET ||
1514		    ifa->ifa_addr->sa_family == AF_INET6 ||
1515		    ifa->ifa_addr->sa_family == AF_LINK))
1516			continue;
1517		n = calloc(1, sizeof(struct ipsec_addr_wrap));
1518		if (n == NULL)
1519			err(1, "ifa_load: calloc");
1520		n->af = ifa->ifa_addr->sa_family;
1521		if ((n->name = strdup(ifa->ifa_name)) == NULL)
1522			err(1, "ifa_load: strdup");
1523		if (n->af == AF_INET) {
1524			n->af = AF_INET;
1525			memcpy(&n->address.v4, &((struct sockaddr_in *)
1526			    ifa->ifa_addr)->sin_addr,
1527			    sizeof(struct in_addr));
1528			memcpy(&n->mask.v4, &((struct sockaddr_in *)
1529			    ifa->ifa_netmask)->sin_addr,
1530			    sizeof(struct in_addr));
1531		} else if (n->af == AF_INET6) {
1532			n->af = AF_INET6;
1533			memcpy(&n->address.v6, &((struct sockaddr_in6 *)
1534			    ifa->ifa_addr)->sin6_addr,
1535			    sizeof(struct in6_addr));
1536			memcpy(&n->mask.v6, &((struct sockaddr_in6 *)
1537			    ifa->ifa_netmask)->sin6_addr,
1538			    sizeof(struct in6_addr));
1539		}
1540		n->next = NULL;
1541		n->tail = n;
1542		if (h == NULL)
1543			h = n;
1544		else {
1545			h->tail->next = n;
1546			h->tail = n;
1547		}
1548	}
1549
1550	iftab = h;
1551	freeifaddrs(ifap);
1552}
1553
1554int
1555ifa_exists(const char *ifa_name)
1556{
1557	struct ipsec_addr_wrap	*n;
1558	struct ifgroupreq	 ifgr;
1559	int			 s;
1560
1561	if (iftab == NULL)
1562		ifa_load();
1563
1564	/* check wether this is a group */
1565	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
1566		err(1, "ifa_exists: socket");
1567	bzero(&ifgr, sizeof(ifgr));
1568	strlcpy(ifgr.ifgr_name, ifa_name, sizeof(ifgr.ifgr_name));
1569	if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == 0) {
1570		close(s);
1571		return (1);
1572	}
1573	close(s);
1574
1575	for (n = iftab; n; n = n->next) {
1576		if (n->af == AF_LINK && !strncmp(n->name, ifa_name,
1577		    IFNAMSIZ))
1578			return (1);
1579	}
1580
1581	return (0);
1582}
1583
1584struct ipsec_addr_wrap *
1585ifa_grouplookup(const char *ifa_name)
1586{
1587	struct ifg_req		*ifg;
1588	struct ifgroupreq	 ifgr;
1589	int			 s;
1590	size_t			 len;
1591	struct ipsec_addr_wrap	*n, *h = NULL, *hn;
1592
1593	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
1594		err(1, "socket");
1595	bzero(&ifgr, sizeof(ifgr));
1596	strlcpy(ifgr.ifgr_name, ifa_name, sizeof(ifgr.ifgr_name));
1597	if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) {
1598		close(s);
1599		return (NULL);
1600	}
1601
1602	len = ifgr.ifgr_len;
1603	if ((ifgr.ifgr_groups = calloc(1, len)) == NULL)
1604		err(1, "calloc");
1605	if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1)
1606		err(1, "ioctl");
1607
1608	for (ifg = ifgr.ifgr_groups; ifg && len >= sizeof(struct ifg_req);
1609	    ifg++) {
1610		len -= sizeof(struct ifg_req);
1611		if ((n = ifa_lookup(ifg->ifgrq_member)) == NULL)
1612			continue;
1613		if (h == NULL)
1614			h = n;
1615		else {
1616			for (hn = h; hn->next != NULL; hn = hn->next)
1617				;	/* nothing */
1618			hn->next = n;
1619			n->tail = hn;
1620		}
1621	}
1622	free(ifgr.ifgr_groups);
1623	close(s);
1624
1625	return (h);
1626}
1627
1628struct ipsec_addr_wrap *
1629ifa_lookup(const char *ifa_name)
1630{
1631	struct ipsec_addr_wrap	*p = NULL, *h = NULL, *n = NULL;
1632
1633	if (iftab == NULL)
1634		ifa_load();
1635
1636	if ((n = ifa_grouplookup(ifa_name)) != NULL)
1637		return (n);
1638
1639	for (p = iftab; p; p = p->next) {
1640		if (p->af != AF_INET && p->af != AF_INET6)
1641			continue;
1642		if (strncmp(p->name, ifa_name, IFNAMSIZ))
1643			continue;
1644		n = calloc(1, sizeof(struct ipsec_addr_wrap));
1645		if (n == NULL)
1646			err(1, "ifa_lookup: calloc");
1647		memcpy(n, p, sizeof(struct ipsec_addr_wrap));
1648		if ((n->name = strdup(p->name)) == NULL)
1649			err(1, "ifa_lookup: strdup");
1650		switch (n->af) {
1651		case AF_INET:
1652			set_ipmask(n, 32);
1653			break;
1654		case AF_INET6:
1655			/* route/show.c and bgpd/util.c give KAME credit */
1656			if (IN6_IS_ADDR_LINKLOCAL(&n->address.v6)) {
1657				u_int16_t tmp16;
1658				/* for now we can not handle link local,
1659				 * therefore bail for now
1660				 */
1661				free(n);
1662				continue;
1663
1664				memcpy(&tmp16, &n->address.v6.s6_addr[2],
1665				    sizeof(tmp16));
1666				/* use this when we support link-local
1667				 * n->??.scopeid = ntohs(tmp16);
1668				 */
1669				n->address.v6.s6_addr[2] = 0;
1670				n->address.v6.s6_addr[3] = 0;
1671			}
1672			set_ipmask(n, 128);
1673			break;
1674		}
1675
1676		n->next = NULL;
1677		n->tail = n;
1678		if (h == NULL)
1679			h = n;
1680		else {
1681			h->tail->next = n;
1682			h->tail = n;
1683		}
1684	}
1685
1686	return (h);
1687}
1688
1689void
1690set_ipmask(struct ipsec_addr_wrap *address, u_int8_t b)
1691{
1692	struct ipsec_addr	*ipa;
1693	int			 i, j = 0;
1694
1695	ipa = &address->mask;
1696	bzero(ipa, sizeof(struct ipsec_addr));
1697
1698	while (b >= 32) {
1699		ipa->addr32[j++] = 0xffffffff;
1700		b -= 32;
1701	}
1702	for (i = 31; i > 31 - b; --i)
1703		ipa->addr32[j] |= (1 << i);
1704	if (b)
1705		ipa->addr32[j] = htonl(ipa->addr32[j]);
1706}
1707
1708const struct ipsec_xf *
1709parse_xf(const char *name, const struct ipsec_xf xfs[])
1710{
1711	int		i;
1712
1713	for (i = 0; xfs[i].name != NULL; i++) {
1714		if (strncmp(name, xfs[i].name, strlen(name)))
1715			continue;
1716		return &xfs[i];
1717	}
1718	return (NULL);
1719}
1720
1721struct ipsec_life *
1722parse_life(int value)
1723{
1724	struct ipsec_life	*life;
1725
1726	life = calloc(1, sizeof(struct ipsec_life));
1727	if (life == NULL)
1728		err(1, "calloc");
1729
1730	life->lifetime = value;
1731
1732	return (life);
1733}
1734
1735struct ipsec_transforms *
1736copytransforms(const struct ipsec_transforms *xfs)
1737{
1738	struct ipsec_transforms *newxfs;
1739
1740	if (xfs == NULL)
1741		return (NULL);
1742
1743	newxfs = calloc(1, sizeof(struct ipsec_transforms));
1744	if (newxfs == NULL)
1745		err(1, "copytransforms: calloc");
1746
1747	memcpy(newxfs, xfs, sizeof(struct ipsec_transforms));
1748	return (newxfs);
1749}
1750
1751struct ipsec_life *
1752copylife(const struct ipsec_life *life)
1753{
1754	struct ipsec_life *newlife;
1755
1756	if (life == NULL)
1757		return (NULL);
1758
1759	newlife = calloc(1, sizeof(struct ipsec_life));
1760	if (newlife == NULL)
1761		err(1, "copylife: calloc");
1762
1763	memcpy(newlife, life, sizeof(struct ipsec_life));
1764	return (newlife);
1765}
1766
1767struct ipsec_auth *
1768copyipsecauth(const struct ipsec_auth *auth)
1769{
1770	struct ipsec_auth	*newauth;
1771
1772	if (auth == NULL)
1773		return (NULL);
1774
1775	if ((newauth = calloc(1, sizeof(struct ipsec_auth))) == NULL)
1776		err(1, "calloc");
1777	if (auth->srcid &&
1778	    asprintf(&newauth->srcid, "%s", auth->srcid) == -1)
1779		err(1, "asprintf");
1780	if (auth->dstid &&
1781	    asprintf(&newauth->dstid, "%s", auth->dstid) == -1)
1782		err(1, "asprintf");
1783
1784	newauth->srcid_type = auth->srcid_type;
1785	newauth->dstid_type = auth->dstid_type;
1786	newauth->type = auth->type;
1787
1788	return (newauth);
1789}
1790
1791struct ike_auth *
1792copyikeauth(const struct ike_auth *auth)
1793{
1794	struct ike_auth	*newauth;
1795
1796	if (auth == NULL)
1797		return (NULL);
1798
1799	if ((newauth = calloc(1, sizeof(struct ike_auth))) == NULL)
1800		err(1, "calloc");
1801	if (auth->string &&
1802	    asprintf(&newauth->string, "%s", auth->string) == -1)
1803		err(1, "asprintf");
1804
1805	newauth->type = auth->type;
1806
1807	return (newauth);
1808}
1809
1810struct ipsec_key *
1811copykey(struct ipsec_key *key)
1812{
1813	struct ipsec_key	*newkey;
1814
1815	if (key == NULL)
1816		return (NULL);
1817
1818	if ((newkey = calloc(1, sizeof(struct ipsec_key))) == NULL)
1819		err(1, "calloc");
1820	if ((newkey->data = calloc(key->len, sizeof(u_int8_t))) == NULL)
1821		err(1, "calloc");
1822	memcpy(newkey->data, key->data, key->len);
1823	newkey->len = key->len;
1824
1825	return (newkey);
1826}
1827
1828struct ipsec_addr_wrap *
1829copyhost(const struct ipsec_addr_wrap *src)
1830{
1831	struct ipsec_addr_wrap *dst;
1832
1833	if (src == NULL)
1834		return (NULL);
1835
1836	dst = calloc(1, sizeof(struct ipsec_addr_wrap));
1837	if (dst == NULL)
1838		err(1, "copyhost: calloc");
1839
1840	memcpy(dst, src, sizeof(struct ipsec_addr_wrap));
1841
1842	if (src->name != NULL && (dst->name = strdup(src->name)) == NULL)
1843		err(1, "copyhost: strdup");
1844
1845	return dst;
1846}
1847
1848char *
1849copytag(const char *src)
1850{
1851	char *tag;
1852
1853	if (src == NULL)
1854		return (NULL);
1855	if ((tag = strdup(src)) == NULL)
1856		err(1, "copytag: strdup");
1857
1858	return (tag);
1859}
1860
1861struct ipsec_rule *
1862copyrule(struct ipsec_rule *rule)
1863{
1864	struct ipsec_rule	*r;
1865
1866	if ((r = calloc(1, sizeof(struct ipsec_rule))) == NULL)
1867		err(1, "calloc");
1868
1869	r->src = copyhost(rule->src);
1870	r->dst = copyhost(rule->dst);
1871	r->local = copyhost(rule->local);
1872	r->peer = copyhost(rule->peer);
1873	r->auth = copyipsecauth(rule->auth);
1874	r->ikeauth = copyikeauth(rule->ikeauth);
1875	r->xfs = copytransforms(rule->xfs);
1876	r->p1xfs = copytransforms(rule->p1xfs);
1877	r->p2xfs = copytransforms(rule->p2xfs);
1878	r->p1life = copylife(rule->p1life);
1879	r->p2life = copylife(rule->p2life);
1880	r->authkey = copykey(rule->authkey);
1881	r->enckey = copykey(rule->enckey);
1882	r->tag = copytag(rule->tag);
1883
1884	r->p1ie = rule->p1ie;
1885	r->p2ie = rule->p2ie;
1886	r->type = rule->type;
1887	r->satype = rule->satype;
1888	r->proto = rule->proto;
1889	r->tmode = rule->tmode;
1890	r->direction = rule->direction;
1891	r->flowtype = rule->flowtype;
1892	r->sport = rule->sport;
1893	r->dport = rule->dport;
1894	r->ikemode = rule->ikemode;
1895	r->spi = rule->spi;
1896	r->nr = rule->nr;
1897
1898	return (r);
1899}
1900
1901int
1902validate_af(struct ipsec_addr_wrap *src, struct ipsec_addr_wrap *dst)
1903{
1904	struct ipsec_addr_wrap *ta;
1905	u_int8_t src_v4 = 0;
1906	u_int8_t dst_v4 = 0;
1907	u_int8_t src_v6 = 0;
1908	u_int8_t dst_v6 = 0;
1909
1910	for (ta = src; ta; ta = ta->next) {
1911		if (ta->af == AF_INET)
1912			src_v4 = 1;
1913		if (ta->af == AF_INET6)
1914			src_v6 = 1;
1915		if (ta->af == AF_UNSPEC)
1916			return 0;
1917		if (src_v4 && src_v6)
1918			break;
1919	}
1920	for (ta = dst; ta; ta = ta->next) {
1921		if (ta->af == AF_INET)
1922			dst_v4 = 1;
1923		if (ta->af == AF_INET6)
1924			dst_v6 = 1;
1925		if (ta->af == AF_UNSPEC)
1926			return 0;
1927		if (dst_v4 && dst_v6)
1928			break;
1929	}
1930	if (src_v4 != dst_v4 && src_v6 != dst_v6)
1931		return (1);
1932
1933	return (0);
1934}
1935
1936
1937int
1938validate_sa(u_int32_t spi, u_int8_t satype, struct ipsec_transforms *xfs,
1939    struct ipsec_key *authkey, struct ipsec_key *enckey, u_int8_t tmode)
1940{
1941	/* Sanity checks */
1942	if (spi == 0) {
1943		yyerror("no SPI specified");
1944		return (0);
1945	}
1946	if (satype == IPSEC_AH) {
1947		if (!xfs) {
1948			yyerror("no transforms specified");
1949			return (0);
1950		}
1951		if (!xfs->authxf)
1952			xfs->authxf = &authxfs[AUTHXF_HMAC_SHA2_256];
1953		if (xfs->encxf) {
1954			yyerror("ah does not provide encryption");
1955			return (0);
1956		}
1957		if (xfs->compxf) {
1958			yyerror("ah does not provide compression");
1959			return (0);
1960		}
1961	}
1962	if (satype == IPSEC_ESP) {
1963		if (!xfs) {
1964			yyerror("no transforms specified");
1965			return (0);
1966		}
1967		if (xfs->compxf) {
1968			yyerror("esp does not provide compression");
1969			return (0);
1970		}
1971		if (!xfs->authxf)
1972			xfs->authxf = &authxfs[AUTHXF_HMAC_SHA2_256];
1973		if (!xfs->encxf)
1974			xfs->encxf = &encxfs[ENCXF_AES];
1975	}
1976	if (satype == IPSEC_IPCOMP) {
1977		if (!xfs) {
1978			yyerror("no transform specified");
1979			return (0);
1980		}
1981		if (xfs->authxf || xfs->encxf) {
1982			yyerror("no encryption or authentication with ipcomp");
1983			return (0);
1984		}
1985		if (!xfs->compxf)
1986			xfs->compxf = &compxfs[COMPXF_DEFLATE];
1987	}
1988	if (satype == IPSEC_IPIP) {
1989		if (!xfs) {
1990			yyerror("no transform specified");
1991			return (0);
1992		}
1993		if (xfs->authxf || xfs->encxf || xfs->compxf) {
1994			yyerror("no encryption, authentication or compression"
1995			    " with ipip");
1996			return (0);
1997		}
1998	}
1999	if (satype == IPSEC_TCPMD5 && authkey == NULL && tmode !=
2000	    IPSEC_TRANSPORT) {
2001		yyerror("authentication key needed for tcpmd5");
2002		return (0);
2003	}
2004	if (xfs && xfs->authxf) {
2005		if (!authkey && xfs->authxf != &authxfs[AUTHXF_NONE]) {
2006			yyerror("no authentication key specified");
2007			return (0);
2008		}
2009		if (authkey && authkey->len != xfs->authxf->keymin) {
2010			yyerror("wrong authentication key length, needs to be "
2011			    "%d bits", xfs->authxf->keymin * 8);
2012			return (0);
2013		}
2014	}
2015	if (xfs && xfs->encxf) {
2016		if (!enckey && xfs->encxf != &encxfs[ENCXF_NULL]) {
2017			yyerror("no encryption key specified");
2018			return (0);
2019		}
2020		if (enckey) {
2021			if (enckey->len < xfs->encxf->keymin) {
2022				yyerror("encryption key too short (%d bits), "
2023				    "minimum %d bits", enckey->len * 8,
2024				    xfs->encxf->keymin * 8);
2025				return (0);
2026			}
2027			if (xfs->encxf->keymax < enckey->len) {
2028				yyerror("encryption key too long (%d bits), "
2029				    "maximum %d bits", enckey->len * 8,
2030				    xfs->encxf->keymax * 8);
2031				return (0);
2032			}
2033		}
2034	}
2035
2036	return 1;
2037}
2038
2039int
2040add_sagroup(struct ipsec_rule *r)
2041{
2042	struct ipsec_rule	*rp, *last, *group;
2043	int			 found = 0;
2044
2045	TAILQ_FOREACH(rp, &ipsec->group_queue, group_entry) {
2046		if ((strcmp(rp->src->name, r->src->name) == 0) &&
2047		    (strcmp(rp->dst->name, r->dst->name) == 0)) {
2048			found = 1;
2049			break;
2050		}
2051	}
2052	if (found) {
2053		last = TAILQ_LAST(&rp->dst_group_queue, dst_group_queue);
2054		TAILQ_INSERT_TAIL(&rp->dst_group_queue, r, dst_group_entry);
2055
2056		group = create_sagroup(last->dst, last->satype, last->spi,
2057		    r->dst, r->satype, r->spi);
2058		if (group == NULL)
2059			return (1);
2060		group->nr = ipsec->rule_nr++;
2061		if (ipsecctl_add_rule(ipsec, group))
2062			return (1);
2063	} else {
2064		TAILQ_INSERT_TAIL(&ipsec->group_queue, r, group_entry);
2065		TAILQ_INIT(&r->dst_group_queue);
2066		TAILQ_INSERT_TAIL(&r->dst_group_queue, r, dst_group_entry);
2067	}
2068
2069	return (0);
2070}
2071
2072struct ipsec_rule *
2073create_sa(u_int8_t satype, u_int8_t tmode, struct ipsec_hosts *hosts,
2074    u_int32_t spi, struct ipsec_transforms *xfs, struct ipsec_key *authkey,
2075    struct ipsec_key *enckey)
2076{
2077	struct ipsec_rule *r;
2078
2079	if (validate_sa(spi, satype, xfs, authkey, enckey, tmode) == 0)
2080		return (NULL);
2081
2082	r = calloc(1, sizeof(struct ipsec_rule));
2083	if (r == NULL)
2084		err(1, "create_sa: calloc");
2085
2086	r->type |= RULE_SA;
2087	r->satype = satype;
2088	r->tmode = tmode;
2089	r->src = hosts->src;
2090	r->dst = hosts->dst;
2091	r->spi = spi;
2092	r->xfs = xfs;
2093	r->authkey = authkey;
2094	r->enckey = enckey;
2095
2096	return r;
2097}
2098
2099struct ipsec_rule *
2100reverse_sa(struct ipsec_rule *rule, u_int32_t spi, struct ipsec_key *authkey,
2101    struct ipsec_key *enckey)
2102{
2103	struct ipsec_rule *reverse;
2104
2105	if (validate_sa(spi, rule->satype, rule->xfs, authkey, enckey,
2106	    rule->tmode) == 0)
2107		return (NULL);
2108
2109	reverse = calloc(1, sizeof(struct ipsec_rule));
2110	if (reverse == NULL)
2111		err(1, "reverse_sa: calloc");
2112
2113	reverse->type |= RULE_SA;
2114	reverse->satype = rule->satype;
2115	reverse->tmode = rule->tmode;
2116	reverse->src = copyhost(rule->dst);
2117	reverse->dst = copyhost(rule->src);
2118	reverse->spi = spi;
2119	reverse->xfs = copytransforms(rule->xfs);
2120	reverse->authkey = authkey;
2121	reverse->enckey = enckey;
2122
2123	return (reverse);
2124}
2125
2126struct ipsec_rule *
2127create_sagroup(struct ipsec_addr_wrap *dst, u_int8_t proto, u_int32_t spi,
2128    struct ipsec_addr_wrap *dst2, u_int8_t proto2, u_int32_t spi2)
2129{
2130	struct ipsec_rule *r;
2131
2132	r = calloc(1, sizeof(struct ipsec_rule));
2133	if (r == NULL)
2134		err(1, "create_sagroup: calloc");
2135
2136	r->type |= RULE_GROUP;
2137
2138	r->dst = copyhost(dst);
2139	r->dst2 = copyhost(dst2);
2140	r->proto = proto;
2141	r->proto2 = proto2;
2142	r->spi = spi;
2143	r->spi2 = spi2;
2144	r->satype = proto;
2145
2146	return (r);
2147}
2148
2149struct ipsec_rule *
2150create_flow(u_int8_t dir, u_int8_t proto, struct ipsec_hosts *hosts,
2151    struct ipsec_hosts *peers,
2152    u_int8_t satype, char *srcid, char *dstid, u_int8_t type)
2153{
2154	struct ipsec_rule *r;
2155
2156	r = calloc(1, sizeof(struct ipsec_rule));
2157	if (r == NULL)
2158		err(1, "create_flow: calloc");
2159
2160	r->type |= RULE_FLOW;
2161
2162	if (dir == IPSEC_INOUT)
2163		r->direction = IPSEC_OUT;
2164	else
2165		r->direction = dir;
2166
2167	r->satype = satype;
2168	r->proto = proto;
2169	r->src = hosts->src;
2170	r->sport = hosts->sport;
2171	r->dst = hosts->dst;
2172	r->dport = hosts->dport;
2173	if ((hosts->sport != 0 || hosts->dport != 0) &&
2174	    (proto != IPPROTO_TCP && proto != IPPROTO_UDP)) {
2175		yyerror("no protocol supplied with source/destination ports");
2176		goto errout;
2177	}
2178
2179	if (type == TYPE_DENY || type == TYPE_BYPASS) {
2180		r->flowtype = type;
2181		return (r);
2182	}
2183
2184	r->flowtype = type;
2185	r->local = peers->src;
2186	if (peers->dst == NULL) {
2187		/* Set peer to remote host.  Must be a host address. */
2188		if (r->direction == IPSEC_IN) {
2189			if (r->src->netaddress) {
2190				yyerror("no peer specified");
2191				goto errout;
2192			}
2193			r->peer = copyhost(r->src);
2194		} else {
2195			if (r->dst->netaddress) {
2196				yyerror("no peer specified");
2197				goto errout;
2198			}
2199			r->peer = copyhost(r->dst);
2200		}
2201	} else
2202		r->peer = peers->dst;
2203
2204	r->auth = calloc(1, sizeof(struct ipsec_auth));
2205	if (r->auth == NULL)
2206		err(1, "create_flow: calloc");
2207	r->auth->srcid = srcid;
2208	r->auth->dstid = dstid;
2209	r->auth->srcid_type = get_id_type(srcid);
2210	r->auth->dstid_type = get_id_type(dstid);
2211	return r;
2212
2213errout:
2214	free(r);
2215	if (srcid)
2216		free(srcid);
2217	if (dstid)
2218		free(dstid);
2219	free(hosts->src);
2220	hosts->src = NULL;
2221	free(hosts->dst);
2222	hosts->dst = NULL;
2223
2224	return NULL;
2225}
2226
2227void
2228expand_any(struct ipsec_addr_wrap *ipa_in)
2229{
2230	struct ipsec_addr_wrap *oldnext, *ipa;
2231
2232	for (ipa = ipa_in; ipa; ipa = ipa->next) {
2233		if (ipa->af != AF_UNSPEC)
2234			continue;
2235		oldnext = ipa->next;
2236
2237		ipa->af = AF_INET;
2238		ipa->netaddress = 1;
2239		if ((ipa->name = strdup("0.0.0.0/0")) == NULL)
2240			err(1, "expand_any: strdup");
2241
2242		ipa->next = calloc(1, sizeof(struct ipsec_addr_wrap));
2243		if (ipa->next == NULL)
2244			err(1, "expand_any: calloc");
2245		ipa->next->af = AF_INET6;
2246		ipa->next->netaddress = 1;
2247		if ((ipa->next->name = strdup("::/0")) == NULL)
2248			err(1, "expand_any: strdup");
2249
2250		ipa->next->next = oldnext;
2251	}
2252}
2253
2254int
2255expand_rule(struct ipsec_rule *rule, u_int8_t direction, u_int32_t spi,
2256    struct ipsec_key *authkey, struct ipsec_key *enckey, int group)
2257{
2258	struct ipsec_rule	*r, *revr;
2259	struct ipsec_addr_wrap	*src, *dst;
2260	int added = 0;
2261
2262	if (validate_af(rule->src, rule->dst)) {
2263		yyerror("source/destination address families do not match");
2264		goto errout;
2265	}
2266	expand_any(rule->src);
2267	expand_any(rule->dst);
2268	expand_any(rule->peer);
2269	for (src = rule->src; src; src = src->next) {
2270		for (dst = rule->dst; dst; dst = dst->next) {
2271			if (src->af != dst->af)
2272				continue;
2273			r = copyrule(rule);
2274
2275			r->src = copyhost(src);
2276			r->dst = copyhost(dst);
2277
2278			r->nr = ipsec->rule_nr++;
2279			if (ipsecctl_add_rule(ipsec, r))
2280				return (1);
2281			if (group && add_sagroup(r))
2282				return (1);
2283
2284			if (direction == IPSEC_INOUT) {
2285				/* Create and add reverse flow rule. */
2286				revr = reverse_rule(r);
2287				if (revr == NULL)
2288					return (1);
2289
2290				revr->nr = ipsec->rule_nr++;
2291				if (ipsecctl_add_rule(ipsec, revr))
2292					return (1);
2293				if (group && add_sagroup(revr))
2294					return (1);
2295			} else if (spi != 0 || authkey || enckey) {
2296				/* Create and add reverse sa rule. */
2297				revr = reverse_sa(r, spi, authkey, enckey);
2298				if (revr == NULL)
2299					return (1);
2300
2301				revr->nr = ipsec->rule_nr++;
2302				if (ipsecctl_add_rule(ipsec, revr))
2303					return (1);
2304				if (group && add_sagroup(revr))
2305					return (1);
2306			}
2307			added++;
2308		}
2309	}
2310	if (!added)
2311		yyerror("rule expands to no valid combination");
2312 errout:
2313	ipsecctl_free_rule(rule);
2314	return (0);
2315}
2316
2317struct ipsec_rule *
2318reverse_rule(struct ipsec_rule *rule)
2319{
2320	struct ipsec_rule *reverse;
2321
2322	reverse = calloc(1, sizeof(struct ipsec_rule));
2323	if (reverse == NULL)
2324		err(1, "reverse_rule: calloc");
2325
2326	reverse->type |= RULE_FLOW;
2327
2328	/* Reverse direction */
2329	if (rule->direction == (u_int8_t)IPSEC_OUT)
2330		reverse->direction = (u_int8_t)IPSEC_IN;
2331	else
2332		reverse->direction = (u_int8_t)IPSEC_OUT;
2333
2334	reverse->flowtype = rule->flowtype;
2335	reverse->src = copyhost(rule->dst);
2336	reverse->dst = copyhost(rule->src);
2337	reverse->sport = rule->dport;
2338	reverse->dport = rule->sport;
2339	if (rule->local)
2340		reverse->local = copyhost(rule->local);
2341	if (rule->peer)
2342		reverse->peer = copyhost(rule->peer);
2343	reverse->satype = rule->satype;
2344	reverse->proto = rule->proto;
2345
2346	if (rule->auth) {
2347		reverse->auth = calloc(1, sizeof(struct ipsec_auth));
2348		if (reverse->auth == NULL)
2349			err(1, "reverse_rule: calloc");
2350		if (rule->auth->dstid && (reverse->auth->dstid =
2351		    strdup(rule->auth->dstid)) == NULL)
2352			err(1, "reverse_rule: strdup");
2353		if (rule->auth->srcid && (reverse->auth->srcid =
2354		    strdup(rule->auth->srcid)) == NULL)
2355			err(1, "reverse_rule: strdup");
2356		reverse->auth->srcid_type = rule->auth->srcid_type;
2357		reverse->auth->dstid_type = rule->auth->dstid_type;
2358		reverse->auth->type = rule->auth->type;
2359	}
2360
2361	return reverse;
2362}
2363
2364struct ipsec_rule *
2365create_ike(u_int8_t proto, struct ipsec_hosts *hosts, struct ipsec_hosts *peers,
2366    struct ike_mode *phase1mode, struct ike_mode *phase2mode, u_int8_t satype,
2367    u_int8_t tmode, u_int8_t mode, char *srcid, char *dstid,
2368    struct ike_auth *authtype, char *tag)
2369{
2370	struct ipsec_rule *r;
2371
2372	r = calloc(1, sizeof(struct ipsec_rule));
2373	if (r == NULL)
2374		err(1, "create_ike: calloc");
2375
2376	r->type = RULE_IKE;
2377
2378	r->proto = proto;
2379	r->src = hosts->src;
2380	r->sport = hosts->sport;
2381	r->dst = hosts->dst;
2382	r->dport = hosts->dport;
2383	if ((hosts->sport != 0 || hosts->dport != 0) &&
2384	    (proto != IPPROTO_TCP && proto != IPPROTO_UDP)) {
2385		yyerror("no protocol supplied with source/destination ports");
2386		free(r);
2387		free(hosts->src);
2388		hosts->src = NULL;
2389		free(hosts->dst);
2390		hosts->dst = NULL;
2391		if (phase1mode) {
2392			free(phase1mode->xfs);
2393			phase1mode->xfs = NULL;
2394			free(phase1mode->life);
2395			phase1mode->life = NULL;
2396		}
2397		if (phase2mode) {
2398			free(phase2mode->xfs);
2399			phase2mode->xfs = NULL;
2400			free(phase2mode->life);
2401			phase2mode->life = NULL;
2402		}
2403		if (srcid)
2404			free(srcid);
2405		if (dstid)
2406			free(dstid);
2407		return NULL;
2408	}
2409
2410	if (peers->dst == NULL) {
2411		/* Set peer to remote host.  Must be a host address. */
2412		if (r->direction == IPSEC_IN) {
2413			if (r->src->netaddress)
2414				r->peer = NULL;
2415			else
2416				r->peer = copyhost(r->src);
2417		} else {
2418			if (r->dst->netaddress)
2419				r->peer = NULL;
2420			else
2421				r->peer = copyhost(r->dst);
2422		}
2423	} else
2424		r->peer = peers->dst;
2425
2426	if (peers->src)
2427		r->local = peers->src;
2428
2429	r->satype = satype;
2430	r->tmode = tmode;
2431	r->ikemode = mode;
2432	if (phase1mode) {
2433		r->p1xfs = phase1mode->xfs;
2434		r->p1life = phase1mode->life;
2435		r->p1ie = phase1mode->ike_exch;
2436	} else {
2437		r->p1ie = IKE_MM;
2438	}
2439	if (phase2mode) {
2440		r->p2xfs = phase2mode->xfs;
2441		r->p2life = phase2mode->life;
2442		r->p2ie = phase2mode->ike_exch;
2443	} else {
2444		r->p2ie = IKE_QM;
2445	}
2446
2447	r->auth = calloc(1, sizeof(struct ipsec_auth));
2448	if (r->auth == NULL)
2449		err(1, "create_ike: calloc");
2450	r->auth->srcid = srcid;
2451	r->auth->dstid = dstid;
2452	r->auth->srcid_type = get_id_type(srcid);
2453	r->auth->dstid_type = get_id_type(dstid);
2454	r->ikeauth = calloc(1, sizeof(struct ike_auth));
2455	if (r->ikeauth == NULL)
2456		err(1, "create_ike: calloc");
2457	r->ikeauth->type = authtype->type;
2458	r->ikeauth->string = authtype->string;
2459	r->tag = tag;
2460
2461	return (r);
2462}
2463