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