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