GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: sbin/ipsecctl/parse.y Lines: 858 1127 76.1 %
Date: 2017-11-07 Branches: 563 819 68.7 %

Line Branch Exec Source
1
/*	$OpenBSD: parse.y,v 1.168 2017/04/19 15:59:38 bluhm Exp $	*/
2
3
/*
4
 * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
5
 * Copyright (c) 2001 Markus Friedl.  All rights reserved.
6
 * Copyright (c) 2001 Daniel Hartmeier.  All rights reserved.
7
 * Copyright (c) 2001 Theo de Raadt.  All rights reserved.
8
 * Copyright (c) 2004, 2005 Hans-Joerg Hoexer <hshoexer@openbsd.org>
9
 *
10
 * Permission to use, copy, modify, and distribute this software for any
11
 * purpose with or without fee is hereby granted, provided that the above
12
 * copyright notice and this permission notice appear in all copies.
13
 *
14
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21
 */
22
23
%{
24
#include <sys/types.h>
25
#include <sys/ioctl.h>
26
#include <sys/queue.h>
27
#include <sys/socket.h>
28
#include <sys/stat.h>
29
#include <net/if.h>
30
#include <netinet/in.h>
31
#include <netinet/ip_ipsp.h>
32
#include <arpa/inet.h>
33
34
#include <ctype.h>
35
#include <err.h>
36
#include <errno.h>
37
#include <fcntl.h>
38
#include <ifaddrs.h>
39
#include <limits.h>
40
#include <netdb.h>
41
#include <stdarg.h>
42
#include <stdio.h>
43
#include <string.h>
44
#include <syslog.h>
45
#include <unistd.h>
46
#include <netdb.h>
47
48
#include "ipsecctl.h"
49
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
    __attribute__((__format__ (printf, 1, 2)))
65
    __attribute__((__nonnull__ (1)));
66
int		 yywarn(const char *, ...)
67
    __attribute__((__format__ (printf, 1, 2)))
68
    __attribute__((__nonnull__ (1)));
69
int		 kw_cmp(const void *, const void *);
70
int		 lookup(char *);
71
int		 lgetc(int);
72
int		 lungetc(int);
73
int		 findeol(void);
74
75
TAILQ_HEAD(symhead, sym)	 symhead = TAILQ_HEAD_INITIALIZER(symhead);
76
struct sym {
77
	TAILQ_ENTRY(sym)	 entry;
78
	int			 used;
79
	int			 persist;
80
	char			*nam;
81
	char			*val;
82
};
83
int		 symset(const char *, const char *, int);
84
char		*symget(const char *);
85
int		 cmdline_symset(char *);
86
87
#define KEYSIZE_LIMIT	1024
88
89
static struct ipsecctl	*ipsec = NULL;
90
static int		 debug = 0;
91
92
const struct ipsec_xf authxfs[] = {
93
	{ "unknown",		AUTHXF_UNKNOWN,		0,	0 },
94
	{ "none",		AUTHXF_NONE,		0,	0 },
95
	{ "hmac-md5",		AUTHXF_HMAC_MD5,	16,	0 },
96
	{ "hmac-ripemd160",	AUTHXF_HMAC_RIPEMD160,	20,	0 },
97
	{ "hmac-sha1",		AUTHXF_HMAC_SHA1,	20,	0 },
98
	{ "hmac-sha2-256",	AUTHXF_HMAC_SHA2_256,	32,	0 },
99
	{ "hmac-sha2-384",	AUTHXF_HMAC_SHA2_384,	48,	0 },
100
	{ "hmac-sha2-512",	AUTHXF_HMAC_SHA2_512,	64,	0 },
101
	{ NULL,			0,			0,	0 },
102
};
103
104
const struct ipsec_xf encxfs[] = {
105
	{ "unknown",		ENCXF_UNKNOWN,		0,	0,	0, 0 },
106
	{ "none",		ENCXF_NONE,		0,	0,	0, 0 },
107
	{ "3des-cbc",		ENCXF_3DES_CBC,		24,	24,	0, 0 },
108
	{ "aes",		ENCXF_AES,		16,	32,	0, 0 },
109
	{ "aes-128",		ENCXF_AES_128,		16,	16,	0, 0 },
110
	{ "aes-192",		ENCXF_AES_192,		24,	24,	0, 0 },
111
	{ "aes-256",		ENCXF_AES_256,		32,	32,	0, 0 },
112
	{ "aesctr",		ENCXF_AESCTR,		16+4,	32+4,	0, 1 },
113
	{ "aes-128-ctr",	ENCXF_AES_128_CTR,	16+4,	16+4,	0, 1 },
114
	{ "aes-192-ctr",	ENCXF_AES_192_CTR,	24+4,	24+4,	0, 1 },
115
	{ "aes-256-ctr",	ENCXF_AES_256_CTR,	32+4,	32+4,	0, 1 },
116
	{ "aes-128-gcm",	ENCXF_AES_128_GCM,	16+4,	16+4,	1, 1 },
117
	{ "aes-192-gcm",	ENCXF_AES_192_GCM,	24+4,	24+4,	1, 1 },
118
	{ "aes-256-gcm",	ENCXF_AES_256_GCM,	32+4,	32+4,	1, 1 },
119
	{ "aes-128-gmac",	ENCXF_AES_128_GMAC,	16+4,	16+4,	1, 1 },
120
	{ "aes-192-gmac",	ENCXF_AES_192_GMAC,	24+4,	24+4,	1, 1 },
121
	{ "aes-256-gmac",	ENCXF_AES_256_GMAC,	32+4,	32+4,	1, 1 },
122
	{ "blowfish",		ENCXF_BLOWFISH,		5,	56,	0, 0 },
123
	{ "cast128",		ENCXF_CAST128,		5,	16,	0, 0 },
124
	{ "chacha20-poly1305",	ENCXF_CHACHA20_POLY1305, 32+4,	32+4,	1, 1 },
125
	{ "null",		ENCXF_NULL,		0,	0,	0, 0 },
126
	{ NULL,			0,			0,	0,	0, 0 },
127
};
128
129
const struct ipsec_xf compxfs[] = {
130
	{ "unknown",		COMPXF_UNKNOWN,		0,	0 },
131
	{ "deflate",		COMPXF_DEFLATE,		0,	0 },
132
	{ "lzs",		COMPXF_LZS,		0,	0 },
133
	{ NULL,			0,			0,	0 },
134
};
135
136
const struct ipsec_xf groupxfs[] = {
137
	{ "unknown",		GROUPXF_UNKNOWN,	0,	0 },
138
	{ "none",		GROUPXF_NONE,		0,	0 },
139
	{ "modp768",		GROUPXF_768,		768,	0 },
140
	{ "grp1",		GROUPXF_768,		768,	0 },
141
	{ "modp1024",		GROUPXF_1024,		1024,	0 },
142
	{ "grp2",		GROUPXF_1024,		1024,	0 },
143
	{ "modp1536",		GROUPXF_1536,		1536,	0 },
144
	{ "grp5",		GROUPXF_1536,		1536,	0 },
145
	{ "modp2048",		GROUPXF_2048,		2048,	0 },
146
	{ "grp14",		GROUPXF_2048,		2048,	0 },
147
	{ "modp3072",		GROUPXF_3072,		3072,	0 },
148
	{ "grp15",		GROUPXF_3072,		3072,	0 },
149
	{ "modp4096",		GROUPXF_4096,		4096,	0 },
150
	{ "grp16",		GROUPXF_4096,		4096,	0 },
151
	{ "modp6144",		GROUPXF_6144,		6144,	0 },
152
	{ "grp17",		GROUPXF_6144,		6144,	0 },
153
	{ "modp8192",		GROUPXF_8192,		8192,	0 },
154
	{ "grp18",		GROUPXF_8192,		8192,	0 },
155
	{ NULL,			0,			0,	0 },
156
};
157
158
int			 atoul(char *, u_long *);
159
int			 atospi(char *, u_int32_t *);
160
u_int8_t		 x2i(unsigned char *);
161
struct ipsec_key	*parsekey(unsigned char *, size_t);
162
struct ipsec_key	*parsekeyfile(char *);
163
struct ipsec_addr_wrap	*host(const char *);
164
struct ipsec_addr_wrap	*host_v6(const char *, int);
165
struct ipsec_addr_wrap	*host_v4(const char *, int);
166
struct ipsec_addr_wrap	*host_dns(const char *, int);
167
struct ipsec_addr_wrap	*host_if(const char *, int);
168
struct ipsec_addr_wrap	*host_any(void);
169
void			 ifa_load(void);
170
int			 ifa_exists(const char *);
171
struct ipsec_addr_wrap	*ifa_lookup(const char *ifa_name);
172
struct ipsec_addr_wrap	*ifa_grouplookup(const char *);
173
void			 set_ipmask(struct ipsec_addr_wrap *, u_int8_t);
174
const struct ipsec_xf	*parse_xf(const char *, const struct ipsec_xf *);
175
struct ipsec_lifetime	*parse_life(const char *);
176
struct ipsec_transforms *copytransforms(const struct ipsec_transforms *);
177
struct ipsec_lifetime	*copylife(const struct ipsec_lifetime *);
178
struct ipsec_auth	*copyipsecauth(const struct ipsec_auth *);
179
struct ike_auth		*copyikeauth(const struct ike_auth *);
180
struct ipsec_key	*copykey(struct ipsec_key *);
181
struct ipsec_addr_wrap	*copyhost(const struct ipsec_addr_wrap *);
182
char			*copytag(const char *);
183
struct ipsec_rule	*copyrule(struct ipsec_rule *);
184
int			 validate_af(struct ipsec_addr_wrap *,
185
			     struct ipsec_addr_wrap *);
186
int			 validate_sa(u_int32_t, u_int8_t,
187
			     struct ipsec_transforms *, struct ipsec_key *,
188
			     struct ipsec_key *, u_int8_t);
189
struct ipsec_rule	*create_sa(u_int8_t, u_int8_t, struct ipsec_hosts *,
190
			     u_int32_t, struct ipsec_transforms *,
191
			     struct ipsec_key *, struct ipsec_key *);
192
struct ipsec_rule	*reverse_sa(struct ipsec_rule *, u_int32_t,
193
			     struct ipsec_key *, struct ipsec_key *);
194
struct ipsec_rule	*create_sabundle(struct ipsec_addr_wrap *, u_int8_t,
195
			     u_int32_t, struct ipsec_addr_wrap *, u_int8_t,
196
			     u_int32_t);
197
struct ipsec_rule	*create_flow(u_int8_t, u_int8_t, struct ipsec_hosts *,
198
			     u_int8_t, char *, char *, u_int8_t);
199
int			 set_rule_peers(struct ipsec_rule *r,
200
			     struct ipsec_hosts *peers);
201
void			 expand_any(struct ipsec_addr_wrap *);
202
int			 expand_rule(struct ipsec_rule *, struct ipsec_hosts *,
203
			     u_int8_t, u_int32_t, struct ipsec_key *,
204
			     struct ipsec_key *, char *);
205
struct ipsec_rule	*reverse_rule(struct ipsec_rule *);
206
struct ipsec_rule	*create_ike(u_int8_t, struct ipsec_hosts *,
207
			     struct ike_mode *, struct ike_mode *, u_int8_t,
208
			     u_int8_t, u_int8_t, char *, char *,
209
			     struct ike_auth *, char *);
210
int			 add_sabundle(struct ipsec_rule *, char *);
211
int			 get_id_type(char *);
212
213
struct ipsec_transforms *ipsec_transforms;
214
215
typedef struct {
216
	union {
217
		int64_t	 	 number;
218
		u_int8_t	 ikemode;
219
		u_int8_t	 dir;
220
		u_int8_t	 satype;	/* encapsulating prococol */
221
		u_int8_t	 proto;		/* encapsulated protocol */
222
		u_int8_t	 tmode;
223
		char		*string;
224
		u_int16_t	 port;
225
		struct ipsec_hosts hosts;
226
		struct ipsec_hosts peers;
227
		struct ipsec_addr_wrap *anyhost;
228
		struct ipsec_addr_wrap *singlehost;
229
		struct ipsec_addr_wrap *host;
230
		struct {
231
			char *srcid;
232
			char *dstid;
233
		} ids;
234
		char		*id;
235
		u_int8_t	 type;
236
		struct ike_auth	 ikeauth;
237
		struct {
238
			u_int32_t	spiout;
239
			u_int32_t	spiin;
240
		} spis;
241
		struct {
242
			struct ipsec_key *keyout;
243
			struct ipsec_key *keyin;
244
		} authkeys;
245
		struct {
246
			struct ipsec_key *keyout;
247
			struct ipsec_key *keyin;
248
		} enckeys;
249
		struct {
250
			struct ipsec_key *keyout;
251
			struct ipsec_key *keyin;
252
		} keys;
253
		struct ipsec_transforms *transforms;
254
		struct ipsec_lifetime	*life;
255
		struct ike_mode		*mode;
256
	} v;
257
	int lineno;
258
} YYSTYPE;
259
260
%}
261
262
%token	FLOW FROM ESP AH IN PEER ON OUT TO SRCID DSTID RSA PSK TCPMD5 SPI
263
%token	AUTHKEY ENCKEY FILENAME AUTHXF ENCXF ERROR IKE MAIN QUICK AGGRESSIVE
264
%token	PASSIVE ACTIVE ANY IPIP IPCOMP COMPXF TUNNEL TRANSPORT DYNAMIC LIFETIME
265
%token	TYPE DENY BYPASS LOCAL PROTO USE ACQUIRE REQUIRE DONTACQ GROUP PORT TAG
266
%token	INCLUDE BUNDLE
267
%token	<v.string>		STRING
268
%token	<v.number>		NUMBER
269
%type	<v.string>		string
270
%type	<v.dir>			dir
271
%type	<v.satype>		satype
272
%type	<v.proto>		proto
273
%type	<v.number>		protoval
274
%type	<v.tmode>		tmode
275
%type	<v.hosts>		hosts
276
%type	<v.port>		port
277
%type	<v.number>		portval
278
%type	<v.peers>		peers
279
%type	<v.anyhost>		anyhost
280
%type	<v.singlehost>		singlehost
281
%type	<v.host>		host host_list host_spec
282
%type	<v.ids>			ids
283
%type	<v.id>			id
284
%type	<v.spis>		spispec
285
%type	<v.authkeys>		authkeyspec
286
%type	<v.enckeys>		enckeyspec
287
%type	<v.string>		bundlestring
288
%type	<v.keys>		keyspec
289
%type	<v.transforms>		transforms
290
%type	<v.ikemode>		ikemode
291
%type	<v.ikeauth>		ikeauth
292
%type	<v.type>		type
293
%type	<v.life>		lifetime
294
%type	<v.mode>		phase1mode phase2mode
295
%type	<v.string>		tag
296
%%
297
298
grammar		: /* empty */
299
		| grammar include '\n'
