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