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