300
		| grammar '\n'
301
		| grammar ikerule '\n'
302
		| grammar flowrule '\n'
303
		| grammar sarule '\n'
304
		| grammar tcpmd5rule '\n'
305
		| grammar varset '\n'
306
		| grammar error '\n'		{ file->errors++; }
307
		;
308
309
comma		: ','
310
		| /* empty */
311
		;
312
313
include		: INCLUDE STRING		{
314
			struct file	*nfile;
315
316
			if ((nfile = pushfile($2, 0)) == NULL) {
317
				yyerror("failed to include file %s", $2);
318
				free($2);
319
				YYERROR;
320
			}
321
			free($2);
322
323
			file = nfile;
324
			lungetc('\n');
325
		}
326
		;
327
328
tcpmd5rule	: TCPMD5 hosts spispec authkeyspec	{
329
			struct ipsec_rule	*r;
330
331
			r = create_sa(IPSEC_TCPMD5, IPSEC_TRANSPORT, &$2,
332
			    $3.spiout, NULL, $4.keyout, NULL);
333
			if (r == NULL)
334
				YYERROR;
335
336
			if (expand_rule(r, NULL, 0, $3.spiin, $4.keyin, NULL,
337
			    NULL))
338
				errx(1, "tcpmd5rule: expand_rule");
339
		}
340
		;
341
342
sarule		: satype tmode hosts spispec transforms authkeyspec
343
		    enckeyspec bundlestring {
344
			struct ipsec_rule	*r;
345
346
			r = create_sa($1, $2, &$3, $4.spiout, $5, $6.keyout,
347
			    $7.keyout);
348
			if (r == NULL)
349
				YYERROR;
350
351
			if (expand_rule(r, NULL, 0, $4.spiin, $6.keyin,
352
			    $7.keyin, $8))
353
				errx(1, "sarule: expand_rule");
354
		}
355
		;
356
357
flowrule	: FLOW satype dir proto hosts peers ids type {
358
			struct ipsec_rule	*r;
359
360
			r = create_flow($3, $4, &$5, $2, $7.srcid,
361
			    $7.dstid, $8);
362
			if (r == NULL)
363
				YYERROR;
364
365
			if (expand_rule(r, &$6, $3, 0, NULL, NULL, NULL))
366
				errx(1, "flowrule: expand_rule");
367
		}
368
		;
369
370
ikerule		: IKE ikemode satype tmode proto hosts peers
371
		    phase1mode phase2mode ids ikeauth tag {
372
			struct ipsec_rule	*r;
373
374
			r = create_ike($5, &$6, $8, $9, $3, $4, $2,
375
			    $10.srcid, $10.dstid, &$11, $12);
376
			if (r == NULL)
377
				YYERROR;
378
379
			if (expand_rule(r, &$7, 0, 0, NULL, NULL, NULL))
380
				errx(1, "ikerule: expand_rule");
381
		}
382
		;
383
384
satype		: /* empty */			{ $$ = IPSEC_ESP; }
385
		| ESP				{ $$ = IPSEC_ESP; }
386
		| AH				{ $$ = IPSEC_AH; }
387
		| IPCOMP			{ $$ = IPSEC_IPCOMP; }
388
		| IPIP				{ $$ = IPSEC_IPIP; }
389
		;
390
391
proto		: /* empty */			{ $$ = 0; }
392
		| PROTO protoval		{ $$ = $2; }
393
		| PROTO ESP 			{ $$ = IPPROTO_ESP; }
394
		| PROTO AH			{ $$ = IPPROTO_AH; }
395
		;
396
397
protoval	: STRING			{
398
			struct protoent *p;
399
400
			p = getprotobyname($1);
401
			if (p == NULL) {
402
				yyerror("unknown protocol: %s", $1);
403
				YYERROR;
404
			}
405
			$$ = p->p_proto;
406
			free($1);
407
		}
408
		| NUMBER			{
409
			if ($1 > 255 || $1 < 0) {
410
				yyerror("protocol outside range");
411
				YYERROR;
412
			}
413
		}
414
		;
415
416
tmode		: /* empty */			{ $$ = IPSEC_TUNNEL; }
417
		| TUNNEL			{ $$ = IPSEC_TUNNEL; }
418
		| TRANSPORT			{ $$ = IPSEC_TRANSPORT; }
419
		;
420
421
dir		: /* empty */			{ $$ = IPSEC_INOUT; }
422
		| IN				{ $$ = IPSEC_IN; }
423
		| OUT				{ $$ = IPSEC_OUT; }
424
		;
425
426
hosts		: FROM host port TO host port		{
427
			struct ipsec_addr_wrap *ipa;
428
			for (ipa = $5; ipa; ipa = ipa->next) {
429
				if (ipa->srcnat) {
430
					yyerror("no flow NAT support for"
431
					    " destination network: %s", ipa->name);
432
					YYERROR;
433
				}
434
			}
435
			$$.src = $2;
436
			$$.sport = $3;
437
			$$.dst = $5;
438
			$$.dport = $6;
439
		}
440
		| TO host port FROM host port		{
441
			struct ipsec_addr_wrap *ipa;
442
			for (ipa = $2; ipa; ipa = ipa->next) {
443
				if (ipa->srcnat) {
444
					yyerror("no flow NAT support for"
445
					    " destination network: %s", ipa->name);
446
					YYERROR;
447
				}
448
			}
449
			$$.src = $5;
450
			$$.sport = $6;
451
			$$.dst = $2;
452
			$$.dport = $3;
453
		}
454
		;
455
456
port		: /* empty */				{ $$ = 0; }
457
		| PORT portval				{ $$ = $2; }
458
		;
459
460
portval		: STRING				{
461
			struct servent *s;
462
463
			if ((s = getservbyname($1, "tcp")) != NULL ||
464
			    (s = getservbyname($1, "udp")) != NULL) {
465
				$$ = s->s_port;
466
			} else {
467
				yyerror("unknown port: %s", $1);
468
				YYERROR;
469
			}
470
		}
471
		| NUMBER				{
472
			if ($1 > USHRT_MAX || $1 < 0) {
473
				yyerror("port outside range");
474
				YYERROR;
475
			}
476
			$$ = htons($1);
477
		}
478
		;
479
480
peers		: /* empty */				{
481
			$$.dst = NULL;
482
			$$.src = NULL;
483
		}
484
		| PEER anyhost LOCAL singlehost		{
485
			$$.dst = $2;
486
			$$.src = $4;
487
		}
488
		| LOCAL singlehost PEER anyhost		{
489
			$$.dst = $4;
490
			$$.src = $2;
491
		}
492
		| PEER anyhost				{
493
			$$.dst = $2;
494
			$$.src = NULL;
495
		}
496
		| LOCAL singlehost			{
497
			$$.dst = NULL;
498
			$$.src = $2;
499
		}
500
		;
501
502
anyhost		: singlehost			{ $$ = $1; }
503
		| ANY				{
504
			$$ = host_any();
505
		}
506
507
singlehost	: /* empty */			{ $$ = NULL; }
508
		| STRING			{
509
			if (($$ = host($1)) == NULL) {
510
				free($1);
511
				yyerror("could not parse host specification");
512
				YYERROR;
513
			}
514
			free($1);
515
		}
516
		;
517
518
host_list	: host				{ $$ = $1; }
519
		| host_list comma host		{
520
			if ($3 == NULL)
521
				$$ = $1;
522
			else if ($1 == NULL)
523
				$$ = $3;
524
			else {
525
				$1->tail->next = $3;
526
				$1->tail = $3->tail;
527
				$$ = $1;
528
			}
529
		}
530
		;
531
532
host_spec	: STRING			{
533
			if (($$ = host($1)) == NULL) {
534
				free($1);
535
				yyerror("could not parse host specification");
536
				YYERROR;
537
			}
538
			free($1);
539
		}
540
		| STRING '/' NUMBER		{
541
			char	*buf;
542
543
			if (asprintf(&buf, "%s/%lld", $1, $3) == -1)
544
				err(1, "host: asprintf");
545
			free($1);
546
			if (($$ = host(buf)) == NULL)	{
547
				free(buf);
548
				yyerror("could not parse host specification");
549
				YYERROR;
550
			}
551
			free(buf);
552
		}
553
		;
554
555
host		: host_spec			{ $$ = $1; }
556
		| host_spec '(' host_spec ')'   {
557
			if ($3->af != $1->af) {
558
				yyerror("Flow NAT address family mismatch");
559
				YYERROR;
560
			}
561
			$$ = $1;
562
			$$->srcnat = $3;
563
		}
564
		| ANY				{
565
			$$ = host_any();
566
		}
567
		| '{' host_list '}'		{ $$ = $2; }
568
		;
569
570
ids		: /* empty */			{
571
			$$.srcid = NULL;
572
			$$.dstid = NULL;
573
		}
574
		| SRCID id DSTID id		{
575
			$$.srcid = $2;
576
			$$.dstid = $4;
577
		}
578
		| SRCID id			{
579
			$$.srcid = $2;
580
			$$.dstid = NULL;
581
		}
582
		| DSTID id			{
583
			$$.srcid = NULL;
584
			$$.dstid = $2;
585
		}
586
		;
587
588
type		: /* empty */			{
589
			$$ = TYPE_UNKNOWN;
590
		}
591
		| TYPE USE			{
592
			$$ = TYPE_USE;
593
		}
594
		| TYPE ACQUIRE			{
595
			$$ = TYPE_ACQUIRE;
596
		}
597
		| TYPE REQUIRE			{
598
			$$ = TYPE_REQUIRE;
599
		}
600
		| TYPE DENY			{
601
			$$ = TYPE_DENY;
602
		}
603
		| TYPE BYPASS			{
604
			$$ = TYPE_BYPASS;
605
		}
606
		| TYPE DONTACQ			{
607
			$$ = TYPE_DONTACQ;
608
		}
609
		;
610
611
id		: STRING			{ $$ = $1; }
612
		;
613
614
spispec		: SPI STRING			{
615
			u_int32_t	 spi;
616
			char		*p = strchr($2, ':');
617
618
			if (p != NULL) {
619
				*p++ = 0;
620
621
				if (atospi(p, &spi) == -1) {
622
					free($2);
623
					YYERROR;
624
				}
625
				$$.spiin = spi;
626
			} else
627
				$$.spiin = 0;
628
629
			if (atospi($2, &spi) == -1) {
630
				free($2);
631
				YYERROR;
632
			}
633
			$$.spiout = spi;
634
635
636
			free($2);
637
		}
638
		| SPI NUMBER			{
639
			if ($2 > UINT_MAX || $2 < 0) {
640
				yyerror("%lld not a valid spi", $2);
641
				YYERROR;
642
			}
643
			if ($2 >= SPI_RESERVED_MIN && $2 <= SPI_RESERVED_MAX) {
644
				yyerror("%lld within reserved spi range", $2);
645
				YYERROR;
646
			}
647
648
			$$.spiin = 0;
649
			$$.spiout = $2;
650
		}
651
		;
652
653
transforms	:					{
654
			if ((ipsec_transforms = calloc(1,
655
			    sizeof(struct ipsec_transforms))) == NULL)
656
				err(1, "transforms: calloc");
657
		}
658
		    transforms_l
659
			{ $$ = ipsec_transforms; }
660
		| /* empty */				{
661
			if (($$ = calloc(1,
662
			    sizeof(struct ipsec_transforms))) == NULL)
663
				err(1, "transforms: calloc");
664
		}
665
		;
666
667
transforms_l	: transforms_l transform
668
		| transform
669
		;
670
671
transform	: AUTHXF STRING			{
672
			if (ipsec_transforms->authxf)
673
				yyerror("auth already set");
674
			else {
675
				ipsec_transforms->authxf = parse_xf($2,
676
				    authxfs);
677
				if (!ipsec_transforms->authxf)
678
					yyerror("%s not a valid transform", $2);
679
			}
680
		}
681
		| ENCXF STRING			{
682
			if (ipsec_transforms->encxf)
683
				yyerror("enc already set");
684
			else {
685
				ipsec_transforms->encxf = parse_xf($2, encxfs);
686
				if (!ipsec_transforms->encxf)
687
					yyerror("%s not a valid transform", $2);
688
			}
689
		}
