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