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