690
		| COMPXF STRING			{
691
			if (ipsec_transforms->compxf)
692
				yyerror("comp already set");
693
			else {
694
				ipsec_transforms->compxf = parse_xf($2,
695
				    compxfs);
696
				if (!ipsec_transforms->compxf)
697
					yyerror("%s not a valid transform", $2);
698
			}
699
		}
700
		| GROUP STRING			{
701
			if (ipsec_transforms->groupxf)
702
				yyerror("group already set");
703
			else {
704
				ipsec_transforms->groupxf = parse_xf($2,
705
				    groupxfs);
706
				if (!ipsec_transforms->groupxf)
707
					yyerror("%s not a valid transform", $2);
708
			}
709
		}
710
		;
711
712
phase1mode	: /* empty */	{
713
			struct ike_mode		*p1;
714
715
			/* We create just an empty main mode */
716
			if ((p1 = calloc(1, sizeof(struct ike_mode))) == NULL)
717
				err(1, "phase1mode: calloc");
718
			p1->ike_exch = IKE_MM;
719
			$$ = p1;
720
		}
721
		| MAIN transforms lifetime		{
722
			struct ike_mode *p1;
723
724
			if ((p1 = calloc(1, sizeof(struct ike_mode))) == NULL)
725
				err(1, "phase1mode: calloc");
726
			p1->xfs = $2;
727
			p1->life = $3;
728
			p1->ike_exch = IKE_MM;
729
			$$ = p1;
730
		}
731
		| AGGRESSIVE transforms lifetime	{
732
			struct ike_mode	*p1;
733
734
			if ((p1 = calloc(1, sizeof(struct ike_mode))) == NULL)
735
				err(1, "phase1mode: calloc");
736
			p1->xfs = $2;
737
			p1->life = $3;
738
			p1->ike_exch = IKE_AM;
739
			$$ = p1;
740
		}
741
		;
742
743
phase2mode	: /* empty */	{
744
			struct ike_mode		*p2;
745
746
			/* We create just an empty quick mode */
747
			if ((p2 = calloc(1, sizeof(struct ike_mode))) == NULL)
748
				err(1, "phase2mode: calloc");
749
			p2->ike_exch = IKE_QM;
750
			$$ = p2;
751
		}
752
		| QUICK transforms lifetime	{
753
			struct ike_mode	*p2;
754
755
			if ((p2 = calloc(1, sizeof(struct ike_mode))) == NULL)
756
				err(1, "phase2mode: calloc");
757
			p2->xfs = $2;
758
			p2->life = $3;
759
			p2->ike_exch = IKE_QM;
760
			$$ = p2;
761
		}
762
		;
763
764
lifetime	: /* empty */			{
765
			struct ipsec_lifetime *life;
766
767
			/* We create just an empty transform */
768
			if ((life = calloc(1, sizeof(struct ipsec_lifetime)))
769
			    == NULL)
770
				err(1, "life: calloc");
771
			life->lt_seconds = -1;
772
			life->lt_bytes = -1;
773
			$$ = life;
774
		}
775
		| LIFETIME NUMBER		{
776
			struct ipsec_lifetime *life;
777
778
			if ((life = calloc(1, sizeof(struct ipsec_lifetime)))
779
			    == NULL)
780
				err(1, "life: calloc");
781
			life->lt_seconds = $2;
782
			life->lt_bytes = -1;
783
			$$ = life;
784
		}
785
		| LIFETIME STRING		{
786
			$$ = parse_life($2);
787
		}
788
		;
789
790
authkeyspec	: /* empty */			{
791
			$$.keyout = NULL;
792
			$$.keyin = NULL;
793
		}
794
		| AUTHKEY keyspec		{
795
			$$.keyout = $2.keyout;
796
			$$.keyin = $2.keyin;
797
		}
798
		;
799
800
enckeyspec	: /* empty */			{
801
			$$.keyout = NULL;
802
			$$.keyin = NULL;
803
		}
804
		| ENCKEY keyspec		{
805
			$$.keyout = $2.keyout;
806
			$$.keyin = $2.keyin;
807
		}
808
		;
809
810
bundlestring	: /* empty */			{ $$ = NULL; }
811
		| BUNDLE STRING			{ $$ = $2; }
812
		;
813
814
keyspec		: STRING			{
815
			unsigned char	*hex;
816
			unsigned char	*p = strchr($1, ':');
817
818
			if (p != NULL ) {
819
				*p++ = 0;
820
821
				if (!strncmp(p, "0x", 2))
822
					p += 2;
823
				$$.keyin = parsekey(p, strlen(p));
824
			} else
825
				$$.keyin = NULL;
826
827
			hex = $1;
828
			if (!strncmp(hex, "0x", 2))
829
				hex += 2;
830
			$$.keyout = parsekey(hex, strlen(hex));
831
832
			free($1);
833
		}
834
		| FILENAME STRING		{
835
			unsigned char	*p = strchr($2, ':');
836
837
			if (p != NULL) {
838
				*p++ = 0;
839
				$$.keyin = parsekeyfile(p);
840
			}
841
			$$.keyout = parsekeyfile($2);
842
			free($2);
843
		}
844
		;
845
846
ikemode		: /* empty */			{ $$ = IKE_ACTIVE; }
847
		| PASSIVE			{ $$ = IKE_PASSIVE; }
848
		| DYNAMIC			{ $$ = IKE_DYNAMIC; }
849
		| ACTIVE			{ $$ = IKE_ACTIVE; }
850
		;
851
852
ikeauth		: /* empty */			{
853
			$$.type = IKE_AUTH_RSA;
854
			$$.string = NULL;
855
		}
856
		| RSA				{
857
			$$.type = IKE_AUTH_RSA;
858
			$$.string = NULL;
859
		}
860
		| PSK STRING			{
861
			$$.type = IKE_AUTH_PSK;
862
			if (($$.string = strdup($2)) == NULL)
863
				err(1, "ikeauth: strdup");
864
		}
865
		;
866
867
tag		: /* empty */
868
		{
869
			$$ = NULL;
870
		}
871
		| TAG STRING
872
		{
873
			$$ = $2;
874
		}
875
		;
876
877
string		: string STRING
878
		{
879
			if (asprintf(&$$, "%s %s", $1, $2) == -1)
880
				err(1, "string: asprintf");
881
			free($1);
882
			free($2);
883
		}
884
		| STRING
885
		;
886
887
varset		: STRING '=' string
888
		{
889
			char *s = $1;
890
			if (ipsec->opts & IPSECCTL_OPT_VERBOSE)
891
				printf("%s = \"%s\"\n", $1, $3);
892
			while (*s++) {
893
				if (isspace((unsigned char)*s)) {
894
					yyerror("macro name cannot contain "
895
					    "whitespace");
896
					YYERROR;
897
				}
898
			}
899
			if (symset($1, $3, 0) == -1)
900
				err(1, "cannot store variable");
901
			free($1);
902
			free($3);
903
		}
904
		;
905
906
%%
907
908
struct keywords {
909
	const char	*k_name;
910
	int		 k_val;
911
};
912
913
int
914
yyerror(const char *fmt, ...)
915
{
916
56
	va_list		 ap;
917
918
28
	file->errors++;
919
28
	va_start(ap, fmt);
920
28
	fprintf(stderr, "%s: %d: ", file->name, yylval.lineno);
921
28
	vfprintf(stderr, fmt, ap);
922
28
	fprintf(stderr, "\n");
923
28
	va_end(ap);
924
28
	return (0);
925
28
}
926
927
int
928
yywarn(const char *fmt, ...)
929
{
930
18
	va_list		 ap;
931
932
9
	va_start(ap, fmt);
933
9
	fprintf(stderr, "%s: %d: ", file->name, yylval.lineno);
934
9
	vfprintf(stderr, fmt, ap);
935
9
	fprintf(stderr, "\n");
936
9
	va_end(ap);
937
9
	return (0);
938
9
}
939
940
int
941
kw_cmp(const void *k, const void *e)
942
{
943
41294
	return (strcmp(k, ((const struct keywords *)e)->k_name));
944
}
945
946
int
947
lookup(char *s)
948
{
949
	/* this has to be sorted always */
950
	static const struct keywords keywords[] = {
951
		{ "acquire",		ACQUIRE },
952
		{ "active",		ACTIVE },
953
		{ "aggressive",		AGGRESSIVE },
954
		{ "ah",			AH },
955
		{ "any",		ANY },
956
		{ "auth",		AUTHXF },
957
		{ "authkey",		AUTHKEY },
958
		{ "bundle",		BUNDLE },
959
		{ "bypass",		BYPASS },
960
		{ "comp",		COMPXF },
961
		{ "deny",		DENY },
962
		{ "dontacq",		DONTACQ },
963
		{ "dstid",		DSTID },
964
		{ "dynamic",		DYNAMIC },
965
		{ "enc",		ENCXF },
966
		{ "enckey",		ENCKEY },
967
		{ "esp",		ESP },
968
		{ "file",		FILENAME },
969
		{ "flow",		FLOW },
970
		{ "from",		FROM },
971
		{ "group",		GROUP },
972
		{ "ike",		IKE },
973
		{ "in",			IN },
974
		{ "include",		INCLUDE },
975
		{ "ipcomp",		IPCOMP },
976
		{ "ipip",		IPIP },
977
		{ "lifetime",		LIFETIME },
978
		{ "local",		LOCAL },
979
		{ "main",		MAIN },
980
		{ "out",		OUT },
981
		{ "passive",		PASSIVE },
982
		{ "peer",		PEER },
983
		{ "port",		PORT },
984
		{ "proto",		PROTO },
985
		{ "psk",		PSK },
986
		{ "quick",		QUICK },
987
		{ "require",		REQUIRE },
988
		{ "rsa",		RSA },
989
		{ "spi",		SPI },
990
		{ "srcid",		SRCID },
991
		{ "tag",		TAG },
992
		{ "tcpmd5",		TCPMD5 },
993
		{ "to",			TO },
994
		{ "transport",		TRANSPORT },
995
		{ "tunnel",		TUNNEL },
996
		{ "type",		TYPE },
997
		{ "use",		USE }
998
	};
999
	const struct keywords	*p;
1000
1001
7652
	p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
1002
	    sizeof(keywords[0]), kw_cmp);
1003
1004
3826
	if (p) {
1005
2405
		if (debug > 1)
1006
			fprintf(stderr, "%s: %d\n", s, p->k_val);
1007
2405
		return (p->k_val);
1008
	} else {
1009
1421
		if (debug > 1)
1010
			fprintf(stderr, "string: %s\n", s);
1011
1421
		return (STRING);
1012
	}
