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