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