1013
3826
}
1014
1015
#define MAXPUSHBACK	128
1016
1017
u_char	*parsebuf;
1018
int	 parseindex;
1019
u_char	 pushback_buffer[MAXPUSHBACK];
1020
int	 pushback_index = 0;
1021
1022
int
1023
lgetc(int quotec)
1024
{
1025
	int		c, next;
1026
1027
92348
	if (parsebuf) {
1028
		/* Read character from the parsebuffer instead of input. */
1029
840
		if (parseindex >= 0) {
1030
840
			c = parsebuf[parseindex++];
1031
840
			if (c != '\0')
1032
815
				return (c);
1033
25
			parsebuf = NULL;
1034
25
		} else
1035
			parseindex++;
1036
	}
1037
1038
45359
	if (pushback_index)
1039
5313
		return (pushback_buffer[--pushback_index]);
1040
1041
40046
	if (quotec) {
1042

40544
		if ((c = getc(file->stream)) == EOF) {
1043
2
			yyerror("reached end of file while parsing quoted string");
1044
2
			if (popfile() == EOF)
1045
2
				return (EOF);
1046
			return (quotec);
1047
		}
1048
10134
		return (c);
1049
	}
1050
1051

121230
	while ((c = getc(file->stream)) == '\\') {
1052

1272
		next = getc(file->stream);
1053
318
		if (next != '\n') {
1054
			c = next;
1055
			break;
1056
		}
1057
318
		yylval.lineno = file->lineno;
1058
318
		file->lineno++;
1059
	}
1060
1061
29910
	while (c == EOF) {
1062
198
		if (popfile() == EOF)
1063
198
			return (EOF);
1064
		c = getc(file->stream);
1065
	}
1066
29712
	return (c);
1067
46174
}
1068
1069
int
1070
lungetc(int c)
1071
{
1072
10930
	if (c == EOF)
1073
		return (EOF);
1074
5465
	if (parsebuf) {
1075
152
		parseindex--;
1076
152
		if (parseindex >= 0)
1077
152
			return (c);
1078
	}
1079
5313
	if (pushback_index < MAXPUSHBACK-1)
1080
5313
		return (pushback_buffer[pushback_index++] = c);
1081
	else
1082
		return (EOF);
1083
5465
}
1084
1085
int
1086
findeol(void)
1087
{
1088
	int	c;
1089
1090
	parsebuf = NULL;
1091
1092
	/* skip to either EOF or the first real EOL */
1093
	while (1) {
1094
		if (pushback_index)
1095
			c = pushback_buffer[--pushback_index];
1096
		else
1097
			c = lgetc(0);
1098
		if (c == '\n') {
1099
			file->lineno++;
1100
			break;
1101
		}
1102
		if (c == EOF)
1103
			break;
1104
	}
1105
	return (ERROR);
1106
}
1107
1108
int
1109
yylex(void)
1110
{
1111
10286
	u_char	 buf[8096];
1112
	u_char	*p, *val;
1113
	int	 quotec, next, c;
1114
5143
	int	 token;
1115
1116
top:
1117
5168
	p = buf;
1118
14387
	while ((c = lgetc(0)) == ' ' || c == '\t')
1119
		; /* nothing */
1120
1121
5168
	yylval.lineno = file->lineno;
1122
5168
	if (c == '#')
1123
338
		while ((c = lgetc(0)) != '\n' && c != EOF)
1124
			; /* nothing */
1125
5168
	if (c == '$' && parsebuf == NULL) {
1126
		while (1) {
1127
103
			if ((c = lgetc(0)) == EOF)
1128
				return (0);
1129
1130
103
			if (p + 1 >= buf + sizeof(buf) - 1) {
1131
				yyerror("string too long");
1132
				return (findeol());
1133
			}
1134
103
			if (isalnum(c) || c == '_') {
1135
78
				*p++ = c;
1136
78
				continue;
1137
			}
1138
25
			*p = '\0';
1139
25
			lungetc(c);
1140
			break;
1141
		}
1142
25
		val = symget(buf);
1143
25
		if (val == NULL) {
1144
			yyerror("macro '%s' not defined", buf);
1145
			return (findeol());
1146
		}
1147
25
		parsebuf = val;
1148
25
		parseindex = 0;
1149
25
		goto top;
1150
	}
1151
1152
5143
	switch (c) {
1153
	case '\'':
1154
	case '"':
1155
		quotec = c;
1156
10125
		while (1) {
1157
10136
			if ((c = lgetc(quotec)) == EOF)
1158
2
				return (0);
1159
10134
			if (c == '\n') {
1160
11
				file->lineno++;
1161
11
				continue;
1162
10123
			} else if (c == '\\') {
1163
				if ((next = lgetc(quotec)) == EOF)
1164
					return (0);
1165
				if (next == quotec || c == ' ' || c == '\t')
1166
					c = next;
1167
				else if (next == '\n') {
1168
					file->lineno++;
1169
					continue;
1170
				} else
1171
					lungetc(next);
1172
10123
			} else if (c == quotec) {
1173
156
				*p = '\0';
1174
				break;
1175
9967
			} else if (c == '\0') {
1176
				yyerror("syntax error");
1177
				return (findeol());
1178
			}
1179
9967
			if (p + 1 >= buf + sizeof(buf) - 1) {
1180
				yyerror("string too long");
1181
				return (findeol());
1182
			}
1183
9967
			*p++ = c;
1184
		}
1185
156
		yylval.v.string = strdup(buf);
1186
156
		if (yylval.v.string == NULL)
1187
			err(1, "yylex: strdup");
1188
156
		return (STRING);
1189
	}
1190
1191
#define allowed_to_end_number(x) \
1192
	(isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
1193
1194

9970
	if (c == '-' || isdigit(c)) {
1195
		do {
1196
1855
			*p++ = c;
1197
1855
			if ((unsigned)(p-buf) >= sizeof(buf)) {
1198
				yyerror("string too long");
1199
				return (findeol());
1200
			}
1201

3710
		} while ((c = lgetc(0)) != EOF && isdigit(c));
1202
1282
		lungetc(c);
1203

2142
		if (p == buf + 1 && buf[0] == '-')
1204
			goto nodigits;
1205

2564
		if (c == EOF || allowed_to_end_number(c)) {
1206
222
			const char *errstr = NULL;
1207
1208
222
			*p = '\0';
1209
222
			yylval.v.number = strtonum(buf, LLONG_MIN,
1210
			    LLONG_MAX, &errstr);
1211
222
			if (errstr) {
1212
				yyerror("\"%s\" invalid number: %s",
1213
				    buf, errstr);
1214
				return (findeol());
1215
			}
1216
222
			return (NUMBER);
1217
222
		} else {
1218
nodigits:
1219
1724
			while (p > buf + 1)
1220
332
				lungetc(*--p);
1221
			c = *--p;
1222
1060
			if (c == '-')
1223
				return (c);
1224
		}
1225
	}
1226
1227
#define allowed_in_string(x) \
1228
	(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
1229
	x != '{' && x != '}' && x != '<' && x != '>' && \
1230
	x != '!' && x != '=' && x != '/' && x != '#' && \
1231
	x != ','))
1232
1233
4763
	if (isalnum(c) || c == ':' || c == '_' || c == '*') {
1234
		do {
1235
24523
			*p++ = c;
1236
24523
			if ((unsigned)(p-buf) >= sizeof(buf)) {
1237
				yyerror("string too long");
1238
				return (findeol());
1239
			}
1240

55801
		} while ((c = lgetc(0)) != EOF && (allowed_in_string(c)));
1241
3826
		lungetc(c);
1242
3826
		*p = '\0';
1243
3826
		if ((token = lookup(buf)) == STRING)
1244
1421
			if ((yylval.v.string = strdup(buf)) == NULL)
1245
				err(1, "yylex: strdup");
1246
3826
		return (token);
1247
	}
1248
937
	if (c == '\n') {
1249
409
		yylval.lineno = file->lineno;
1250
409
		file->lineno++;
1251
409
	}
1252
937
	if (c == EOF)
1253
198
		return (0);
1254
739
	return (c);
1255
5143
}
1256
1257
int
1258
check_file_secrecy(int fd, const char *fname)
1259
{
1260
	struct stat	st;
1261
1262
	if (fstat(fd, &st)) {
1263
		warn("cannot stat %s", fname);
1264
		return (-1);
1265
	}
1266
	if (st.st_uid != 0 && st.st_uid != getuid()) {
1267
		warnx("%s: owner not root or current user", fname);
1268
		return (-1);
1269
	}
1270
	if (st.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO)) {
1271
		warnx("%s: group writable or world read/writable", fname);
1272
		return (-1);
1273
	}
1274
	return (0);
1275
}
1276
1277
struct file *
1278
pushfile(const char *name, int secret)
1279
{
1280
	struct file	*nfile;
1281
1282
400
	if ((nfile = calloc(1, sizeof(struct file))) == NULL) {
1283
		warn("malloc");
1284
		return (NULL);
1285
	}
1286
200
	if ((nfile->name = strdup(name)) == NULL) {
1287
		warn("malloc");
1288
		free(nfile);
1289
		return (NULL);
1290
	}
1291

400
	if (TAILQ_FIRST(&files) == NULL && strcmp(nfile->name, "-") == 0) {
1292
200
		nfile->stream = stdin;
1293
200
		free(nfile->name);
1294
200
		if ((nfile->name = strdup("stdin")) == NULL) {
1295
			warn("strdup");
1296
			free(nfile);
1297
			return (NULL);
1298
		}
1299
	} else if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
1300
		warn("%s", nfile->name);
1301
		free(nfile->name);
1302
		free(nfile);
1303
		return (NULL);
1304
	} else if (secret &&
1305
	    check_file_secrecy(fileno(nfile->stream), nfile->name)) {
1306
		fclose(nfile->stream);
1307
		free(nfile->name);
1308
		free(nfile);
1309
		return (NULL);
1310
	}
1311
200
	nfile->lineno = 1;
1312
200
	TAILQ_INSERT_TAIL(&files, nfile, entry);
1313
200
	return (nfile);
