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