1 /*	$NetBSD: parse.y,v 1.23 2019/07/23 04:30:32 ozaki-r Exp $	*/
2 /*	$KAME: parse.y,v 1.81 2003/07/01 04:01:48 itojun Exp $	*/
3 
4 /*
5  * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the project nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32 
33 %{
34 #ifdef HAVE_CONFIG_H
35 #include "config.h"
36 #endif
37 
38 #include <sys/types.h>
39 #include <sys/param.h>
40 #include <sys/socket.h>
41 
42 #include <netinet/in.h>
43 #include <net/pfkeyv2.h>
44 #include PATH_IPSEC_H
45 #include <arpa/inet.h>
46 
47 #include <string.h>
48 #include <unistd.h>
49 #include <stdio.h>
50 #include <netdb.h>
51 #include <ctype.h>
52 #include <errno.h>
53 #include <stdlib.h>
54 
55 #include "libpfkey.h"
56 #include "vchar.h"
57 #include "extern.h"
58 
59 #define DEFAULT_NATT_PORT	4500
60 
61 #ifndef UDP_ENCAP_ESPINUDP
62 #define UDP_ENCAP_ESPINUDP	2
63 #endif
64 
65 #define ATOX(c) \
66   (isdigit((int)c) ? (c - '0') : \
67     (isupper((int)c) ? (c - 'A' + 10) : (c - 'a' + 10)))
68 
69 u_int32_t p_spi;
70 u_int p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode;
71 u_int32_t p_reqid;
72 u_int p_key_enc_len, p_key_auth_len;
73 const char *p_key_enc;
74 const char *p_key_auth;
75 time_t p_lt_hard, p_lt_soft;
76 size_t p_lb_hard, p_lb_soft;
77 
78 struct security_ctx {
79 	u_int8_t doi;
80 	u_int8_t alg;
81 	u_int16_t len;
82 	char *buf;
83 };
84 
85 struct security_ctx sec_ctx;
86 
87 static u_int p_natt_type, p_esp_frag;
88 static struct addrinfo * p_natt_oa = NULL;
89 
90 static int p_aiflags = 0, p_aifamily = PF_UNSPEC;
91 
92 static struct addrinfo *parse_addr(char *, char *);
93 static int fix_portstr(int, vchar_t *, vchar_t *, vchar_t *);
94 static int setvarbuf(char *, int *, struct sadb_ext *, int,
95     const void *, int);
96 void parse_init(void);
97 void free_buffer(void);
98 
99 int setkeymsg0(struct sadb_msg *, unsigned int, unsigned int, size_t);
100 static int setkeymsg_spdaddr(unsigned int, unsigned int, vchar_t *,
101 	struct addrinfo *, int, struct addrinfo *, int);
102 static int setkeymsg_spdaddr_tag(unsigned int, char *, vchar_t *);
103 static int setkeymsg_addr(unsigned int, unsigned int,
104 	struct addrinfo *, struct addrinfo *, int);
105 static int setkeymsg_add(unsigned int, unsigned int,
106 	struct addrinfo *, struct addrinfo *);
107 %}
108 
109 %union {
110 	int num;
111 	unsigned long ulnum;
112 	vchar_t val;
113 	struct addrinfo *res;
114 }
115 
116 %token EOT SLASH BLCL ELCL
117 %token ADD UPDATE GET GETSPI DELETE DELETEALL FLUSH DUMP EXIT
118 %token PR_ESP PR_AH PR_IPCOMP PR_ESPUDP PR_TCP
119 %token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI
120 %token F_MODE MODE F_REQID
121 %token F_EXT EXTENSION NOCYCLICSEQ
122 %token ALG_AUTH ALG_AUTH_NOKEY
123 %token ALG_ENC ALG_ENC_NOKEY ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD
124 %token ALG_COMP
125 %token F_LIFETIME_HARD F_LIFETIME_SOFT
126 %token F_LIFEBYTE_HARD F_LIFEBYTE_SOFT
127 %token F_ESPFRAG
128 %token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY
129 	/* SPD management */
130 %token SPDADD SPDUPDATE SPDDELETE SPDDUMP SPDFLUSH
131 %token F_POLICY PL_REQUESTS
132 %token F_AIFLAGS
133 %token TAGGED
134 %token SECURITY_CTX
135 
136 %type <num> prefix protocol_spec upper_spec
137 %type <num> ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD ALG_ENC_NOKEY
138 %type <num> ALG_AUTH ALG_AUTH_NOKEY
139 %type <num> ALG_COMP
140 %type <num> PR_ESP PR_AH PR_IPCOMP PR_ESPUDP PR_TCP
141 %type <num> EXTENSION MODE
142 %type <ulnum> DECSTRING
143 %type <val> PL_REQUESTS portstr portstr_notempty key_string
144 %type <val> policy_requests
145 %type <val> QUOTEDSTRING HEXSTRING STRING
146 %type <val> F_AIFLAGS
147 %type <val> upper_misc_spec policy_spec
148 %type <res> ipaddr ipandport
149 
150 %%
151 commands
152 	:	/*NOTHING*/
153 	|	commands command
154 		{
155 			free_buffer();
156 			parse_init();
157 		}
158 	;
159 
160 command
161 	:	add_command
162 	|	update_command
163 	|	get_command
164 	|	getspi_command
165 	|	delete_command
166 	|	deleteall_command
167 	|	flush_command
168 	|	dump_command
169 	|	exit_command
170 	|	spdadd_command
171 	|	spdupdate_command
172 	|	spddelete_command
173 	|	spddump_command
174 	|	spdflush_command
175 	;
176 	/* commands concerned with management, there is in tail of this file. */
177 
178 	/* add command */
179 add_command
180 	:	ADD ipaddropts ipandport ipandport protocol_spec spi extension_spec algorithm_spec EOT
181 		{
182 			int status;
183 
184 			status = setkeymsg_add(SADB_ADD, $5, $3, $4);
185 			if (status < 0)
186 				return -1;
187 		}
188 	;
189 
190 	/* update */
191 update_command
192 	:	UPDATE ipaddropts ipandport ipandport protocol_spec spi extension_spec algorithm_spec EOT
193 		{
194 			int status;
195 
196 			status = setkeymsg_add(SADB_UPDATE, $5, $3, $4);
197 			if (status < 0)
198 				return -1;
199 		}
200 	;
201 
202 	/* delete */
203 delete_command
204 	:	DELETE ipaddropts ipandport ipandport protocol_spec spi extension_spec EOT
205 		{
206 			int status;
207 
208 			if ($3->ai_next || $4->ai_next) {
209 				yyerror("multiple address specified");
210 				return -1;
211 			}
212 			if (p_mode != IPSEC_MODE_ANY)
213 				yyerror("WARNING: mode is obsolete");
214 
215 			status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 0);
216 			if (status < 0)
217 				return -1;
218 		}
219 	;
220 
221 	/* deleteall command */
222 deleteall_command
223 	:	DELETEALL ipaddropts ipaddr ipaddr protocol_spec EOT
224 		{
225 #ifndef __linux__
226 			if (setkeymsg_addr(SADB_DELETE, $5, $3, $4, 1) < 0)
227 				return -1;
228 #else /* __linux__ */
229 			/* linux strictly adheres to RFC2367, and returns
230 			 * an error if we send an SADB_DELETE request without
231 			 * an SPI. Therefore, we must first retrieve a list
232 			 * of SPIs for all matching SADB entries, and then
233 			 * delete each one separately. */
234 			u_int32_t *spi;
235 			int i, n;
236 
237 			spi = sendkeymsg_spigrep($5, $3, $4, &n);
238 			for (i = 0; i < n; i++) {
239 				p_spi = spi[i];
240 				if (setkeymsg_addr(SADB_DELETE,
241 							$5, $3, $4, 0) < 0)
242 					return -1;
243 			}
244 			free(spi);
245 #endif /* __linux__ */
246 		}
247 	;
248 
249 	/* get command */
250 get_command
251 	:	GET ipaddropts ipandport ipandport protocol_spec spi extension_spec EOT
252 		{
253 			int status;
254 
255 			if (p_mode != IPSEC_MODE_ANY)
256 				yyerror("WARNING: mode is obsolete");
257 
258 			status = setkeymsg_addr(SADB_GET, $5, $3, $4, 0);
259 			if (status < 0)
260 				return -1;
261 		}
262 	;
263 
264 	/* getspi command */
265 getspi_command
266 	:	GETSPI ipaddropts ipandport ipandport protocol_spec spi extension_spec EOT
267 		{
268 			int status;
269 
270 			status = setkeymsg_add(SADB_GETSPI, $5, $3, $4);
271 			if (status < 0)
272 				return -1;
273 		}
274 
275 	/* flush */
276 flush_command
277 	:	FLUSH protocol_spec EOT
278 		{
279 			struct sadb_msg msg;
280 			setkeymsg0(&msg, SADB_FLUSH, $2, sizeof(msg));
281 			sendkeymsg((char *)&msg, sizeof(msg));
282 		}
283 	;
284 
285 	/* dump */
286 dump_command
287 	:	DUMP protocol_spec EOT
288 		{
289 			struct sadb_msg msg;
290 			setkeymsg0(&msg, SADB_DUMP, $2, sizeof(msg));
291 			sendkeymsg((char *)&msg, sizeof(msg));
292 		}
293 	;
294 
295 protocol_spec
296 	:	/*NOTHING*/
297 		{
298 			$$ = SADB_SATYPE_UNSPEC;
299 		}
300 	|	PR_ESP
301 		{
302 			$$ = SADB_SATYPE_ESP;
303 			if ($1 == 1)
304 				p_ext |= SADB_X_EXT_OLD;
305 			else
306 				p_ext &= ~SADB_X_EXT_OLD;
307 		}
308 	|	PR_AH
309 		{
310 			$$ = SADB_SATYPE_AH;
311 			if ($1 == 1)
312 				p_ext |= SADB_X_EXT_OLD;
313 			else
314 				p_ext &= ~SADB_X_EXT_OLD;
315 		}
316 	|	PR_IPCOMP
317 		{
318 			$$ = SADB_X_SATYPE_IPCOMP;
319 		}
320 	|	PR_ESPUDP
321 		{
322 			$$ = SADB_SATYPE_ESP;
323 			p_ext &= ~SADB_X_EXT_OLD;
324 			p_natt_oa = 0;
325 			p_natt_type = UDP_ENCAP_ESPINUDP;
326 		}
327 	|	PR_ESPUDP ipaddr
328 		{
329 			$$ = SADB_SATYPE_ESP;
330 			p_ext &= ~SADB_X_EXT_OLD;
331 			p_natt_oa = $2;
332 			p_natt_type = UDP_ENCAP_ESPINUDP;
333 		}
334 	|	PR_TCP
335 		{
336 #ifdef SADB_X_SATYPE_TCPSIGNATURE
337 			$$ = SADB_X_SATYPE_TCPSIGNATURE;
338 #endif
339 		}
340 	;
341 
342 spi
343 	:	DECSTRING { p_spi = $1; }
344 	|	HEXSTRING
345 		{
346 			char *ep;
347 			unsigned long v;
348 
349 			ep = NULL;
350 			v = strtoul($1.buf, &ep, 16);
351 			if (!ep || *ep) {
352 				yyerror("invalid SPI");
353 				return -1;
354 			}
355 			if (v & ~0xffffffff) {
356 				yyerror("SPI too big.");
357 				return -1;
358 			}
359 
360 			p_spi = v;
361 		}
362 	;
363 
364 algorithm_spec
365 	:	esp_spec
366 	|	ah_spec
367 	|	ipcomp_spec
368 	;
369 
370 esp_spec
371 	:	F_ENC enc_alg F_AUTH auth_alg
372 	|	F_ENC enc_alg
373 	;
374 
375 ah_spec
376 	:	F_AUTH auth_alg
377 	;
378 
379 ipcomp_spec
380 	:	F_COMP ALG_COMP
381 		{
382 			if ($2 < 0) {
383 				yyerror("unsupported algorithm");
384 				return -1;
385 			}
386 			p_alg_enc = $2;
387 		}
388 	|	F_COMP ALG_COMP F_RAWCPI
389 		{
390 			if ($2 < 0) {
391 				yyerror("unsupported algorithm");
392 				return -1;
393 			}
394 			p_alg_enc = $2;
395 			p_ext |= SADB_X_EXT_RAWCPI;
396 		}
397 	;
398 
399 enc_alg
400 	:	ALG_ENC_NOKEY {
401 			if ($1 < 0) {
402 				yyerror("unsupported algorithm");
403 				return -1;
404 			}
405 			p_alg_enc = $1;
406 
407 			p_key_enc_len = 0;
408 			p_key_enc = "";
409 			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
410 			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
411 				yyerror(ipsec_strerror());
412 				return -1;
413 			}
414 		}
415 	|	ALG_ENC key_string {
416 			if ($1 < 0) {
417 				yyerror("unsupported algorithm");
418 				return -1;
419 			}
420 			p_alg_enc = $1;
421 
422 			p_key_enc_len = $2.len;
423 			p_key_enc = $2.buf;
424 			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
425 			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
426 				yyerror(ipsec_strerror());
427 				return -1;
428 			}
429 		}
430 	|	ALG_ENC_OLD {
431 			if ($1 < 0) {
432 				yyerror("unsupported algorithm");
433 				return -1;
434 			}
435 			yyerror("WARNING: obsolete algorithm");
436 			p_alg_enc = $1;
437 
438 			p_key_enc_len = 0;
439 			p_key_enc = "";
440 			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
441 			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
442 				yyerror(ipsec_strerror());
443 				return -1;
444 			}
445 		}
446 	|	ALG_ENC_DESDERIV key_string
447 		{
448 			if ($1 < 0) {
449 				yyerror("unsupported algorithm");
450 				return -1;
451 			}
452 			p_alg_enc = $1;
453 			if (p_ext & SADB_X_EXT_OLD) {
454 				yyerror("algorithm mismatched");
455 				return -1;
456 			}
457 			p_ext |= SADB_X_EXT_DERIV;
458 
459 			p_key_enc_len = $2.len;
460 			p_key_enc = $2.buf;
461 			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
462 			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
463 				yyerror(ipsec_strerror());
464 				return -1;
465 			}
466 		}
467 	|	ALG_ENC_DES32IV key_string
468 		{
469 			if ($1 < 0) {
470 				yyerror("unsupported algorithm");
471 				return -1;
472 			}
473 			p_alg_enc = $1;
474 			if (!(p_ext & SADB_X_EXT_OLD)) {
475 				yyerror("algorithm mismatched");
476 				return -1;
477 			}
478 			p_ext |= SADB_X_EXT_IV4B;
479 
480 			p_key_enc_len = $2.len;
481 			p_key_enc = $2.buf;
482 			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
483 			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
484 				yyerror(ipsec_strerror());
485 				return -1;
486 			}
487 		}
488 	;
489 
490 auth_alg
491 	:	ALG_AUTH key_string {
492 			if ($1 < 0) {
493 				yyerror("unsupported algorithm");
494 				return -1;
495 			}
496 			p_alg_auth = $1;
497 
498 			p_key_auth_len = $2.len;
499 			p_key_auth = $2.buf;
500 #ifdef SADB_X_AALG_TCP_MD5
501 			if (p_alg_auth == SADB_X_AALG_TCP_MD5) {
502 				if ((p_key_auth_len < 1) ||
503 				    (p_key_auth_len > 80))
504 					return -1;
505 			} else
506 #endif
507 			{
508 				if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH,
509 				    p_alg_auth,
510 				    PFKEY_UNUNIT64(p_key_auth_len)) < 0) {
511 					yyerror(ipsec_strerror());
512 					return -1;
513 				}
514 			}
515 		}
516 	|	ALG_AUTH_NOKEY {
517 			if ($1 < 0) {
518 				yyerror("unsupported algorithm");
519 				return -1;
520 			}
521 			p_alg_auth = $1;
522 
523 			p_key_auth_len = 0;
524 			p_key_auth = "";
525 			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH,
526 			    p_alg_auth,
527 			    PFKEY_UNUNIT64(p_key_auth_len)) < 0) {
528 				yyerror(ipsec_strerror());
529 				return -1;
530 			}
531 		}
532 	;
533 
534 key_string
535 	:	QUOTEDSTRING
536 		{
537 			$$ = $1;
538 		}
539 	|	HEXSTRING
540 		{
541 			caddr_t pp_key;
542 			caddr_t bp;
543 			caddr_t yp = $1.buf;
544 			int l;
545 
546 			l = strlen(yp) % 2 + strlen(yp) / 2;
547 			if ((pp_key = malloc(l)) == 0) {
548 				yyerror("not enough core");
549 				return -1;
550 			}
551 			memset(pp_key, 0, l);
552 
553 			bp = pp_key;
554 			if (strlen(yp) % 2) {
555 				*bp = ATOX(yp[0]);
556 				yp++, bp++;
557 			}
558 			while (*yp) {
559 				*bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]);
560 				yp += 2, bp++;
561 			}
562 
563 			$$.len = l;
564 			$$.buf = pp_key;
565 		}
566 	;
567 
568 extension_spec
569 	:	/*NOTHING*/
570 	|	extension_spec extension
571 	;
572 
573 extension
574 	:	F_EXT EXTENSION { p_ext |= $2; }
575 	|	F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; }
576 	|	F_MODE MODE { p_mode = $2; }
577 	|	F_MODE ANY { p_mode = IPSEC_MODE_ANY; }
578 	|	F_REQID DECSTRING { p_reqid = $2; }
579 	|	F_ESPFRAG DECSTRING
580 		{
581 			if (p_natt_type == 0) {
582 				yyerror("esp fragment size only valid for NAT-T");
583 				return -1;
584 			}
585 			p_esp_frag = $2;
586 		}
587 	|	F_REPLAY DECSTRING
588 		{
589 			if ((p_ext & SADB_X_EXT_OLD) != 0) {
590 				yyerror("replay prevention cannot be used with "
591 				    "ah/esp-old");
592 				return -1;
593 			}
594 			p_replay = $2;
595 		}
596 	|	F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; }
597 	|	F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; }
598 	|	F_LIFEBYTE_HARD DECSTRING { p_lb_hard = $2; }
599 	|	F_LIFEBYTE_SOFT DECSTRING { p_lb_soft = $2; }
600 	|	SECURITY_CTX DECSTRING DECSTRING QUOTEDSTRING {
601 		sec_ctx.doi = $2;
602 		sec_ctx.alg = $3;
603 		sec_ctx.len = $4.len+1;
604 		sec_ctx.buf = $4.buf;
605 	}
606 	;
607 
608 	/* definition about command for SPD management */
609 	/* spdadd */
610 spdadd_command
611 	/* XXX merge with spdupdate ??? */
612 	:	SPDADD ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec context_spec policy_spec EOT
613 		{
614 			int status;
615 			struct addrinfo *src, *dst;
616 
617 #ifdef HAVE_PFKEY_POLICY_PRIORITY
618 			last_msg_type = SADB_X_SPDADD;
619 #endif
620 
621 			/* fixed port fields if ulp is icmp */
622 			if (fix_portstr($9, &$10, &$5, &$8))
623 				return -1;
624 
625 			src = parse_addr($3.buf, $5.buf);
626 			dst = parse_addr($6.buf, $8.buf);
627 			if (!src || !dst) {
628 				/* yyerror is already called */
629 				return -1;
630 			}
631 			if (src->ai_next || dst->ai_next) {
632 				yyerror("multiple address specified");
633 				freeaddrinfo(src);
634 				freeaddrinfo(dst);
635 				return -1;
636 			}
637 
638 			status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$12,
639 			    src, $4, dst, $7);
640 			freeaddrinfo(src);
641 			freeaddrinfo(dst);
642 			if (status < 0)
643 				return -1;
644 		}
645 	|	SPDADD TAGGED QUOTEDSTRING policy_spec EOT
646 		{
647 			int status;
648 
649 			status = setkeymsg_spdaddr_tag(SADB_X_SPDADD,
650 			    $3.buf, &$4);
651 			if (status < 0)
652 				return -1;
653 		}
654 	;
655 
656 spdupdate_command
657 	/* XXX merge with spdadd ??? */
658 	:	SPDUPDATE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec context_spec policy_spec EOT
659 		{
660 			int status;
661 			struct addrinfo *src, *dst;
662 
663 #ifdef HAVE_PFKEY_POLICY_PRIORITY
664 			last_msg_type = SADB_X_SPDUPDATE;
665 #endif
666 
667 			/* fixed port fields if ulp is icmp */
668 			if (fix_portstr($9, &$10, &$5, &$8))
669 				return -1;
670 
671 			src = parse_addr($3.buf, $5.buf);
672 			dst = parse_addr($6.buf, $8.buf);
673 			if (!src || !dst) {
674 				/* yyerror is already called */
675 				return -1;
676 			}
677 			if (src->ai_next || dst->ai_next) {
678 				yyerror("multiple address specified");
679 				freeaddrinfo(src);
680 				freeaddrinfo(dst);
681 				return -1;
682 			}
683 
684 			status = setkeymsg_spdaddr(SADB_X_SPDUPDATE, $9, &$12,
685 			    src, $4, dst, $7);
686 			freeaddrinfo(src);
687 			freeaddrinfo(dst);
688 			if (status < 0)
689 				return -1;
690 		}
691 	|	SPDUPDATE TAGGED QUOTEDSTRING policy_spec EOT
692 		{
693 			int status;
694 
695 			status = setkeymsg_spdaddr_tag(SADB_X_SPDUPDATE,
696 			    $3.buf, &$4);
697 			if (status < 0)
698 				return -1;
699 		}
700 	;
701 
702 spddelete_command
703 	:	SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec context_spec policy_spec EOT
704 		{
705 			int status;
706 			struct addrinfo *src, *dst;
707 
708 			/* fixed port fields if ulp is icmp */
709 			if (fix_portstr($9, &$10, &$5, &$8))
710 				return -1;
711 
712 			src = parse_addr($3.buf, $5.buf);
713 			dst = parse_addr($6.buf, $8.buf);
714 			if (!src || !dst) {
715 				/* yyerror is already called */
716 				return -1;
717 			}
718 			if (src->ai_next || dst->ai_next) {
719 				yyerror("multiple address specified");
720 				freeaddrinfo(src);
721 				freeaddrinfo(dst);
722 				return -1;
723 			}
724 
725 			status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$12,
726 			    src, $4, dst, $7);
727 			freeaddrinfo(src);
728 			freeaddrinfo(dst);
729 			if (status < 0)
730 				return -1;
731 		}
732 	;
733 
734 spddump_command:
735 		SPDDUMP EOT
736 		{
737 			struct sadb_msg msg;
738 			setkeymsg0(&msg, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC,
739 			    sizeof(msg));
740 			sendkeymsg((char *)&msg, sizeof(msg));
741 		}
742 	;
743 
744 spdflush_command
745 	:
746 		SPDFLUSH EOT
747 		{
748 			struct sadb_msg msg;
749 			setkeymsg0(&msg, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC,
750 			    sizeof(msg));
751 			sendkeymsg((char *)&msg, sizeof(msg));
752 		}
753 	;
754 
755 ipaddropts
756 	:	/* nothing */
757 	|	ipaddropts ipaddropt
758 	;
759 
760 ipaddropt
761 	:	F_AIFLAGS
762 		{
763 			char *p;
764 
765 			for (p = $1.buf + 1; *p; p++)
766 				switch (*p) {
767 				case '4':
768 					p_aifamily = AF_INET;
769 					break;
770 #ifdef INET6
771 				case '6':
772 					p_aifamily = AF_INET6;
773 					break;
774 #endif
775 				case 'n':
776 					p_aiflags = AI_NUMERICHOST;
777 					break;
778 				default:
779 					yyerror("invalid flag");
780 					return -1;
781 				}
782 		}
783 	;
784 
785 ipaddr
786 	:	STRING
787 		{
788 			$$ = parse_addr($1.buf, NULL);
789 			if ($$ == NULL) {
790 				/* yyerror already called by parse_addr */
791 				return -1;
792 			}
793 		}
794 	;
795 
796 ipandport
797 	:	STRING
798 		{
799 			$$ = parse_addr($1.buf, NULL);
800 			if ($$ == NULL) {
801 				/* yyerror already called by parse_addr */
802 				return -1;
803 			}
804 		}
805 	|	STRING portstr_notempty
806 		{
807 			$$ = parse_addr($1.buf, $2.buf);
808 			if ($$ == NULL) {
809 				/* yyerror already called by parse_addr */
810 				return -1;
811 			}
812 		}
813 	;
814 
815 prefix
816 	:	/*NOTHING*/ { $$ = -1; }
817 	|	SLASH DECSTRING { $$ = $2; }
818 	;
819 
820 portstr
821 	:	/*NOTHING*/
822 		{
823 			$$.buf = strdup("0");
824 			if (!$$.buf) {
825 				yyerror("insufficient memory");
826 				return -1;
827 			}
828 			$$.len = strlen($$.buf);
829 		}
830 	| portstr_notempty
831 	;
832 
833 portstr_notempty
834 	: 	BLCL ANY ELCL
835 		{
836 			$$.buf = strdup("0");
837 			if (!$$.buf) {
838 				yyerror("insufficient memory");
839 				return -1;
840 			}
841 			$$.len = strlen($$.buf);
842 		}
843 	|	BLCL DECSTRING ELCL
844 		{
845 			char buf[20];
846 			snprintf(buf, sizeof(buf), "%lu", $2);
847 			$$.buf = strdup(buf);
848 			if (!$$.buf) {
849 				yyerror("insufficient memory");
850 				return -1;
851 			}
852 			$$.len = strlen($$.buf);
853 		}
854 	|	BLCL STRING ELCL
855 		{
856 			$$ = $2;
857 		}
858 	;
859 
860 upper_spec
861 	:	DECSTRING { $$ = $1; }
862 	|	ANY { $$ = IPSEC_ULPROTO_ANY; }
863 	|	PR_TCP {
864 				$$ = IPPROTO_TCP;
865 			}
866 	|	STRING
867 		{
868 			struct protoent *ent;
869 
870 			ent = getprotobyname($1.buf);
871 			if (ent)
872 				$$ = ent->p_proto;
873 			else {
874 				if (strcmp("icmp6", $1.buf) == 0) {
875 					$$ = IPPROTO_ICMPV6;
876 				} else if(strcmp("ip4", $1.buf) == 0) {
877 					$$ = IPPROTO_IPV4;
878 				} else {
879 					yyerror("invalid upper layer protocol");
880 					return -1;
881 				}
882 			}
883 			endprotoent();
884 		}
885 	;
886 
887 upper_misc_spec
888 	:	/*NOTHING*/
889 		{
890 			$$.buf = NULL;
891 			$$.len = 0;
892 		}
893 	|	STRING
894 		{
895 			$$.buf = strdup($1.buf);
896 			if (!$$.buf) {
897 				yyerror("insufficient memory");
898 				return -1;
899 			}
900 			$$.len = strlen($$.buf);
901 		}
902 	;
903 
904 context_spec
905 	:	/* NOTHING */
906 	|	SECURITY_CTX DECSTRING DECSTRING QUOTEDSTRING {
907 			sec_ctx.doi = $2;
908 			sec_ctx.alg = $3;
909 			sec_ctx.len = $4.len+1;
910 			sec_ctx.buf = $4.buf;
911 		}
912 	;
913 
914 policy_spec
915 	:	F_POLICY policy_requests
916 		{
917 			char *policy;
918 #ifdef HAVE_PFKEY_POLICY_PRIORITY
919 			struct sadb_x_policy *xpl;
920 #endif
921 
922 			policy = ipsec_set_policy($2.buf, $2.len);
923 			if (policy == NULL) {
924 				yyerror(ipsec_strerror());
925 				return -1;
926 			}
927 
928 			$$.buf = policy;
929 			$$.len = ipsec_get_policylen(policy);
930 
931 #ifdef HAVE_PFKEY_POLICY_PRIORITY
932 			xpl = (struct sadb_x_policy *) $$.buf;
933 			last_priority = xpl->sadb_x_policy_priority;
934 #endif
935 		}
936 	;
937 
938 policy_requests
939 	:	PL_REQUESTS { $$ = $1; }
940 	;
941 
942 	/* exit */
943 exit_command
944 	:	EXIT EOT
945 		{
946 			exit_now = 1;
947 			YYACCEPT;
948 		}
949 	;
950 %%
951 
952 int
953 setkeymsg0(struct sadb_msg *msg, unsigned int type, unsigned int satype,
954     size_t l)
955 {
956 
957 	msg->sadb_msg_version = PF_KEY_V2;
958 	msg->sadb_msg_type = type;
959 	msg->sadb_msg_errno = 0;
960 	msg->sadb_msg_satype = satype;
961 	msg->sadb_msg_reserved = 0;
962 	msg->sadb_msg_seq = 0;
963 	msg->sadb_msg_pid = getpid();
964 	msg->sadb_msg_len = PFKEY_UNIT64(l);
965 	return 0;
966 }
967 
968 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
969 static int
setkeymsg_spdaddr(unsigned int type,unsigned int upper,vchar_t * policy,struct addrinfo * srcs,int splen,struct addrinfo * dsts,int dplen)970 setkeymsg_spdaddr(unsigned int type, unsigned int upper, vchar_t *policy,
971     struct addrinfo *srcs, int splen, struct addrinfo *dsts, int dplen)
972 {
973 	struct sadb_msg *msg;
974 	char buf[BUFSIZ];
975 	int l, l0;
976 	struct sadb_address m_addr;
977 	struct addrinfo *s, *d;
978 	int n;
979 	int plen;
980 	struct sockaddr *sa;
981 	int salen;
982 #ifdef HAVE_POLICY_FWD
983 	struct sadb_x_ipsecrequest *ps = NULL;
984 	int saved_level, saved_id = 0;
985 #endif
986 
987 	msg = (struct sadb_msg *)buf;
988 
989 	if (!srcs || !dsts)
990 		return -1;
991 
992 	/* fix up length afterwards */
993 	setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0);
994 	l = sizeof(struct sadb_msg);
995 
996 	memcpy(buf + l, policy->buf, policy->len);
997 	l += policy->len;
998 
999 	l0 = l;
1000 	n = 0;
1001 
1002 	/* do it for all src/dst pairs */
1003 	for (s = srcs; s; s = s->ai_next) {
1004 		for (d = dsts; d; d = d->ai_next) {
1005 			/* rewind pointer */
1006 			l = l0;
1007 
1008 			if (s->ai_addr->sa_family != d->ai_addr->sa_family)
1009 				continue;
1010 			switch (s->ai_addr->sa_family) {
1011 			case AF_INET:
1012 				plen = sizeof(struct in_addr) << 3;
1013 				break;
1014 #ifdef INET6
1015 			case AF_INET6:
1016 				plen = sizeof(struct in6_addr) << 3;
1017 				break;
1018 #endif
1019 			default:
1020 				continue;
1021 			}
1022 
1023 			/* set src */
1024 			sa = s->ai_addr;
1025 			salen = sysdep_sa_len(s->ai_addr);
1026 			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1027 			    PFKEY_ALIGN8(salen));
1028 			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
1029 			m_addr.sadb_address_proto = upper;
1030 			m_addr.sadb_address_prefixlen =
1031 			    (splen >= 0 ? splen : plen);
1032 			m_addr.sadb_address_reserved = 0;
1033 
1034 			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1035 			    sizeof(m_addr), (caddr_t)sa, salen);
1036 
1037 			/* set dst */
1038 			sa = d->ai_addr;
1039 			salen = sysdep_sa_len(d->ai_addr);
1040 			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1041 			    PFKEY_ALIGN8(salen));
1042 			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
1043 			m_addr.sadb_address_proto = upper;
1044 			m_addr.sadb_address_prefixlen =
1045 			    (dplen >= 0 ? dplen : plen);
1046 			m_addr.sadb_address_reserved = 0;
1047 
1048 			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1049 			    sizeof(m_addr), sa, salen);
1050 #ifdef SADB_X_EXT_SEC_CTX
1051 			/* Add security context label */
1052 			if (sec_ctx.doi) {
1053 				struct sadb_x_sec_ctx m_sec_ctx;
1054 				u_int slen = sizeof(struct sadb_x_sec_ctx);
1055 
1056 				memset(&m_sec_ctx, 0, slen);
1057 
1058 				m_sec_ctx.sadb_x_sec_len =
1059 				PFKEY_UNIT64(slen + PFKEY_ALIGN8(sec_ctx.len));
1060 
1061 				m_sec_ctx.sadb_x_sec_exttype =
1062 					SADB_X_EXT_SEC_CTX;
1063 				m_sec_ctx.sadb_x_ctx_len = sec_ctx.len;/*bytes*/
1064 				m_sec_ctx.sadb_x_ctx_doi = sec_ctx.doi;
1065 				m_sec_ctx.sadb_x_ctx_alg = sec_ctx.alg;
1066 				setvarbuf(buf, &l,
1067 					  (struct sadb_ext *)&m_sec_ctx, slen,
1068 					  (caddr_t)sec_ctx.buf, sec_ctx.len);
1069 			}
1070 #endif
1071 			msg->sadb_msg_len = PFKEY_UNIT64(l);
1072 
1073 			sendkeymsg(buf, l);
1074 
1075 #ifdef HAVE_POLICY_FWD
1076 			/* create extra call for FWD policy */
1077 			if (f_rfcmode && sp->sadb_x_policy_dir == IPSEC_DIR_INBOUND) {
1078 				sp->sadb_x_policy_dir = IPSEC_DIR_FWD;
1079 				ps = (struct sadb_x_ipsecrequest*) (sp+1);
1080 
1081 				/* if request level is unique, change it to
1082 				 * require for fwd policy */
1083 				/* XXX: currently, only first policy is updated
1084 				 * only. Update following too... */
1085 				saved_level = ps->sadb_x_ipsecrequest_level;
1086 				if (saved_level == IPSEC_LEVEL_UNIQUE) {
1087 					saved_id = ps->sadb_x_ipsecrequest_reqid;
1088 					ps->sadb_x_ipsecrequest_reqid=0;
1089 					ps->sadb_x_ipsecrequest_level=IPSEC_LEVEL_REQUIRE;
1090 				}
1091 
1092 				sendkeymsg(buf, l);
1093 				/* restoring for next message */
1094 				sp->sadb_x_policy_dir = IPSEC_DIR_INBOUND;
1095 				if (saved_level == IPSEC_LEVEL_UNIQUE) {
1096 					ps->sadb_x_ipsecrequest_reqid = saved_id;
1097 					ps->sadb_x_ipsecrequest_level = saved_level;
1098 				}
1099 			}
1100 #endif
1101 
1102 			n++;
1103 		}
1104 	}
1105 
1106 	if (n == 0)
1107 		return -1;
1108 	else
1109 		return 0;
1110 }
1111 
1112 static int
setkeymsg_spdaddr_tag(unsigned int type,char * tag,vchar_t * policy)1113 setkeymsg_spdaddr_tag(unsigned int type, char *tag, vchar_t *policy)
1114 {
1115 	struct sadb_msg *msg;
1116 	char buf[BUFSIZ];
1117 	int l;
1118 #ifdef SADB_X_EXT_TAG
1119 	struct sadb_x_tag m_tag;
1120 #endif
1121 
1122 	msg = (struct sadb_msg *)buf;
1123 
1124 	/* fix up length afterwards */
1125 	setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0);
1126 	l = sizeof(struct sadb_msg);
1127 
1128 	memcpy(buf + l, policy->buf, policy->len);
1129 	l += policy->len;
1130 
1131 #ifdef SADB_X_EXT_TAG
1132 	memset(&m_tag, 0, sizeof(m_tag));
1133 	m_tag.sadb_x_tag_len = PFKEY_UNIT64(sizeof(m_tag));
1134 	m_tag.sadb_x_tag_exttype = SADB_X_EXT_TAG;
1135 	if (strlcpy(m_tag.sadb_x_tag_name, tag,
1136 	    sizeof(m_tag.sadb_x_tag_name)) >= sizeof(m_tag.sadb_x_tag_name))
1137 		return -1;
1138 	memcpy(buf + l, &m_tag, sizeof(m_tag));
1139 	l += sizeof(m_tag);
1140 #endif
1141 
1142 	msg->sadb_msg_len = PFKEY_UNIT64(l);
1143 
1144 	sendkeymsg(buf, l);
1145 
1146 	return 0;
1147 }
1148 
1149 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
1150 static int
setkeymsg_addr(unsigned int type,unsigned int satype,struct addrinfo * srcs,struct addrinfo * dsts,int no_spi)1151 setkeymsg_addr(unsigned int type, unsigned int satype, struct addrinfo *srcs,
1152     struct addrinfo *dsts, int no_spi)
1153 {
1154 	struct sadb_msg *msg;
1155 	char buf[BUFSIZ];
1156 	int l, l0, len;
1157 	struct sadb_sa m_sa;
1158 	struct sadb_x_sa2 m_sa2;
1159 	struct sadb_address m_addr;
1160 	struct addrinfo *s, *d;
1161 	int n;
1162 	int plen;
1163 	struct sockaddr *sa;
1164 	int salen;
1165 
1166 	msg = (struct sadb_msg *)buf;
1167 
1168 	if (!srcs || !dsts)
1169 		return -1;
1170 
1171 	/* fix up length afterwards */
1172 	setkeymsg0(msg, type, satype, 0);
1173 	l = sizeof(struct sadb_msg);
1174 
1175 	if (!no_spi) {
1176 		len = sizeof(struct sadb_sa);
1177 		m_sa.sadb_sa_len = PFKEY_UNIT64(len);
1178 		m_sa.sadb_sa_exttype = SADB_EXT_SA;
1179 		m_sa.sadb_sa_spi = htonl(p_spi);
1180 		m_sa.sadb_sa_replay = p_replay;
1181 		m_sa.sadb_sa_state = 0;
1182 		m_sa.sadb_sa_auth = p_alg_auth;
1183 		m_sa.sadb_sa_encrypt = p_alg_enc;
1184 		m_sa.sadb_sa_flags = p_ext;
1185 
1186 		memcpy(buf + l, &m_sa, len);
1187 		l += len;
1188 
1189 		len = sizeof(struct sadb_x_sa2);
1190 		m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
1191 		m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
1192 		m_sa2.sadb_x_sa2_mode = p_mode;
1193 		m_sa2.sadb_x_sa2_reqid = p_reqid;
1194 
1195 		memcpy(buf + l, &m_sa2, len);
1196 		l += len;
1197 	}
1198 
1199 	l0 = l;
1200 	n = 0;
1201 
1202 	/* do it for all src/dst pairs */
1203 	for (s = srcs; s; s = s->ai_next) {
1204 		for (d = dsts; d; d = d->ai_next) {
1205 			/* rewind pointer */
1206 			l = l0;
1207 
1208 			if (s->ai_addr->sa_family != d->ai_addr->sa_family)
1209 				continue;
1210 			switch (s->ai_addr->sa_family) {
1211 			case AF_INET:
1212 				plen = sizeof(struct in_addr) << 3;
1213 				break;
1214 #ifdef INET6
1215 			case AF_INET6:
1216 				plen = sizeof(struct in6_addr) << 3;
1217 				break;
1218 #endif
1219 			default:
1220 				continue;
1221 			}
1222 
1223 			/* set src */
1224 			sa = s->ai_addr;
1225 			salen = sysdep_sa_len(s->ai_addr);
1226 			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1227 			    PFKEY_ALIGN8(salen));
1228 			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
1229 			m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1230 			m_addr.sadb_address_prefixlen = plen;
1231 			m_addr.sadb_address_reserved = 0;
1232 
1233 			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1234 			    sizeof(m_addr), sa, salen);
1235 
1236 			/* set dst */
1237 			sa = d->ai_addr;
1238 			salen = sysdep_sa_len(d->ai_addr);
1239 			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1240 			    PFKEY_ALIGN8(salen));
1241 			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
1242 			m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1243 			m_addr.sadb_address_prefixlen = plen;
1244 			m_addr.sadb_address_reserved = 0;
1245 
1246 			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1247 			    sizeof(m_addr), sa, salen);
1248 
1249 			msg->sadb_msg_len = PFKEY_UNIT64(l);
1250 
1251 			sendkeymsg(buf, l);
1252 
1253 			n++;
1254 		}
1255 	}
1256 
1257 	if (n == 0)
1258 		return -1;
1259 	else
1260 		return 0;
1261 }
1262 
1263 #ifdef SADB_X_EXT_NAT_T_TYPE
get_port(struct addrinfo * addr)1264 static u_int16_t get_port (struct addrinfo *addr)
1265 {
1266 	struct sockaddr *s = addr->ai_addr;
1267 	u_int16_t port = 0;
1268 
1269 	switch (s->sa_family) {
1270 	case AF_INET:
1271 	  {
1272 		struct sockaddr_in *sin4 = (struct sockaddr_in *)s;
1273 		port = ntohs(sin4->sin_port);
1274 		break;
1275 	  }
1276 	case AF_INET6:
1277 	  {
1278 		struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)s;
1279 		port = ntohs(sin6->sin6_port);
1280 		break;
1281 	  }
1282 	}
1283 
1284 	if (port == 0)
1285 		port = DEFAULT_NATT_PORT;
1286 
1287 	return port;
1288 }
1289 #endif
1290 
1291 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
1292 static int
setkeymsg_add(unsigned int type,unsigned int satype,struct addrinfo * srcs,struct addrinfo * dsts)1293 setkeymsg_add(unsigned int type, unsigned int satype, struct addrinfo *srcs,
1294     struct addrinfo *dsts)
1295 {
1296 	struct sadb_msg *msg;
1297 	char buf[BUFSIZ];
1298 	int l, l0, len;
1299 	struct sadb_sa m_sa;
1300 	struct sadb_x_sa2 m_sa2;
1301 	struct sadb_address m_addr;
1302 	struct addrinfo *s, *d;
1303 	int n;
1304 	int plen;
1305 	struct sockaddr *sa;
1306 	int salen;
1307 
1308 	msg = (struct sadb_msg *)buf;
1309 
1310 	if (!srcs || !dsts)
1311 		return -1;
1312 
1313 	/* fix up length afterwards */
1314 	setkeymsg0(msg, type, satype, 0);
1315 	l = sizeof(struct sadb_msg);
1316 
1317 	/* set encryption algorithm, if present. */
1318 	if (satype != SADB_X_SATYPE_IPCOMP && p_key_enc) {
1319 		union {
1320 			struct sadb_key key;
1321 			struct sadb_ext ext;
1322 		} m;
1323 
1324 		m.key.sadb_key_len =
1325 			PFKEY_UNIT64(sizeof(m.key)
1326 				   + PFKEY_ALIGN8(p_key_enc_len));
1327 		m.key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
1328 		m.key.sadb_key_bits = p_key_enc_len * 8;
1329 		m.key.sadb_key_reserved = 0;
1330 
1331 		setvarbuf(buf, &l, &m.ext, sizeof(m.key),
1332 			p_key_enc, p_key_enc_len);
1333 	}
1334 
1335 	/* set authentication algorithm, if present. */
1336 	if (p_key_auth) {
1337 		union {
1338 			struct sadb_key key;
1339 			struct sadb_ext ext;
1340 		} m;
1341 
1342 		m.key.sadb_key_len =
1343 			PFKEY_UNIT64(sizeof(m.key)
1344 				   + PFKEY_ALIGN8(p_key_auth_len));
1345 		m.key.sadb_key_exttype = SADB_EXT_KEY_AUTH;
1346 		m.key.sadb_key_bits = p_key_auth_len * 8;
1347 		m.key.sadb_key_reserved = 0;
1348 
1349 		setvarbuf(buf, &l, &m.ext, sizeof(m.key),
1350 			p_key_auth, p_key_auth_len);
1351 	}
1352 
1353 	/* set lifetime for HARD */
1354 	if (p_lt_hard != 0 || p_lb_hard != 0) {
1355 		struct sadb_lifetime m_lt;
1356 		u_int slen = sizeof(struct sadb_lifetime);
1357 
1358 		m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1359 		m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
1360 		m_lt.sadb_lifetime_allocations = 0;
1361 		m_lt.sadb_lifetime_bytes = p_lb_hard;
1362 		m_lt.sadb_lifetime_addtime = p_lt_hard;
1363 		m_lt.sadb_lifetime_usetime = 0;
1364 
1365 		memcpy(buf + l, &m_lt, slen);
1366 		l += slen;
1367 	}
1368 
1369 	/* set lifetime for SOFT */
1370 	if (p_lt_soft != 0 || p_lb_soft != 0) {
1371 		struct sadb_lifetime m_lt;
1372 		u_int slen = sizeof(struct sadb_lifetime);
1373 
1374 		m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1375 		m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
1376 		m_lt.sadb_lifetime_allocations = 0;
1377 		m_lt.sadb_lifetime_bytes = p_lb_soft;
1378 		m_lt.sadb_lifetime_addtime = p_lt_soft;
1379 		m_lt.sadb_lifetime_usetime = 0;
1380 
1381 		memcpy(buf + l, &m_lt, slen);
1382 		l += slen;
1383 	}
1384 
1385 #ifdef SADB_X_EXT_SEC_CTX
1386 	/* Add security context label */
1387 	if (sec_ctx.doi) {
1388 		struct sadb_x_sec_ctx m_sec_ctx;
1389 		u_int slen = sizeof(struct sadb_x_sec_ctx);
1390 
1391 		memset(&m_sec_ctx, 0, slen);
1392 
1393 		m_sec_ctx.sadb_x_sec_len = PFKEY_UNIT64(slen +
1394 					PFKEY_ALIGN8(sec_ctx.len));
1395 		m_sec_ctx.sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX;
1396 		m_sec_ctx.sadb_x_ctx_len = sec_ctx.len; /* bytes */
1397 		m_sec_ctx.sadb_x_ctx_doi = sec_ctx.doi;
1398 		m_sec_ctx.sadb_x_ctx_alg = sec_ctx.alg;
1399 		setvarbuf(buf, &l, (struct sadb_ext *)&m_sec_ctx, slen,
1400 			  (caddr_t)sec_ctx.buf, sec_ctx.len);
1401 	}
1402 #endif
1403 
1404 	/* SPI == 0 allows the kernel to pick a random SPI */
1405 	if (type == SADB_GETSPI && p_spi != 0) {
1406 		struct sadb_spirange spirange;
1407 		u_int slen = sizeof(struct sadb_spirange);
1408 
1409 		memset(&spirange, 0, sizeof(spirange));
1410 		spirange.sadb_spirange_len = PFKEY_UNIT64(slen);
1411 		spirange.sadb_spirange_exttype = SADB_EXT_SPIRANGE;
1412 		spirange.sadb_spirange_min = p_spi;
1413 		spirange.sadb_spirange_max = p_spi;
1414 
1415 		memcpy(buf + l, &spirange, slen);
1416 		l += slen;
1417 	}
1418 
1419 	len = sizeof(struct sadb_sa);
1420 	m_sa.sadb_sa_len = PFKEY_UNIT64(len);
1421 	m_sa.sadb_sa_exttype = SADB_EXT_SA;
1422 	m_sa.sadb_sa_spi = htonl(p_spi);
1423 	m_sa.sadb_sa_replay = p_replay;
1424 	m_sa.sadb_sa_state = 0;
1425 	m_sa.sadb_sa_auth = p_alg_auth;
1426 	m_sa.sadb_sa_encrypt = p_alg_enc;
1427 	m_sa.sadb_sa_flags = p_ext;
1428 
1429 	memcpy(buf + l, &m_sa, len);
1430 	l += len;
1431 
1432 	len = sizeof(struct sadb_x_sa2);
1433 	m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
1434 	m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
1435 	m_sa2.sadb_x_sa2_mode = p_mode;
1436 	m_sa2.sadb_x_sa2_reqid = p_reqid;
1437 
1438 	memcpy(buf + l, &m_sa2, len);
1439 	l += len;
1440 
1441 #ifdef SADB_X_EXT_NAT_T_TYPE
1442 	if (p_natt_type) {
1443 		struct sadb_x_nat_t_type natt_type;
1444 
1445 		len = sizeof(struct sadb_x_nat_t_type);
1446 		memset(&natt_type, 0, len);
1447 		natt_type.sadb_x_nat_t_type_len = PFKEY_UNIT64(len);
1448 		natt_type.sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
1449 		natt_type.sadb_x_nat_t_type_type = p_natt_type;
1450 
1451 		memcpy(buf + l, &natt_type, len);
1452 		l += len;
1453 
1454 		if (p_natt_oa) {
1455 			sa = p_natt_oa->ai_addr;
1456 			switch (sa->sa_family) {
1457 			case AF_INET:
1458 				plen = sizeof(struct in_addr) << 3;
1459 				break;
1460 #ifdef INET6
1461 			case AF_INET6:
1462 				plen = sizeof(struct in6_addr) << 3;
1463 				break;
1464 #endif
1465 			default:
1466 				return -1;
1467 			}
1468 			salen = sysdep_sa_len(sa);
1469 			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1470 			    PFKEY_ALIGN8(salen));
1471 			m_addr.sadb_address_exttype = SADB_X_EXT_NAT_T_OA;
1472 			m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1473 			m_addr.sadb_address_prefixlen = plen;
1474 			m_addr.sadb_address_reserved = 0;
1475 
1476 			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1477 			    sizeof(m_addr), sa, salen);
1478 		}
1479 	}
1480 #endif
1481 
1482 	l0 = l;
1483 	n = 0;
1484 
1485 	/* do it for all src/dst pairs */
1486 	for (s = srcs; s; s = s->ai_next) {
1487 		for (d = dsts; d; d = d->ai_next) {
1488 			/* rewind pointer */
1489 			l = l0;
1490 
1491 			if (s->ai_addr->sa_family != d->ai_addr->sa_family)
1492 				continue;
1493 			switch (s->ai_addr->sa_family) {
1494 			case AF_INET:
1495 				plen = sizeof(struct in_addr) << 3;
1496 				break;
1497 #ifdef INET6
1498 			case AF_INET6:
1499 				plen = sizeof(struct in6_addr) << 3;
1500 				break;
1501 #endif
1502 			default:
1503 				continue;
1504 			}
1505 
1506 			/* set src */
1507 			sa = s->ai_addr;
1508 			salen = sysdep_sa_len(s->ai_addr);
1509 			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1510 			    PFKEY_ALIGN8(salen));
1511 			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
1512 			m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1513 			m_addr.sadb_address_prefixlen = plen;
1514 			m_addr.sadb_address_reserved = 0;
1515 
1516 			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1517 			    sizeof(m_addr), sa, salen);
1518 
1519 			/* set dst */
1520 			sa = d->ai_addr;
1521 			salen = sysdep_sa_len(d->ai_addr);
1522 			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1523 			    PFKEY_ALIGN8(salen));
1524 			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
1525 			m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1526 			m_addr.sadb_address_prefixlen = plen;
1527 			m_addr.sadb_address_reserved = 0;
1528 
1529 			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1530 			    sizeof(m_addr), sa, salen);
1531 
1532 #ifdef SADB_X_EXT_NAT_T_TYPE
1533 			if (p_natt_type) {
1534 				struct sadb_x_nat_t_port natt_port;
1535 
1536 				/* NATT_SPORT */
1537 				len = sizeof(struct sadb_x_nat_t_port);
1538 				memset(&natt_port, 0, len);
1539 				natt_port.sadb_x_nat_t_port_len = PFKEY_UNIT64(len);
1540 				natt_port.sadb_x_nat_t_port_exttype =
1541 					SADB_X_EXT_NAT_T_SPORT;
1542 				natt_port.sadb_x_nat_t_port_port = htons(get_port(s));
1543 
1544 				memcpy(buf + l, &natt_port, len);
1545 				l += len;
1546 
1547 				/* NATT_DPORT */
1548 				natt_port.sadb_x_nat_t_port_exttype =
1549 					SADB_X_EXT_NAT_T_DPORT;
1550 				natt_port.sadb_x_nat_t_port_port = htons(get_port(d));
1551 
1552 				memcpy(buf + l, &natt_port, len);
1553 				l += len;
1554 #ifdef SADB_X_EXT_NAT_T_FRAG
1555 				if (p_esp_frag) {
1556 					struct sadb_x_nat_t_frag esp_frag;
1557 
1558 					/* NATT_FRAG */
1559 					len = sizeof(struct sadb_x_nat_t_frag);
1560 					memset(&esp_frag, 0, len);
1561 					esp_frag.sadb_x_nat_t_frag_len = PFKEY_UNIT64(len);
1562 					esp_frag.sadb_x_nat_t_frag_exttype =
1563 						SADB_X_EXT_NAT_T_FRAG;
1564 					esp_frag.sadb_x_nat_t_frag_fraglen = p_esp_frag;
1565 
1566 					memcpy(buf + l, &esp_frag, len);
1567 					l += len;
1568 				}
1569 #endif
1570 			}
1571 #endif
1572 			msg->sadb_msg_len = PFKEY_UNIT64(l);
1573 
1574 			sendkeymsg(buf, l);
1575 
1576 			n++;
1577 		}
1578 	}
1579 
1580 	if (n == 0)
1581 		return -1;
1582 	else
1583 		return 0;
1584 }
1585 
1586 static struct addrinfo *
parse_addr(char * host,char * port)1587 parse_addr(char *host, char *port)
1588 {
1589 	struct addrinfo hints, *res = NULL;
1590 	int error;
1591 
1592 	memset(&hints, 0, sizeof(hints));
1593 	hints.ai_family = p_aifamily;
1594 	hints.ai_socktype = SOCK_DGRAM;		/*dummy*/
1595 	hints.ai_protocol = IPPROTO_UDP;	/*dummy*/
1596 	hints.ai_flags = p_aiflags;
1597 	error = getaddrinfo(host, port, &hints, &res);
1598 	if (error != 0) {
1599 		yyerror(gai_strerror(error));
1600 		return NULL;
1601 	}
1602 	return res;
1603 }
1604 
1605 static int
fix_portstr(int ulproto,vchar_t * spec,vchar_t * sport,vchar_t * dport)1606 fix_portstr(int ulproto, vchar_t *spec, vchar_t *sport, vchar_t *dport)
1607 {
1608 	char sp[16], dp[16];
1609 	int a, b, c, d;
1610 	unsigned long u;
1611 
1612 	if (spec->buf == NULL)
1613 		return 0;
1614 
1615 	switch (ulproto) {
1616 	case IPPROTO_ICMP:
1617 	case IPPROTO_ICMPV6:
1618 	case IPPROTO_MH:
1619 		if (sscanf(spec->buf, "%d,%d", &a, &b) == 2) {
1620 			sprintf(sp, "%d", a);
1621 			sprintf(dp, "%d", b);
1622 		} else if (sscanf(spec->buf, "%d", &a) == 1) {
1623 			sprintf(sp, "%d", a);
1624 		} else {
1625 			yyerror("invalid an upper layer protocol spec");
1626 			return -1;
1627 		}
1628 		break;
1629 	case IPPROTO_GRE:
1630 		if (sscanf(spec->buf, "%d.%d.%d.%d", &a, &b, &c, &d) == 4) {
1631 			sprintf(sp, "%d", (a << 8) + b);
1632 			sprintf(dp, "%d", (c << 8) + d);
1633 		} else if (sscanf(spec->buf, "%lu", &u) == 1) {
1634 			sprintf(sp, "%d", (int) (u >> 16));
1635 			sprintf(dp, "%d", (int) (u & 0xffff));
1636 		} else {
1637 			yyerror("invalid an upper layer protocol spec");
1638 			return -1;
1639 		}
1640 		break;
1641 	}
1642 
1643 	free(sport->buf);
1644 	sport->buf = strdup(sp);
1645 	if (!sport->buf) {
1646 		yyerror("insufficient memory");
1647 		return -1;
1648 	}
1649 	sport->len = strlen(sport->buf);
1650 
1651 	free(dport->buf);
1652 	dport->buf = strdup(dp);
1653 	if (!dport->buf) {
1654 		yyerror("insufficient memory");
1655 		return -1;
1656 	}
1657 	dport->len = strlen(dport->buf);
1658 
1659 	return 0;
1660 }
1661 
1662 static int
setvarbuf(char * buf,int * off,struct sadb_ext * ebuf,int elen,const void * vbuf,int vlen)1663 setvarbuf(char *buf, int *off, struct sadb_ext *ebuf, int elen,
1664     const void *vbuf, int vlen)
1665 {
1666 	memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len));
1667 	memcpy(buf + *off, (caddr_t)ebuf, elen);
1668 	memcpy(buf + *off + elen, vbuf, vlen);
1669 	(*off) += PFKEY_ALIGN8(elen + vlen);
1670 
1671 	return 0;
1672 }
1673 
1674 void
parse_init(void)1675 parse_init(void)
1676 {
1677 	p_spi = 0;
1678 
1679 	p_ext = SADB_X_EXT_CYCSEQ;
1680 	p_alg_enc = SADB_EALG_NONE;
1681 	p_alg_auth = SADB_AALG_NONE;
1682 	p_mode = IPSEC_MODE_ANY;
1683 	p_reqid = 0;
1684 	p_replay = 0;
1685 	p_key_enc_len = p_key_auth_len = 0;
1686 	p_key_enc = p_key_auth = 0;
1687 	p_lt_hard = p_lt_soft = 0;
1688 	p_lb_hard = p_lb_soft = 0;
1689 
1690 	memset(&sec_ctx, 0, sizeof(struct security_ctx));
1691 
1692 	p_aiflags = 0;
1693 	p_aifamily = PF_UNSPEC;
1694 
1695 	/* Clear out any natt OA information */
1696 	if (p_natt_oa)
1697 		freeaddrinfo (p_natt_oa);
1698 	p_natt_oa = NULL;
1699 	p_natt_type = 0;
1700 	p_esp_frag = 0;
1701 
1702 	return;
1703 }
1704 
1705 void
free_buffer(void)1706 free_buffer(void)
1707 {
1708 	/* we got tons of memory leaks in the parser anyways, leave them */
1709 
1710 	return;
1711 }
1712