1314
200
}
1315
1316
int
1317
popfile(void)
1318
{
1319
	struct file	*prev;
1320
1321
800
	if ((prev = TAILQ_PREV(file, files, entry)) != NULL) {
1322
		prev->errors += file->errors;
1323
		TAILQ_REMOVE(&files, file, entry);
1324
		fclose(file->stream);
1325
		free(file->name);
1326
		free(file);
1327
		file = prev;
1328
		return (0);
1329
	}
1330
400
	return (EOF);
1331
400
}
1332
1333
int
1334
parse_rules(const char *filename, struct ipsecctl *ipsecx)
1335
{
1336
	struct sym	*sym;
1337
	int		 errors = 0;
1338
1339
400
	ipsec = ipsecx;
1340
1341
200
	if ((file = pushfile(filename, 1)) == NULL) {
1342
		return (-1);
1343
	}
1344
1345
200
	yyparse();
1346
200
	errors = file->errors;
1347
200
	popfile();
1348
1349
	/* Free macros and check which have not been used. */
1350
456
	while ((sym = TAILQ_FIRST(&symhead))) {
1351

28
		if ((ipsec->opts & IPSECCTL_OPT_VERBOSE2) && !sym->used)
1352
			fprintf(stderr, "warning: macro '%s' not "
1353
			    "used\n", sym->nam);
1354
28
		free(sym->nam);
1355
28
		free(sym->val);
1356
69
		TAILQ_REMOVE(&symhead, sym, entry);
1357
28
		free(sym);
1358
	}
1359
1360
200
	return (errors ? -1 : 0);
1361
200
}
1362
1363
int
1364
symset(const char *nam, const char *val, int persist)
1365
{
1366
	struct sym	*sym;
1367
1368
124
	TAILQ_FOREACH(sym, &symhead, entry) {
1369
20
		if (strcmp(nam, sym->nam) == 0)
1370
			break;
1371
	}
1372
1373
28
	if (sym != NULL) {
1374
		if (sym->persist == 1)
1375
			return (0);
1376
		else {
1377
			free(sym->nam);
1378
			free(sym->val);
1379
			TAILQ_REMOVE(&symhead, sym, entry);
1380
			free(sym);
1381
		}
1382
	}
1383
28
	if ((sym = calloc(1, sizeof(*sym))) == NULL)
1384
		return (-1);
1385
1386
28
	sym->nam = strdup(nam);
1387
28
	if (sym->nam == NULL) {
1388
		free(sym);
1389
		return (-1);
1390
	}
1391
28
	sym->val = strdup(val);
1392
28
	if (sym->val == NULL) {
1393
		free(sym->nam);
1394
		free(sym);
1395
		return (-1);
1396
	}
1397
28
	sym->used = 0;
1398
28
	sym->persist = persist;
1399
28
	TAILQ_INSERT_TAIL(&symhead, sym, entry);
1400
28
	return (0);
1401
28
}
1402
1403
int
1404
cmdline_symset(char *s)
1405
{
1406
	char	*sym, *val;
1407
	int	ret;
1408
	size_t	len;
1409
1410
	if ((val = strrchr(s, '=')) == NULL)
1411
		return (-1);
1412
1413
	len = strlen(s) - strlen(val) + 1;
1414
	if ((sym = malloc(len)) == NULL)
1415
		err(1, "cmdline_symset: malloc");
1416
1417
	strlcpy(sym, s, len);
1418
1419
	ret = symset(sym, val + 1, 1);
1420
	free(sym);
1421
1422
	return (ret);
1423
}
1424
1425
char *
1426
symget(const char *nam)
1427
{
1428
	struct sym	*sym;
1429
1430
113
	TAILQ_FOREACH(sym, &symhead, entry) {
1431
44
		if (strcmp(nam, sym->nam) == 0) {
1432
25
			sym->used = 1;
1433
25
			return (sym->val);
1434
		}
1435
	}
1436
	return (NULL);
1437
25
}
1438
1439
int
1440
atoul(char *s, u_long *ulvalp)
1441
{
1442
	u_long	 ulval;
1443
444
	char	*ep;
1444
1445
222
	errno = 0;
1446
222
	ulval = strtoul(s, &ep, 0);
1447

444
	if (s[0] == '\0' || *ep != '\0')
1448
		return (-1);
1449
222
	if (errno == ERANGE && ulval == ULONG_MAX)
1450
		return (-1);
1451
222
	*ulvalp = ulval;
1452
222
	return (0);
1453
222
}
1454
1455
int
1456
atospi(char *s, u_int32_t *spivalp)
1457
{
1458
444
	unsigned long	ulval;
1459
1460
222
	if (atoul(s, &ulval) == -1)
1461
		return (-1);
1462
222
	if (ulval > UINT_MAX) {
1463
		yyerror("%lu not a valid spi", ulval);
1464
		return (-1);
1465
	}
1466
222
	if (ulval >= SPI_RESERVED_MIN && ulval <= SPI_RESERVED_MAX) {
1467
		yyerror("%lu within reserved spi range", ulval);
1468
		return (-1);
1469
	}
1470
222
	*spivalp = ulval;
1471
222
	return (0);
1472
222
}
1473
1474
u_int8_t
1475
x2i(unsigned char *s)
1476
{
1477
14416
	char	ss[3];
1478
1479
7208
	ss[0] = s[0];
1480
7208
	ss[1] = s[1];
1481
7208
	ss[2] = 0;
1482
1483

14416
	if (!isxdigit(s[0]) || !isxdigit(s[1])) {
1484
		yyerror("keys need to be specified in hex digits");
1485
		return (-1);
1486
	}
1487
7208
	return ((u_int8_t)strtoul(ss, NULL, 16));
1488
7208
}
1489
1490
struct ipsec_key *
1491
parsekey(unsigned char *hexkey, size_t len)
1492
{
1493
	struct ipsec_key *key;
1494
	int		  i;
1495
1496
596
	key = calloc(1, sizeof(struct ipsec_key));
1497
298
	if (key == NULL)
1498
		err(1, "parsekey: calloc");
1499
1500
298
	key->len = len / 2;
1501
298
	key->data = calloc(key->len, sizeof(u_int8_t));
1502
298
	if (key->data == NULL)
1503
		err(1, "parsekey: calloc");
1504
1505
15012
	for (i = 0; i < (int)key->len; i++)
1506
7208
		key->data[i] = x2i(hexkey + 2 * i);
1507
1508
298
	return (key);
1509
}
1510
1511
struct ipsec_key *
1512
parsekeyfile(char *filename)
1513
{
1514
492
	struct stat	 sb;
1515
	int		 fd;
1516
	unsigned char	*hex;
1517
1518
246
	if ((fd = open(filename, O_RDONLY)) < 0)
1519
		err(1, "open %s", filename);
1520
246
	if (fstat(fd, &sb) < 0)
1521
		err(1, "parsekeyfile: stat %s", filename);
1522

492
	if ((sb.st_size > KEYSIZE_LIMIT) || (sb.st_size == 0))
1523
		errx(1, "%s: key too %s", filename, sb.st_size ? "large" :
1524
		    "small");
1525
246
	if ((hex = calloc(sb.st_size, sizeof(unsigned char))) == NULL)
1526
		err(1, "parsekeyfile: calloc");
1527
246
	if (read(fd, hex, sb.st_size) < sb.st_size)
1528
		err(1, "parsekeyfile: read");
1529
246
	close(fd);
1530
492
	return (parsekey(hex, sb.st_size));
1531
246
}
1532
1533
int
1534
get_id_type(char *string)
1535
{
1536
912
	struct in6_addr ia;
1537
1538
456
	if (string == NULL)
1539
350
		return (ID_UNKNOWN);
1540
1541
106
	if (inet_pton(AF_INET, string, &ia) == 1)
1542
4
		return (ID_IPV4);
1543
102
	else if (inet_pton(AF_INET6, string, &ia) == 1)
1544
4
		return (ID_IPV6);
1545
98
	else if (strchr(string, '@'))
1546
4
		return (ID_UFQDN);
1547
	else
1548
94
		return (ID_FQDN);
1549
456
}
1550
1551
struct ipsec_addr_wrap *
1552
host(const char *s)
1553
{
1554
	struct ipsec_addr_wrap	*ipa = NULL;
1555
	int			 mask, cont = 1;
1556
1772
	char			*p, *q, *ps;
1557
1558
886
	if ((p = strrchr(s, '/')) != NULL) {
1559
202
		errno = 0;
1560
202
		mask = strtol(p + 1, &q, 0);
1561

606
		if (errno == ERANGE || !q || *q || mask > 128 || q == (p + 1))
1562
			errx(1, "host: invalid netmask '%s'", p);
1563
202
		if ((ps = malloc(strlen(s) - strlen(p) + 1)) == NULL)
1564
			err(1, "host: calloc");
1565
202
		strlcpy(ps, s, strlen(s) - strlen(p) + 1);
1566
202
	} else {
1567
684
		if ((ps = strdup(s)) == NULL)
1568
			err(1, "host: strdup");
1569
		mask = -1;
1570
	}
1571
1572
	/* Does interface with this name exist? */
1573

1772
	if (cont && (ipa = host_if(ps, mask)) != NULL)
1574
1
		cont = 0;
1575
1576
	/* IPv4 address? */
1577

1771
	if (cont && (ipa = host_v4(s, mask == -1 ? 32 : mask)) != NULL)
1578
552
		cont = 0;
1579
1580
	/* IPv6 address? */
1581

1219
	if (cont && (ipa = host_v6(ps, mask == -1 ? 128 : mask)) != NULL)
1582
332
		cont = 0;
1583
1584
	/* dns lookup */
1585

887
	if (cont && mask == -1 && (ipa = host_dns(s, mask)) != NULL)
1586
1
		cont = 0;
1587
886
	free(ps);
1588
1589
886
	if (ipa == NULL || cont == 1) {
1590
		fprintf(stderr, "no IP address found for %s\n", s);
1591
		return (NULL);
1592
	}
1593
886
	return (ipa);
1594
886
}
1595
1596
struct ipsec_addr_wrap *
1597
host_v6(const char *s, int prefixlen)
1598
{
1599
	struct ipsec_addr_wrap	*ipa = NULL;
1600
666
	struct addrinfo		 hints, *res;
1601
333
	char			 hbuf[NI_MAXHOST];
1602
1603
333
	bzero(&hints, sizeof(struct addrinfo));
1604
333
	hints.ai_family = AF_INET6;
1605
333
	hints.ai_socktype = SOCK_STREAM;
1606
333
	hints.ai_flags = AI_NUMERICHOST;
1607
333
	if (getaddrinfo(s, NULL, &hints, &res))
1608
1
		return (NULL);
1609
332
	if (res->ai_next)
1610
		err(1, "host_v6: numeric hostname expanded to multiple item");
1611
1612
332
	ipa = calloc(1, sizeof(struct ipsec_addr_wrap));
1613
332
	if (ipa == NULL)
1614
		err(1, "host_v6: calloc");
1615
332
	ipa->af = res->ai_family;
1616
664
	memcpy(&ipa->address.v6,
1617
332
	    &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
1618
	    sizeof(struct in6_addr));
1619
332
	if (prefixlen > 128)
1620
		prefixlen = 128;
1621
332
	ipa->next = NULL;
1622
332
	ipa->tail = ipa;
1623
1624
332
	set_ipmask(ipa, prefixlen);
1625
664
	if (getnameinfo(res->ai_addr, res->ai_addrlen,
1626
332
	    hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST)) {
1627
		errx(1, "could not get a numeric hostname");
1628
	}
1629
1630
332
	if (prefixlen != 128) {
1631
66
		ipa->netaddress = 1;
1632
66
		if (asprintf(&ipa->name, "%s/%d", hbuf, prefixlen) == -1)
1633
			err(1, "host_v6: asprintf");
1634
	} else {
1635
266
		if ((ipa->name = strdup(hbuf)) == NULL)
1636
			err(1, "host_v6: strdup");
1637
	}
1638
1639
332
	freeaddrinfo(res);
1640
1641
332
	return (ipa);
1642
333
}
1643
1644
struct ipsec_addr_wrap *
1645
host_v4(const char *s, int mask)
1646
{
1647
	struct ipsec_addr_wrap	*ipa = NULL;
1648
1770
	struct in_addr		 ina;
1649
	int			 bits = 32;
1650
1651
885
	bzero(&ina, sizeof(struct in_addr));
1652
885
	if (strrchr(s, '/') != NULL) {
1653
202
		if ((bits = inet_net_pton(AF_INET, s, &ina, sizeof(ina))) == -1)
1654
66
			return (NULL);
1655
	} else {
1656
683
		if (inet_pton(AF_INET, s, &ina) != 1)
1657
267
			return (NULL);
1658
	}
1659
1660
552
	ipa = calloc(1, sizeof(struct ipsec_addr_wrap));
1661
552
	if (ipa == NULL)
1662
		err(1, "host_v4: calloc");
1663
1664
552
	ipa->address.v4 = ina;
1665
552
	ipa->name = strdup(s);
1666
552
	if (ipa->name == NULL)
1667
		err(1, "host_v4: strdup");
1668
552
	ipa->af = AF_INET;
1669
552
	ipa->next = NULL;
1670
552
	ipa->tail = ipa;
1671
1672
552
	set_ipmask(ipa, bits);
1673
552
	if (strrchr(s, '/') != NULL)
1674
136
		ipa->netaddress = 1;
1675
1676
552
	return (ipa);
1677
885
}
1678
1679
struct ipsec_addr_wrap *
1680
host_dns(const char *s, int mask)
1681
{
1682
	struct ipsec_addr_wrap	*ipa = NULL, *head = NULL;
1683
2
	struct addrinfo		 hints, *res0, *res;
1684
	int			 error;
1685
1
	char			 hbuf[NI_MAXHOST];
1686
1687
1
	bzero(&hints, sizeof(struct addrinfo));
1688
1
	hints.ai_family = PF_UNSPEC;
1689
1
	hints.ai_socktype = SOCK_STREAM;
1690
1
	error = getaddrinfo(s, NULL, &hints, &res0);
1691
1
	if (error)
1692
		return (NULL);
1693
1694
6
	for (res = res0; res; res = res->ai_next) {
1695

3
		if (res->ai_family != AF_INET && res->ai_family != AF_INET6)
1696
			continue;
1697
1698
2
		ipa = calloc(1, sizeof(struct ipsec_addr_wrap));
1699
2
		if (ipa == NULL)
1700
			err(1, "host_dns: calloc");
1701
4
		switch (res->ai_family) {
1702
		case AF_INET:
1703
2
			memcpy(&ipa->address.v4,
1704
1
			    &((struct sockaddr_in *)res->ai_addr)->sin_addr,
1705
			    sizeof(struct in_addr));
1706
1
			break;
1707
		case AF_INET6:
1708
			/* XXX we do not support scoped IPv6 address yet */
1709
1
			if (((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id) {
1710
				free(ipa);
1711
				continue;
1712
			}
1713
2
			memcpy(&ipa->address.v6,
1714
1
			    &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
1715
			    sizeof(struct in6_addr));
1716
1
			break;
1717
		}
1718
2
		error = getnameinfo(res->ai_addr, res->ai_addrlen, hbuf,
1719
		    sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
1720
2
		if (error)
1721
			err(1, "host_dns: getnameinfo");
1722
2
		ipa->name = strdup(hbuf);
1723
2
		if (ipa->name == NULL)
1724
			err(1, "host_dns: strdup");
1725
2
		ipa->af = res->ai_family;
1726
2
		ipa->next = NULL;
1727
2
		ipa->tail = ipa;
1728
2
		if (head == NULL)
1729
1
			head = ipa;
1730
		else {
1731
1
			head->tail->next = ipa;
1732
1
			head->tail = ipa;
1733
		}
1734
1735
		/*
1736
		 * XXX for now, no netmask support for IPv6.
1737
		 * but since there's no way to specify address family, once you
1738
		 * have IPv6 address on a host, you cannot use dns/netmask
1739
		 * syntax.
1740
		 */
1741
2
		if (ipa->af == AF_INET)
1742
1
			set_ipmask(ipa, mask == -1 ? 32 : mask);
1743
		else
1744
1
			if (mask != -1)
1745
				err(1, "host_dns: cannot apply netmask "
1746
				    "on non-IPv4 address");
1747
	}
1748
1
	freeaddrinfo(res0);
1749
1750
1
	return (head);
1751
1
}
1752
1753
struct ipsec_addr_wrap *
1754
host_if(const char *s, int mask)
1755
{
1756
	struct ipsec_addr_wrap *ipa = NULL;
1757
1758
1772
	if (ifa_exists(s))
1759
1
		ipa = ifa_lookup(s);
1760
1761
886
	return (ipa);
1762
}
1763
1764
struct ipsec_addr_wrap *
1765
host_any(void)
1766
{
1767
	struct ipsec_addr_wrap	*ipa;
1768
1769
78
	ipa = calloc(1, sizeof(struct ipsec_addr_wrap));
1770
39
	if (ipa == NULL)
1771
		err(1, "host_any: calloc");
1772
39
	ipa->af = AF_UNSPEC;
1773
39
	ipa->netaddress = 1;
1774
39
	ipa->tail = ipa;
1775
39
	return (ipa);
1776
}
1777
1778
/* interface lookup routintes */
1779
1780
struct ipsec_addr_wrap	*iftab;
1781
1782
void
1783
ifa_load(void)
1784
{
1785
388
	struct ifaddrs		*ifap, *ifa;
1786
	struct ipsec_addr_wrap	*n = NULL, *h = NULL;
1787
1788
194
	if (getifaddrs(&ifap) < 0)
1789
		err(1, "ifa_load: getifaddrs");
1790
1791
5044
	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
1792

3686
		if (!(ifa->ifa_addr->sa_family == AF_INET ||
1793
1746
		    ifa->ifa_addr->sa_family == AF_INET6 ||
1794
1358
		    ifa->ifa_addr->sa_family == AF_LINK))
1795
			continue;
1796
2328
		n = calloc(1, sizeof(struct ipsec_addr_wrap));
1797
2328
		if (n == NULL)
1798
			err(1, "ifa_load: calloc");
1799
2328
		n->af = ifa->ifa_addr->sa_family;
1800
2328
		if ((n->name = strdup(ifa->ifa_name)) == NULL)
1801
			err(1, "ifa_load: strdup");
1802
2328
		if (n->af == AF_INET) {
1803
582
			n->af = AF_INET;
1804
1164
			memcpy(&n->address.v4, &((struct sockaddr_in *)
1805
582
			    ifa->ifa_addr)->sin_addr,
1806
			    sizeof(struct in_addr));
1807
1164
			memcpy(&n->mask.v4, &((struct sockaddr_in *)
1808
582
			    ifa->ifa_netmask)->sin_addr,
1809
			    sizeof(struct in_addr));
1810
2328
		} else if (n->af == AF_INET6) {
1811
388
			n->af = AF_INET6;
1812
776
			memcpy(&n->address.v6, &((struct sockaddr_in6 *)
1813
388
			    ifa->ifa_addr)->sin6_addr,
1814
			    sizeof(struct in6_addr));
1815
776
			memcpy(&n->mask.v6, &((struct sockaddr_in6 *)
1816
388
			    ifa->ifa_netmask)->sin6_addr,
1817
			    sizeof(struct in6_addr));
1818
388
		}
1819
2328
		n->next = NULL;
1820
2328
		n->tail = n;
1821
2328
		if (h == NULL)
1822
194
			h = n;
1823
		else {
1824
2134
			h->tail->next = n;
1825
2134
			h->tail = n;
1826
		}
1827
	}
1828
1829
194
	iftab = h;
1830
194
	freeifaddrs(ifap);
1831
194
}
1832
1833
int
1834
ifa_exists(const char *ifa_name)
1835
{
1836
	struct ipsec_addr_wrap	*n;
1837
1772
	struct ifgroupreq	 ifgr;
1838
	int			 s;
1839
1840
886
	if (iftab == NULL)
1841
194
		ifa_load();
1842
1843
	/* check whether this is a group */
1844
886
	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
1845
		err(1, "ifa_exists: socket");
1846
886
	bzero(&ifgr, sizeof(ifgr));
1847
886
	strlcpy(ifgr.ifgr_name, ifa_name, sizeof(ifgr.ifgr_name));
1848
1772
	if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == 0) {
1849
886
		close(s);
1850
		return (1);
1851
	}
1852
	close(s);
1853
1854
23012
	for (n = iftab; n; n = n->next) {
1855

16817
		if (n->af == AF_LINK && !strncmp(n->name, ifa_name,
1856
		    IFNAMSIZ))
1857
1
			return (1);
1858
	}
1859
1860
885
	return (0);
1861
886
}
1862
1863
struct ipsec_addr_wrap *
1864
ifa_grouplookup(const char *ifa_name)
1865
{
1866
	struct ifg_req		*ifg;
1867
2
	struct ifgroupreq	 ifgr;
1868
	int			 s;
1869
	size_t			 len;
1870
	struct ipsec_addr_wrap	*n, *h = NULL, *hn;
1871
1872
1
	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
1873
		err(1, "socket");
1874
1
	bzero(&ifgr, sizeof(ifgr));
1875
1
	strlcpy(ifgr.ifgr_name, ifa_name, sizeof(ifgr.ifgr_name));
1876
1
	if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) {
1877
1
		close(s);
1878
1
		return (NULL);
1879
	}
1880
1881
	len = ifgr.ifgr_len;
1882
	if ((ifgr.ifgr_groups = calloc(1, len)) == NULL)
1883
		err(1, "calloc");
1884
	if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1)
