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