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