1885
		err(1, "ioctl");
1886
1887
	for (ifg = ifgr.ifgr_groups; ifg && len >= sizeof(struct ifg_req);
1888
	    ifg++) {
1889
		len -= sizeof(struct ifg_req);
1890
		if ((n = ifa_lookup(ifg->ifgrq_member)) == NULL)
1891
			continue;
1892
		if (h == NULL)
1893
			h = n;
1894
		else {
1895
			for (hn = h; hn->next != NULL; hn = hn->next)
1896
				;	/* nothing */
1897
			hn->next = n;
1898
			n->tail = hn;
1899
		}
1900
	}
1901
	free(ifgr.ifgr_groups);
1902
	close(s);
1903
1904
	return (h);
1905
1
}
1906
1907
struct ipsec_addr_wrap *
1908
ifa_lookup(const char *ifa_name)
1909
{
1910
	struct ipsec_addr_wrap	*p = NULL, *h = NULL, *n = NULL;
1911
1912
2
	if (iftab == NULL)
1913
		ifa_load();
1914
1915
1
	if ((n = ifa_grouplookup(ifa_name)) != NULL)
1916
		return (n);
1917
1918
26
	for (p = iftab; p; p = p->next) {
1919

21
		if (p->af != AF_INET && p->af != AF_INET6)
1920
			continue;
1921
5
		if (strncmp(p->name, ifa_name, IFNAMSIZ))
1922
			continue;
1923
3
		n = calloc(1, sizeof(struct ipsec_addr_wrap));
1924
3
		if (n == NULL)
1925
			err(1, "ifa_lookup: calloc");
1926
3
		memcpy(n, p, sizeof(struct ipsec_addr_wrap));
1927
3
		if ((n->name = strdup(p->name)) == NULL)
1928
			err(1, "ifa_lookup: strdup");
1929
5
		switch (n->af) {
1930
		case AF_INET:
1931
1
			set_ipmask(n, 32);
1932
1
			break;
1933
		case AF_INET6:
1934
			/* route/show.c and bgpd/util.c give KAME credit */
1935

3
			if (IN6_IS_ADDR_LINKLOCAL(&n->address.v6)) {
1936
				u_int16_t tmp16;
1937
				/* for now we can not handle link local,
1938
				 * therefore bail for now
1939
				 */
1940
1
				free(n);
1941
				continue;
1942
1943
				memcpy(&tmp16, &n->address.v6.s6_addr[2],
1944
				    sizeof(tmp16));
1945
				/* use this when we support link-local
1946
				 * n->??.scopeid = ntohs(tmp16);
1947
				 */
1948
				n->address.v6.s6_addr[2] = 0;
1949
				n->address.v6.s6_addr[3] = 0;
1950
			}
1951
1
			set_ipmask(n, 128);
1952
1
			break;
1953
		}
1954
1955
2
		n->next = NULL;
1956
2
		n->tail = n;
1957
2
		if (h == NULL)
1958
1
			h = n;
1959
		else {
1960
1
			h->tail->next = n;
1961
1
			h->tail = n;
1962
		}
1963
	}
1964
1965
1
	return (h);
1966
1
}
1967
1968
void
1969
set_ipmask(struct ipsec_addr_wrap *address, u_int8_t b)
1970
{
1971
	struct ipsec_addr	*ipa;
1972
	int			 i, j = 0;
1973
1974
1774
	ipa = &address->mask;
1975
887
	bzero(ipa, sizeof(struct ipsec_addr));
1976
1977
4850
	while (b >= 32) {
1978
1538
		ipa->addr32[j++] = 0xffffffff;
1979
1538
		b -= 32;
1980
	}
1981
9790
	for (i = 31; i > 31 - b; --i)
1982
4008
		ipa->addr32[j] |= (1 << i);
1983
887
	if (b)
1984
171
		ipa->addr32[j] = htonl(ipa->addr32[j]);
1985
887
}
1986
1987
const struct ipsec_xf *
1988
parse_xf(const char *name, const struct ipsec_xf xfs[])
1989
{
1990
	int		i;
1991
1992
3046
	for (i = 0; xfs[i].name != NULL; i++) {
1993
1424
		if (strncmp(name, xfs[i].name, strlen(name)))
1994
			continue;
1995
198
		return &xfs[i];
1996
	}
1997
	return (NULL);
1998
198
}
1999
2000
struct ipsec_lifetime *
2001
parse_life(const char *value)
2002
{
2003
	struct ipsec_lifetime	*life;
2004
	int			ret;
2005
	int			seconds = 0;
2006
	char			unit = 0;
2007
2008
	ret = sscanf(value, "%d%c", &seconds, &unit);
2009
	if (ret == 2) {
2010
		switch (tolower((unsigned char)unit)) {
2011
		case 'm':
2012
			seconds *= 60;
2013
			break;
2014
		case 'h':
2015
			seconds *= 60 * 60;
2016
			break;
2017
		default:
2018
			err(1, "invalid time unit");
2019
		}
2020
	} else if (ret != 1)
2021
		err(1, "invalid time specification: %s", value);
2022
2023
	life = calloc(1, sizeof(struct ipsec_lifetime));
2024
	if (life == NULL)
2025
		err(1, "calloc");
2026
2027
	life->lt_seconds = seconds;
2028
	life->lt_bytes = -1;
2029
2030
	return (life);
2031
}
2032
2033
struct ipsec_transforms *
2034
copytransforms(const struct ipsec_transforms *xfs)
2035
{
2036
	struct ipsec_transforms *newxfs;
2037
2038
2570
	if (xfs == NULL)
2039
1054
		return (NULL);
2040
2041
231
	newxfs = calloc(1, sizeof(struct ipsec_transforms));
2042
231
	if (newxfs == NULL)
2043
		err(1, "copytransforms: calloc");
2044
2045
231
	memcpy(newxfs, xfs, sizeof(struct ipsec_transforms));
2046
231
	return (newxfs);
2047
1285
}
2048
2049
struct ipsec_lifetime *
2050
copylife(const struct ipsec_lifetime *life)
2051
{
2052
	struct ipsec_lifetime *newlife;
2053
2054
1592
	if (life == NULL)
2055
753
		return (NULL);
2056
2057
43
	newlife = calloc(1, sizeof(struct ipsec_lifetime));
2058
43
	if (newlife == NULL)
2059
		err(1, "copylife: calloc");
2060
2061
43
	memcpy(newlife, life, sizeof(struct ipsec_lifetime));
2062
43
	return (newlife);
2063
796
}
2064
2065
struct ipsec_auth *
2066
copyipsecauth(const struct ipsec_auth *auth)
2067
{
2068
	struct ipsec_auth	*newauth;
2069
2070
796
	if (auth == NULL)
2071
120
		return (NULL);
2072
2073
278
	if ((newauth = calloc(1, sizeof(struct ipsec_auth))) == NULL)
2074
		err(1, "calloc");
2075

334
	if (auth->srcid &&
2076
56
	    asprintf(&newauth->srcid, "%s", auth->srcid) == -1)
2077
		err(1, "asprintf");
2078

330
	if (auth->dstid &&
2079
52
	    asprintf(&newauth->dstid, "%s", auth->dstid) == -1)
2080
		err(1, "asprintf");
2081
2082
278
	newauth->srcid_type = auth->srcid_type;
2083
278
	newauth->dstid_type = auth->dstid_type;
2084
278
	newauth->type = auth->type;
2085
2086
278
	return (newauth);
2087
398
}
2088
2089
struct ike_auth *
2090
copyikeauth(const struct ike_auth *auth)
2091
{
2092
	struct ike_auth	*newauth;
2093
2094
796
	if (auth == NULL)
2095
224
		return (NULL);
2096
2097
174
	if ((newauth = calloc(1, sizeof(struct ike_auth))) == NULL)
2098
		err(1, "calloc");
2099

181
	if (auth->string &&
2100
7
	    asprintf(&newauth->string, "%s", auth->string) == -1)
2101
		err(1, "asprintf");
2102
2103
174
	newauth->type = auth->type;
2104
2105
174
	return (newauth);
2106
398
}
2107
2108
struct ipsec_key *
2109
copykey(struct ipsec_key *key)
2110
{
2111
	struct ipsec_key	*newkey;
2112
2113
1592
	if (key == NULL)
2114
658
		return (NULL);
2115
2116
138
	if ((newkey = calloc(1, sizeof(struct ipsec_key))) == NULL)
2117
		err(1, "calloc");
2118
138
	if ((newkey->data = calloc(key->len, sizeof(u_int8_t))) == NULL)
2119
		err(1, "calloc");
2120
138
	memcpy(newkey->data, key->data, key->len);
2121
138
	newkey->len = key->len;
2122
2123
138
	return (newkey);
2124
796
}
2125
2126
struct ipsec_addr_wrap *
2127
copyhost(const struct ipsec_addr_wrap *src)
2128
{
2129
	struct ipsec_addr_wrap *dst;
2130
2131
6962
	if (src == NULL)
2132
1171
		return (NULL);
2133
2134
2310
	dst = calloc(1, sizeof(struct ipsec_addr_wrap));
2135
2310
	if (dst == NULL)
2136
		err(1, "copyhost: calloc");
2137
2138
2310
	memcpy(dst, src, sizeof(struct ipsec_addr_wrap));
2139
2140

4615
	if (src->name != NULL && (dst->name = strdup(src->name)) == NULL)
2141
		err(1, "copyhost: strdup");
2142
2143
2310
	return dst;
2144
3481
}
2145
2146
char *
2147
copytag(const char *src)
2148
{
2149
	char *tag;
2150
2151
796
	if (src == NULL)
2152
398
		return (NULL);
2153
	if ((tag = strdup(src)) == NULL)
2154
		err(1, "copytag: strdup");
2155
2156
	return (tag);
2157
398
}
2158
2159
struct ipsec_rule *
2160
copyrule(struct ipsec_rule *rule)
2161
{
2162
	struct ipsec_rule	*r;
2163
2164
796
	if ((r = calloc(1, sizeof(struct ipsec_rule))) == NULL)
2165
		err(1, "calloc");
2166
2167
398
	r->src = copyhost(rule->src);
2168
398
	r->dst = copyhost(rule->dst);
2169
398
	r->local = copyhost(rule->local);
2170
398
	r->peer = copyhost(rule->peer);
2171
398
	r->auth = copyipsecauth(rule->auth);
2172
398
	r->ikeauth = copyikeauth(rule->ikeauth);
2173
398
	r->xfs = copytransforms(rule->xfs);
2174
398
	r->p1xfs = copytransforms(rule->p1xfs);
2175
398
	r->p2xfs = copytransforms(rule->p2xfs);
2176
398
	r->p1life = copylife(rule->p1life);
2177
398
	r->p2life = copylife(rule->p2life);
2178
398
	r->authkey = copykey(rule->authkey);
2179
398
	r->enckey = copykey(rule->enckey);
2180
398
	r->tag = copytag(rule->tag);
2181
2182
398
	r->p1ie = rule->p1ie;
2183
398
	r->p2ie = rule->p2ie;
2184
398
	r->type = rule->type;
2185
398
	r->satype = rule->satype;
2186
398
	r->proto = rule->proto;
2187
398
	r->tmode = rule->tmode;
2188
398
	r->direction = rule->direction;
2189
398
	r->flowtype = rule->flowtype;
2190
398
	r->sport = rule->sport;
2191
398
	r->dport = rule->dport;
2192
398
	r->ikemode = rule->ikemode;
2193
398
	r->spi = rule->spi;
2194
398
	r->nr = rule->nr;
2195
2196
398
	return (r);
2197
}
2198
2199
int
2200
validate_af(struct ipsec_addr_wrap *src, struct ipsec_addr_wrap *dst)
2201
{
2202
	struct ipsec_addr_wrap *ta;
2203
	u_int8_t src_v4 = 0;
2204
	u_int8_t dst_v4 = 0;
2205
	u_int8_t src_v6 = 0;
2206
	u_int8_t dst_v6 = 0;
2207
2208
1764
	for (ta = src; ta; ta = ta->next) {
2209
367
		if (ta->af == AF_INET)
2210
224
			src_v4 = 1;
2211
367
		if (ta->af == AF_INET6)
2212
136
			src_v6 = 1;
2213
367
		if (ta->af == AF_UNSPEC)
2214
7
			return 0;
2215

585
		if (src_v4 && src_v6)
2216
			break;
2217
	}
2218
1358
	for (ta = dst; ta; ta = ta->next) {
2219
361
		if (ta->af == AF_INET)
2220
209
			dst_v4 = 1;
2221
361
		if (ta->af == AF_INET6)
2222
129
			dst_v6 = 1;
2223
361
		if (ta->af == AF_UNSPEC)
2224
23
			return 0;
2225

548
		if (dst_v4 && dst_v6)
2226
			break;
2227
	}
2228

327
	if (src_v4 != dst_v4 && src_v6 != dst_v6)
2229
6
		return (1);
2230
2231
314
	return (0);
2232
350
}
2233
2234
2235
int
2236
validate_sa(u_int32_t spi, u_int8_t satype, struct ipsec_transforms *xfs,
2237
    struct ipsec_key *authkey, struct ipsec_key *enckey, u_int8_t tmode)
