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