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