2238
{
2239
	/* Sanity checks */
2240
416
	if (spi == 0) {
2241
		yyerror("no SPI specified");
2242
		return (0);
2243
	}
2244
208
	if (satype == IPSEC_AH) {
2245
66
		if (!xfs) {
2246
			yyerror("no transforms specified");
2247
			return (0);
2248
		}
2249
66
		if (!xfs->authxf)
2250
9
			xfs->authxf = &authxfs[AUTHXF_HMAC_SHA2_256];
2251
66
		if (xfs->encxf) {
2252
			yyerror("ah does not provide encryption");
2253
			return (0);
2254
		}
2255
66
		if (xfs->compxf) {
2256
			yyerror("ah does not provide compression");
2257
			return (0);
2258
		}
2259
	}
2260
208
	if (satype == IPSEC_ESP) {
2261
113
		if (!xfs) {
2262
			yyerror("no transforms specified");
2263
			return (0);
2264
		}
2265
113
		if (xfs->compxf) {
2266
1
			yyerror("esp does not provide compression");
2267
1
			return (0);
2268
		}
2269
112
		if (!xfs->encxf)
2270
19
			xfs->encxf = &encxfs[ENCXF_AES];
2271
112
		if (xfs->encxf->nostatic) {
2272
10
			yyerror("%s is disallowed with static keys",
2273
10
			    xfs->encxf->name);
2274
10
			return 0;
2275
		}
2276

102
		if (xfs->encxf->noauth && xfs->authxf) {
2277
			yyerror("authentication is implicit for %s",
2278
			    xfs->encxf->name);
2279
			return (0);
2280

204
		} else if (!xfs->encxf->noauth && !xfs->authxf)
2281
19
			xfs->authxf = &authxfs[AUTHXF_HMAC_SHA2_256];
2282
	}
2283
197
	if (satype == IPSEC_IPCOMP) {
2284
17
		if (!xfs) {
2285
			yyerror("no transform specified");
2286
			return (0);
2287
		}
2288

33
		if (xfs->authxf || xfs->encxf) {
2289
1
			yyerror("no encryption or authentication with ipcomp");
2290
1
			return (0);
2291
		}
2292
16
		if (!xfs->compxf)
2293
4
			xfs->compxf = &compxfs[COMPXF_DEFLATE];
2294
	}
2295
196
	if (satype == IPSEC_IPIP) {
2296
6
		if (!xfs) {
2297
			yyerror("no transform specified");
2298
			return (0);
2299
		}
2300

18
		if (xfs->authxf || xfs->encxf || xfs->compxf) {
2301
			yyerror("no encryption, authentication or compression"
2302
			    " with ipip");
2303
			return (0);
2304
		}
2305
	}
2306

196
	if (satype == IPSEC_TCPMD5 && authkey == NULL && tmode !=
2307
	    IPSEC_TRANSPORT) {
2308
		yyerror("authentication key needed for tcpmd5");
2309
		return (0);
2310
	}
2311

386
	if (xfs && xfs->authxf) {
2312

168
		if (!authkey && xfs->authxf != &authxfs[AUTHXF_NONE]) {
2313
			yyerror("no authentication key specified");
2314
			return (0);
2315
		}
2316

336
		if (authkey && authkey->len != xfs->authxf->keymin) {
2317
			yyerror("wrong authentication key length, needs to be "
2318
			    "%zu bits", xfs->authxf->keymin * 8);
2319
			return (0);
2320
		}
2321
	}
2322

386
	if (xfs && xfs->encxf) {
2323

116
		if (!enckey && xfs->encxf != &encxfs[ENCXF_NULL]) {
2324
			yyerror("no encryption key specified");
2325
			return (0);
2326
		}
2327
102
		if (enckey) {
2328
88
			if (enckey->len < xfs->encxf->keymin) {
2329
				yyerror("encryption key too short (%zu bits), "
2330
				    "minimum %zu bits", enckey->len * 8,
2331
				    xfs->encxf->keymin * 8);
2332
				return (0);
2333
			}
2334
88
			if (xfs->encxf->keymax < enckey->len) {
2335
				yyerror("encryption key too long (%zu bits), "
2336
				    "maximum %zu bits", enckey->len * 8,
2337
				    xfs->encxf->keymax * 8);
2338
				return (0);
2339
			}
2340
		}
2341
	}
2342
2343
196
	return 1;
2344
208
}
2345
2346
int
2347
add_sabundle(struct ipsec_rule *r, char *bundle)
2348
{
2349
	struct ipsec_rule	*rp, *last, *sabundle;
2350
	int			 found = 0;
2351
2352
136
	TAILQ_FOREACH(rp, &ipsec->bundle_queue, bundle_entry) {
2353

60
		if ((strcmp(rp->src->name, r->src->name) == 0) &&
2354
19
		    (strcmp(rp->dst->name, r->dst->name) == 0) &&
2355
16
		    (strcmp(rp->bundle, bundle) == 0)) {
2356
			found = 1;
2357
12
			break;
2358
		}
2359
	}
2360
24
	if (found) {
2361
12
		last = TAILQ_LAST(&rp->dst_bundle_queue, dst_bundle_queue);
2362
12
		TAILQ_INSERT_TAIL(&rp->dst_bundle_queue, r, dst_bundle_entry);
2363
2364
24
		sabundle = create_sabundle(last->dst, last->satype, last->spi,
2365
12
		    r->dst, r->satype, r->spi);
2366
12
		if (sabundle == NULL)
2367
			return (1);
2368
12
		sabundle->nr = ipsec->rule_nr++;
2369
12
		if (ipsecctl_add_rule(ipsec, sabundle))
2370
			return (1);
2371
	} else {
2372
12
		TAILQ_INSERT_TAIL(&ipsec->bundle_queue, r, bundle_entry);
2373
12
		TAILQ_INIT(&r->dst_bundle_queue);
2374
12
		TAILQ_INSERT_TAIL(&r->dst_bundle_queue, r, dst_bundle_entry);
2375
12
		r->bundle = bundle;
2376
	}
2377
2378
24
	return (0);
2379
24
}
2380
2381
struct ipsec_rule *
2382
create_sa(u_int8_t satype, u_int8_t tmode, struct ipsec_hosts *hosts,
2383
    u_int32_t spi, struct ipsec_transforms *xfs, struct ipsec_key *authkey,
2384
    struct ipsec_key *enckey)
2385
{
2386
	struct ipsec_rule *r;
2387
2388
234
	if (validate_sa(spi, satype, xfs, authkey, enckey, tmode) == 0)
2389
12
		return (NULL);
2390
2391
105
	r = calloc(1, sizeof(struct ipsec_rule));
2392
105
	if (r == NULL)
2393
		err(1, "create_sa: calloc");
2394
2395
105
	r->type |= RULE_SA;
2396
105
	r->satype = satype;
2397
105
	r->tmode = tmode;
2398
105
	r->src = hosts->src;
2399
105
	r->dst = hosts->dst;
2400
105
	r->spi = spi;
2401
105
	r->xfs = xfs;
2402
105
	r->authkey = authkey;
2403
105
	r->enckey = enckey;
2404
2405
105
	return r;
2406
117
}
2407
2408
struct ipsec_rule *
2409
reverse_sa(struct ipsec_rule *rule, u_int32_t spi, struct ipsec_key *authkey,
2410
    struct ipsec_key *enckey)
2411
{
2412
	struct ipsec_rule *reverse;
2413
2414
364
	if (validate_sa(spi, rule->satype, rule->xfs, authkey, enckey,
2415
182
	    rule->tmode) == 0)
2416
		return (NULL);
2417
2418
91
	reverse = calloc(1, sizeof(struct ipsec_rule));
2419
91
	if (reverse == NULL)
2420
		err(1, "reverse_sa: calloc");
2421
2422
91
	reverse->type |= RULE_SA;
2423
91
	reverse->satype = rule->satype;
2424
91
	reverse->tmode = rule->tmode;
2425
91
	reverse->src = copyhost(rule->dst);
2426
91
	reverse->dst = copyhost(rule->src);
2427
91
	reverse->spi = spi;
2428
91
	reverse->xfs = copytransforms(rule->xfs);
2429
91
	reverse->authkey = authkey;
2430
91
	reverse->enckey = enckey;
2431
2432
91
	return (reverse);
2433
91
}
2434
2435
struct ipsec_rule *
2436
create_sabundle(struct ipsec_addr_wrap *dst, u_int8_t proto, u_int32_t spi,
2437
    struct ipsec_addr_wrap *dst2, u_int8_t proto2, u_int32_t spi2)
2438
{
2439
	struct ipsec_rule *r;
2440
2441
24
	r = calloc(1, sizeof(struct ipsec_rule));
2442
12
	if (r == NULL)
2443
		err(1, "create_sabundle: calloc");
2444
2445
12
	r->type |= RULE_BUNDLE;
2446
2447
12
	r->dst = copyhost(dst);
2448
12
	r->dst2 = copyhost(dst2);
2449
12
	r->proto = proto;
2450
12
	r->proto2 = proto2;
2451
12
	r->spi = spi;
2452
12
	r->spi2 = spi2;
2453
12
	r->satype = proto;
2454
2455
12
	return (r);
2456
}
2457
2458
struct ipsec_rule *
2459
create_flow(u_int8_t dir, u_int8_t proto, struct ipsec_hosts *hosts,
2460
    u_int8_t satype, char *srcid, char *dstid, u_int8_t type)
