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