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