2461
{
2462
	struct ipsec_rule *r;
2463
2464
214
	r = calloc(1, sizeof(struct ipsec_rule));
2465
107
	if (r == NULL)
2466
		err(1, "create_flow: calloc");
2467
2468
107
	r->type |= RULE_FLOW;
2469
2470
107
	if (dir == IPSEC_INOUT)
2471
		r->direction = IPSEC_OUT;
2472
	else
2473
		r->direction = dir;
2474
2475
107
	r->satype = satype;
2476
107
	r->proto = proto;
2477
107
	r->src = hosts->src;
2478
107
	r->sport = hosts->sport;
2479
107
	r->dst = hosts->dst;
2480
107
	r->dport = hosts->dport;
2481

214
	if ((hosts->sport != 0 || hosts->dport != 0) &&
2482
7
	    (proto != IPPROTO_TCP && proto != IPPROTO_UDP)) {
2483
1
		yyerror("no protocol supplied with source/destination ports");
2484
		goto errout;
2485
	}
2486
2487
106
	switch (satype) {
2488
	case IPSEC_IPCOMP:
2489
	case IPSEC_IPIP:
2490
2
		if (type == TYPE_UNKNOWN)
2491
2
			type = TYPE_USE;
2492
		break;
2493
	default:
2494
104
		if (type == TYPE_UNKNOWN)
2495
63
			type = TYPE_REQUIRE;
2496
		break;
2497
	}
2498
2499
106
	r->flowtype = type;
2500

204
	if (type == TYPE_DENY || type == TYPE_BYPASS)
2501
17
		return (r);
2502
2503
89
	r->auth = calloc(1, sizeof(struct ipsec_auth));
2504
89
	if (r->auth == NULL)
2505
		err(1, "create_flow: calloc");
2506
89
	r->auth->srcid = srcid;
2507
89
	r->auth->dstid = dstid;
2508
89
	r->auth->srcid_type = get_id_type(srcid);
2509
89
	r->auth->dstid_type = get_id_type(dstid);
2510
89
	return r;
2511
2512
errout:
2513
1
	free(r);
2514
1
	if (srcid)
2515
		free(srcid);
2516
1
	if (dstid)
2517
		free(dstid);
2518
1
	free(hosts->src);
2519
1
	hosts->src = NULL;
2520
1
	free(hosts->dst);
2521
1
	hosts->dst = NULL;
2522
2523
1
	return NULL;
2524
107
}
2525
2526
void
2527
expand_any(struct ipsec_addr_wrap *ipa_in)
2528
{
2529
	struct ipsec_addr_wrap *oldnext, *ipa;
2530
2531
3584
	for (ipa = ipa_in; ipa; ipa = ipa->next) {
2532
760
		if (ipa->af != AF_UNSPEC)
2533
			continue;
2534
35
		oldnext = ipa->next;
2535
2536
35
		ipa->af = AF_INET;
2537
35
		ipa->netaddress = 1;
2538
35
		if ((ipa->name = strdup("0.0.0.0/0")) == NULL)
2539
			err(1, "expand_any: strdup");
2540
2541
35
		ipa->next = calloc(1, sizeof(struct ipsec_addr_wrap));
2542
35
		if (ipa->next == NULL)
2543
			err(1, "expand_any: calloc");
2544
35
		ipa->next->af = AF_INET6;
2545
35
		ipa->next->netaddress = 1;
2546
35
		if ((ipa->next->name = strdup("::/0")) == NULL)
2547
			err(1, "expand_any: strdup");
2548
2549
35
		ipa->next->next = oldnext;
2550
35
	}
2551
688
}
2552
2553
int
2554
set_rule_peers(struct ipsec_rule *r, struct ipsec_hosts *peers)
2555
{
2556

703
	if (r->type == RULE_FLOW &&
2557
234
	    (r->flowtype == TYPE_DENY || r->flowtype == TYPE_BYPASS))
2558
17
		return (0);
2559
2560
278
	r->local = copyhost(peers->src);
2561
278
	r->peer = copyhost(peers->dst);
2562
278
	if (r->peer == NULL) {
2563
		/* Set peer to remote host.  Must be a host address. */
2564
116
		if (r->direction == IPSEC_IN) {
2565
			if (!r->src->netaddress)
2566
				r->peer = copyhost(r->src);
2567
		} else {
2568
116
			if (!r->dst->netaddress)
2569
97
				r->peer = copyhost(r->dst);
2570
		}
2571
	}
2572

382
	if (r->type == RULE_FLOW && r->peer == NULL) {
2573
1
		yyerror("no peer specified for destination %s",
2574
1
		    r->dst->name);
2575
1
		return (1);
2576
	}
2577

536
	if (r->peer != NULL && r->peer->af == AF_UNSPEC) {
2578
		/* If peer has been specified as any, use the default peer. */
2579
5
		free(r->peer);
2580
5
		r->peer = NULL;
2581
5
	}
2582

451
	if (r->type == RULE_IKE && r->peer == NULL) {
2583
		/*
2584
                 * Check if the default peer is consistent for all
2585
                 * rules.  Only warn to avoid breaking existing configs.
2586
		 */
2587
		static struct ipsec_rule *pdr = NULL;
2588
2589
22
		if (pdr == NULL) {
2590
			/* Remember first default peer rule for comparison. */
2591
12
			pdr = r;
2592
12
		} else {
2593
			/* The new default peer must create the same config. */
2594

19
			if ((pdr->local == NULL && r->local != NULL) ||
2595

13
			    (pdr->local != NULL && r->local == NULL) ||
2596

11
			    (pdr->local != NULL && r->local != NULL &&
2597
2
			    strcmp(pdr->local->name, r->local->name)))
2598
2
				yywarn("default peer local mismatch");
2599
10
			if (pdr->ikeauth->type != r->ikeauth->type)
2600
1
				yywarn("default peer phase 1 auth mismatch");
2601

13
			if (pdr->ikeauth->type == IKE_AUTH_PSK &&
2602
4
			    r->ikeauth->type == IKE_AUTH_PSK &&
2603
3
			    strcmp(pdr->ikeauth->string, r->ikeauth->string))
2604
1
				yywarn("default peer psk mismatch");
2605
10
			if (pdr->p1ie != r->p1ie)
2606
1
				yywarn("default peer phase 1 mode mismatch");
2607
			/*
2608
			 * Transforms have ADD insted of SET so they may be
2609
			 * different and are not checked here.
2610
			 */
2611

12
			if ((pdr->auth->srcid == NULL &&
2612
7
			    r->auth->srcid != NULL) ||
2613
10
			    (pdr->auth->srcid != NULL &&
2614
3
			    r->auth->srcid == NULL) ||
2615
9
			    (pdr->auth->srcid != NULL &&
2616
2
			    r->auth->srcid != NULL &&
2617
2
			    strcmp(pdr->auth->srcid, r->auth->srcid)))
2618
2
				yywarn("default peer srcid mismatch");
2619

12
			if ((pdr->auth->dstid == NULL &&
2620
7
			    r->auth->dstid != NULL) ||
2621
10
			    (pdr->auth->dstid != NULL &&
2622
3
			    r->auth->dstid == NULL) ||
2623
9
			    (pdr->auth->dstid != NULL &&
2624
2
			    r->auth->dstid != NULL &&
2625
2
			    strcmp(pdr->auth->dstid, r->auth->dstid)))
2626
2
				yywarn("default peer dstid mismatch");
2627
		}
2628
	}
2629
277
	return (0);
2630
295
}
2631
2632
int
2633
expand_rule(struct ipsec_rule *rule, struct ipsec_hosts *peers,
2634
    u_int8_t direction, u_int32_t spi, struct ipsec_key *authkey,
2635
    struct ipsec_key *enckey, char *bundle)
2636
{
2637
	struct ipsec_rule	*r, *revr;
2638
	struct ipsec_addr_wrap	*src, *dst;
2639
	int added = 0, ret = 1;
2640
2641
700
	if (validate_af(rule->src, rule->dst)) {
2642
6
		yyerror("source/destination address families do not match");
2643
6
		goto errout;
2644
	}
2645
344
	expand_any(rule->src);
2646
344
	expand_any(rule->dst);
2647
1424
	for (src = rule->src; src; src = src->next) {
2648
1616
		for (dst = rule->dst; dst; dst = dst->next) {
2649
440
			if (src->af != dst->af)
2650
				continue;
2651
398
			r = copyrule(rule);
2652
2653
398
			r->src = copyhost(src);
2654
398
			r->dst = copyhost(dst);
2655
2656

693
			if (peers && set_rule_peers(r, peers)) {
2657
1
				ipsecctl_free_rule(r);
2658
1
				goto errout;
2659
			}
2660
2661
397
			r->nr = ipsec->rule_nr++;
2662
397
			if (ipsecctl_add_rule(ipsec, r))
2663
				goto out;
2664

409
			if (bundle && add_sabundle(r, bundle))
2665
				goto out;
2666
2667
397
			if (direction == IPSEC_INOUT) {
2668
				/* Create and add reverse flow rule. */
2669
78
				revr = reverse_rule(r);
2670
78
				if (revr == NULL)
2671
					goto out;
2672
2673
78
				revr->nr = ipsec->rule_nr++;
2674
78
				if (ipsecctl_add_rule(ipsec, revr))
2675
					goto out;
2676

78
				if (bundle && add_sabundle(revr, bundle))
2677
					goto out;
2678
319
			} else if (spi != 0 || authkey || enckey) {
2679
				/* Create and add reverse sa rule. */
2680
91
				revr = reverse_sa(r, spi, authkey, enckey);
2681
91
				if (revr == NULL)
2682
					goto out;
2683
2684
91
				revr->nr = ipsec->rule_nr++;
2685
91
				if (ipsecctl_add_rule(ipsec, revr))
2686
					goto out;
2687

103
				if (bundle && add_sabundle(revr, bundle))
2688
					goto out;
2689
			}
2690
397
			added++;
2691
397
		}
2692
	}
2693
343
	if (!added)
2694
		yyerror("rule expands to no valid combination");
2695
 errout:
2696
	ret = 0;
2697
350
	ipsecctl_free_rule(rule);
2698
 out:
2699
350
	if (peers) {
2700
245
		if (peers->src)
2701
18
			free(peers->src);
2702
245
		if (peers->dst)
2703
135
			free(peers->dst);
2704
	}
2705
350
	return (ret);
2706
}
2707
2708
struct ipsec_rule *
2709
reverse_rule(struct ipsec_rule *rule)
2710
{
2711
	struct ipsec_rule *reverse;
2712
2713
156
	reverse = calloc(1, sizeof(struct ipsec_rule));
2714
78
	if (reverse == NULL)
2715
		err(1, "reverse_rule: calloc");
2716
2717
78
	reverse->type |= RULE_FLOW;
2718
2719
	/* Reverse direction */
2720
78
	if (rule->direction == (u_int8_t)IPSEC_OUT)
2721
		reverse->direction = (u_int8_t)IPSEC_IN;
2722
	else
2723
		reverse->direction = (u_int8_t)IPSEC_OUT;
2724
2725
78
	reverse->flowtype = rule->flowtype;
2726
78
	reverse->src = copyhost(rule->dst);
2727
78
	reverse->dst = copyhost(rule->src);
2728
78
	reverse->sport = rule->dport;
2729
78
	reverse->dport = rule->sport;
2730
78
	if (rule->local)
2731
6
		reverse->local = copyhost(rule->local);
2732
78
	if (rule->peer)
2733
72
		reverse->peer = copyhost(rule->peer);
2734
78
	reverse->satype = rule->satype;
2735
78
	reverse->proto = rule->proto;
2736
2737
78
	if (rule->auth) {
2738
73
		reverse->auth = calloc(1, sizeof(struct ipsec_auth));
2739
73
		if (reverse->auth == NULL)
2740
			err(1, "reverse_rule: calloc");
2741

97
		if (rule->auth->dstid && (reverse->auth->dstid =
2742
24
		    strdup(rule->auth->dstid)) == NULL)
2743
			err(1, "reverse_rule: strdup");
2744

97
		if (rule->auth->srcid && (reverse->auth->srcid =
2745
24
		    strdup(rule->auth->srcid)) == NULL)
2746
			err(1, "reverse_rule: strdup");
2747
73
		reverse->auth->srcid_type = rule->auth->srcid_type;
2748
73
		reverse->auth->dstid_type = rule->auth->dstid_type;
2749
73
		reverse->auth->type = rule->auth->type;
2750
73
	}
2751
2752
78
	return reverse;
2753
}
2754
2755
struct ipsec_rule *
2756
create_ike(u_int8_t proto, struct ipsec_hosts *hosts,
2757
    struct ike_mode *phase1mode, struct ike_mode *phase2mode, u_int8_t satype,
2758
    u_int8_t tmode, u_int8_t mode, char *srcid, char *dstid,
2759
    struct ike_auth *authtype, char *tag)
2760
{
2761
	struct ipsec_rule *r;
2762
2763
280
	r = calloc(1, sizeof(struct ipsec_rule));
2764
140
	if (r == NULL)
2765
		err(1, "create_ike: calloc");
2766
2767
140
	r->type = RULE_IKE;
2768
2769
140
	r->proto = proto;
2770
140
	r->src = hosts->src;
2771
140
	r->sport = hosts->sport;
2772
140
	r->dst = hosts->dst;
2773
140
	r->dport = hosts->dport;
2774

279
	if ((hosts->sport != 0 || hosts->dport != 0) &&
2775
10
	    (proto != IPPROTO_TCP && proto != IPPROTO_UDP)) {
2776
1
		yyerror("no protocol supplied with source/destination ports");
2777
1
		goto errout;
2778
	}
2779
2780
139
	r->satype = satype;
2781
139
	r->tmode = tmode;
2782
139
	r->ikemode = mode;
2783
139
	if (phase1mode) {
2784
139
		r->p1xfs = phase1mode->xfs;
2785
139
		r->p1life = phase1mode->life;
2786
139
		r->p1ie = phase1mode->ike_exch;
2787
139
	} else {
2788
		r->p1ie = IKE_MM;
2789
	}
2790
139
	if (phase2mode) {
2791

160
		if (phase2mode->xfs && phase2mode->xfs->encxf &&
2792
16
		    phase2mode->xfs->encxf->noauth &&
2793
		    phase2mode->xfs->authxf) {
2794
			yyerror("authentication is implicit for %s",
2795
			    phase2mode->xfs->encxf->name);
2796
			goto errout;
2797
		}
2798
139
		r->p2xfs = phase2mode->xfs;
2799
139
		r->p2life = phase2mode->life;
2800
139
		r->p2ie = phase2mode->ike_exch;
2801
139
	} else {
2802
		r->p2ie = IKE_QM;
2803
	}
2804
2805
139
	r->auth = calloc(1, sizeof(struct ipsec_auth));
2806
139
	if (r->auth == NULL)
2807
		err(1, "create_ike: calloc");
2808
139
	r->auth->srcid = srcid;
2809
139
	r->auth->dstid = dstid;
2810
139
	r->auth->srcid_type = get_id_type(srcid);
2811
139
	r->auth->dstid_type = get_id_type(dstid);
2812
139
	r->ikeauth = calloc(1, sizeof(struct ike_auth));
2813
139
	if (r->ikeauth == NULL)
2814
		err(1, "create_ike: calloc");
2815
139
	r->ikeauth->type = authtype->type;
2816
139
	r->ikeauth->string = authtype->string;
2817
139
	r->tag = tag;
2818
2819
139
	return (r);
2820
2821
errout:
2822
1
	free(r);
2823
1
	free(hosts->src);
2824
1
	hosts->src = NULL;
2825
1
	free(hosts->dst);
2826
1
	hosts->dst = NULL;
2827
1
	if (phase1mode) {
2828
1
		free(phase1mode->xfs);
2829
1
		phase1mode->xfs = NULL;
2830
1
		free(phase1mode->life);
2831
1
		phase1mode->life = NULL;
2832
1
	}
2833
1
	if (phase2mode) {
2834
1
		free(phase2mode->xfs);
2835
1
		phase2mode->xfs = NULL;
2836
1
		free(phase2mode->life);
2837
1
		phase2mode->life = NULL;
2838
1
	}
2839
1
	if (srcid)
2840
		free(srcid);
2841
1
	if (dstid)
2842
		free(dstid);
2843
1
	return NULL;
2844
140
}