xref: /freebsd/sbin/setkey/parse.y (revision c697fb7f)
1 /*	$FreeBSD$	*/
2 /*	$KAME: parse.y,v 1.83 2004/05/18 08:48:23 sakane Exp $	*/
3 
4 /*-
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the project nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 
35 %{
36 #include <sys/types.h>
37 #include <sys/param.h>
38 #include <sys/socket.h>
39 
40 #include <net/route.h>
41 #include <netinet/in.h>
42 #include <net/pfkeyv2.h>
43 #include <netipsec/key_var.h>
44 #include <netipsec/ipsec.h>
45 #include <arpa/inet.h>
46 
47 #include <string.h>
48 #include <unistd.h>
49 #include <stdio.h>
50 #include <stdint.h>
51 #include <netdb.h>
52 #include <ctype.h>
53 #include <errno.h>
54 
55 #include "libpfkey.h"
56 #include "vchar.h"
57 
58 #define ATOX(c) \
59   (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10)))
60 
61 u_int32_t p_spi;
62 u_int p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode;
63 u_int32_t p_reqid;
64 u_int p_key_enc_len, p_key_auth_len;
65 caddr_t p_key_enc, p_key_auth;
66 time_t p_lt_hard, p_lt_soft;
67 
68 static int p_aiflags = 0, p_aifamily = PF_UNSPEC;
69 
70 static struct addrinfo *parse_addr(char *, char *);
71 static int fix_portstr(vchar_t *, vchar_t *, vchar_t *);
72 static int setvarbuf(char *, int *, struct sadb_ext *, int, caddr_t, int);
73 void parse_init(void);
74 void free_buffer(void);
75 
76 int setkeymsg0(struct sadb_msg *, unsigned int, unsigned int, size_t);
77 static int setkeymsg_spdaddr(unsigned int, unsigned int, vchar_t *,
78 	struct addrinfo *, int, struct addrinfo *, int);
79 static int setkeymsg_addr(unsigned int, unsigned int,
80 	struct addrinfo *, struct addrinfo *, int);
81 static int setkeymsg_add(unsigned int, unsigned int,
82 	struct addrinfo *, struct addrinfo *);
83 extern int setkeymsg(char *, size_t *);
84 extern int sendkeymsg(char *, size_t);
85 
86 extern int yylex(void);
87 extern void yyfatal(const char *);
88 extern void yyerror(const char *);
89 %}
90 
91 %union {
92 	int num;
93 	unsigned long ulnum;
94 	vchar_t val;
95 	struct addrinfo *res;
96 }
97 
98 %token EOT SLASH BLCL ELCL
99 %token ADD GET DELETE DELETEALL FLUSH DUMP
100 %token PR_ESP PR_AH PR_IPCOMP PR_TCP
101 %token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI
102 %token F_MODE MODE F_REQID
103 %token F_EXT EXTENSION NOCYCLICSEQ
104 %token ALG_AUTH ALG_AUTH_NOKEY
105 %token ALG_ENC ALG_ENC_NOKEY ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD
106 %token ALG_ENC_SALT
107 %token ALG_COMP
108 %token F_LIFETIME_HARD F_LIFETIME_SOFT
109 %token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY
110 	/* SPD management */
111 %token SPDADD SPDDELETE SPDDUMP SPDFLUSH
112 %token F_POLICY PL_REQUESTS
113 %token F_AIFLAGS
114 %token TAGGED
115 
116 %type <num> prefix protocol_spec upper_spec
117 %type <num> ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD ALG_ENC_NOKEY
118 %type <num> ALG_ENC_SALT
119 %type <num> ALG_AUTH ALG_AUTH_NOKEY
120 %type <num> ALG_COMP
121 %type <num> PR_ESP PR_AH PR_IPCOMP PR_TCP
122 %type <num> EXTENSION MODE
123 %type <ulnum> DECSTRING
124 %type <val> PL_REQUESTS portstr key_string
125 %type <val> policy_requests
126 %type <val> QUOTEDSTRING HEXSTRING STRING
127 %type <val> F_AIFLAGS
128 %type <val> upper_misc_spec policy_spec
129 %type <res> ipaddr
130 
131 %%
132 commands
133 	:	/*NOTHING*/
134 	|	commands command
135 		{
136 			free_buffer();
137 			parse_init();
138 		}
139 	;
140 
141 command
142 	:	add_command
143 	|	get_command
144 	|	delete_command
145 	|	deleteall_command
146 	|	flush_command
147 	|	dump_command
148 	|	spdadd_command
149 	|	spddelete_command
150 	|	spddump_command
151 	|	spdflush_command
152 	;
153 	/* commands concerned with management, there is in tail of this file. */
154 
155 	/* add command */
156 add_command
157 	:	ADD ipaddropts ipaddr ipaddr protocol_spec spi extension_spec algorithm_spec EOT
158 		{
159 			int status;
160 
161 			status = setkeymsg_add(SADB_ADD, $5, $3, $4);
162 			if (status < 0)
163 				return -1;
164 		}
165 	;
166 
167 	/* delete */
168 delete_command
169 	:	DELETE ipaddropts ipaddr ipaddr protocol_spec spi extension_spec EOT
170 		{
171 			int status;
172 
173 			if ($3->ai_next || $4->ai_next) {
174 				yyerror("multiple address specified");
175 				return -1;
176 			}
177 			if (p_mode != IPSEC_MODE_ANY)
178 				yyerror("WARNING: mode is obsolete");
179 
180 			status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 0);
181 			if (status < 0)
182 				return -1;
183 		}
184 	;
185 
186 	/* deleteall command */
187 deleteall_command
188 	:	DELETEALL ipaddropts ipaddr ipaddr protocol_spec EOT
189 		{
190 			int status;
191 
192 			status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 1);
193 			if (status < 0)
194 				return -1;
195 		}
196 	;
197 
198 	/* get command */
199 get_command
200 	:	GET ipaddropts ipaddr ipaddr protocol_spec spi extension_spec EOT
201 		{
202 			int status;
203 
204 			if (p_mode != IPSEC_MODE_ANY)
205 				yyerror("WARNING: mode is obsolete");
206 
207 			status = setkeymsg_addr(SADB_GET, $5, $3, $4, 0);
208 			if (status < 0)
209 				return -1;
210 		}
211 	;
212 
213 	/* flush */
214 flush_command
215 	:	FLUSH protocol_spec EOT
216 		{
217 			struct sadb_msg msg;
218 			setkeymsg0(&msg, SADB_FLUSH, $2, sizeof(msg));
219 			sendkeymsg((char *)&msg, sizeof(msg));
220 		}
221 	;
222 
223 	/* dump */
224 dump_command
225 	:	DUMP protocol_spec EOT
226 		{
227 			struct sadb_msg msg;
228 			setkeymsg0(&msg, SADB_DUMP, $2, sizeof(msg));
229 			sendkeymsg((char *)&msg, sizeof(msg));
230 		}
231 	;
232 
233 protocol_spec
234 	:	/*NOTHING*/
235 		{
236 			$$ = SADB_SATYPE_UNSPEC;
237 		}
238 	|	PR_ESP
239 		{
240 			$$ = SADB_SATYPE_ESP;
241 			if ($1 == 1)
242 				p_ext |= SADB_X_EXT_OLD;
243 			else
244 				p_ext &= ~SADB_X_EXT_OLD;
245 		}
246 	|	PR_AH
247 		{
248 			$$ = SADB_SATYPE_AH;
249 			if ($1 == 1)
250 				p_ext |= SADB_X_EXT_OLD;
251 			else
252 				p_ext &= ~SADB_X_EXT_OLD;
253 		}
254 	|	PR_IPCOMP
255 		{
256 			$$ = SADB_X_SATYPE_IPCOMP;
257 		}
258 	|	PR_TCP
259 		{
260 			$$ = SADB_X_SATYPE_TCPSIGNATURE;
261 		}
262 	;
263 
264 spi
265 	:	DECSTRING { p_spi = $1; }
266 	|	HEXSTRING
267 		{
268 			char *ep;
269 			unsigned long v;
270 
271 			ep = NULL;
272 			v = strtoul($1.buf, &ep, 16);
273 			if (!ep || *ep) {
274 				yyerror("invalid SPI");
275 				return -1;
276 			}
277 			if (v & ~0xffffffff) {
278 				yyerror("SPI too big.");
279 				return -1;
280 			}
281 
282 			p_spi = v;
283 		}
284 	;
285 
286 algorithm_spec
287 	:	esp_spec
288 	|	ah_spec
289 	|	ipcomp_spec
290 	;
291 
292 esp_spec
293 	:	F_ENC enc_alg F_AUTH auth_alg
294 	|	F_ENC enc_alg
295 	;
296 
297 ah_spec
298 	:	F_AUTH auth_alg
299 	;
300 
301 ipcomp_spec
302 	:	F_COMP ALG_COMP
303 		{
304 			if ($2 < 0) {
305 				yyerror("unsupported algorithm");
306 				return -1;
307 			}
308 			p_alg_enc = $2;
309 		}
310 	|	F_COMP ALG_COMP F_RAWCPI
311 		{
312 			if ($2 < 0) {
313 				yyerror("unsupported algorithm");
314 				return -1;
315 			}
316 			p_alg_enc = $2;
317 			p_ext |= SADB_X_EXT_RAWCPI;
318 		}
319 	;
320 
321 enc_alg
322 	:	ALG_ENC_NOKEY {
323 			if ($1 < 0) {
324 				yyerror("unsupported algorithm");
325 				return -1;
326 			}
327 			p_alg_enc = $1;
328 
329 			p_key_enc_len = 0;
330 			p_key_enc = NULL;
331 			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
332 			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
333 				yyerror(ipsec_strerror());
334 				return -1;
335 			}
336 		}
337 	|	ALG_ENC key_string {
338 			if ($1 < 0) {
339 				yyerror("unsupported algorithm");
340 				return -1;
341 			}
342 			p_alg_enc = $1;
343 
344 			p_key_enc_len = $2.len;
345 			p_key_enc = $2.buf;
346 			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
347 			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
348 				yyerror(ipsec_strerror());
349 				return -1;
350 			}
351 		}
352 	|	ALG_ENC_OLD {
353 			if ($1 < 0) {
354 				yyerror("unsupported algorithm");
355 				return -1;
356 			}
357 			yyerror("WARNING: obsolete algorithm");
358 			p_alg_enc = $1;
359 
360 			p_key_enc_len = 0;
361 			p_key_enc = NULL;
362 			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
363 			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
364 				yyerror(ipsec_strerror());
365 				return -1;
366 			}
367 		}
368 	|	ALG_ENC_DESDERIV key_string
369 		{
370 			if ($1 < 0) {
371 				yyerror("unsupported algorithm");
372 				return -1;
373 			}
374 			p_alg_enc = $1;
375 			if (p_ext & SADB_X_EXT_OLD) {
376 				yyerror("algorithm mismatched");
377 				return -1;
378 			}
379 			p_ext |= SADB_X_EXT_DERIV;
380 
381 			p_key_enc_len = $2.len;
382 			p_key_enc = $2.buf;
383 			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
384 			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
385 				yyerror(ipsec_strerror());
386 				return -1;
387 			}
388 		}
389 	|	ALG_ENC_DES32IV key_string
390 		{
391 			if ($1 < 0) {
392 				yyerror("unsupported algorithm");
393 				return -1;
394 			}
395 			p_alg_enc = $1;
396 			if (!(p_ext & SADB_X_EXT_OLD)) {
397 				yyerror("algorithm mismatched");
398 				return -1;
399 			}
400 			p_ext |= SADB_X_EXT_IV4B;
401 
402 			p_key_enc_len = $2.len;
403 			p_key_enc = $2.buf;
404 			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
405 			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
406 				yyerror(ipsec_strerror());
407 				return -1;
408 			}
409 		}
410 	|	ALG_ENC_SALT key_string
411 		{
412 			if ($1 < 0) {
413 				yyerror("unsupported algorithm");
414 				return -1;
415 			}
416 			p_alg_enc = $1;
417 
418 			p_key_enc_len = $2.len;
419 
420 			p_key_enc = $2.buf;
421 			/*
422 			 * Salted keys include a 4 byte value that is
423 			 * not part of the key.
424 			 */
425 			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
426 			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len - 4)) < 0) {
427 				yyerror(ipsec_strerror());
428 				return -1;
429 			}
430 		}
431 	;
432 
433 auth_alg
434 	:	ALG_AUTH key_string {
435 			if ($1 < 0) {
436 				yyerror("unsupported algorithm");
437 				return -1;
438 			}
439 			p_alg_auth = $1;
440 
441 			p_key_auth_len = $2.len;
442 			p_key_auth = $2.buf;
443 
444 			if (p_alg_auth == SADB_X_AALG_TCP_MD5) {
445 				if ((p_key_auth_len < 1) || (p_key_auth_len >
446 				    80))
447 					return -1;
448 			} else if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH,
449 			    p_alg_auth, PFKEY_UNUNIT64(p_key_auth_len)) < 0) {
450 				yyerror(ipsec_strerror());
451 				return -1;
452 			}
453 		}
454 	|	ALG_AUTH_NOKEY {
455 			if ($1 < 0) {
456 				yyerror("unsupported algorithm");
457 				return -1;
458 			}
459 			p_alg_auth = $1;
460 
461 			p_key_auth_len = 0;
462 			p_key_auth = NULL;
463 		}
464 	;
465 
466 key_string
467 	:	QUOTEDSTRING
468 		{
469 			$$ = $1;
470 		}
471 	|	HEXSTRING
472 		{
473 			caddr_t pp_key;
474 			caddr_t bp;
475 			caddr_t yp = $1.buf;
476 			int l;
477 
478 			l = strlen(yp) % 2 + strlen(yp) / 2;
479 			if ((pp_key = malloc(l)) == 0) {
480 				yyerror("not enough core");
481 				return -1;
482 			}
483 			memset(pp_key, 0, l);
484 
485 			bp = pp_key;
486 			if (strlen(yp) % 2) {
487 				*bp = ATOX(yp[0]);
488 				yp++, bp++;
489 			}
490 			while (*yp) {
491 				*bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]);
492 				yp += 2, bp++;
493 			}
494 
495 			$$.len = l;
496 			$$.buf = pp_key;
497 		}
498 	;
499 
500 extension_spec
501 	:	/*NOTHING*/
502 	|	extension_spec extension
503 	;
504 
505 extension
506 	:	F_EXT EXTENSION { p_ext |= $2; }
507 	|	F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; }
508 	|	F_MODE MODE { p_mode = $2; }
509 	|	F_MODE ANY { p_mode = IPSEC_MODE_ANY; }
510 	|	F_REQID DECSTRING { p_reqid = $2; }
511 	|	F_REPLAY DECSTRING
512 		{
513 			if ((p_ext & SADB_X_EXT_OLD) != 0) {
514 				yyerror("replay prevention cannot be used with "
515 				    "ah/esp-old");
516 				return -1;
517 			}
518 			p_replay = $2;
519 			if (p_replay > (UINT32_MAX - 32) >> 3)
520 				yyerror("replay window is too large");
521 		}
522 	|	F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; }
523 	|	F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; }
524 	;
525 
526 	/* definition about command for SPD management */
527 	/* spdadd */
528 spdadd_command
529 	:	SPDADD ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT
530 		{
531 			int status;
532 			struct addrinfo *src, *dst;
533 
534 			/* fixed port fields if ulp is icmpv6 */
535 			if ($10.buf != NULL) {
536 				if ($9 != IPPROTO_ICMPV6)
537 					return -1;
538 				free($5.buf);
539 				free($8.buf);
540 				if (fix_portstr(&$10, &$5, &$8))
541 					return -1;
542 			}
543 
544 			src = parse_addr($3.buf, $5.buf);
545 			dst = parse_addr($6.buf, $8.buf);
546 			if (!src || !dst) {
547 				/* yyerror is already called */
548 				return -1;
549 			}
550 			if (src->ai_next || dst->ai_next) {
551 				yyerror("multiple address specified");
552 				freeaddrinfo(src);
553 				freeaddrinfo(dst);
554 				return -1;
555 			}
556 
557 			status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$11,
558 			    src, $4, dst, $7);
559 			freeaddrinfo(src);
560 			freeaddrinfo(dst);
561 			if (status < 0)
562 				return -1;
563 		}
564 	|	SPDADD TAGGED QUOTEDSTRING policy_spec EOT
565 		{
566 			return -1;
567 		}
568 	;
569 
570 spddelete_command
571 	:	SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT
572 		{
573 			int status;
574 			struct addrinfo *src, *dst;
575 
576 			/* fixed port fields if ulp is icmpv6 */
577 			if ($10.buf != NULL) {
578 				if ($9 != IPPROTO_ICMPV6)
579 					return -1;
580 				free($5.buf);
581 				free($8.buf);
582 				if (fix_portstr(&$10, &$5, &$8))
583 					return -1;
584 			}
585 
586 			src = parse_addr($3.buf, $5.buf);
587 			dst = parse_addr($6.buf, $8.buf);
588 			if (!src || !dst) {
589 				/* yyerror is already called */
590 				return -1;
591 			}
592 			if (src->ai_next || dst->ai_next) {
593 				yyerror("multiple address specified");
594 				freeaddrinfo(src);
595 				freeaddrinfo(dst);
596 				return -1;
597 			}
598 
599 			status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$11,
600 			    src, $4, dst, $7);
601 			freeaddrinfo(src);
602 			freeaddrinfo(dst);
603 			if (status < 0)
604 				return -1;
605 		}
606 	;
607 
608 spddump_command:
609 		SPDDUMP EOT
610 		{
611 			struct sadb_msg msg;
612 			setkeymsg0(&msg, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC,
613 			    sizeof(msg));
614 			sendkeymsg((char *)&msg, sizeof(msg));
615 		}
616 	;
617 
618 spdflush_command:
619 		SPDFLUSH EOT
620 		{
621 			struct sadb_msg msg;
622 			setkeymsg0(&msg, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC,
623 			    sizeof(msg));
624 			sendkeymsg((char *)&msg, sizeof(msg));
625 		}
626 	;
627 
628 ipaddropts
629 	:	/* nothing */
630 	|	ipaddropts ipaddropt
631 	;
632 
633 ipaddropt
634 	:	F_AIFLAGS
635 		{
636 			char *p;
637 
638 			for (p = $1.buf + 1; *p; p++)
639 				switch (*p) {
640 				case '4':
641 					p_aifamily = AF_INET;
642 					break;
643 #ifdef INET6
644 				case '6':
645 					p_aifamily = AF_INET6;
646 					break;
647 #endif
648 				case 'n':
649 					p_aiflags = AI_NUMERICHOST;
650 					break;
651 				default:
652 					yyerror("invalid flag");
653 					return -1;
654 				}
655 		}
656 	;
657 
658 ipaddr
659 	:	STRING
660 		{
661 			$$ = parse_addr($1.buf, NULL);
662 			if ($$ == NULL) {
663 				/* yyerror already called by parse_addr */
664 				return -1;
665 			}
666 		}
667 	;
668 
669 prefix
670 	:	/*NOTHING*/ { $$ = -1; }
671 	|	SLASH DECSTRING { $$ = $2; }
672 	;
673 
674 portstr
675 	:	/*NOTHING*/
676 		{
677 			$$.buf = strdup("0");
678 			if (!$$.buf) {
679 				yyerror("insufficient memory");
680 				return -1;
681 			}
682 			$$.len = strlen($$.buf);
683 		}
684 	|	BLCL ANY ELCL
685 		{
686 			$$.buf = strdup("0");
687 			if (!$$.buf) {
688 				yyerror("insufficient memory");
689 				return -1;
690 			}
691 			$$.len = strlen($$.buf);
692 		}
693 	|	BLCL DECSTRING ELCL
694 		{
695 			char buf[20];
696 			snprintf(buf, sizeof(buf), "%lu", $2);
697 			$$.buf = strdup(buf);
698 			if (!$$.buf) {
699 				yyerror("insufficient memory");
700 				return -1;
701 			}
702 			$$.len = strlen($$.buf);
703 		}
704 	|	BLCL STRING ELCL
705 		{
706 			$$ = $2;
707 		}
708 	;
709 
710 upper_spec
711 	:	DECSTRING { $$ = $1; }
712 	|	ANY { $$ = IPSEC_ULPROTO_ANY; }
713 	|	PR_TCP { $$ = IPPROTO_TCP; }
714 	|	PR_ESP { $$ = IPPROTO_ESP; }
715 	|	STRING
716 		{
717 			struct protoent *ent;
718 
719 			ent = getprotobyname($1.buf);
720 			if (ent)
721 				$$ = ent->p_proto;
722 			else {
723 				if (strcmp("icmp6", $1.buf) == 0) {
724 					$$ = IPPROTO_ICMPV6;
725 				} else if(strcmp("ip4", $1.buf) == 0) {
726 					$$ = IPPROTO_IPV4;
727 				} else {
728 					yyerror("invalid upper layer protocol");
729 					return -1;
730 				}
731 			}
732 			endprotoent();
733 		}
734 	;
735 
736 upper_misc_spec
737 	:	/*NOTHING*/
738 		{
739 			$$.buf = NULL;
740 			$$.len = 0;
741 		}
742 	|	STRING
743 		{
744 			$$.buf = strdup($1.buf);
745 			if (!$$.buf) {
746 				yyerror("insufficient memory");
747 				return -1;
748 			}
749 			$$.len = strlen($$.buf);
750 		}
751 	;
752 
753 policy_spec
754 	:	F_POLICY policy_requests
755 		{
756 			char *policy;
757 
758 			policy = ipsec_set_policy($2.buf, $2.len);
759 			if (policy == NULL) {
760 				yyerror(ipsec_strerror());
761 				return -1;
762 			}
763 
764 			$$.buf = policy;
765 			$$.len = ipsec_get_policylen(policy);
766 		}
767 	;
768 
769 policy_requests
770 	:	PL_REQUESTS { $$ = $1; }
771 	;
772 
773 %%
774 
775 int
776 setkeymsg0(msg, type, satype, l)
777 	struct sadb_msg *msg;
778 	unsigned int type;
779 	unsigned int satype;
780 	size_t l;
781 {
782 
783 	msg->sadb_msg_version = PF_KEY_V2;
784 	msg->sadb_msg_type = type;
785 	msg->sadb_msg_errno = 0;
786 	msg->sadb_msg_satype = satype;
787 	msg->sadb_msg_reserved = 0;
788 	msg->sadb_msg_seq = 0;
789 	msg->sadb_msg_pid = getpid();
790 	msg->sadb_msg_len = PFKEY_UNIT64(l);
791 	return 0;
792 }
793 
794 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
795 static int
796 setkeymsg_spdaddr(type, upper, policy, srcs, splen, dsts, dplen)
797 	unsigned int type;
798 	unsigned int upper;
799 	vchar_t *policy;
800 	struct addrinfo *srcs;
801 	int splen;
802 	struct addrinfo *dsts;
803 	int dplen;
804 {
805 	struct sadb_msg *msg;
806 	char buf[BUFSIZ];
807 	int l, l0;
808 	struct sadb_address m_addr;
809 	struct addrinfo *s, *d;
810 	int n;
811 	int plen;
812 	struct sockaddr *sa;
813 	int salen;
814 
815 	msg = (struct sadb_msg *)buf;
816 
817 	if (!srcs || !dsts)
818 		return -1;
819 
820 	/* fix up length afterwards */
821 	setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0);
822 	l = sizeof(struct sadb_msg);
823 
824 	memcpy(buf + l, policy->buf, policy->len);
825 	l += policy->len;
826 
827 	l0 = l;
828 	n = 0;
829 
830 	/* do it for all src/dst pairs */
831 	for (s = srcs; s; s = s->ai_next) {
832 		for (d = dsts; d; d = d->ai_next) {
833 			/* rewind pointer */
834 			l = l0;
835 
836 			if (s->ai_addr->sa_family != d->ai_addr->sa_family)
837 				continue;
838 			switch (s->ai_addr->sa_family) {
839 			case AF_INET:
840 				plen = sizeof(struct in_addr) << 3;
841 				break;
842 #ifdef INET6
843 			case AF_INET6:
844 				plen = sizeof(struct in6_addr) << 3;
845 				break;
846 #endif
847 			default:
848 				continue;
849 			}
850 
851 			/* set src */
852 			sa = s->ai_addr;
853 			salen = s->ai_addr->sa_len;
854 			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
855 			    PFKEY_ALIGN8(salen));
856 			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
857 			m_addr.sadb_address_proto = upper;
858 			m_addr.sadb_address_prefixlen =
859 			    (splen >= 0 ? splen : plen);
860 			m_addr.sadb_address_reserved = 0;
861 
862 			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
863 			    sizeof(m_addr), (caddr_t)sa, salen);
864 
865 			/* set dst */
866 			sa = d->ai_addr;
867 			salen = d->ai_addr->sa_len;
868 			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
869 			    PFKEY_ALIGN8(salen));
870 			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
871 			m_addr.sadb_address_proto = upper;
872 			m_addr.sadb_address_prefixlen =
873 			    (dplen >= 0 ? dplen : plen);
874 			m_addr.sadb_address_reserved = 0;
875 
876 			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
877 			    sizeof(m_addr), (caddr_t)sa, salen);
878 
879 			msg->sadb_msg_len = PFKEY_UNIT64(l);
880 
881 			sendkeymsg(buf, l);
882 
883 			n++;
884 		}
885 	}
886 
887 	if (n == 0)
888 		return -1;
889 	else
890 		return 0;
891 }
892 
893 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
894 static int
895 setkeymsg_addr(type, satype, srcs, dsts, no_spi)
896 	unsigned int type;
897 	unsigned int satype;
898 	struct addrinfo *srcs;
899 	struct addrinfo *dsts;
900 	int no_spi;
901 {
902 	struct sadb_msg *msg;
903 	char buf[BUFSIZ];
904 	int l, l0, len;
905 	struct sadb_sa m_sa;
906 	struct sadb_x_sa2 m_sa2;
907 	struct sadb_x_sa_replay m_replay;
908 	struct sadb_address m_addr;
909 	struct addrinfo *s, *d;
910 	int n;
911 	int plen;
912 	struct sockaddr *sa;
913 	int salen;
914 
915 	msg = (struct sadb_msg *)buf;
916 
917 	if (!srcs || !dsts)
918 		return -1;
919 
920 	/* fix up length afterwards */
921 	setkeymsg0(msg, type, satype, 0);
922 	l = sizeof(struct sadb_msg);
923 
924 	if (!no_spi) {
925 		len = sizeof(struct sadb_sa);
926 		m_sa.sadb_sa_len = PFKEY_UNIT64(len);
927 		m_sa.sadb_sa_exttype = SADB_EXT_SA;
928 		m_sa.sadb_sa_spi = htonl(p_spi);
929 		m_sa.sadb_sa_replay = p_replay > UINT8_MAX ? UINT8_MAX:
930 		    p_replay;
931 		m_sa.sadb_sa_state = 0;
932 		m_sa.sadb_sa_auth = p_alg_auth;
933 		m_sa.sadb_sa_encrypt = p_alg_enc;
934 		m_sa.sadb_sa_flags = p_ext;
935 
936 		memcpy(buf + l, &m_sa, len);
937 		l += len;
938 
939 		len = sizeof(struct sadb_x_sa2);
940 		m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
941 		m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
942 		m_sa2.sadb_x_sa2_mode = p_mode;
943 		m_sa2.sadb_x_sa2_reqid = p_reqid;
944 
945 		memcpy(buf + l, &m_sa2, len);
946 		l += len;
947 
948 		if (p_replay > UINT8_MAX) {
949 			len = sizeof(struct sadb_x_sa_replay);
950 			m_replay.sadb_x_sa_replay_len = PFKEY_UNIT64(len);
951 			m_replay.sadb_x_sa_replay_exttype =
952 			    SADB_X_EXT_SA_REPLAY;
953 			m_replay.sadb_x_sa_replay_replay = p_replay << 3;
954 
955 			memcpy(buf + l, &m_replay, len);
956 			l += len;
957 		}
958 	}
959 
960 	l0 = l;
961 	n = 0;
962 
963 	/* do it for all src/dst pairs */
964 	for (s = srcs; s; s = s->ai_next) {
965 		for (d = dsts; d; d = d->ai_next) {
966 			/* rewind pointer */
967 			l = l0;
968 
969 			if (s->ai_addr->sa_family != d->ai_addr->sa_family)
970 				continue;
971 			switch (s->ai_addr->sa_family) {
972 			case AF_INET:
973 				plen = sizeof(struct in_addr) << 3;
974 				break;
975 #ifdef INET6
976 			case AF_INET6:
977 				plen = sizeof(struct in6_addr) << 3;
978 				break;
979 #endif
980 			default:
981 				continue;
982 			}
983 
984 			/* set src */
985 			sa = s->ai_addr;
986 			salen = s->ai_addr->sa_len;
987 			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
988 			    PFKEY_ALIGN8(salen));
989 			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
990 			m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
991 			m_addr.sadb_address_prefixlen = plen;
992 			m_addr.sadb_address_reserved = 0;
993 
994 			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
995 			    sizeof(m_addr), (caddr_t)sa, salen);
996 
997 			/* set dst */
998 			sa = d->ai_addr;
999 			salen = d->ai_addr->sa_len;
1000 			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1001 			    PFKEY_ALIGN8(salen));
1002 			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
1003 			m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1004 			m_addr.sadb_address_prefixlen = plen;
1005 			m_addr.sadb_address_reserved = 0;
1006 
1007 			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1008 			    sizeof(m_addr), (caddr_t)sa, salen);
1009 
1010 			msg->sadb_msg_len = PFKEY_UNIT64(l);
1011 
1012 			sendkeymsg(buf, l);
1013 
1014 			n++;
1015 		}
1016 	}
1017 
1018 	if (n == 0)
1019 		return -1;
1020 	else
1021 		return 0;
1022 }
1023 
1024 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
1025 static int
1026 setkeymsg_add(type, satype, srcs, dsts)
1027 	unsigned int type;
1028 	unsigned int satype;
1029 	struct addrinfo *srcs;
1030 	struct addrinfo *dsts;
1031 {
1032 	struct sadb_msg *msg;
1033 	char buf[BUFSIZ];
1034 	int l, l0, len;
1035 	struct sadb_sa m_sa;
1036 	struct sadb_x_sa2 m_sa2;
1037 	struct sadb_address m_addr;
1038 	struct sadb_x_sa_replay m_replay;
1039 	struct addrinfo *s, *d;
1040 	int n;
1041 	int plen;
1042 	struct sockaddr *sa;
1043 	int salen;
1044 
1045 	msg = (struct sadb_msg *)buf;
1046 
1047 	if (!srcs || !dsts)
1048 		return -1;
1049 
1050 	/* fix up length afterwards */
1051 	setkeymsg0(msg, type, satype, 0);
1052 	l = sizeof(struct sadb_msg);
1053 
1054 	/* set encryption algorithm, if present. */
1055 	if (satype != SADB_X_SATYPE_IPCOMP && p_key_enc) {
1056 		struct sadb_key m_key;
1057 
1058 		m_key.sadb_key_len =
1059 			PFKEY_UNIT64(sizeof(m_key)
1060 				   + PFKEY_ALIGN8(p_key_enc_len));
1061 		m_key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
1062 		m_key.sadb_key_bits = p_key_enc_len * 8;
1063 		m_key.sadb_key_reserved = 0;
1064 
1065 		setvarbuf(buf, &l,
1066 			(struct sadb_ext *)&m_key, sizeof(m_key),
1067 			(caddr_t)p_key_enc, p_key_enc_len);
1068 	}
1069 
1070 	/* set authentication algorithm, if present. */
1071 	if (p_key_auth) {
1072 		struct sadb_key m_key;
1073 
1074 		m_key.sadb_key_len =
1075 			PFKEY_UNIT64(sizeof(m_key)
1076 				   + PFKEY_ALIGN8(p_key_auth_len));
1077 		m_key.sadb_key_exttype = SADB_EXT_KEY_AUTH;
1078 		m_key.sadb_key_bits = p_key_auth_len * 8;
1079 		m_key.sadb_key_reserved = 0;
1080 
1081 		setvarbuf(buf, &l,
1082 			(struct sadb_ext *)&m_key, sizeof(m_key),
1083 			(caddr_t)p_key_auth, p_key_auth_len);
1084 	}
1085 
1086 	/* set lifetime for HARD */
1087 	if (p_lt_hard != 0) {
1088 		struct sadb_lifetime m_lt;
1089 		u_int slen = sizeof(struct sadb_lifetime);
1090 
1091 		m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1092 		m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
1093 		m_lt.sadb_lifetime_allocations = 0;
1094 		m_lt.sadb_lifetime_bytes = 0;
1095 		m_lt.sadb_lifetime_addtime = p_lt_hard;
1096 		m_lt.sadb_lifetime_usetime = 0;
1097 
1098 		memcpy(buf + l, &m_lt, slen);
1099 		l += slen;
1100 	}
1101 
1102 	/* set lifetime for SOFT */
1103 	if (p_lt_soft != 0) {
1104 		struct sadb_lifetime m_lt;
1105 		u_int slen = sizeof(struct sadb_lifetime);
1106 
1107 		m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1108 		m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
1109 		m_lt.sadb_lifetime_allocations = 0;
1110 		m_lt.sadb_lifetime_bytes = 0;
1111 		m_lt.sadb_lifetime_addtime = p_lt_soft;
1112 		m_lt.sadb_lifetime_usetime = 0;
1113 
1114 		memcpy(buf + l, &m_lt, slen);
1115 		l += slen;
1116 	}
1117 
1118 	len = sizeof(struct sadb_sa);
1119 	m_sa.sadb_sa_len = PFKEY_UNIT64(len);
1120 	m_sa.sadb_sa_exttype = SADB_EXT_SA;
1121 	m_sa.sadb_sa_spi = htonl(p_spi);
1122 	m_sa.sadb_sa_replay = p_replay > UINT8_MAX ? UINT8_MAX: p_replay;
1123 	m_sa.sadb_sa_state = 0;
1124 	m_sa.sadb_sa_auth = p_alg_auth;
1125 	m_sa.sadb_sa_encrypt = p_alg_enc;
1126 	m_sa.sadb_sa_flags = p_ext;
1127 
1128 	memcpy(buf + l, &m_sa, len);
1129 	l += len;
1130 
1131 	len = sizeof(struct sadb_x_sa2);
1132 	m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
1133 	m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
1134 	m_sa2.sadb_x_sa2_mode = p_mode;
1135 	m_sa2.sadb_x_sa2_reqid = p_reqid;
1136 
1137 	memcpy(buf + l, &m_sa2, len);
1138 	l += len;
1139 
1140 	if (p_replay > UINT8_MAX) {
1141 		len = sizeof(struct sadb_x_sa_replay);
1142 		m_replay.sadb_x_sa_replay_len = PFKEY_UNIT64(len);
1143 		m_replay.sadb_x_sa_replay_exttype = SADB_X_EXT_SA_REPLAY;
1144 		m_replay.sadb_x_sa_replay_replay = p_replay << 3;
1145 
1146 		memcpy(buf + l, &m_replay, len);
1147 		l += len;
1148 	}
1149 	l0 = l;
1150 	n = 0;
1151 
1152 	/* do it for all src/dst pairs */
1153 	for (s = srcs; s; s = s->ai_next) {
1154 		for (d = dsts; d; d = d->ai_next) {
1155 			/* rewind pointer */
1156 			l = l0;
1157 
1158 			if (s->ai_addr->sa_family != d->ai_addr->sa_family)
1159 				continue;
1160 			switch (s->ai_addr->sa_family) {
1161 			case AF_INET:
1162 				plen = sizeof(struct in_addr) << 3;
1163 				break;
1164 #ifdef INET6
1165 			case AF_INET6:
1166 				plen = sizeof(struct in6_addr) << 3;
1167 				break;
1168 #endif
1169 			default:
1170 				continue;
1171 			}
1172 
1173 			/* set src */
1174 			sa = s->ai_addr;
1175 			salen = s->ai_addr->sa_len;
1176 			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1177 			    PFKEY_ALIGN8(salen));
1178 			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
1179 			m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1180 			m_addr.sadb_address_prefixlen = plen;
1181 			m_addr.sadb_address_reserved = 0;
1182 
1183 			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1184 			    sizeof(m_addr), (caddr_t)sa, salen);
1185 
1186 			/* set dst */
1187 			sa = d->ai_addr;
1188 			salen = d->ai_addr->sa_len;
1189 			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1190 			    PFKEY_ALIGN8(salen));
1191 			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
1192 			m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1193 			m_addr.sadb_address_prefixlen = plen;
1194 			m_addr.sadb_address_reserved = 0;
1195 
1196 			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1197 			    sizeof(m_addr), (caddr_t)sa, salen);
1198 
1199 			msg->sadb_msg_len = PFKEY_UNIT64(l);
1200 
1201 			sendkeymsg(buf, l);
1202 
1203 			n++;
1204 		}
1205 	}
1206 
1207 	if (n == 0)
1208 		return -1;
1209 	else
1210 		return 0;
1211 }
1212 
1213 static struct addrinfo *
1214 parse_addr(host, port)
1215 	char *host;
1216 	char *port;
1217 {
1218 	struct addrinfo hints, *res = NULL;
1219 	int error;
1220 
1221 	memset(&hints, 0, sizeof(hints));
1222 	hints.ai_family = p_aifamily;
1223 	hints.ai_socktype = SOCK_DGRAM;		/*dummy*/
1224 	hints.ai_protocol = IPPROTO_UDP;	/*dummy*/
1225 	hints.ai_flags = p_aiflags;
1226 	error = getaddrinfo(host, port, &hints, &res);
1227 	if (error != 0) {
1228 		yyerror(gai_strerror(error));
1229 		return NULL;
1230 	}
1231 	return res;
1232 }
1233 
1234 static int
1235 fix_portstr(spec, sport, dport)
1236 	vchar_t *spec, *sport, *dport;
1237 {
1238 	char *p, *p2;
1239 	u_int l;
1240 
1241 	l = 0;
1242 	for (p = spec->buf; *p != ',' && *p != '\0' && l < spec->len; p++, l++)
1243 		;
1244 	if (*p == '\0') {
1245 		p2 = "0";
1246 	} else {
1247 		if (*p == ',') {
1248 			*p = '\0';
1249 			p2 = ++p;
1250 		}
1251 		for (p = p2; *p != '\0' && l < spec->len; p++, l++)
1252 			;
1253 		if (*p != '\0' || *p2 == '\0') {
1254 			yyerror("invalid an upper layer protocol spec");
1255 			return -1;
1256 		}
1257 	}
1258 
1259 	sport->buf = strdup(spec->buf);
1260 	if (!sport->buf) {
1261 		yyerror("insufficient memory");
1262 		return -1;
1263 	}
1264 	sport->len = strlen(sport->buf);
1265 	dport->buf = strdup(p2);
1266 	if (!dport->buf) {
1267 		yyerror("insufficient memory");
1268 		return -1;
1269 	}
1270 	dport->len = strlen(dport->buf);
1271 
1272 	return 0;
1273 }
1274 
1275 static int
1276 setvarbuf(buf, off, ebuf, elen, vbuf, vlen)
1277 	char *buf;
1278 	int *off;
1279 	struct sadb_ext *ebuf;
1280 	int elen;
1281 	caddr_t vbuf;
1282 	int vlen;
1283 {
1284 	memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len));
1285 	memcpy(buf + *off, (caddr_t)ebuf, elen);
1286 	memcpy(buf + *off + elen, vbuf, vlen);
1287 	(*off) += PFKEY_ALIGN8(elen + vlen);
1288 
1289 	return 0;
1290 }
1291 
1292 void
1293 parse_init()
1294 {
1295 	p_spi = 0;
1296 
1297 	p_ext = SADB_X_EXT_CYCSEQ;
1298 	p_alg_enc = SADB_EALG_NONE;
1299 	p_alg_auth = SADB_AALG_NONE;
1300 	p_mode = IPSEC_MODE_ANY;
1301 	p_reqid = 0;
1302 	p_replay = 0;
1303 	p_key_enc_len = p_key_auth_len = 0;
1304 	p_key_enc = p_key_auth = 0;
1305 	p_lt_hard = p_lt_soft = 0;
1306 
1307 	p_aiflags = 0;
1308 	p_aifamily = PF_UNSPEC;
1309 
1310 	return;
1311 }
1312 
1313 void
1314 free_buffer()
1315 {
1316 	/* we got tons of memory leaks in the parser anyways, leave them */
1317 
1318 	return;
1319 }
1320