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