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