]> git.saurik.com Git - apple/ipsec.git/blame_incremental - ipsec-tools/racoon/cfparse.y
ipsec-317.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / cfparse.y
... / ...
CommitLineData
1/* $NetBSD: cfparse.y,v 1.18.4.3 2007/08/01 11:52:19 vanhu Exp $ */
2
3/* Id: cfparse.y,v 1.66 2006/08/22 18:17:17 manubsd Exp */
4
5%{
6/*
7 * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 and 2003 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#include "config.h"
36
37#include <sys/types.h>
38#include <sys/param.h>
39#include <sys/queue.h>
40#include <sys/socket.h>
41
42#include <netinet/in.h>
43#ifdef HAVE_NETINET6_IPSEC
44# include <netinet6/ipsec.h>
45#else
46# include <netinet/ipsec.h>
47#endif
48
49#ifdef ENABLE_HYBRID
50#include <arpa/inet.h>
51#endif
52
53#include <stdlib.h>
54#include <stdio.h>
55#include <string.h>
56#include <errno.h>
57#include <netdb.h>
58#include <pwd.h>
59#include <grp.h>
60#include <signal.h>
61
62#include "var.h"
63#include "misc.h"
64#include "vmbuf.h"
65#include "plog.h"
66#include "sockmisc.h"
67#include "str2val.h"
68#include "genlist.h"
69#include "debug.h"
70
71#include "cfparse_proto.h"
72#include "cftoken_proto.h"
73#include "algorithm.h"
74#include "localconf.h"
75#include "policy.h"
76#include "sainfo.h"
77#include "oakley.h"
78#include "pfkey.h"
79#include "remoteconf.h"
80#include "grabmyaddr.h"
81#include "isakmp_var.h"
82#include "handler.h"
83#include "isakmp.h"
84#include "nattraversal.h"
85#include "isakmp_frag.h"
86#include "session.h"
87#ifdef ENABLE_HYBRID
88#include "isakmp_unity.h"
89#include "isakmp_xauth.h"
90#include "isakmp_cfg.h"
91#endif
92#include "ipsec_doi.h"
93#include "strnames.h"
94#include "gcmalloc.h"
95#include "vendorid.h"
96#include "ipsecConfigTracer.h"
97#include "ipsecMessageTracer.h"
98
99static int num2dhgroup[] = {
100 0,
101 OAKLEY_ATTR_GRP_DESC_MODP768,
102 OAKLEY_ATTR_GRP_DESC_MODP1024,
103 OAKLEY_ATTR_GRP_DESC_EC2N155,
104 OAKLEY_ATTR_GRP_DESC_EC2N185,
105 OAKLEY_ATTR_GRP_DESC_MODP1536,
106 0,
107 0,
108 0,
109 0,
110 0,
111 0,
112 0,
113 0,
114 OAKLEY_ATTR_GRP_DESC_MODP2048,
115 OAKLEY_ATTR_GRP_DESC_MODP3072,
116 OAKLEY_ATTR_GRP_DESC_MODP4096,
117 OAKLEY_ATTR_GRP_DESC_MODP6144,
118 OAKLEY_ATTR_GRP_DESC_MODP8192
119};
120
121struct remote_index_val {
122 int prefix;
123 struct sockaddr_storage *addr;
124};
125
126static struct remoteconf *cur_rmconf;
127static int tmpalgtype[MAXALGCLASS];
128static struct sainfo *cur_sainfo;
129static int cur_algclass;
130
131static struct proposalspec *newprspec (void);
132static void insprspec (struct proposalspec *, struct proposalspec **);
133static struct secprotospec *newspspec (void);
134static void insspspec (struct secprotospec *, struct proposalspec **);
135
136static int set_isakmp_proposal (struct remoteconf *, struct proposalspec *);
137static void clean_tmpalgtype (void);
138static int expand_isakmpspec (int, int, int *,
139 int, int, time_t, int, int, int, char *, struct remoteconf *);
140static int listen_addr (struct sockaddr_storage *addr, int udp_encap);
141
142void freeetypes (struct etypes **etypes);
143
144#if 0
145static int fix_lifebyte (u_long);
146#endif
147%}
148
149%union {
150 unsigned long num;
151 vchar_t *val;
152 struct remoteconf *rmconf;
153 struct sockaddr_storage *saddr;
154 struct sainfoalg *alg;
155 struct remote_index_val *rmidx;
156}
157
158 /* path */
159%token PATH PATHTYPE
160 /* include */
161%token INCLUDE
162 /* self information */
163%token IDENTIFIER VENDORID
164 /* logging */
165%token LOGGING LOGLEV
166 /* padding */
167%token PADDING PAD_RANDOMIZE PAD_RANDOMIZELEN PAD_MAXLEN PAD_STRICT PAD_EXCLTAIL
168 /* listen */
169%token LISTEN X_ISAKMP X_ISAKMP_NATT X_ADMIN STRICT_ADDRESS ADMINSOCK DISABLED
170 /* modecfg */
171%token MODECFG CFG_NET4 CFG_MASK4 CFG_DNS4 CFG_NBNS4 CFG_DEFAULT_DOMAIN
172%token CFG_AUTH_SOURCE CFG_AUTH_GROUPS CFG_SYSTEM CFG_RADIUS CFG_PAM CFG_LDAP CFG_LOCAL CFG_NONE
173%token CFG_GROUP_SOURCE CFG_ACCOUNTING CFG_CONF_SOURCE CFG_MOTD CFG_POOL_SIZE CFG_AUTH_THROTTLE
174%token CFG_SPLIT_NETWORK CFG_SPLIT_LOCAL CFG_SPLIT_INCLUDE CFG_SPLIT_DNS
175%token CFG_PFS_GROUP CFG_SAVE_PASSWD
176 /* timer */
177%token RETRY RETRY_COUNTER RETRY_INTERVAL RETRY_PERSEND
178%token RETRY_PHASE1 RETRY_PHASE2 NATT_KA AUTO_EXIT_DELAY
179 /* algorithm */
180%token ALGORITHM_CLASS ALGORITHMTYPE STRENGTHTYPE
181 /* sainfo */
182%token SAINFO FROM GROUP
183 /* remote */
184%token REMOTE ANONYMOUS INHERIT
185%token EXCHANGE_MODE EXCHANGETYPE DOI DOITYPE SITUATION SITUATIONTYPE
186%token CERTIFICATE_TYPE CERTTYPE PEERS_CERTFILE CA_TYPE
187%token VERIFY_CERT SEND_CERT SEND_CR
188%token IDENTIFIERTYPE IDENTIFIERQUAL MY_IDENTIFIER
189%token PEERS_IDENTIFIER VERIFY_IDENTIFIER
190%token LOCAL_ADDRESS
191%token SHARED_SECRET SECRETTYPE
192%token OPEN_DIR_AUTH_GROUP IN_KEYCHAIN
193%token CERTIFICATE_VERIFICATION VERIFICATION_MODULE VERIFICATION_OPTION
194%token DNSSEC CERT_X509 CERT_PLAINRSA
195%token NONCE_SIZE DH_GROUP KEEPALIVE PASSIVE INITIAL_CONTACT
196%token NAT_TRAVERSAL REMOTE_FORCE_LEVEL NAT_TRAVERSAL_LEVEL NAT_TRAVERSAL_MULTI_USER NAT_TRAVERSAL_KEEPALIVE
197%token PROPOSAL_CHECK PROPOSAL_CHECK_LEVEL
198%token GENERATE_POLICY GENERATE_LEVEL SUPPORT_PROXY
199%token PROPOSAL
200%token EXEC_PATH EXEC_COMMAND EXEC_SUCCESS EXEC_FAILURE
201%token GSS_ID GSS_ID_ENC GSS_ID_ENCTYPE
202%token COMPLEX_BUNDLE
203%token DPD DPD_DELAY DPD_RETRY DPD_MAXFAIL DPD_ALGORITHM
204%token DISCONNECT_ON_IDLE IDLE_TIMEOUT IDLE_DIRECTION
205%token XAUTH_LOGIN WEAK_PHASE1_CHECK
206
207%token PREFIX PORT PORTANY UL_PROTO ANY IKE_FRAG ESP_FRAG MODE_CFG
208%token PFS_GROUP LIFETIME LIFETYPE_TIME LIFETYPE_BYTE STRENGTH REMOTEID
209
210%token NUMBER SWITCH BOOLEAN
211%token HEXSTRING QUOTEDSTRING ADDRSTRING ADDRRANGE
212%token UNITTYPE_BYTE UNITTYPE_KBYTES UNITTYPE_MBYTES UNITTYPE_TBYTES
213%token UNITTYPE_SEC UNITTYPE_MIN UNITTYPE_HOUR
214%token EOS BOC EOC COMMA
215%token DPD_ALGO_TYPE_DEFAULT DPD_ALGO_TYPE_INBOUND DPD_ALGO_TYPE_BLACKHOLE
216%token IDLE_DIRECTION_IN IDLE_DIRECTION_OUT IDLE_DIRECTION_ANY IKE_VERSION
217
218%type <num> NUMBER BOOLEAN SWITCH keylength
219%type <num> PATHTYPE IDENTIFIERTYPE IDENTIFIERQUAL LOGLEV GSS_ID_ENCTYPE
220%type <num> SECRETTYPE
221%type <num> ALGORITHM_CLASS dh_group_num
222%type <num> ALGORITHMTYPE STRENGTHTYPE
223%type <num> PREFIX prefix PORT port ike_port
224%type <num> ul_proto UL_PROTO
225%type <num> EXCHANGETYPE DOITYPE SITUATIONTYPE
226%type <num> CERTTYPE CERT_X509 CERT_PLAINRSA PROPOSAL_CHECK_LEVEL NAT_TRAVERSAL_LEVEL GENERATE_LEVEL
227%type <num> VERIFICATION_MODULE VERIFICATION_OPTION
228%type <num> unittype_time unittype_byte
229%type <val> QUOTEDSTRING HEXSTRING ADDRSTRING ADDRRANGE sainfo_id
230%type <val> identifierstring
231%type <saddr> ike_addrinfo_port
232%type <alg> algorithm
233%type <num> dpd_algo_type
234%type <num> idle_dir_type
235%type <rmidx> remote_index ike_addrinfo_prefix_port
236
237%%
238
239statements
240 : /* nothing */
241 | statements statement
242 ;
243statement
244 : path_statement
245 | include_statement
246 | identifier_statement
247 | logging_statement
248 | padding_statement
249 | listen_statement
250 | modecfg_statement
251 | timer_statement
252 | sainfo_statement
253 | remote_statement
254 | special_statement
255 ;
256
257 /* path */
258path_statement
259 : PATH PATHTYPE QUOTEDSTRING
260 {
261 if ($2 >= LC_PATHTYPE_MAX) {
262 racoon_yyerror("invalid path type %d", $2);
263 return -1;
264 }
265
266 /* free old pathinfo */
267 if (lcconf->pathinfo[$2])
268 racoon_free(lcconf->pathinfo[$2]);
269
270 /* set new pathinfo */
271 lcconf->pathinfo[$2] = racoon_strdup($3->v);
272 STRDUP_FATAL(lcconf->pathinfo[$2]);
273 vfree($3);
274 }
275 EOS
276 ;
277
278 /* special */
279special_statement
280 : COMPLEX_BUNDLE SWITCH { lcconf->complex_bundle = $2; } EOS
281 ;
282
283 /* include */
284include_statement
285 : INCLUDE QUOTEDSTRING EOS
286 {
287 char path[MAXPATHLEN];
288
289 getpathname(path, sizeof(path),
290 LC_PATHTYPE_INCLUDE, $2->v);
291 vfree($2);
292 if (yycf_switch_buffer(path) != 0)
293 return -1;
294 }
295 ;
296
297 /* self information */
298identifier_statement
299 : IDENTIFIER identifier_stmt
300 ;
301identifier_stmt
302 : VENDORID
303 {
304 /*XXX to be deleted */
305 }
306 QUOTEDSTRING EOS
307 | IDENTIFIERTYPE QUOTEDSTRING
308 {
309 /*XXX to be deleted */
310 $2->l--; /* nuke '\0' */
311 lcconf->ident[$1] = $2;
312 if (lcconf->ident[$1] == NULL) {
313 racoon_yyerror("failed to set my ident: %s",
314 strerror(errno));
315 return -1;
316 }
317 }
318 EOS
319 ;
320
321 /* logging */
322logging_statement
323 : LOGGING log_level EOS
324 ;
325log_level
326 : QUOTEDSTRING
327 {
328 /*
329 * XXX ignore it because this specification
330 * will be obsoleted.
331 */
332 plogsetlevelquotedstr($1->v);
333 vfree($1);
334 }
335 | LOGLEV
336 {
337 plogsetlevel($1);
338 }
339 ;
340
341 /* padding */
342padding_statement
343 : PADDING BOC padding_stmts EOC
344 ;
345padding_stmts
346 : /* nothing */
347 | padding_stmts padding_stmt
348 ;
349padding_stmt
350 : PAD_RANDOMIZE SWITCH { lcconf->pad_random = $2; } EOS
351 | PAD_RANDOMIZELEN SWITCH { lcconf->pad_randomlen = $2; } EOS
352 | PAD_MAXLEN NUMBER { lcconf->pad_maxsize = $2; } EOS
353 | PAD_STRICT SWITCH { lcconf->pad_strict = $2; } EOS
354 | PAD_EXCLTAIL SWITCH { lcconf->pad_excltail = $2; } EOS
355 ;
356
357 /* listen */
358listen_statement
359 : LISTEN BOC listen_stmts EOC
360 ;
361listen_stmts
362 : /* nothing */
363 | listen_stmts listen_stmt
364 ;
365listen_stmt
366 : X_ISAKMP ike_addrinfo_port
367 {
368 listen_addr ($2, 0);
369 }
370 EOS
371 | X_ISAKMP_NATT ike_addrinfo_port
372 {
373#ifdef ENABLE_NATT
374 listen_addr ($2, 1);
375#else
376 racoon_yyerror("NAT-T support not compiled in.");
377#endif
378 }
379 EOS
380 | X_ADMIN
381 {
382 racoon_yyerror("admin directive is obsoleted.");
383 }
384 PORT EOS
385 | ADMINSOCK QUOTEDSTRING QUOTEDSTRING QUOTEDSTRING NUMBER
386 {
387 racoon_yywarn("admin port support not compiled in");
388 }
389 EOS
390 | ADMINSOCK QUOTEDSTRING
391 {
392 racoon_yywarn("admin port support not compiled in");
393 }
394 EOS
395 | ADMINSOCK DISABLED
396 {
397 racoon_yywarn("admin port support not compiled in");
398 }
399 EOS
400 | STRICT_ADDRESS { lcconf->strict_address = TRUE; } EOS
401 ;
402ike_addrinfo_port
403 : ADDRSTRING ike_port
404 {
405 char portbuf[10];
406
407 snprintf(portbuf, sizeof(portbuf), "%ld", $2);
408 $$ = str2saddr($1->v, portbuf);
409 vfree($1);
410 if (!$$)
411 return -1;
412 }
413 ;
414ike_addrinfo_prefix_port
415 : ADDRSTRING prefix ike_port
416 {
417 char portbuf[10];
418 struct remote_index_val *new;
419
420 new = racoon_calloc(1, sizeof(*new));
421 if (new == NULL) {
422 racoon_yyerror("failed to allocate remote index struct");
423 vfree($1);
424 return -1;
425 }
426 snprintf(portbuf, sizeof(portbuf), "%ld", $3);
427 new->addr = str2saddr($1->v, portbuf);
428 vfree($1);
429 if (!new->addr) {
430 racoon_yyerror("failed to allocate sockaddr storage");
431 return -1;
432 }
433 new->prefix = $2;
434 $$ = new;
435 }
436 ;
437ike_port
438 : /* nothing */ { $$ = PORT_ISAKMP; }
439 | PORT { $$ = $1; }
440 ;
441 /* modecfg */
442modecfg_statement
443 : MODECFG BOC modecfg_stmts EOC
444 ;
445modecfg_stmts
446 : /* nothing */
447 | modecfg_stmts modecfg_stmt
448 ;
449modecfg_stmt
450 : CFG_NET4 ADDRSTRING
451 {
452#ifdef ENABLE_HYBRID
453 if (inet_pton(AF_INET, $2->v,
454 &isakmp_cfg_config.network4) != 1)
455 racoon_yyerror("bad IPv4 network address.");
456 vfree($2);
457#else
458 racoon_yyerror("racoon not configured with --enable-hybrid");
459#endif
460 }
461 EOS
462 | CFG_MASK4 ADDRSTRING
463 {
464#ifdef ENABLE_HYBRID
465 if (inet_pton(AF_INET, $2->v,
466 &isakmp_cfg_config.netmask4) != 1)
467 racoon_yyerror("bad IPv4 netmask address.");
468 vfree($2);
469#else
470 racoon_yyerror("racoon not configured with --enable-hybrid");
471#endif
472 }
473 EOS
474 | CFG_DNS4 addrdnslist
475 EOS
476 | CFG_NBNS4 addrwinslist
477 EOS
478 | CFG_SPLIT_NETWORK CFG_SPLIT_LOCAL splitnetlist
479 {
480#ifdef ENABLE_HYBRID
481 isakmp_cfg_config.splitnet_type = UNITY_LOCAL_LAN;
482#else
483 racoon_yyerror("racoon not configured with --enable-hybrid");
484#endif
485 }
486 EOS
487 | CFG_SPLIT_NETWORK CFG_SPLIT_INCLUDE splitnetlist
488 {
489#ifdef ENABLE_HYBRID
490 isakmp_cfg_config.splitnet_type = UNITY_SPLIT_INCLUDE;
491#else
492 racoon_yyerror("racoon not configured with --enable-hybrid");
493#endif
494 }
495 EOS
496 | CFG_SPLIT_DNS splitdnslist
497 {
498#ifndef ENABLE_HYBRID
499 racoon_yyerror("racoon not configured with --enable-hybrid");
500#endif
501 }
502 EOS
503 | CFG_DEFAULT_DOMAIN QUOTEDSTRING
504 {
505#ifdef ENABLE_HYBRID
506 strlcpy(&isakmp_cfg_config.default_domain[0],
507 $2->v, sizeof(isakmp_cfg_config.default_domain));
508 vfree($2);
509#else
510 racoon_yyerror("racoon not configured with --enable-hybrid");
511#endif
512 }
513 EOS
514 | CFG_AUTH_SOURCE CFG_SYSTEM
515 {
516#ifdef ENABLE_HYBRID
517 isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_SYSTEM;
518#else
519 racoon_yyerror("racoon not configured with --enable-hybrid");
520#endif
521 }
522 EOS
523 | CFG_AUTH_SOURCE CFG_RADIUS
524 {
525#ifdef ENABLE_HYBRID
526 racoon_yyerror("racoon not configured with --with-libradius");
527#else /* ENABLE_HYBRID */
528 racoon_yyerror("racoon not configured with --enable-hybrid");
529#endif /* ENABLE_HYBRID */
530 }
531 EOS
532 | CFG_AUTH_SOURCE CFG_PAM
533 {
534#ifdef ENABLE_HYBRID
535 racoon_yyerror("racoon not configured with --with-libpam");
536#else /* ENABLE_HYBRID */
537 racoon_yyerror("racoon not configured with --enable-hybrid");
538#endif /* ENABLE_HYBRID */
539 }
540 EOS
541 | CFG_AUTH_SOURCE CFG_LDAP
542 {
543#ifdef ENABLE_HYBRID
544 racoon_yyerror("racoon not configured with --with-libldap");
545#else /* ENABLE_HYBRID */
546 racoon_yyerror("racoon not configured with --enable-hybrid");
547#endif /* ENABLE_HYBRID */
548 }
549 EOS
550 | CFG_AUTH_GROUPS authgrouplist
551 {
552#ifndef ENABLE_HYBRID
553 racoon_yyerror("racoon not configured with --enable-hybrid");
554#endif
555 }
556 EOS
557 | CFG_GROUP_SOURCE CFG_SYSTEM
558 {
559#ifdef ENABLE_HYBRID
560 isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_SYSTEM;
561#else
562 racoon_yyerror("racoon not configured with --enable-hybrid");
563#endif
564 }
565 EOS
566 | CFG_GROUP_SOURCE CFG_LDAP
567 {
568#ifdef ENABLE_HYBRID
569 racoon_yyerror("racoon not configured with --with-libldap");
570#else /* ENABLE_HYBRID */
571 racoon_yyerror("racoon not configured with --enable-hybrid");
572#endif /* ENABLE_HYBRID */
573 }
574 EOS
575 | CFG_ACCOUNTING CFG_NONE
576 {
577#ifdef ENABLE_HYBRID
578 isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_NONE;
579#else
580 racoon_yyerror("racoon not configured with --enable-hybrid");
581#endif
582 }
583 EOS
584 | CFG_ACCOUNTING CFG_SYSTEM
585 {
586#ifdef ENABLE_HYBRID
587 isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_SYSTEM;
588#else
589 racoon_yyerror("racoon not configured with --enable-hybrid");
590#endif
591 }
592 EOS
593 | CFG_ACCOUNTING CFG_RADIUS
594 {
595#ifdef ENABLE_HYBRID
596 racoon_yyerror("racoon not configured with --with-libradius");
597#else /* ENABLE_HYBRID */
598 racoon_yyerror("racoon not configured with --enable-hybrid");
599#endif /* ENABLE_HYBRID */
600 }
601 EOS
602 | CFG_ACCOUNTING CFG_PAM
603 {
604#ifdef ENABLE_HYBRID
605 racoon_yyerror("racoon not configured with --with-libpam");
606#else /* ENABLE_HYBRID */
607 racoon_yyerror("racoon not configured with --enable-hybrid");
608#endif /* ENABLE_HYBRID */
609 }
610 EOS
611 | CFG_POOL_SIZE NUMBER
612 {
613#ifdef ENABLE_HYBRID
614 if (isakmp_cfg_resize_pool($2) != 0)
615 racoon_yyerror("cannot allocate memory for pool");
616#else /* ENABLE_HYBRID */
617 racoon_yyerror("racoon not configured with --enable-hybrid");
618#endif /* ENABLE_HYBRID */
619 }
620 EOS
621 | CFG_PFS_GROUP NUMBER
622 {
623#ifdef ENABLE_HYBRID
624 isakmp_cfg_config.pfs_group = $2;
625 switch (isakmp_cfg_config.pfs_group)
626 {
627 case OAKLEY_ATTR_GRP_DESC_MODP768:
628 case OAKLEY_ATTR_GRP_DESC_MODP1024:
629 case OAKLEY_ATTR_GRP_DESC_MODP1536:
630 case OAKLEY_ATTR_GRP_DESC_MODP2048:
631 case OAKLEY_ATTR_GRP_DESC_MODP3072:
632 case OAKLEY_ATTR_GRP_DESC_MODP4096:
633 case OAKLEY_ATTR_GRP_DESC_MODP6144:
634 case OAKLEY_ATTR_GRP_DESC_MODP8192:
635 break;
636 default:
637 racoon_yyerror("Invalid PFS group specified");
638 return -1;
639 break;
640 }
641#else /* ENABLE_HYBRID */
642 racoon_yyerror("racoon not configured with --enable-hybrid");
643#endif /* ENABLE_HYBRID */
644 }
645 EOS
646 | CFG_SAVE_PASSWD SWITCH
647 {
648#ifdef ENABLE_HYBRID
649 isakmp_cfg_config.save_passwd = $2;
650#else /* ENABLE_HYBRID */
651 racoon_yyerror("racoon not configured with --enable-hybrid");
652#endif /* ENABLE_HYBRID */
653 }
654 EOS
655 | CFG_AUTH_THROTTLE NUMBER
656 {
657#ifdef ENABLE_HYBRID
658 isakmp_cfg_config.auth_throttle = $2;
659#else /* ENABLE_HYBRID */
660 racoon_yyerror("racoon not configured with --enable-hybrid");
661#endif /* ENABLE_HYBRID */
662 }
663 EOS
664 | CFG_CONF_SOURCE CFG_LOCAL
665 {
666#ifdef ENABLE_HYBRID
667 isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LOCAL;
668#else /* ENABLE_HYBRID */
669 racoon_yyerror("racoon not configured with --enable-hybrid");
670#endif /* ENABLE_HYBRID */
671 }
672 EOS
673 | CFG_CONF_SOURCE CFG_RADIUS
674 {
675#ifdef ENABLE_HYBRID
676 racoon_yyerror("racoon not configured with --with-libradius");
677#else /* ENABLE_HYBRID */
678 racoon_yyerror("racoon not configured with --enable-hybrid");
679#endif /* ENABLE_HYBRID */
680 }
681 EOS
682 | CFG_CONF_SOURCE CFG_LDAP
683 {
684#ifdef ENABLE_HYBRID
685 racoon_yyerror("racoon not configured with --with-libldap");
686#else /* ENABLE_HYBRID */
687 racoon_yyerror("racoon not configured with --enable-hybrid");
688#endif /* ENABLE_HYBRID */
689 }
690 EOS
691 | CFG_MOTD QUOTEDSTRING
692 {
693#ifdef ENABLE_HYBRID
694 strlcpy(&isakmp_cfg_config.motd[0], $2->v, sizeof(isakmp_cfg_config.motd));
695 vfree($2);
696#else
697 racoon_yyerror("racoon not configured with --enable-hybrid");
698#endif
699 }
700 EOS
701 ;
702
703addrdnslist
704 : addrdns
705 | addrdns COMMA addrdnslist
706 ;
707addrdns
708 : ADDRSTRING
709 {
710#ifdef ENABLE_HYBRID
711 struct isakmp_cfg_config *icc = &isakmp_cfg_config;
712
713 if (icc->dns4_index >= MAXNS) {
714 racoon_yyerror("No more than %d DNS", MAXNS);
715 return -1;
716 }
717 if (inet_pton(AF_INET, $1->v,
718 &icc->dns4[icc->dns4_index++]) != 1)
719 racoon_yyerror("bad IPv4 DNS address.");
720
721 vfree($1);
722#else
723 racoon_yyerror("racoon not configured with --enable-hybrid");
724#endif
725 }
726 ;
727
728addrwinslist
729 : addrwins
730 | addrwins COMMA addrwinslist
731 ;
732addrwins
733 : ADDRSTRING
734 {
735#ifdef ENABLE_HYBRID
736 struct isakmp_cfg_config *icc = &isakmp_cfg_config;
737
738 if (icc->nbns4_index > MAXWINS) {
739 racoon_yyerror("No more than %d WINS", MAXWINS);
740 return -1;
741 }
742 if (inet_pton(AF_INET, $1->v,
743 &icc->nbns4[icc->nbns4_index++]) != 1)
744 racoon_yyerror("bad IPv4 WINS address.");
745
746 vfree($1);
747#else
748 racoon_yyerror("racoon not configured with --enable-hybrid");
749#endif
750 }
751 ;
752
753splitnetlist
754 : splitnet
755 | splitnetlist COMMA splitnet
756 ;
757splitnet
758 : ADDRSTRING PREFIX
759 {
760#ifdef ENABLE_HYBRID
761 struct isakmp_cfg_config *icc = &isakmp_cfg_config;
762 struct unity_network network;
763
764 if (inet_pton(AF_INET, $1->v, &network.addr4) != 1)
765 racoon_yyerror("bad IPv4 SPLIT address.");
766
767 /* Turn $2 (the prefix) into a subnet mask */
768 network.mask4.s_addr = ($2) ? htonl(~((1 << (32 - $2)) - 1)) : 0;
769
770 /* add the network to our list */
771 if (splitnet_list_add(&icc->splitnet_list, &network,&icc->splitnet_count))
772 racoon_yyerror("Unable to allocate split network");
773
774 vfree($1);
775#else
776 racoon_yyerror("racoon not configured with --enable-hybrid");
777#endif
778 }
779 ;
780
781authgrouplist
782 : authgroup
783 | authgroup COMMA authgrouplist
784 ;
785authgroup
786 : QUOTEDSTRING
787 {
788#ifdef ENABLE_HYBRID
789 char * groupname = NULL;
790 char ** grouplist = NULL;
791 struct isakmp_cfg_config *icc = &isakmp_cfg_config;
792
793 grouplist = racoon_realloc(icc->grouplist,
794 sizeof(char**)*(icc->groupcount+1));
795 if (grouplist == NULL)
796 racoon_yyerror("unable to allocate auth group list");
797
798 groupname = racoon_malloc($1->l+1);
799 if (groupname == NULL)
800 racoon_yyerror("unable to allocate auth group name");
801
802 memcpy(groupname,$1->v,$1->l);
803 groupname[$1->l]=0;
804 grouplist[icc->groupcount]=groupname;
805 icc->grouplist = grouplist;
806 icc->groupcount++;
807
808 vfree($1);
809#else
810 racoon_yyerror("racoon not configured with --enable-hybrid");
811#endif
812 }
813 ;
814
815splitdnslist
816 : splitdns
817 | splitdns COMMA splitdnslist
818 ;
819splitdns
820 : QUOTEDSTRING
821 {
822#ifdef ENABLE_HYBRID
823 struct isakmp_cfg_config *icc = &isakmp_cfg_config;
824
825 if (!icc->splitdns_len)
826 {
827 icc->splitdns_list = racoon_malloc($1->l);
828 if(icc->splitdns_list == NULL)
829 racoon_yyerror("error allocating splitdns list buffer");
830 memcpy(icc->splitdns_list,$1->v,$1->l);
831 icc->splitdns_len = $1->l;
832 }
833 else
834 {
835 int len = icc->splitdns_len + $1->l + 1;
836 icc->splitdns_list = racoon_realloc(icc->splitdns_list,len);
837 if(icc->splitdns_list == NULL)
838 racoon_yyerror("error allocating splitdns list buffer");
839 icc->splitdns_list[icc->splitdns_len] = ',';
840 memcpy(icc->splitdns_list + icc->splitdns_len + 1, $1->v, $1->l);
841 icc->splitdns_len = len;
842 }
843 vfree($1);
844#else
845 racoon_yyerror("racoon not configured with --enable-hybrid");
846#endif
847 }
848 ;
849
850
851 /* timer */
852timer_statement
853 : RETRY BOC timer_stmts EOC
854 ;
855timer_stmts
856 : /* nothing */
857 | timer_stmts timer_stmt
858 ;
859timer_stmt
860 : RETRY_COUNTER NUMBER
861 {
862 lcconf->retry_counter = $2;
863 }
864 EOS
865 | RETRY_INTERVAL NUMBER unittype_time
866 {
867 lcconf->retry_interval = $2 * $3;
868 }
869 EOS
870 | RETRY_PERSEND NUMBER
871 {
872 lcconf->count_persend = $2;
873 }
874 EOS
875 | RETRY_PHASE1 NUMBER unittype_time
876 {
877 lcconf->retry_checkph1 = $2 * $3;
878 }
879 EOS
880 | RETRY_PHASE2 NUMBER unittype_time
881 {
882 lcconf->wait_ph2complete = $2 * $3;
883 }
884 EOS
885 | AUTO_EXIT_DELAY NUMBER unittype_time
886 {
887 lcconf->auto_exit_delay = $2 * $3;
888 lcconf->auto_exit_state |= LC_AUTOEXITSTATE_SET;
889 }
890 EOS
891
892 | NATT_KA NUMBER unittype_time
893 {
894#ifdef ENABLE_NATT
895 lcconf->natt_ka_interval = $2 * $3;
896#else
897 racoon_yyerror("NAT-T support not compiled in.");
898#endif
899 }
900 EOS
901 ;
902
903 /* sainfo */
904sainfo_statement
905 : SAINFO
906 {
907 cur_sainfo = create_sainfo();
908 if (cur_sainfo == NULL) {
909 racoon_yyerror("failed to allocate sainfo");
910 return -1;
911 }
912 }
913 sainfo_name sainfo_param BOC sainfo_specs
914 {
915 struct sainfo *check;
916
917 /* default */
918 if (cur_sainfo->algs[algclass_ipsec_enc] == 0) {
919 racoon_yyerror("no encryption algorithm at %s",
920 sainfo2str(cur_sainfo));
921 return -1;
922 }
923 if (cur_sainfo->algs[algclass_ipsec_auth] == 0) {
924 racoon_yyerror("no authentication algorithm at %s",
925 sainfo2str(cur_sainfo));
926 return -1;
927 }
928 if (cur_sainfo->algs[algclass_ipsec_comp] == 0) {
929 racoon_yyerror("no compression algorithm at %s",
930 sainfo2str(cur_sainfo));
931 return -1;
932 }
933
934 /* duplicate check */
935 check = getsainfo(cur_sainfo->idsrc,
936 cur_sainfo->iddst,
937 cur_sainfo->id_i, 0);
938 if (check && (!check->idsrc && !cur_sainfo->idsrc)) {
939 racoon_yyerror("duplicated sainfo: %s",
940 sainfo2str(cur_sainfo));
941 return -1;
942 }
943 inssainfo(cur_sainfo);
944 }
945 EOC
946 ;
947sainfo_name
948 : ANONYMOUS
949 {
950 cur_sainfo->idsrc = NULL;
951 cur_sainfo->iddst = NULL;
952 }
953 | ANONYMOUS sainfo_id
954 {
955 cur_sainfo->idsrc = NULL;
956 cur_sainfo->iddst = $2;
957 }
958 | sainfo_id ANONYMOUS
959 {
960 cur_sainfo->idsrc = $1;
961 cur_sainfo->iddst = NULL;
962 }
963 | sainfo_id sainfo_id
964 {
965 cur_sainfo->idsrc = $1;
966 cur_sainfo->iddst = $2;
967 }
968 ;
969sainfo_id
970 : IDENTIFIERTYPE ADDRSTRING prefix port ul_proto
971 {
972 char portbuf[10];
973 struct sockaddr_storage *saddr;
974
975 if (($5 == IPPROTO_ICMP || $5 == IPPROTO_ICMPV6)
976 && ($4 != IPSEC_PORT_ANY || $4 != IPSEC_PORT_ANY)) {
977 racoon_yyerror("port number must be \"any\".");
978 return -1;
979 }
980
981 snprintf(portbuf, sizeof(portbuf), "%lu", $4);
982 saddr = str2saddr($2->v, portbuf);
983 vfree($2);
984 if (saddr == NULL)
985 return -1;
986
987 switch (saddr->ss_family) {
988 case AF_INET:
989 if ($5 == IPPROTO_ICMPV6) {
990 racoon_yyerror("upper layer protocol mismatched.\n");
991 racoon_free(saddr);
992 return -1;
993 }
994 $$ = ipsecdoi_sockaddr2id(saddr,
995 $3 == ~0 ? (sizeof(struct in_addr) << 3): $3,
996 $5);
997 break;
998#ifdef INET6
999 case AF_INET6:
1000 if ($5 == IPPROTO_ICMP) {
1001 racoon_yyerror("upper layer protocol mismatched.\n");
1002 racoon_free(saddr);
1003 return -1;
1004 }
1005 $$ = ipsecdoi_sockaddr2id(saddr,
1006 $3 == ~0 ? (sizeof(struct in6_addr) << 3): $3,
1007 $5);
1008 break;
1009#endif
1010 default:
1011 racoon_yyerror("invalid family: %d", saddr->ss_family);
1012 $$ = NULL;
1013 break;
1014 }
1015 racoon_free(saddr);
1016 if ($$ == NULL)
1017 return -1;
1018 }
1019 | IDENTIFIERTYPE ADDRSTRING ADDRRANGE prefix port ul_proto
1020 {
1021 char portbuf[10];
1022 struct sockaddr_storage *laddr = NULL, *haddr = NULL;
1023
1024 if (($6 == IPPROTO_ICMP || $6 == IPPROTO_ICMPV6)
1025 && ($5 != IPSEC_PORT_ANY || $5 != IPSEC_PORT_ANY)) {
1026 racoon_yyerror("port number must be \"any\".");
1027 return -1;
1028 }
1029
1030 snprintf(portbuf, sizeof(portbuf), "%lu", $5);
1031
1032 laddr = str2saddr($2->v, portbuf);
1033 if (laddr == NULL) {
1034 return -1;
1035 }
1036 vfree($2);
1037 haddr = str2saddr($3->v, portbuf);
1038 if (haddr == NULL) {
1039 racoon_free(laddr);
1040 return -1;
1041 }
1042 vfree($3);
1043
1044 switch (laddr->ss_family) {
1045 case AF_INET:
1046 if ($6 == IPPROTO_ICMPV6) {
1047 racoon_yyerror("upper layer protocol mismatched.\n");
1048 if (laddr)
1049 racoon_free(laddr);
1050 if (haddr)
1051 racoon_free(haddr);
1052 return -1;
1053 }
1054 $$ = ipsecdoi_sockrange2id(laddr, haddr,
1055 $6);
1056 break;
1057#ifdef INET6
1058 case AF_INET6:
1059 if ($6 == IPPROTO_ICMP) {
1060 racoon_yyerror("upper layer protocol mismatched.\n");
1061 if (laddr)
1062 racoon_free(laddr);
1063 if (haddr)
1064 racoon_free(haddr);
1065 return -1;
1066 }
1067 $$ = ipsecdoi_sockrange2id(laddr, haddr,
1068 $6);
1069 break;
1070#endif
1071 default:
1072 racoon_yyerror("invalid family: %d", laddr->ss_family);
1073 $$ = NULL;
1074 break;
1075 }
1076 if (laddr)
1077 racoon_free(laddr);
1078 if (haddr)
1079 racoon_free(haddr);
1080 if ($$ == NULL)
1081 return -1;
1082 }
1083 | IDENTIFIERTYPE QUOTEDSTRING
1084 {
1085 struct ipsecdoi_id_b *id_b;
1086
1087 if ($1 == IDTYPE_ASN1DN) {
1088 racoon_yyerror("id type forbidden: %d", $1);
1089 $$ = NULL;
1090 return -1;
1091 }
1092
1093 $2->l--;
1094
1095 $$ = vmalloc(sizeof(*id_b) + $2->l);
1096 if ($$ == NULL) {
1097 racoon_yyerror("failed to allocate identifier");
1098 return -1;
1099 }
1100
1101 id_b = ALIGNED_CAST(struct ipsecdoi_id_b *)$$->v;
1102 id_b->type = idtype2doi($1);
1103
1104 id_b->proto_id = 0;
1105 id_b->port = 0;
1106
1107 memcpy($$->v + sizeof(*id_b), $2->v, $2->l);
1108 }
1109 ;
1110sainfo_param
1111 : /* nothing */
1112 {
1113 cur_sainfo->id_i = NULL;
1114 }
1115
1116 | FROM IDENTIFIERTYPE identifierstring
1117 {
1118 struct ipsecdoi_id_b *id_b;
1119 vchar_t *idv;
1120
1121 if (set_identifier(&idv, $2, $3) != 0) {
1122 racoon_yyerror("failed to set identifer.\n");
1123 return -1;
1124 }
1125 cur_sainfo->id_i = vmalloc(sizeof(*id_b) + idv->l);
1126 if (cur_sainfo->id_i == NULL) {
1127 racoon_yyerror("failed to allocate identifier");
1128 return -1;
1129 }
1130
1131 id_b = ALIGNED_CAST(struct ipsecdoi_id_b *)cur_sainfo->id_i->v;
1132 id_b->type = idtype2doi($2);
1133
1134 id_b->proto_id = 0;
1135 id_b->port = 0;
1136
1137 memcpy(cur_sainfo->id_i->v + sizeof(*id_b),
1138 idv->v, idv->l);
1139 vfree(idv);
1140 }
1141 | GROUP QUOTEDSTRING
1142 {
1143#ifdef ENABLE_HYBRID
1144 if ((cur_sainfo->group = vdup($2)) == NULL) {
1145 racoon_yyerror("failed to set sainfo xauth group.\n");
1146 return -1;
1147 }
1148#else
1149 racoon_yyerror("racoon not configured with --enable-hybrid");
1150 return -1;
1151#endif
1152 }
1153 ;
1154sainfo_specs
1155 : /* nothing */
1156 | sainfo_specs sainfo_spec
1157 ;
1158sainfo_spec
1159 : PFS_GROUP dh_group_num
1160 {
1161 cur_sainfo->pfs_group = $2;
1162 switch (cur_sainfo->pfs_group)
1163 {
1164 case OAKLEY_ATTR_GRP_DESC_MODP768:
1165 case OAKLEY_ATTR_GRP_DESC_MODP1024:
1166 case OAKLEY_ATTR_GRP_DESC_MODP1536:
1167 case OAKLEY_ATTR_GRP_DESC_MODP2048:
1168 case OAKLEY_ATTR_GRP_DESC_MODP3072:
1169 case OAKLEY_ATTR_GRP_DESC_MODP4096:
1170 case OAKLEY_ATTR_GRP_DESC_MODP6144:
1171 case OAKLEY_ATTR_GRP_DESC_MODP8192:
1172 break;
1173 default:
1174 racoon_yyerror("Invalid PFS group specified");
1175 return -1;
1176 break;
1177 }
1178 }
1179 EOS
1180 | LIFETIME LIFETYPE_TIME NUMBER unittype_time
1181 {
1182 cur_sainfo->lifetime = $3 * $4;
1183 }
1184 EOS
1185 | LIFETIME LIFETYPE_BYTE NUMBER unittype_byte
1186 {
1187#if 1
1188 racoon_yyerror("byte lifetime support is deprecated");
1189 return -1;
1190#else
1191 cur_sainfo->lifebyte = fix_lifebyte($3 * $4);
1192 if (cur_sainfo->lifebyte == 0)
1193 return -1;
1194#endif
1195 }
1196 EOS
1197 | ALGORITHM_CLASS {
1198 cur_algclass = $1;
1199 }
1200 algorithms EOS
1201 | IDENTIFIER IDENTIFIERTYPE
1202 {
1203 racoon_yyerror("it's deprecated to specify a identifier in phase 2");
1204 }
1205 EOS
1206 | MY_IDENTIFIER IDENTIFIERTYPE QUOTEDSTRING
1207 {
1208 racoon_yyerror("it's deprecated to specify a identifier in phase 2");
1209 }
1210 EOS
1211 ;
1212
1213algorithms
1214 : algorithm
1215 {
1216 inssainfoalg(&cur_sainfo->algs[cur_algclass], $1);
1217 }
1218 | algorithm
1219 {
1220 inssainfoalg(&cur_sainfo->algs[cur_algclass], $1);
1221 }
1222 COMMA algorithms
1223 ;
1224algorithm
1225 : ALGORITHMTYPE keylength
1226 {
1227 int defklen;
1228
1229 $$ = newsainfoalg();
1230 if ($$ == NULL) {
1231 racoon_yyerror("failed to get algorithm allocation");
1232 return -1;
1233 }
1234
1235 $$->alg = algtype2doi(cur_algclass, $1);
1236 if ($$->alg == -1) {
1237 racoon_yyerror("algorithm mismatched");
1238 racoon_free($$);
1239 $$ = NULL;
1240 return -1;
1241 }
1242
1243 defklen = default_keylen(cur_algclass, $1);
1244 if (defklen == 0) {
1245 if ($2) {
1246 racoon_yyerror("keylen not allowed");
1247 racoon_free($$);
1248 $$ = NULL;
1249 return -1;
1250 }
1251 } else {
1252 if ($2 && check_keylen(cur_algclass, $1, $2) < 0) {
1253 racoon_yyerror("invalid keylen %d", $2);
1254 racoon_free($$);
1255 $$ = NULL;
1256 return -1;
1257 }
1258 }
1259
1260 if ($2)
1261 $$->encklen = $2;
1262 else
1263 $$->encklen = defklen;
1264
1265 /* check if it's supported algorithm by kernel */
1266 if (!(cur_algclass == algclass_ipsec_auth && $1 == algtype_non_auth)
1267 && pk_checkalg(cur_algclass, $1, $$->encklen)) {
1268 int a = algclass2doi(cur_algclass);
1269 int b = algtype2doi(cur_algclass, $1);
1270 if (a == IPSECDOI_ATTR_AUTH)
1271 a = IPSECDOI_PROTO_IPSEC_AH;
1272 racoon_yyerror("algorithm %s not supported by the kernel (missing module?)",
1273 s_ipsecdoi_trns(a, b));
1274 racoon_free($$);
1275 $$ = NULL;
1276 return -1;
1277 }
1278 }
1279 ;
1280prefix
1281 : /* nothing */ { $$ = ~0; }
1282 | PREFIX { $$ = $1; }
1283 ;
1284port
1285 : /* nothing */ { $$ = IPSEC_PORT_ANY; }
1286 | PORT { $$ = $1; }
1287 | PORTANY { $$ = IPSEC_PORT_ANY; }
1288 ;
1289ul_proto
1290 : NUMBER { $$ = $1; }
1291 | UL_PROTO { $$ = $1; }
1292 | ANY { $$ = IPSEC_ULPROTO_ANY; }
1293 ;
1294keylength
1295 : /* nothing */ { $$ = 0; }
1296 | NUMBER { $$ = $1; }
1297 ;
1298
1299 /* remote */
1300remote_statement
1301 : REMOTE remote_index INHERIT remote_index
1302 {
1303 struct remoteconf *new;
1304 struct proposalspec *prspec;
1305
1306 new = copyrmconf($4->addr);
1307 if (new == NULL) {
1308 racoon_yyerror("failed to get remoteconf for %s.", saddr2str((struct sockaddr *)$4));
1309 racoon_free($2->addr);
1310 racoon_free($2);
1311 racoon_free($4->addr);
1312 racoon_free($4);
1313 return -1;
1314 }
1315
1316 new->remote = $2->addr;
1317 new->remote_prefix = ($2->prefix == ~0 ? 0 : $2->prefix);
1318 new->inherited_from = getrmconf_strict($4->addr, 1);
1319 new->proposal = NULL;
1320 new->prhead = NULL;
1321 cur_rmconf = new;
1322 racoon_free($2);
1323 racoon_free($4->addr);
1324 racoon_free($4);
1325
1326 prspec = newprspec();
1327 if (prspec == NULL || !cur_rmconf->inherited_from
1328 || !cur_rmconf->inherited_from->proposal)
1329 return -1;
1330 prspec->lifetime = cur_rmconf->inherited_from->proposal->lifetime;
1331 prspec->lifebyte = cur_rmconf->inherited_from->proposal->lifebyte;
1332 insprspec(prspec, &cur_rmconf->prhead);
1333 }
1334 remote_specs_block
1335 | REMOTE remote_index
1336 {
1337 struct remoteconf *new;
1338 struct proposalspec *prspec;
1339
1340 new = create_rmconf();
1341 if (new == NULL) {
1342 racoon_yyerror("failed to get new remoteconf.");
1343 racoon_free($2->addr);
1344 racoon_free($2);
1345 return -1;
1346 }
1347 new->remote = $2->addr;
1348 new->remote_prefix = ($2->prefix == ~0 ? 0 : $2->prefix);
1349 cur_rmconf = new;
1350 racoon_free($2);
1351
1352 prspec = newprspec();
1353 if (prspec == NULL)
1354 return -1;
1355 prspec->lifetime = oakley_get_defaultlifetime();
1356 insprspec(prspec, &cur_rmconf->prhead);
1357 }
1358 remote_specs_block
1359 ;
1360
1361remote_specs_block
1362 : BOC remote_specs EOC
1363 {
1364 /* check a exchange mode */
1365 if (cur_rmconf->etypes == NULL) {
1366 racoon_yyerror("no exchange mode specified.\n");
1367 return -1;
1368 }
1369
1370 if (cur_rmconf->idvtype == IDTYPE_UNDEFINED)
1371 cur_rmconf->idvtype = IDTYPE_ADDRESS;
1372
1373
1374 if (cur_rmconf->idvtype == IDTYPE_ASN1DN) {
1375 if (cur_rmconf->identity_in_keychain)
1376 {
1377 if (cur_rmconf->idv)
1378 racoon_yywarn("Both CERT and ASN1 ID "
1379 "are set. Hope this is OK.\n");
1380 /* TODO: Preparse the DN here */
1381 } else if (cur_rmconf->idv) {
1382 /* OK, using asn1dn without X.509. */
1383 } else {
1384 racoon_yyerror("ASN1 ID not specified "
1385 "and no CERT defined!\n");
1386 return -1;
1387 }
1388 }
1389
1390 if (cur_rmconf->cert_verification_option == VERIFICATION_OPTION_PEERS_IDENTIFIER) {
1391 struct genlist_entry *gpb;
1392 if (genlist_next(cur_rmconf->idvl_p, &gpb) == NULL) {
1393 racoon_yyerror("peers_identifier required for specified certificate "
1394 "verification option.\n");
1395 return -1;
1396 }
1397 }
1398
1399 if (cur_rmconf->prhead->spspec == NULL
1400 && cur_rmconf->inherited_from
1401 && cur_rmconf->inherited_from->prhead) {
1402 cur_rmconf->prhead->spspec = cur_rmconf->inherited_from->prhead->spspec;
1403 }
1404 if (set_isakmp_proposal(cur_rmconf, cur_rmconf->prhead) != 0)
1405 return -1;
1406
1407 /* DH group setting if aggressive mode or IKEv2. */
1408 if (check_etypeok(cur_rmconf, ISAKMP_ETYPE_AGG) != NULL) {
1409 struct isakmpsa *p;
1410 int b = 0;
1411
1412 /* DH group */
1413 for (p = cur_rmconf->proposal; p; p = p->next) {
1414 if (b == 0 || (b && b == p->dh_group)) {
1415 b = p->dh_group;
1416 continue;
1417 }
1418 racoon_yyerror("DH group must be equal "
1419 "in all proposals "
1420 "when aggressive mode is "
1421 "used.\n");
1422 return -1;
1423 }
1424 cur_rmconf->dh_group = b;
1425
1426 if (cur_rmconf->dh_group == 0) {
1427 racoon_yyerror("DH group must be set in the proposal.\n");
1428 return -1;
1429 }
1430
1431 /* DH group settting if PFS is required. */
1432 if (oakley_setdhgroup(cur_rmconf->dh_group,
1433 &cur_rmconf->dhgrp) < 0) {
1434 racoon_yyerror("failed to set DH value.\n");
1435 return -1;
1436 }
1437 }
1438
1439 insrmconf(cur_rmconf);
1440 }
1441 ;
1442remote_index
1443 : ANONYMOUS ike_port
1444 {
1445
1446 struct remote_index_val *new;
1447
1448 new = racoon_calloc(1, sizeof(*new));
1449 if (new == NULL) {
1450 racoon_yyerror("failed to allocate remote index struct");
1451 return -1;
1452 }
1453 new->addr = newsaddr(sizeof(struct sockaddr_storage));
1454 if (new->addr == NULL) {
1455 racoon_yyerror("failed to allocate sockaddr storage");
1456 racoon_free(new);
1457 return -1;
1458 }
1459 new->addr->ss_family = AF_UNSPEC;
1460 (ALIGNED_CAST(struct sockaddr_in *)new->addr)->sin_port = htons($2);
1461 new->prefix = ~0;
1462 $$ = new;
1463 }
1464 | ike_addrinfo_prefix_port
1465 {
1466 $$ = $1;
1467 if ($$ == NULL) {
1468 racoon_yyerror("failed to allocate sockaddr_storage");
1469 return -1;
1470 }
1471 }
1472 ;
1473remote_specs
1474 : /* nothing */
1475 | remote_specs remote_spec
1476 ;
1477remote_spec
1478 : EXCHANGE_MODE
1479 {
1480 cur_rmconf->etypes = NULL;
1481 }
1482 exchange_types EOS
1483 | DOI DOITYPE { cur_rmconf->doitype = $2; } EOS
1484 | SITUATION SITUATIONTYPE { cur_rmconf->sittype = $2; } EOS
1485 | IKE_VERSION NUMBER
1486 {
1487 if ($2 == 1)
1488 cur_rmconf->ike_version = ISAKMP_VERSION_NUMBER_IKEV1;
1489 else {
1490 racoon_yyerror("invalid IKE version specified.\n");
1491 return -1;
1492 }
1493 } EOS
1494 | CERTIFICATE_TYPE cert_spec
1495 | VERIFY_CERT SWITCH { cur_rmconf->verify_cert = $2; } EOS
1496 | SEND_CERT SWITCH { cur_rmconf->send_cert = $2; } EOS
1497 | SEND_CR SWITCH { cur_rmconf->send_cr = $2; } EOS
1498 | CERTIFICATE_VERIFICATION VERIFICATION_MODULE
1499 {
1500 cur_rmconf->cert_verification = $2;
1501 } EOS
1502 | CERTIFICATE_VERIFICATION VERIFICATION_MODULE VERIFICATION_OPTION
1503 {
1504 cur_rmconf->cert_verification = $2;
1505 cur_rmconf->cert_verification_option = $3;
1506 }
1507 EOS
1508 | OPEN_DIR_AUTH_GROUP QUOTEDSTRING
1509 {
1510#if HAVE_OPENDIR
1511 cur_rmconf->open_dir_auth_group = $2;
1512#else
1513 racoon_yyerror("Apple specific features not compiled in.");
1514 return -1;
1515#endif
1516 } EOS
1517 | MY_IDENTIFIER IDENTIFIERTYPE identifierstring
1518 {
1519 if (set_identifier(&cur_rmconf->idv, $2, $3) != 0) {
1520 racoon_yyerror("failed to set identifer.\n");
1521 vfree($3); //%%% BUG FIX - memory leak
1522 return -1;
1523 }
1524 vfree($3); //%%% BUG FIX - memory leak
1525 cur_rmconf->idvtype = $2;
1526 }
1527 EOS
1528 | MY_IDENTIFIER IDENTIFIERTYPE IDENTIFIERQUAL identifierstring
1529 {
1530 if (set_identifier_qual(&cur_rmconf->idv, $2, $4, $3) != 0) {
1531 racoon_yyerror("failed to set identifer.\n");
1532 return -1;
1533 }
1534 cur_rmconf->idvtype = $2;
1535 }
1536 EOS
1537 | XAUTH_LOGIN identifierstring
1538 {
1539#ifdef ENABLE_HYBRID
1540 /* formerly identifier type login */
1541 if (xauth_rmconf_used(&cur_rmconf->xauth) == -1) {
1542 racoon_yyerror("failed to allocate xauth state\n");
1543 return -1;
1544 }
1545 if ((cur_rmconf->xauth->login = vdup($2)) == NULL) {
1546 racoon_yyerror("failed to set identifer.\n");
1547 return -1;
1548 }
1549 vfree($2); //%%% BUG FIX - memory leak
1550#else
1551 racoon_yyerror("racoon not configured with --enable-hybrid");
1552#endif
1553 }
1554 EOS
1555 | PEERS_IDENTIFIER IDENTIFIERTYPE identifierstring
1556 {
1557 struct idspec *id;
1558 id = newidspec();
1559 if (id == NULL) {
1560 racoon_yyerror("failed to allocate idspec");
1561 return -1;
1562 }
1563 if (set_identifier(&id->id, $2, $3) != 0) {
1564 racoon_yyerror("failed to set identifer.\n");
1565 racoon_free(id);
1566 vfree($3); //%%% BUG FIX - memory leak
1567 return -1;
1568 }
1569 vfree($3); //%%% BUG FIX - memory leak
1570 id->idtype = $2;
1571 genlist_append (cur_rmconf->idvl_p, id);
1572 }
1573 EOS
1574 | PEERS_IDENTIFIER IDENTIFIERTYPE IDENTIFIERQUAL identifierstring
1575 {
1576 struct idspec *id;
1577 id = newidspec();
1578 if (id == NULL) {
1579 racoon_yyerror("failed to allocate idspec");
1580 return -1;
1581 }
1582 if (set_identifier_qual(&id->id, $2, $4, $3) != 0) {
1583 racoon_yyerror("failed to set identifer.\n");
1584 racoon_free(id);
1585 return -1;
1586 }
1587 id->idtype = $2;
1588 genlist_append (cur_rmconf->idvl_p, id);
1589 }
1590 EOS
1591 | VERIFY_IDENTIFIER SWITCH { cur_rmconf->verify_identifier = $2; } EOS
1592 | LOCAL_ADDRESS ADDRSTRING
1593 {
1594 struct sockaddr_storage *saddr;
1595 saddr = str2saddr($2->v, NULL);
1596 vfree($2);
1597 if (saddr == NULL)
1598 return -1;
1599 cur_rmconf->forced_local = saddr;
1600 } EOS
1601 | SHARED_SECRET SECRETTYPE QUOTEDSTRING
1602 {
1603 cur_rmconf->secrettype = $2;
1604 cur_rmconf->shared_secret = $3;
1605 } EOS
1606 | SHARED_SECRET SECRETTYPE
1607 {
1608 if ($2 != SECRETTYPE_KEYCHAIN_BY_ID) {
1609 racoon_yyerror("shared secret value missing.\n");
1610 return -1;
1611 }
1612 cur_rmconf->secrettype = $2;
1613 } EOS
1614 | NONCE_SIZE NUMBER { cur_rmconf->nonce_size = $2; } EOS
1615 | DH_GROUP
1616 {
1617 racoon_yyerror("dh_group cannot be defined here.");
1618 return -1;
1619 }
1620 dh_group_num EOS
1621 | PASSIVE SWITCH { cur_rmconf->passive = $2; } EOS
1622 | IKE_FRAG SWITCH { cur_rmconf->ike_frag = $2; } EOS
1623 | IKE_FRAG REMOTE_FORCE_LEVEL { cur_rmconf->ike_frag = ISAKMP_FRAG_FORCE; } EOS
1624 | ESP_FRAG NUMBER {
1625#ifdef SADB_X_EXT_NAT_T_FRAG
1626 if (libipsec_opt & LIBIPSEC_OPT_FRAG)
1627 cur_rmconf->esp_frag = $2;
1628 else
1629 racoon_yywarn("libipsec lacks IKE frag support");
1630#else
1631 racoon_yywarn("Your kernel does not support esp_frag");
1632#endif
1633 } EOS
1634 | MODE_CFG SWITCH { cur_rmconf->mode_cfg = $2; } EOS
1635 | WEAK_PHASE1_CHECK SWITCH {
1636 cur_rmconf->weak_phase1_check = $2;
1637 } EOS
1638 | GENERATE_POLICY SWITCH { cur_rmconf->gen_policy = $2; } EOS
1639 | GENERATE_POLICY GENERATE_LEVEL { cur_rmconf->gen_policy = $2; } EOS
1640 | SUPPORT_PROXY SWITCH { cur_rmconf->support_proxy = $2; } EOS
1641 | INITIAL_CONTACT SWITCH { cur_rmconf->ini_contact = $2; } EOS
1642 | NAT_TRAVERSAL SWITCH
1643 {
1644#ifdef ENABLE_NATT
1645 cur_rmconf->nat_traversal = $2;
1646#else
1647 racoon_yyerror("NAT-T support not compiled in.");
1648#endif
1649 } EOS
1650 | NAT_TRAVERSAL NAT_TRAVERSAL_LEVEL
1651 {
1652#ifdef ENABLE_NATT
1653 cur_rmconf->nat_traversal = $2;
1654#else
1655 racoon_yyerror("NAT-T support not compiled in.");
1656#endif
1657 } EOS
1658 | NAT_TRAVERSAL_MULTI_USER SWITCH
1659 {
1660#ifdef ENABLE_NATT
1661 cur_rmconf->natt_multiple_user = $2;
1662#else
1663 racoon_yyerror("NAT-T support not compiled in.");
1664#endif
1665 } EOS
1666 | NAT_TRAVERSAL_KEEPALIVE SWITCH
1667 {
1668#ifdef ENABLE_NATT
1669 cur_rmconf->natt_keepalive = $2;
1670#else
1671 racoon_yyerror("NAT-T support not compiled in.");
1672#endif
1673 } EOS
1674| DPD SWITCH
1675 {
1676#ifdef ENABLE_DPD
1677 cur_rmconf->dpd = $2;
1678#else
1679 racoon_yyerror("DPD support not compiled in.");
1680#endif
1681 } EOS
1682 | DPD_DELAY NUMBER
1683 {
1684#ifdef ENABLE_DPD
1685 cur_rmconf->dpd_interval = $2;
1686#else
1687 racoon_yyerror("DPD support not compiled in.");
1688#endif
1689 }
1690 EOS
1691 | DPD_RETRY NUMBER
1692 {
1693#ifdef ENABLE_DPD
1694 cur_rmconf->dpd_retry = $2;
1695#else
1696 racoon_yyerror("DPD support not compiled in.");
1697#endif
1698 }
1699 EOS
1700 | DPD_MAXFAIL NUMBER
1701 {
1702#ifdef ENABLE_DPD
1703 cur_rmconf->dpd_maxfails = $2;
1704#else
1705 racoon_yyerror("DPD support not compiled in.");
1706#endif
1707 }
1708 EOS
1709 | DPD_ALGORITHM dpd_algo_type
1710 {
1711#ifdef ENABLE_DPD
1712 cur_rmconf->dpd_algo = $2;
1713#else
1714 racoon_yyerror("DPD support not compiled in.");
1715#endif
1716 }
1717 EOS
1718 | DISCONNECT_ON_IDLE IDLE_TIMEOUT NUMBER IDLE_DIRECTION idle_dir_type
1719 {
1720 cur_rmconf->idle_timeout = $3;
1721 cur_rmconf->idle_timeout_dir = $5;
1722 }
1723 EOS
1724 | LIFETIME LIFETYPE_TIME NUMBER unittype_time
1725 {
1726 cur_rmconf->prhead->lifetime = $3 * $4;
1727 }
1728 EOS
1729 | PROPOSAL_CHECK PROPOSAL_CHECK_LEVEL { cur_rmconf->pcheck_level = $2; } EOS
1730 | LIFETIME LIFETYPE_BYTE NUMBER unittype_byte
1731 {
1732#if 1
1733 racoon_yyerror("byte lifetime support is deprecated in Phase 1");
1734 return -1;
1735#else
1736 racoon_yywarn("the lifetime of bytes in phase 1 "
1737 "will be ignored at the moment.");
1738 cur_rmconf->prhead->lifebyte = fix_lifebyte($3 * $4);
1739 if (cur_rmconf->prhead->lifebyte == 0)
1740 return -1;
1741#endif
1742 }
1743 EOS
1744 | PROPOSAL
1745 {
1746 struct secprotospec *spspec;
1747
1748 spspec = newspspec();
1749 if (spspec == NULL)
1750 return -1;
1751 insspspec(spspec, &cur_rmconf->prhead);
1752 }
1753 BOC isakmpproposal_specs EOC
1754 ;
1755exchange_types
1756 : /* nothing */
1757 | exchange_types EXCHANGETYPE
1758 {
1759 struct etypes *new;
1760 new = racoon_malloc(sizeof(struct etypes));
1761 if (new == NULL) {
1762 racoon_yyerror("failed to allocate etypes");
1763 return -1;
1764 }
1765 new->type = $2;
1766 new->next = NULL;
1767 if (cur_rmconf->etypes == NULL)
1768 cur_rmconf->etypes = new;
1769 else {
1770 struct etypes *p;
1771 for (p = cur_rmconf->etypes;
1772 p->next != NULL;
1773 p = p->next)
1774 ;
1775 p->next = new;
1776 }
1777 }
1778 ;
1779cert_spec
1780 : CERT_X509 IN_KEYCHAIN
1781 {
1782 cur_rmconf->certtype = $1;
1783 cur_rmconf->identity_in_keychain = 1;
1784 cur_rmconf->keychainCertRef = NULL;
1785 }
1786 EOS
1787 ;
1788 | CERT_X509 IN_KEYCHAIN QUOTEDSTRING
1789 {
1790 cur_rmconf->certtype = $1;
1791 cur_rmconf->identity_in_keychain = 1;
1792 cur_rmconf->keychainCertRef = $3;
1793 }
1794 EOS
1795 ;
1796dh_group_num
1797 : ALGORITHMTYPE
1798 {
1799 $$ = algtype2doi(algclass_isakmp_dh, $1);
1800 if ($$ == -1) {
1801 racoon_yyerror("must be DH group");
1802 return -1;
1803 }
1804 switch ($$)
1805 {
1806 case OAKLEY_ATTR_GRP_DESC_MODP768:
1807 case OAKLEY_ATTR_GRP_DESC_MODP1024:
1808 case OAKLEY_ATTR_GRP_DESC_MODP1536:
1809 case OAKLEY_ATTR_GRP_DESC_MODP2048:
1810 case OAKLEY_ATTR_GRP_DESC_MODP3072:
1811 case OAKLEY_ATTR_GRP_DESC_MODP4096:
1812 case OAKLEY_ATTR_GRP_DESC_MODP6144:
1813 case OAKLEY_ATTR_GRP_DESC_MODP8192:
1814 break;
1815 default:
1816 racoon_yyerror("Invalid DH group specified");
1817 return -1;
1818 break;
1819 }
1820 }
1821 | NUMBER
1822 {
1823 if (ARRAYLEN(num2dhgroup) > $1 && num2dhgroup[$1] != 0) {
1824 $$ = num2dhgroup[$1];
1825 } else {
1826 racoon_yyerror("must be DH group");
1827 $$ = 0;
1828 return -1;
1829 }
1830 switch ($$)
1831 {
1832 case OAKLEY_ATTR_GRP_DESC_MODP768:
1833 case OAKLEY_ATTR_GRP_DESC_MODP1024:
1834 case OAKLEY_ATTR_GRP_DESC_MODP1536:
1835 case OAKLEY_ATTR_GRP_DESC_MODP2048:
1836 case OAKLEY_ATTR_GRP_DESC_MODP3072:
1837 case OAKLEY_ATTR_GRP_DESC_MODP4096:
1838 case OAKLEY_ATTR_GRP_DESC_MODP6144:
1839 case OAKLEY_ATTR_GRP_DESC_MODP8192:
1840 break;
1841 default:
1842 racoon_yyerror("Invalid DH group specified");
1843 return -1;
1844 break;
1845 }
1846 }
1847 ;
1848identifierstring
1849 : /* nothing */ { $$ = NULL; }
1850 | ADDRSTRING { $$ = $1; }
1851 | QUOTEDSTRING { $$ = $1; }
1852 ;
1853isakmpproposal_specs
1854 : /* nothing */
1855 | isakmpproposal_specs isakmpproposal_spec
1856 ;
1857isakmpproposal_spec
1858 : STRENGTH
1859 {
1860 racoon_yyerror("strength directive is obsoleted.");
1861 } STRENGTHTYPE EOS
1862 | LIFETIME LIFETYPE_TIME NUMBER unittype_time
1863 {
1864 cur_rmconf->prhead->spspec->lifetime = $3 * $4;
1865 }
1866 EOS
1867 | LIFETIME LIFETYPE_BYTE NUMBER unittype_byte
1868 {
1869#if 1
1870 racoon_yyerror("byte lifetime support is deprecated");
1871 return -1;
1872#else
1873 cur_rmconf->prhead->spspec->lifebyte = fix_lifebyte($3 * $4);
1874 if (cur_rmconf->prhead->spspec->lifebyte == 0)
1875 return -1;
1876#endif
1877 }
1878 EOS
1879 | DH_GROUP dh_group_num
1880 {
1881 cur_rmconf->prhead->spspec->algclass[algclass_isakmp_dh] = $2;
1882 }
1883 EOS
1884 | GSS_ID QUOTEDSTRING
1885 {
1886 if (cur_rmconf->prhead->spspec->vendorid != VENDORID_GSSAPI) {
1887 racoon_yyerror("wrong Vendor ID for gssapi_id");
1888 return -1;
1889 }
1890 if (cur_rmconf->prhead->spspec->gssid != NULL)
1891 racoon_free(cur_rmconf->prhead->spspec->gssid);
1892 cur_rmconf->prhead->spspec->gssid =
1893 racoon_strdup($2->v);
1894 STRDUP_FATAL(cur_rmconf->prhead->spspec->gssid);
1895 }
1896 EOS
1897 | ALGORITHM_CLASS ALGORITHMTYPE keylength
1898 {
1899 int doi;
1900 int defklen;
1901 {
1902 doi = algtype2doi($1, $2);
1903 if (doi == -1) {
1904 racoon_yyerror("algorithm mismatched 1");
1905 return -1;
1906 }
1907 }
1908
1909 switch ($1) {
1910 case algclass_isakmp_enc:
1911 /* reject suppressed algorithms */
1912 cur_rmconf->prhead->spspec->algclass[algclass_isakmp_enc] = doi;
1913 defklen = default_keylen($1, $2);
1914 if (defklen == 0) {
1915 if ($3) {
1916 racoon_yyerror("keylen not allowed");
1917 return -1;
1918 }
1919 } else {
1920 if ($3 && check_keylen($1, $2, $3) < 0) {
1921 racoon_yyerror("invalid keylen %d", $3);
1922 return -1;
1923 }
1924 }
1925 if ($3)
1926 cur_rmconf->prhead->spspec->encklen = $3;
1927 else
1928 cur_rmconf->prhead->spspec->encklen = defklen;
1929 break;
1930 case algclass_isakmp_hash:
1931 cur_rmconf->prhead->spspec->algclass[algclass_isakmp_hash] = doi;
1932 break;
1933 case algclass_isakmp_ameth:
1934 cur_rmconf->prhead->spspec->algclass[algclass_isakmp_ameth] = doi;
1935 /*
1936 * We may have to set the Vendor ID for the
1937 * authentication method we're using.
1938 */
1939 switch ($2) {
1940 case algtype_gssapikrb:
1941 if (cur_rmconf->prhead->spspec->vendorid !=
1942 VENDORID_UNKNOWN) {
1943 racoon_yyerror("Vendor ID mismatch "
1944 "for auth method");
1945 return -1;
1946 }
1947 /*
1948 * For interoperability with Win2k,
1949 * we set the Vendor ID to "GSSAPI".
1950 */
1951 cur_rmconf->prhead->spspec->vendorid =
1952 VENDORID_GSSAPI;
1953 break;
1954 default:
1955 break;
1956 }
1957 break;
1958 default:
1959 racoon_yyerror("algorithm mismatched 2");
1960 return -1;
1961 }
1962 }
1963 EOS
1964 ;
1965
1966unittype_time
1967 : UNITTYPE_SEC { $$ = 1; }
1968 | UNITTYPE_MIN { $$ = 60; }
1969 | UNITTYPE_HOUR { $$ = (60 * 60); }
1970 ;
1971unittype_byte
1972 : UNITTYPE_BYTE { $$ = 1; }
1973 | UNITTYPE_KBYTES { $$ = 1024; }
1974 | UNITTYPE_MBYTES { $$ = (1024 * 1024); }
1975 | UNITTYPE_TBYTES { $$ = (1024 * 1024 * 1024); }
1976 ;
1977dpd_algo_type
1978 : DPD_ALGO_TYPE_DEFAULT { $$ = DPD_ALGO_DEFAULT; }
1979 | DPD_ALGO_TYPE_INBOUND { $$ = DPD_ALGO_INBOUND_DETECT; }
1980 | DPD_ALGO_TYPE_BLACKHOLE { $$ = DPD_ALGO_BLACKHOLE_DETECT; }
1981 ;
1982idle_dir_type
1983 : IDLE_DIRECTION_ANY { $$ = IPSEC_DIR_ANY; }
1984 | IDLE_DIRECTION_IN { $$ = IPSEC_DIR_INBOUND; }
1985 | IDLE_DIRECTION_OUT { $$ = IPSEC_DIR_OUTBOUND; }
1986 ;
1987%%
1988
1989static struct proposalspec *
1990newprspec()
1991{
1992 struct proposalspec *new;
1993
1994 new = racoon_calloc(1, sizeof(*new));
1995 if (new == NULL)
1996 racoon_yyerror("failed to allocate proposal");
1997
1998 return new;
1999}
2000
2001/*
2002 * insert into head of list.
2003 */
2004static void
2005insprspec(prspec, head)
2006 struct proposalspec *prspec;
2007 struct proposalspec **head;
2008{
2009 if (*head != NULL)
2010 (*head)->prev = prspec;
2011 prspec->next = *head;
2012 *head = prspec;
2013}
2014
2015static struct secprotospec *
2016newspspec()
2017{
2018 struct secprotospec *new;
2019
2020 new = racoon_calloc(1, sizeof(*new));
2021 if (new == NULL) {
2022 racoon_yyerror("failed to allocate spproto");
2023 return NULL;
2024 }
2025
2026 new->encklen = 0; /*XXX*/
2027
2028 /*
2029 * Default to "uknown" vendor -- we will override this
2030 * as necessary. When we send a Vendor ID payload, an
2031 * "unknown" will be translated to a KAME/racoon ID.
2032 */
2033 new->vendorid = VENDORID_UNKNOWN;
2034
2035 return new;
2036}
2037
2038/*
2039 * insert into head of list.
2040 */
2041static void
2042insspspec(spspec, head)
2043 struct secprotospec *spspec;
2044 struct proposalspec **head;
2045{
2046 spspec->back = *head;
2047
2048 if ((*head)->spspec != NULL)
2049 (*head)->spspec->prev = spspec;
2050 spspec->next = (*head)->spspec;
2051 (*head)->spspec = spspec;
2052}
2053
2054/* set final acceptable proposal */
2055static int
2056set_isakmp_proposal(rmconf, prspec)
2057 struct remoteconf *rmconf;
2058 struct proposalspec *prspec;
2059{
2060 struct proposalspec *p;
2061 struct secprotospec *s;
2062 int prop_no = 1;
2063 int trns_no = 1;
2064 int32_t types[MAXALGCLASS];
2065
2066 p = prspec;
2067 if (p->next != 0) {
2068 plog(ASL_LEVEL_ERR,
2069 "multiple proposal definition.\n");
2070 return -1;
2071 }
2072
2073 /* mandatory check */
2074 if (p->spspec == NULL) {
2075 racoon_yyerror("no remote specification found: %s.\n",
2076 saddr2str((struct sockaddr *)rmconf->remote));
2077 return -1;
2078 }
2079 for (s = p->spspec; s != NULL; s = s->next) {
2080 /* XXX need more to check */
2081 if (s->algclass[algclass_isakmp_enc] == 0) {
2082 racoon_yyerror("encryption algorithm required.");
2083 return -1;
2084 }
2085 if (s->algclass[algclass_isakmp_hash] == 0) {
2086 racoon_yyerror("hash algorithm required.");
2087 return -1;
2088 }
2089 if (s->algclass[algclass_isakmp_dh] == 0) {
2090 racoon_yyerror("DH group required.");
2091 return -1;
2092 }
2093 if (s->algclass[algclass_isakmp_ameth] == 0) {
2094 racoon_yyerror("authentication method required.");
2095 return -1;
2096 }
2097 }
2098
2099 /* skip to last part */
2100 for (s = p->spspec; s->next != NULL; s = s->next)
2101 ;
2102
2103 while (s != NULL) {
2104 plog(ASL_LEVEL_DEBUG,
2105 "lifetime = %ld\n", (long)
2106 (s->lifetime ? s->lifetime : p->lifetime));
2107 plog(ASL_LEVEL_DEBUG,
2108 "lifebyte = %d\n",
2109 s->lifebyte ? s->lifebyte : p->lifebyte);
2110 plog(ASL_LEVEL_DEBUG,
2111 "encklen=%d\n", s->encklen);
2112
2113 memset(types, 0, ARRAYLEN(types));
2114 types[algclass_isakmp_enc] = s->algclass[algclass_isakmp_enc];
2115 types[algclass_isakmp_hash] = s->algclass[algclass_isakmp_hash];
2116 types[algclass_isakmp_dh] = s->algclass[algclass_isakmp_dh];
2117 types[algclass_isakmp_ameth] =
2118 s->algclass[algclass_isakmp_ameth];
2119
2120 /* expanding spspec */
2121 clean_tmpalgtype();
2122 trns_no = expand_isakmpspec(prop_no, trns_no, types,
2123 algclass_isakmp_enc, algclass_isakmp_ameth + 1,
2124 s->lifetime ? s->lifetime : p->lifetime,
2125 s->lifebyte ? s->lifebyte : p->lifebyte,
2126 s->encklen, s->vendorid, s->gssid,
2127 rmconf);
2128 if (trns_no == -1) {
2129 plog(ASL_LEVEL_ERR,
2130 "failed to expand isakmp proposal.\n");
2131 return -1;
2132 }
2133
2134 s = s->prev;
2135 }
2136
2137 if (rmconf->proposal == NULL) {
2138 plog(ASL_LEVEL_ERR,
2139 "no proposal found.\n");
2140 return -1;
2141 }
2142
2143 return 0;
2144}
2145
2146static void
2147clean_tmpalgtype()
2148{
2149 int i;
2150 for (i = 0; i < MAXALGCLASS; i++)
2151 tmpalgtype[i] = 0; /* means algorithm undefined. */
2152}
2153
2154static int
2155expand_isakmpspec(prop_no, trns_no, types,
2156 class, last, lifetime, lifebyte, encklen, vendorid, gssid,
2157 rmconf)
2158 int prop_no, trns_no;
2159 int *types, class, last;
2160 time_t lifetime;
2161 int lifebyte;
2162 int encklen;
2163 int vendorid;
2164 char *gssid;
2165 struct remoteconf *rmconf;
2166{
2167 struct isakmpsa *new;
2168
2169 /* debugging */
2170 {
2171 int j;
2172 char tb[10];
2173 plog(ASL_LEVEL_DEBUG,
2174 "p:%d t:%d\n", prop_no, trns_no);
2175 for (j = class; j < MAXALGCLASS; j++) {
2176 snprintf(tb, sizeof(tb), "%d", types[j]);
2177 plog(ASL_LEVEL_DEBUG,
2178 "%s%s%s%s\n",
2179 s_algtype(j, types[j]),
2180 types[j] ? "(" : "",
2181 tb[0] == '0' ? "" : tb,
2182 types[j] ? ")" : "");
2183 }
2184 plog(ASL_LEVEL_DEBUG, "\n");
2185 }
2186
2187#define TMPALGTYPE2STR(n) \
2188 s_algtype(algclass_isakmp_##n, types[algclass_isakmp_##n])
2189 /* check mandatory values */
2190 if (types[algclass_isakmp_enc] == 0
2191 || types[algclass_isakmp_ameth] == 0
2192 || types[algclass_isakmp_dh] == 0) {
2193 racoon_yyerror("few definition of algorithm "
2194 "enc=%s ameth=%s hash=%s dhgroup=%s.\n",
2195 TMPALGTYPE2STR(enc),
2196 TMPALGTYPE2STR(ameth),
2197 TMPALGTYPE2STR(hash),
2198 TMPALGTYPE2STR(dh));
2199 return -1;
2200 }
2201#undef TMPALGTYPE2STR
2202
2203 /* set new sa */
2204 new = newisakmpsa();
2205 if (new == NULL) {
2206 racoon_yyerror("failed to allocate isakmp sa");
2207 return -1;
2208 }
2209 new->prop_no = prop_no;
2210 new->trns_no = trns_no++;
2211 new->lifetime = lifetime;
2212 new->lifebyte = lifebyte;
2213 new->enctype = types[algclass_isakmp_enc];
2214 new->encklen = encklen;
2215 new->authmethod = types[algclass_isakmp_ameth];
2216 new->hashtype = types[algclass_isakmp_hash];
2217 new->prf = types[algclass_isakmp_hash];
2218 new->dh_group = types[algclass_isakmp_dh];
2219 new->vendorid = vendorid;
2220 insisakmpsa(new, rmconf);
2221
2222 return trns_no;
2223}
2224
2225static int
2226listen_addr (struct sockaddr_storage *addr, int udp_encap)
2227{
2228 struct myaddrs *p;
2229
2230 p = newmyaddr();
2231 if (p == NULL) {
2232 racoon_yyerror("failed to allocate myaddrs");
2233 return -1;
2234 }
2235 p->addr = addr;
2236 if (p->addr == NULL) {
2237 racoon_yyerror("failed to copy sockaddr_storage ");
2238 delmyaddr(p);
2239 return -1;
2240 }
2241 p->udp_encap = udp_encap;
2242 /* These need to be initialized for Apple modifications
2243 * to open code for isakmp sockets
2244 */
2245 p->sock = -1;
2246 p->in_use = 1;
2247
2248 insmyaddr(p, &lcconf->myaddrs);
2249
2250 lcconf->autograbaddr = 0;
2251 return 0;
2252}
2253
2254#if 0
2255/*
2256 * fix lifebyte.
2257 * Must be more than 1024B because its unit is kilobytes.
2258 * That is defined RFC2407.
2259 */
2260static int
2261fix_lifebyte(t)
2262 unsigned long t;
2263{
2264 if (t < 1024) {
2265 racoon_yyerror("byte size should be more than 1024B.");
2266 return 0;
2267 }
2268
2269 return(t / 1024);
2270}
2271#endif
2272
2273int
2274cfparse()
2275{
2276 int error;
2277
2278 plog(ASL_LEVEL_DEBUG, "===== parsing configuration\n");
2279
2280 yycf_init_buffer();
2281
2282 if (yycf_switch_buffer(lcconf->racoon_conf) != 0) {
2283 IPSECCONFIGTRACEREVENT(CONSTSTR(lcconf->racoon_conf),
2284 IPSECCONFIGEVENTCODE_PARSE_ERROR,
2285 CONSTSTR("could not read configuration file"),
2286 CONSTSTR("cfparse: yycf_switch_buffer erred"));
2287 plog(ASL_LEVEL_ERR,
2288 "could not read configuration file \"%s\"\n",
2289 lcconf->racoon_conf);
2290 return -1;
2291 }
2292
2293 error = yyparse();
2294 if (error != 0) {
2295 if (yyerrorcount) {
2296 plog(ASL_LEVEL_ERR,
2297 "fatal parse failure (%d errors)\n",
2298 yyerrorcount);
2299 } else {
2300 plog(ASL_LEVEL_ERR,
2301 "fatal parse failure.\n");
2302 }
2303 IPSECCONFIGTRACEREVENT(CONSTSTR(lcconf->racoon_conf),
2304 IPSECCONFIGEVENTCODE_PARSE_ERROR,
2305 CONSTSTR("fatal parse failure"),
2306 CONSTSTR("cfparse: yyparse erred"));
2307 yycf_clean_buffer();
2308 return -1;
2309 }
2310
2311 if (error == 0 && yyerrorcount) {
2312 plog(ASL_LEVEL_ERR,
2313 "parse error is nothing, but yyerrorcount is %d.\n",
2314 yyerrorcount);
2315 IPSECCONFIGTRACEREVENT(CONSTSTR(lcconf->racoon_conf),
2316 IPSECCONFIGEVENTCODE_PARSE_ERROR,
2317 CONSTSTR("ambivalent error code"),
2318 CONSTSTR("cfparse: error == 0 && yerrorcount"));
2319 yycf_clean_buffer();
2320 exit(1);
2321 }
2322
2323 yycf_clean_buffer();
2324
2325 plog(ASL_LEVEL_DEBUG, "parse succeeded.\n");
2326
2327 return 0;
2328}
2329
2330int
2331cfreparse(int sig)
2332{
2333 int result;
2334 int ignore_estab_or_assert_handles = (sig == SIGUSR1);
2335
2336 if (sig >= 0 && sig < NSIG) {
2337 plog(ASL_LEVEL_DEBUG, "==== Got %s signal - re-parsing configuration.\n", sys_signame[sig]);
2338 } else {
2339 plog(ASL_LEVEL_ERR, "==== Got Unknown signal - re-parsing configuration.\n");
2340 IPSECCONFIGTRACEREVENT(CONSTSTR("reparse"),
2341 IPSECCONFIGEVENTCODE_REPARSE_ERROR,
2342 CONSTSTR("Unknown signal"),
2343 CONSTSTR("cfreparse: triggered by unknown signal"));
2344 }
2345 plog(ASL_LEVEL_DEBUG, "==== %s sessions.\n", ignore_estab_or_assert_handles? "flush negotiating" : "flush all");
2346
2347 ike_session_flush_all_phase2(ignore_estab_or_assert_handles);
2348 ike_session_flush_all_phase1(ignore_estab_or_assert_handles);
2349 flushrmconf();
2350 flushsainfo();
2351 check_auto_exit(); /* check/change state of auto exit */
2352 clean_tmpalgtype();
2353 savelcconf();
2354 result = cfparse();
2355 restorelcconf();
2356 return result;
2357}
2358
2359