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