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
setkeymsg0(msg,type,satype,l)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
setkeymsg_spdaddr(type,upper,policy,srcs,splen,dsts,dplen)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
setkeymsg_addr(type,satype,srcs,dsts,no_spi)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
setkeymsg_add(type,satype,srcs,dsts)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 *
parse_addr(host,port)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
fix_portstr(spec,sport,dport)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
setvarbuf(buf,off,ebuf,elen,vbuf,vlen)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
parse_init()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
free_buffer()1286 free_buffer()
1287 {
1288 /* we got tons of memory leaks in the parser anyways, leave them */
1289
1290 return;
1291 }
1292