Return to cfparse.y CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / ipsec-tools / src / racoon |
1.1 ! misho 1: /* $NetBSD: cfparse.y,v 1.42 2011/03/14 15:50:36 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: #include PATH_IPSEC_H ! 44: ! 45: #ifdef ENABLE_HYBRID ! 46: #include <arpa/inet.h> ! 47: #endif ! 48: ! 49: #include <stdlib.h> ! 50: #include <stdio.h> ! 51: #include <string.h> ! 52: #include <errno.h> ! 53: #include <netdb.h> ! 54: #include <pwd.h> ! 55: #include <grp.h> ! 56: ! 57: #include "var.h" ! 58: #include "misc.h" ! 59: #include "vmbuf.h" ! 60: #include "plog.h" ! 61: #include "sockmisc.h" ! 62: #include "str2val.h" ! 63: #include "genlist.h" ! 64: #include "debug.h" ! 65: ! 66: #include "admin.h" ! 67: #include "privsep.h" ! 68: #include "cfparse_proto.h" ! 69: #include "cftoken_proto.h" ! 70: #include "algorithm.h" ! 71: #include "localconf.h" ! 72: #include "policy.h" ! 73: #include "sainfo.h" ! 74: #include "oakley.h" ! 75: #include "pfkey.h" ! 76: #include "remoteconf.h" ! 77: #include "grabmyaddr.h" ! 78: #include "isakmp_var.h" ! 79: #include "handler.h" ! 80: #include "isakmp.h" ! 81: #include "nattraversal.h" ! 82: #include "isakmp_frag.h" ! 83: #ifdef ENABLE_HYBRID ! 84: #include "resolv.h" ! 85: #include "isakmp_unity.h" ! 86: #include "isakmp_xauth.h" ! 87: #include "isakmp_cfg.h" ! 88: #endif ! 89: #include "ipsec_doi.h" ! 90: #include "strnames.h" ! 91: #include "gcmalloc.h" ! 92: #ifdef HAVE_GSSAPI ! 93: #include "gssapi.h" ! 94: #endif ! 95: #include "vendorid.h" ! 96: #include "rsalist.h" ! 97: #include "crypto_openssl.h" ! 98: ! 99: struct secprotospec { ! 100: int prop_no; ! 101: int trns_no; ! 102: int strength; /* for isakmp/ipsec */ ! 103: int encklen; /* for isakmp/ipsec */ ! 104: time_t lifetime; /* for isakmp */ ! 105: int lifebyte; /* for isakmp */ ! 106: int proto_id; /* for ipsec (isakmp?) */ ! 107: int ipsec_level; /* for ipsec */ ! 108: int encmode; /* for ipsec */ ! 109: int vendorid; /* for isakmp */ ! 110: char *gssid; ! 111: struct sockaddr *remote; ! 112: int algclass[MAXALGCLASS]; ! 113: ! 114: struct secprotospec *next; /* the tail is the most prefiered. */ ! 115: struct secprotospec *prev; ! 116: }; ! 117: ! 118: static int num2dhgroup[] = { ! 119: 0, ! 120: OAKLEY_ATTR_GRP_DESC_MODP768, ! 121: OAKLEY_ATTR_GRP_DESC_MODP1024, ! 122: OAKLEY_ATTR_GRP_DESC_EC2N155, ! 123: OAKLEY_ATTR_GRP_DESC_EC2N185, ! 124: OAKLEY_ATTR_GRP_DESC_MODP1536, ! 125: 0, ! 126: 0, ! 127: 0, ! 128: 0, ! 129: 0, ! 130: 0, ! 131: 0, ! 132: 0, ! 133: OAKLEY_ATTR_GRP_DESC_MODP2048, ! 134: OAKLEY_ATTR_GRP_DESC_MODP3072, ! 135: OAKLEY_ATTR_GRP_DESC_MODP4096, ! 136: OAKLEY_ATTR_GRP_DESC_MODP6144, ! 137: OAKLEY_ATTR_GRP_DESC_MODP8192 ! 138: }; ! 139: ! 140: static struct remoteconf *cur_rmconf; ! 141: static int tmpalgtype[MAXALGCLASS]; ! 142: static struct sainfo *cur_sainfo; ! 143: static int cur_algclass; ! 144: static int oldloglevel = LLV_BASE; ! 145: ! 146: static struct secprotospec *newspspec __P((void)); ! 147: static void insspspec __P((struct remoteconf *, struct secprotospec *)); ! 148: void dupspspec_list __P((struct remoteconf *dst, struct remoteconf *src)); ! 149: void flushspspec __P((struct remoteconf *)); ! 150: static void adminsock_conf __P((vchar_t *, vchar_t *, vchar_t *, int)); ! 151: ! 152: static int set_isakmp_proposal __P((struct remoteconf *)); ! 153: static void clean_tmpalgtype __P((void)); ! 154: static int expand_isakmpspec __P((int, int, int *, ! 155: int, int, time_t, int, int, int, char *, struct remoteconf *)); ! 156: ! 157: void freeetypes (struct etypes **etypes); ! 158: ! 159: static int load_x509(const char *file, char **filenameptr, ! 160: vchar_t **certptr) ! 161: { ! 162: char path[PATH_MAX]; ! 163: ! 164: getpathname(path, sizeof(path), LC_PATHTYPE_CERT, file); ! 165: *certptr = eay_get_x509cert(path); ! 166: if (*certptr == NULL) ! 167: return -1; ! 168: ! 169: *filenameptr = racoon_strdup(file); ! 170: STRDUP_FATAL(*filenameptr); ! 171: ! 172: return 0; ! 173: } ! 174: ! 175: %} ! 176: ! 177: %union { ! 178: unsigned long num; ! 179: vchar_t *val; ! 180: struct remoteconf *rmconf; ! 181: struct sockaddr *saddr; ! 182: struct sainfoalg *alg; ! 183: } ! 184: ! 185: /* privsep */ ! 186: %token PRIVSEP USER GROUP CHROOT ! 187: /* path */ ! 188: %token PATH PATHTYPE ! 189: /* include */ ! 190: %token INCLUDE ! 191: /* PFKEY_BUFFER */ ! 192: %token PFKEY_BUFFER ! 193: /* logging */ ! 194: %token LOGGING LOGLEV ! 195: /* padding */ ! 196: %token PADDING PAD_RANDOMIZE PAD_RANDOMIZELEN PAD_MAXLEN PAD_STRICT PAD_EXCLTAIL ! 197: /* listen */ ! 198: %token LISTEN X_ISAKMP X_ISAKMP_NATT X_ADMIN STRICT_ADDRESS ADMINSOCK DISABLED ! 199: /* ldap config */ ! 200: %token LDAPCFG LDAP_HOST LDAP_PORT LDAP_PVER LDAP_BASE LDAP_BIND_DN LDAP_BIND_PW LDAP_SUBTREE ! 201: %token LDAP_ATTR_USER LDAP_ATTR_ADDR LDAP_ATTR_MASK LDAP_ATTR_GROUP LDAP_ATTR_MEMBER ! 202: /* radius config */ ! 203: %token RADCFG RAD_AUTH RAD_ACCT RAD_TIMEOUT RAD_RETRIES ! 204: /* modecfg */ ! 205: %token MODECFG CFG_NET4 CFG_MASK4 CFG_DNS4 CFG_NBNS4 CFG_DEFAULT_DOMAIN ! 206: %token CFG_AUTH_SOURCE CFG_AUTH_GROUPS CFG_SYSTEM CFG_RADIUS CFG_PAM CFG_LDAP CFG_LOCAL CFG_NONE ! 207: %token CFG_GROUP_SOURCE CFG_ACCOUNTING CFG_CONF_SOURCE CFG_MOTD CFG_POOL_SIZE CFG_AUTH_THROTTLE ! 208: %token CFG_SPLIT_NETWORK CFG_SPLIT_LOCAL CFG_SPLIT_INCLUDE CFG_SPLIT_DNS ! 209: %token CFG_PFS_GROUP CFG_SAVE_PASSWD ! 210: ! 211: /* timer */ ! 212: %token RETRY RETRY_COUNTER RETRY_INTERVAL RETRY_PERSEND ! 213: %token RETRY_PHASE1 RETRY_PHASE2 NATT_KA ! 214: /* algorithm */ ! 215: %token ALGORITHM_CLASS ALGORITHMTYPE STRENGTHTYPE ! 216: /* sainfo */ ! 217: %token SAINFO FROM ! 218: /* remote */ ! 219: %token REMOTE ANONYMOUS CLIENTADDR INHERIT REMOTE_ADDRESS ! 220: %token EXCHANGE_MODE EXCHANGETYPE DOI DOITYPE SITUATION SITUATIONTYPE ! 221: %token CERTIFICATE_TYPE CERTTYPE PEERS_CERTFILE CA_TYPE ! 222: %token VERIFY_CERT SEND_CERT SEND_CR MATCH_EMPTY_CR ! 223: %token IDENTIFIERTYPE IDENTIFIERQUAL MY_IDENTIFIER ! 224: %token PEERS_IDENTIFIER VERIFY_IDENTIFIER ! 225: %token DNSSEC CERT_X509 CERT_PLAINRSA ! 226: %token NONCE_SIZE DH_GROUP KEEPALIVE PASSIVE INITIAL_CONTACT ! 227: %token NAT_TRAVERSAL REMOTE_FORCE_LEVEL ! 228: %token PROPOSAL_CHECK PROPOSAL_CHECK_LEVEL ! 229: %token GENERATE_POLICY GENERATE_LEVEL SUPPORT_PROXY ! 230: %token PROPOSAL ! 231: %token EXEC_PATH EXEC_COMMAND EXEC_SUCCESS EXEC_FAILURE ! 232: %token GSS_ID GSS_ID_ENC GSS_ID_ENCTYPE ! 233: %token COMPLEX_BUNDLE ! 234: %token DPD DPD_DELAY DPD_RETRY DPD_MAXFAIL ! 235: %token PH1ID ! 236: %token XAUTH_LOGIN WEAK_PHASE1_CHECK ! 237: %token REKEY ! 238: ! 239: %token PREFIX PORT PORTANY UL_PROTO ANY IKE_FRAG ESP_FRAG MODE_CFG ! 240: %token PFS_GROUP LIFETIME LIFETYPE_TIME LIFETYPE_BYTE STRENGTH REMOTEID ! 241: ! 242: %token SCRIPT PHASE1_UP PHASE1_DOWN PHASE1_DEAD ! 243: ! 244: %token NUMBER SWITCH BOOLEAN ! 245: %token HEXSTRING QUOTEDSTRING ADDRSTRING ADDRRANGE ! 246: %token UNITTYPE_BYTE UNITTYPE_KBYTES UNITTYPE_MBYTES UNITTYPE_TBYTES ! 247: %token UNITTYPE_SEC UNITTYPE_MIN UNITTYPE_HOUR ! 248: %token EOS BOC EOC COMMA ! 249: ! 250: %type <num> NUMBER BOOLEAN SWITCH keylength ! 251: %type <num> PATHTYPE IDENTIFIERTYPE IDENTIFIERQUAL LOGLEV GSS_ID_ENCTYPE ! 252: %type <num> ALGORITHM_CLASS dh_group_num ! 253: %type <num> ALGORITHMTYPE STRENGTHTYPE ! 254: %type <num> PREFIX prefix PORT port ike_port ! 255: %type <num> ul_proto UL_PROTO ! 256: %type <num> EXCHANGETYPE DOITYPE SITUATIONTYPE ! 257: %type <num> CERTTYPE CERT_X509 CERT_PLAINRSA PROPOSAL_CHECK_LEVEL REMOTE_FORCE_LEVEL GENERATE_LEVEL ! 258: %type <num> unittype_time unittype_byte ! 259: %type <val> QUOTEDSTRING HEXSTRING ADDRSTRING ADDRRANGE sainfo_id ! 260: %type <val> identifierstring ! 261: %type <saddr> remote_index ike_addrinfo_port ! 262: %type <alg> algorithm ! 263: ! 264: %% ! 265: ! 266: statements ! 267: : /* nothing */ ! 268: | statements statement ! 269: ; ! 270: statement ! 271: : privsep_statement ! 272: | path_statement ! 273: | include_statement ! 274: | pfkey_statement ! 275: | gssenc_statement ! 276: | logging_statement ! 277: | padding_statement ! 278: | listen_statement ! 279: | ldapcfg_statement ! 280: | radcfg_statement ! 281: | modecfg_statement ! 282: | timer_statement ! 283: | sainfo_statement ! 284: | remote_statement ! 285: | special_statement ! 286: ; ! 287: ! 288: /* privsep */ ! 289: privsep_statement ! 290: : PRIVSEP BOC privsep_stmts EOC ! 291: ; ! 292: privsep_stmts ! 293: : /* nothing */ ! 294: | privsep_stmts privsep_stmt ! 295: ; ! 296: privsep_stmt ! 297: : USER QUOTEDSTRING ! 298: { ! 299: struct passwd *pw; ! 300: ! 301: if ((pw = getpwnam($2->v)) == NULL) { ! 302: yyerror("unknown user \"%s\"", $2->v); ! 303: return -1; ! 304: } ! 305: lcconf->uid = pw->pw_uid; ! 306: } ! 307: EOS ! 308: | USER NUMBER { lcconf->uid = $2; } EOS ! 309: | GROUP QUOTEDSTRING ! 310: { ! 311: struct group *gr; ! 312: ! 313: if ((gr = getgrnam($2->v)) == NULL) { ! 314: yyerror("unknown group \"%s\"", $2->v); ! 315: return -1; ! 316: } ! 317: lcconf->gid = gr->gr_gid; ! 318: } ! 319: EOS ! 320: | GROUP NUMBER { lcconf->gid = $2; } EOS ! 321: | CHROOT QUOTEDSTRING { lcconf->chroot = $2->v; } EOS ! 322: ; ! 323: ! 324: /* path */ ! 325: path_statement ! 326: : PATH PATHTYPE QUOTEDSTRING ! 327: { ! 328: if ($2 >= LC_PATHTYPE_MAX) { ! 329: yyerror("invalid path type %d", $2); ! 330: return -1; ! 331: } ! 332: ! 333: /* free old pathinfo */ ! 334: if (lcconf->pathinfo[$2]) ! 335: racoon_free(lcconf->pathinfo[$2]); ! 336: ! 337: /* set new pathinfo */ ! 338: lcconf->pathinfo[$2] = racoon_strdup($3->v); ! 339: STRDUP_FATAL(lcconf->pathinfo[$2]); ! 340: vfree($3); ! 341: } ! 342: EOS ! 343: ; ! 344: ! 345: /* special */ ! 346: special_statement ! 347: : COMPLEX_BUNDLE SWITCH { lcconf->complex_bundle = $2; } EOS ! 348: ; ! 349: ! 350: /* include */ ! 351: include_statement ! 352: : INCLUDE QUOTEDSTRING EOS ! 353: { ! 354: char path[MAXPATHLEN]; ! 355: ! 356: getpathname(path, sizeof(path), ! 357: LC_PATHTYPE_INCLUDE, $2->v); ! 358: vfree($2); ! 359: if (yycf_switch_buffer(path) != 0) ! 360: return -1; ! 361: } ! 362: ; ! 363: ! 364: /* pfkey_buffer */ ! 365: pfkey_statement ! 366: : PFKEY_BUFFER NUMBER EOS ! 367: { ! 368: lcconf->pfkey_buffer_size = $2; ! 369: } ! 370: ; ! 371: /* gss_id_enc */ ! 372: gssenc_statement ! 373: : GSS_ID_ENC GSS_ID_ENCTYPE EOS ! 374: { ! 375: if ($2 >= LC_GSSENC_MAX) { ! 376: yyerror("invalid GSS ID encoding %d", $2); ! 377: return -1; ! 378: } ! 379: lcconf->gss_id_enc = $2; ! 380: } ! 381: ; ! 382: ! 383: /* logging */ ! 384: logging_statement ! 385: : LOGGING log_level EOS ! 386: ; ! 387: log_level ! 388: : LOGLEV ! 389: { ! 390: /* ! 391: * set the loglevel to the value specified ! 392: * in the configuration file plus the number ! 393: * of -d options specified on the command line ! 394: */ ! 395: loglevel += $1 - oldloglevel; ! 396: oldloglevel = $1; ! 397: } ! 398: ; ! 399: ! 400: /* padding */ ! 401: padding_statement ! 402: : PADDING BOC padding_stmts EOC ! 403: ; ! 404: padding_stmts ! 405: : /* nothing */ ! 406: | padding_stmts padding_stmt ! 407: ; ! 408: padding_stmt ! 409: : PAD_RANDOMIZE SWITCH { lcconf->pad_random = $2; } EOS ! 410: | PAD_RANDOMIZELEN SWITCH { lcconf->pad_randomlen = $2; } EOS ! 411: | PAD_MAXLEN NUMBER { lcconf->pad_maxsize = $2; } EOS ! 412: | PAD_STRICT SWITCH { lcconf->pad_strict = $2; } EOS ! 413: | PAD_EXCLTAIL SWITCH { lcconf->pad_excltail = $2; } EOS ! 414: ; ! 415: ! 416: /* listen */ ! 417: listen_statement ! 418: : LISTEN BOC listen_stmts EOC ! 419: ; ! 420: listen_stmts ! 421: : /* nothing */ ! 422: | listen_stmts listen_stmt ! 423: ; ! 424: listen_stmt ! 425: : X_ISAKMP ike_addrinfo_port ! 426: { ! 427: myaddr_listen($2, FALSE); ! 428: racoon_free($2); ! 429: } ! 430: EOS ! 431: | X_ISAKMP_NATT ike_addrinfo_port ! 432: { ! 433: #ifdef ENABLE_NATT ! 434: myaddr_listen($2, TRUE); ! 435: racoon_free($2); ! 436: #else ! 437: racoon_free($2); ! 438: yyerror("NAT-T support not compiled in."); ! 439: #endif ! 440: } ! 441: EOS ! 442: | ADMINSOCK QUOTEDSTRING QUOTEDSTRING QUOTEDSTRING NUMBER ! 443: { ! 444: #ifdef ENABLE_ADMINPORT ! 445: adminsock_conf($2, $3, $4, $5); ! 446: #else ! 447: yywarn("admin port support not compiled in"); ! 448: #endif ! 449: } ! 450: EOS ! 451: | ADMINSOCK QUOTEDSTRING ! 452: { ! 453: #ifdef ENABLE_ADMINPORT ! 454: adminsock_conf($2, NULL, NULL, -1); ! 455: #else ! 456: yywarn("admin port support not compiled in"); ! 457: #endif ! 458: } ! 459: EOS ! 460: | ADMINSOCK DISABLED ! 461: { ! 462: #ifdef ENABLE_ADMINPORT ! 463: adminsock_path = NULL; ! 464: #else ! 465: yywarn("admin port support not compiled in"); ! 466: #endif ! 467: } ! 468: EOS ! 469: | STRICT_ADDRESS { lcconf->strict_address = TRUE; } EOS ! 470: ; ! 471: ike_addrinfo_port ! 472: : ADDRSTRING ike_port ! 473: { ! 474: char portbuf[10]; ! 475: ! 476: snprintf(portbuf, sizeof(portbuf), "%ld", $2); ! 477: $$ = str2saddr($1->v, portbuf); ! 478: vfree($1); ! 479: if (!$$) ! 480: return -1; ! 481: } ! 482: ; ! 483: ike_port ! 484: : /* nothing */ { $$ = PORT_ISAKMP; } ! 485: | PORT { $$ = $1; } ! 486: ; ! 487: ! 488: /* radius configuration */ ! 489: radcfg_statement ! 490: : RADCFG { ! 491: #ifndef ENABLE_HYBRID ! 492: yyerror("racoon not configured with --enable-hybrid"); ! 493: return -1; ! 494: #endif ! 495: #ifndef HAVE_LIBRADIUS ! 496: yyerror("racoon not configured with --with-libradius"); ! 497: return -1; ! 498: #endif ! 499: #ifdef ENABLE_HYBRID ! 500: #ifdef HAVE_LIBRADIUS ! 501: xauth_rad_config.timeout = 3; ! 502: xauth_rad_config.retries = 3; ! 503: #endif ! 504: #endif ! 505: } BOC radcfg_stmts EOC ! 506: ; ! 507: radcfg_stmts ! 508: : /* nothing */ ! 509: | radcfg_stmts radcfg_stmt ! 510: ; ! 511: radcfg_stmt ! 512: : RAD_AUTH QUOTEDSTRING QUOTEDSTRING ! 513: { ! 514: #ifdef ENABLE_HYBRID ! 515: #ifdef HAVE_LIBRADIUS ! 516: int i = xauth_rad_config.auth_server_count; ! 517: if (i == RADIUS_MAX_SERVERS) { ! 518: yyerror("maximum radius auth servers exceeded"); ! 519: return -1; ! 520: } ! 521: ! 522: xauth_rad_config.auth_server_list[i].host = vdup($2); ! 523: xauth_rad_config.auth_server_list[i].secret = vdup($3); ! 524: xauth_rad_config.auth_server_list[i].port = 0; // default port ! 525: xauth_rad_config.auth_server_count++; ! 526: #endif ! 527: #endif ! 528: } ! 529: EOS ! 530: | RAD_AUTH QUOTEDSTRING NUMBER QUOTEDSTRING ! 531: { ! 532: #ifdef ENABLE_HYBRID ! 533: #ifdef HAVE_LIBRADIUS ! 534: int i = xauth_rad_config.auth_server_count; ! 535: if (i == RADIUS_MAX_SERVERS) { ! 536: yyerror("maximum radius auth servers exceeded"); ! 537: return -1; ! 538: } ! 539: ! 540: xauth_rad_config.auth_server_list[i].host = vdup($2); ! 541: xauth_rad_config.auth_server_list[i].secret = vdup($4); ! 542: xauth_rad_config.auth_server_list[i].port = $3; ! 543: xauth_rad_config.auth_server_count++; ! 544: #endif ! 545: #endif ! 546: } ! 547: EOS ! 548: | RAD_ACCT QUOTEDSTRING QUOTEDSTRING ! 549: { ! 550: #ifdef ENABLE_HYBRID ! 551: #ifdef HAVE_LIBRADIUS ! 552: int i = xauth_rad_config.acct_server_count; ! 553: if (i == RADIUS_MAX_SERVERS) { ! 554: yyerror("maximum radius account servers exceeded"); ! 555: return -1; ! 556: } ! 557: ! 558: xauth_rad_config.acct_server_list[i].host = vdup($2); ! 559: xauth_rad_config.acct_server_list[i].secret = vdup($3); ! 560: xauth_rad_config.acct_server_list[i].port = 0; // default port ! 561: xauth_rad_config.acct_server_count++; ! 562: #endif ! 563: #endif ! 564: } ! 565: EOS ! 566: | RAD_ACCT QUOTEDSTRING NUMBER QUOTEDSTRING ! 567: { ! 568: #ifdef ENABLE_HYBRID ! 569: #ifdef HAVE_LIBRADIUS ! 570: int i = xauth_rad_config.acct_server_count; ! 571: if (i == RADIUS_MAX_SERVERS) { ! 572: yyerror("maximum radius account servers exceeded"); ! 573: return -1; ! 574: } ! 575: ! 576: xauth_rad_config.acct_server_list[i].host = vdup($2); ! 577: xauth_rad_config.acct_server_list[i].secret = vdup($4); ! 578: xauth_rad_config.acct_server_list[i].port = $3; ! 579: xauth_rad_config.acct_server_count++; ! 580: #endif ! 581: #endif ! 582: } ! 583: EOS ! 584: | RAD_TIMEOUT NUMBER ! 585: { ! 586: #ifdef ENABLE_HYBRID ! 587: #ifdef HAVE_LIBRADIUS ! 588: xauth_rad_config.timeout = $2; ! 589: #endif ! 590: #endif ! 591: } ! 592: EOS ! 593: | RAD_RETRIES NUMBER ! 594: { ! 595: #ifdef ENABLE_HYBRID ! 596: #ifdef HAVE_LIBRADIUS ! 597: xauth_rad_config.retries = $2; ! 598: #endif ! 599: #endif ! 600: } ! 601: EOS ! 602: ; ! 603: ! 604: /* ldap configuration */ ! 605: ldapcfg_statement ! 606: : LDAPCFG { ! 607: #ifndef ENABLE_HYBRID ! 608: yyerror("racoon not configured with --enable-hybrid"); ! 609: return -1; ! 610: #endif ! 611: #ifndef HAVE_LIBLDAP ! 612: yyerror("racoon not configured with --with-libldap"); ! 613: return -1; ! 614: #endif ! 615: } BOC ldapcfg_stmts EOC ! 616: ; ! 617: ldapcfg_stmts ! 618: : /* nothing */ ! 619: | ldapcfg_stmts ldapcfg_stmt ! 620: ; ! 621: ldapcfg_stmt ! 622: : LDAP_PVER NUMBER ! 623: { ! 624: #ifdef ENABLE_HYBRID ! 625: #ifdef HAVE_LIBLDAP ! 626: if (($2<2)||($2>3)) ! 627: yyerror("invalid ldap protocol version (2|3)"); ! 628: xauth_ldap_config.pver = $2; ! 629: #endif ! 630: #endif ! 631: } ! 632: EOS ! 633: | LDAP_HOST QUOTEDSTRING ! 634: { ! 635: #ifdef ENABLE_HYBRID ! 636: #ifdef HAVE_LIBLDAP ! 637: if (xauth_ldap_config.host != NULL) ! 638: vfree(xauth_ldap_config.host); ! 639: xauth_ldap_config.host = vdup($2); ! 640: #endif ! 641: #endif ! 642: } ! 643: EOS ! 644: | LDAP_PORT NUMBER ! 645: { ! 646: #ifdef ENABLE_HYBRID ! 647: #ifdef HAVE_LIBLDAP ! 648: xauth_ldap_config.port = $2; ! 649: #endif ! 650: #endif ! 651: } ! 652: EOS ! 653: | LDAP_BASE QUOTEDSTRING ! 654: { ! 655: #ifdef ENABLE_HYBRID ! 656: #ifdef HAVE_LIBLDAP ! 657: if (xauth_ldap_config.base != NULL) ! 658: vfree(xauth_ldap_config.base); ! 659: xauth_ldap_config.base = vdup($2); ! 660: #endif ! 661: #endif ! 662: } ! 663: EOS ! 664: | LDAP_SUBTREE SWITCH ! 665: { ! 666: #ifdef ENABLE_HYBRID ! 667: #ifdef HAVE_LIBLDAP ! 668: xauth_ldap_config.subtree = $2; ! 669: #endif ! 670: #endif ! 671: } ! 672: EOS ! 673: | LDAP_BIND_DN QUOTEDSTRING ! 674: { ! 675: #ifdef ENABLE_HYBRID ! 676: #ifdef HAVE_LIBLDAP ! 677: if (xauth_ldap_config.bind_dn != NULL) ! 678: vfree(xauth_ldap_config.bind_dn); ! 679: xauth_ldap_config.bind_dn = vdup($2); ! 680: #endif ! 681: #endif ! 682: } ! 683: EOS ! 684: | LDAP_BIND_PW QUOTEDSTRING ! 685: { ! 686: #ifdef ENABLE_HYBRID ! 687: #ifdef HAVE_LIBLDAP ! 688: if (xauth_ldap_config.bind_pw != NULL) ! 689: vfree(xauth_ldap_config.bind_pw); ! 690: xauth_ldap_config.bind_pw = vdup($2); ! 691: #endif ! 692: #endif ! 693: } ! 694: EOS ! 695: | LDAP_ATTR_USER QUOTEDSTRING ! 696: { ! 697: #ifdef ENABLE_HYBRID ! 698: #ifdef HAVE_LIBLDAP ! 699: if (xauth_ldap_config.attr_user != NULL) ! 700: vfree(xauth_ldap_config.attr_user); ! 701: xauth_ldap_config.attr_user = vdup($2); ! 702: #endif ! 703: #endif ! 704: } ! 705: EOS ! 706: | LDAP_ATTR_ADDR QUOTEDSTRING ! 707: { ! 708: #ifdef ENABLE_HYBRID ! 709: #ifdef HAVE_LIBLDAP ! 710: if (xauth_ldap_config.attr_addr != NULL) ! 711: vfree(xauth_ldap_config.attr_addr); ! 712: xauth_ldap_config.attr_addr = vdup($2); ! 713: #endif ! 714: #endif ! 715: } ! 716: EOS ! 717: | LDAP_ATTR_MASK QUOTEDSTRING ! 718: { ! 719: #ifdef ENABLE_HYBRID ! 720: #ifdef HAVE_LIBLDAP ! 721: if (xauth_ldap_config.attr_mask != NULL) ! 722: vfree(xauth_ldap_config.attr_mask); ! 723: xauth_ldap_config.attr_mask = vdup($2); ! 724: #endif ! 725: #endif ! 726: } ! 727: EOS ! 728: | LDAP_ATTR_GROUP QUOTEDSTRING ! 729: { ! 730: #ifdef ENABLE_HYBRID ! 731: #ifdef HAVE_LIBLDAP ! 732: if (xauth_ldap_config.attr_group != NULL) ! 733: vfree(xauth_ldap_config.attr_group); ! 734: xauth_ldap_config.attr_group = vdup($2); ! 735: #endif ! 736: #endif ! 737: } ! 738: EOS ! 739: | LDAP_ATTR_MEMBER QUOTEDSTRING ! 740: { ! 741: #ifdef ENABLE_HYBRID ! 742: #ifdef HAVE_LIBLDAP ! 743: if (xauth_ldap_config.attr_member != NULL) ! 744: vfree(xauth_ldap_config.attr_member); ! 745: xauth_ldap_config.attr_member = vdup($2); ! 746: #endif ! 747: #endif ! 748: } ! 749: EOS ! 750: ; ! 751: ! 752: /* modecfg */ ! 753: modecfg_statement ! 754: : MODECFG BOC modecfg_stmts EOC ! 755: ; ! 756: modecfg_stmts ! 757: : /* nothing */ ! 758: | modecfg_stmts modecfg_stmt ! 759: ; ! 760: modecfg_stmt ! 761: : CFG_NET4 ADDRSTRING ! 762: { ! 763: #ifdef ENABLE_HYBRID ! 764: if (inet_pton(AF_INET, $2->v, ! 765: &isakmp_cfg_config.network4) != 1) ! 766: yyerror("bad IPv4 network address."); ! 767: #else ! 768: yyerror("racoon not configured with --enable-hybrid"); ! 769: #endif ! 770: } ! 771: EOS ! 772: | CFG_MASK4 ADDRSTRING ! 773: { ! 774: #ifdef ENABLE_HYBRID ! 775: if (inet_pton(AF_INET, $2->v, ! 776: &isakmp_cfg_config.netmask4) != 1) ! 777: yyerror("bad IPv4 netmask address."); ! 778: #else ! 779: yyerror("racoon not configured with --enable-hybrid"); ! 780: #endif ! 781: } ! 782: EOS ! 783: | CFG_DNS4 addrdnslist ! 784: EOS ! 785: | CFG_NBNS4 addrwinslist ! 786: EOS ! 787: | CFG_SPLIT_NETWORK CFG_SPLIT_LOCAL splitnetlist ! 788: { ! 789: #ifdef ENABLE_HYBRID ! 790: isakmp_cfg_config.splitnet_type = UNITY_LOCAL_LAN; ! 791: #else ! 792: yyerror("racoon not configured with --enable-hybrid"); ! 793: #endif ! 794: } ! 795: EOS ! 796: | CFG_SPLIT_NETWORK CFG_SPLIT_INCLUDE splitnetlist ! 797: { ! 798: #ifdef ENABLE_HYBRID ! 799: isakmp_cfg_config.splitnet_type = UNITY_SPLIT_INCLUDE; ! 800: #else ! 801: yyerror("racoon not configured with --enable-hybrid"); ! 802: #endif ! 803: } ! 804: EOS ! 805: | CFG_SPLIT_DNS splitdnslist ! 806: { ! 807: #ifndef ENABLE_HYBRID ! 808: yyerror("racoon not configured with --enable-hybrid"); ! 809: #endif ! 810: } ! 811: EOS ! 812: | CFG_DEFAULT_DOMAIN QUOTEDSTRING ! 813: { ! 814: #ifdef ENABLE_HYBRID ! 815: strncpy(&isakmp_cfg_config.default_domain[0], ! 816: $2->v, MAXPATHLEN); ! 817: isakmp_cfg_config.default_domain[MAXPATHLEN] = '\0'; ! 818: vfree($2); ! 819: #else ! 820: yyerror("racoon not configured with --enable-hybrid"); ! 821: #endif ! 822: } ! 823: EOS ! 824: | CFG_AUTH_SOURCE CFG_SYSTEM ! 825: { ! 826: #ifdef ENABLE_HYBRID ! 827: isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_SYSTEM; ! 828: #else ! 829: yyerror("racoon not configured with --enable-hybrid"); ! 830: #endif ! 831: } ! 832: EOS ! 833: | CFG_AUTH_SOURCE CFG_RADIUS ! 834: { ! 835: #ifdef ENABLE_HYBRID ! 836: #ifdef HAVE_LIBRADIUS ! 837: isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_RADIUS; ! 838: #else /* HAVE_LIBRADIUS */ ! 839: yyerror("racoon not configured with --with-libradius"); ! 840: #endif /* HAVE_LIBRADIUS */ ! 841: #else /* ENABLE_HYBRID */ ! 842: yyerror("racoon not configured with --enable-hybrid"); ! 843: #endif /* ENABLE_HYBRID */ ! 844: } ! 845: EOS ! 846: | CFG_AUTH_SOURCE CFG_PAM ! 847: { ! 848: #ifdef ENABLE_HYBRID ! 849: #ifdef HAVE_LIBPAM ! 850: isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_PAM; ! 851: #else /* HAVE_LIBPAM */ ! 852: yyerror("racoon not configured with --with-libpam"); ! 853: #endif /* HAVE_LIBPAM */ ! 854: #else /* ENABLE_HYBRID */ ! 855: yyerror("racoon not configured with --enable-hybrid"); ! 856: #endif /* ENABLE_HYBRID */ ! 857: } ! 858: EOS ! 859: | CFG_AUTH_SOURCE CFG_LDAP ! 860: { ! 861: #ifdef ENABLE_HYBRID ! 862: #ifdef HAVE_LIBLDAP ! 863: isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_LDAP; ! 864: #else /* HAVE_LIBLDAP */ ! 865: yyerror("racoon not configured with --with-libldap"); ! 866: #endif /* HAVE_LIBLDAP */ ! 867: #else /* ENABLE_HYBRID */ ! 868: yyerror("racoon not configured with --enable-hybrid"); ! 869: #endif /* ENABLE_HYBRID */ ! 870: } ! 871: EOS ! 872: | CFG_AUTH_GROUPS authgrouplist ! 873: { ! 874: #ifndef ENABLE_HYBRID ! 875: yyerror("racoon not configured with --enable-hybrid"); ! 876: #endif ! 877: } ! 878: EOS ! 879: | CFG_GROUP_SOURCE CFG_SYSTEM ! 880: { ! 881: #ifdef ENABLE_HYBRID ! 882: isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_SYSTEM; ! 883: #else ! 884: yyerror("racoon not configured with --enable-hybrid"); ! 885: #endif ! 886: } ! 887: EOS ! 888: | CFG_GROUP_SOURCE CFG_LDAP ! 889: { ! 890: #ifdef ENABLE_HYBRID ! 891: #ifdef HAVE_LIBLDAP ! 892: isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_LDAP; ! 893: #else /* HAVE_LIBLDAP */ ! 894: yyerror("racoon not configured with --with-libldap"); ! 895: #endif /* HAVE_LIBLDAP */ ! 896: #else /* ENABLE_HYBRID */ ! 897: yyerror("racoon not configured with --enable-hybrid"); ! 898: #endif /* ENABLE_HYBRID */ ! 899: } ! 900: EOS ! 901: | CFG_ACCOUNTING CFG_NONE ! 902: { ! 903: #ifdef ENABLE_HYBRID ! 904: isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_NONE; ! 905: #else ! 906: yyerror("racoon not configured with --enable-hybrid"); ! 907: #endif ! 908: } ! 909: EOS ! 910: | CFG_ACCOUNTING CFG_SYSTEM ! 911: { ! 912: #ifdef ENABLE_HYBRID ! 913: isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_SYSTEM; ! 914: #else ! 915: yyerror("racoon not configured with --enable-hybrid"); ! 916: #endif ! 917: } ! 918: EOS ! 919: | CFG_ACCOUNTING CFG_RADIUS ! 920: { ! 921: #ifdef ENABLE_HYBRID ! 922: #ifdef HAVE_LIBRADIUS ! 923: isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_RADIUS; ! 924: #else /* HAVE_LIBRADIUS */ ! 925: yyerror("racoon not configured with --with-libradius"); ! 926: #endif /* HAVE_LIBRADIUS */ ! 927: #else /* ENABLE_HYBRID */ ! 928: yyerror("racoon not configured with --enable-hybrid"); ! 929: #endif /* ENABLE_HYBRID */ ! 930: } ! 931: EOS ! 932: | CFG_ACCOUNTING CFG_PAM ! 933: { ! 934: #ifdef ENABLE_HYBRID ! 935: #ifdef HAVE_LIBPAM ! 936: isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_PAM; ! 937: #else /* HAVE_LIBPAM */ ! 938: yyerror("racoon not configured with --with-libpam"); ! 939: #endif /* HAVE_LIBPAM */ ! 940: #else /* ENABLE_HYBRID */ ! 941: yyerror("racoon not configured with --enable-hybrid"); ! 942: #endif /* ENABLE_HYBRID */ ! 943: } ! 944: EOS ! 945: | CFG_POOL_SIZE NUMBER ! 946: { ! 947: #ifdef ENABLE_HYBRID ! 948: if (isakmp_cfg_resize_pool($2) != 0) ! 949: yyerror("cannot allocate memory for pool"); ! 950: #else /* ENABLE_HYBRID */ ! 951: yyerror("racoon not configured with --enable-hybrid"); ! 952: #endif /* ENABLE_HYBRID */ ! 953: } ! 954: EOS ! 955: | CFG_PFS_GROUP NUMBER ! 956: { ! 957: #ifdef ENABLE_HYBRID ! 958: isakmp_cfg_config.pfs_group = $2; ! 959: #else /* ENABLE_HYBRID */ ! 960: yyerror("racoon not configured with --enable-hybrid"); ! 961: #endif /* ENABLE_HYBRID */ ! 962: } ! 963: EOS ! 964: | CFG_SAVE_PASSWD SWITCH ! 965: { ! 966: #ifdef ENABLE_HYBRID ! 967: isakmp_cfg_config.save_passwd = $2; ! 968: #else /* ENABLE_HYBRID */ ! 969: yyerror("racoon not configured with --enable-hybrid"); ! 970: #endif /* ENABLE_HYBRID */ ! 971: } ! 972: EOS ! 973: | CFG_AUTH_THROTTLE NUMBER ! 974: { ! 975: #ifdef ENABLE_HYBRID ! 976: isakmp_cfg_config.auth_throttle = $2; ! 977: #else /* ENABLE_HYBRID */ ! 978: yyerror("racoon not configured with --enable-hybrid"); ! 979: #endif /* ENABLE_HYBRID */ ! 980: } ! 981: EOS ! 982: | CFG_CONF_SOURCE CFG_LOCAL ! 983: { ! 984: #ifdef ENABLE_HYBRID ! 985: isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LOCAL; ! 986: #else /* ENABLE_HYBRID */ ! 987: yyerror("racoon not configured with --enable-hybrid"); ! 988: #endif /* ENABLE_HYBRID */ ! 989: } ! 990: EOS ! 991: | CFG_CONF_SOURCE CFG_RADIUS ! 992: { ! 993: #ifdef ENABLE_HYBRID ! 994: #ifdef HAVE_LIBRADIUS ! 995: isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_RADIUS; ! 996: #else /* HAVE_LIBRADIUS */ ! 997: yyerror("racoon not configured with --with-libradius"); ! 998: #endif /* HAVE_LIBRADIUS */ ! 999: #else /* ENABLE_HYBRID */ ! 1000: yyerror("racoon not configured with --enable-hybrid"); ! 1001: #endif /* ENABLE_HYBRID */ ! 1002: } ! 1003: EOS ! 1004: | CFG_CONF_SOURCE CFG_LDAP ! 1005: { ! 1006: #ifdef ENABLE_HYBRID ! 1007: #ifdef HAVE_LIBLDAP ! 1008: isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LDAP; ! 1009: #else /* HAVE_LIBLDAP */ ! 1010: yyerror("racoon not configured with --with-libldap"); ! 1011: #endif /* HAVE_LIBLDAP */ ! 1012: #else /* ENABLE_HYBRID */ ! 1013: yyerror("racoon not configured with --enable-hybrid"); ! 1014: #endif /* ENABLE_HYBRID */ ! 1015: } ! 1016: EOS ! 1017: | CFG_MOTD QUOTEDSTRING ! 1018: { ! 1019: #ifdef ENABLE_HYBRID ! 1020: strncpy(&isakmp_cfg_config.motd[0], $2->v, MAXPATHLEN); ! 1021: isakmp_cfg_config.motd[MAXPATHLEN] = '\0'; ! 1022: vfree($2); ! 1023: #else ! 1024: yyerror("racoon not configured with --enable-hybrid"); ! 1025: #endif ! 1026: } ! 1027: EOS ! 1028: ; ! 1029: ! 1030: addrdnslist ! 1031: : addrdns ! 1032: | addrdns COMMA addrdnslist ! 1033: ; ! 1034: addrdns ! 1035: : ADDRSTRING ! 1036: { ! 1037: #ifdef ENABLE_HYBRID ! 1038: struct isakmp_cfg_config *icc = &isakmp_cfg_config; ! 1039: ! 1040: if (icc->dns4_index > MAXNS) ! 1041: yyerror("No more than %d DNS", MAXNS); ! 1042: if (inet_pton(AF_INET, $1->v, ! 1043: &icc->dns4[icc->dns4_index++]) != 1) ! 1044: yyerror("bad IPv4 DNS address."); ! 1045: #else ! 1046: yyerror("racoon not configured with --enable-hybrid"); ! 1047: #endif ! 1048: } ! 1049: ; ! 1050: ! 1051: addrwinslist ! 1052: : addrwins ! 1053: | addrwins COMMA addrwinslist ! 1054: ; ! 1055: addrwins ! 1056: : ADDRSTRING ! 1057: { ! 1058: #ifdef ENABLE_HYBRID ! 1059: struct isakmp_cfg_config *icc = &isakmp_cfg_config; ! 1060: ! 1061: if (icc->nbns4_index > MAXWINS) ! 1062: yyerror("No more than %d WINS", MAXWINS); ! 1063: if (inet_pton(AF_INET, $1->v, ! 1064: &icc->nbns4[icc->nbns4_index++]) != 1) ! 1065: yyerror("bad IPv4 WINS address."); ! 1066: #else ! 1067: yyerror("racoon not configured with --enable-hybrid"); ! 1068: #endif ! 1069: } ! 1070: ; ! 1071: ! 1072: splitnetlist ! 1073: : splitnet ! 1074: | splitnetlist COMMA splitnet ! 1075: ; ! 1076: splitnet ! 1077: : ADDRSTRING PREFIX ! 1078: { ! 1079: #ifdef ENABLE_HYBRID ! 1080: struct isakmp_cfg_config *icc = &isakmp_cfg_config; ! 1081: struct unity_network network; ! 1082: memset(&network,0,sizeof(network)); ! 1083: ! 1084: if (inet_pton(AF_INET, $1->v, &network.addr4) != 1) ! 1085: yyerror("bad IPv4 SPLIT address."); ! 1086: ! 1087: /* Turn $2 (the prefix) into a subnet mask */ ! 1088: network.mask4.s_addr = ($2) ? htonl(~((1 << (32 - $2)) - 1)) : 0; ! 1089: ! 1090: /* add the network to our list */ ! 1091: if (splitnet_list_add(&icc->splitnet_list, &network,&icc->splitnet_count)) ! 1092: yyerror("Unable to allocate split network"); ! 1093: #else ! 1094: yyerror("racoon not configured with --enable-hybrid"); ! 1095: #endif ! 1096: } ! 1097: ; ! 1098: ! 1099: authgrouplist ! 1100: : authgroup ! 1101: | authgroup COMMA authgrouplist ! 1102: ; ! 1103: authgroup ! 1104: : QUOTEDSTRING ! 1105: { ! 1106: #ifdef ENABLE_HYBRID ! 1107: char * groupname = NULL; ! 1108: char ** grouplist = NULL; ! 1109: struct isakmp_cfg_config *icc = &isakmp_cfg_config; ! 1110: ! 1111: grouplist = racoon_realloc(icc->grouplist, ! 1112: sizeof(char**)*(icc->groupcount+1)); ! 1113: if (grouplist == NULL) { ! 1114: yyerror("unable to allocate auth group list"); ! 1115: return -1; ! 1116: } ! 1117: ! 1118: groupname = racoon_malloc($1->l+1); ! 1119: if (groupname == NULL) { ! 1120: yyerror("unable to allocate auth group name"); ! 1121: return -1; ! 1122: } ! 1123: ! 1124: memcpy(groupname,$1->v,$1->l); ! 1125: groupname[$1->l]=0; ! 1126: grouplist[icc->groupcount]=groupname; ! 1127: icc->grouplist = grouplist; ! 1128: icc->groupcount++; ! 1129: ! 1130: vfree($1); ! 1131: #else ! 1132: yyerror("racoon not configured with --enable-hybrid"); ! 1133: #endif ! 1134: } ! 1135: ; ! 1136: ! 1137: splitdnslist ! 1138: : splitdns ! 1139: | splitdns COMMA splitdnslist ! 1140: ; ! 1141: splitdns ! 1142: : QUOTEDSTRING ! 1143: { ! 1144: #ifdef ENABLE_HYBRID ! 1145: struct isakmp_cfg_config *icc = &isakmp_cfg_config; ! 1146: ! 1147: if (!icc->splitdns_len) ! 1148: { ! 1149: icc->splitdns_list = racoon_malloc($1->l); ! 1150: if(icc->splitdns_list == NULL) { ! 1151: yyerror("error allocating splitdns list buffer"); ! 1152: return -1; ! 1153: } ! 1154: memcpy(icc->splitdns_list,$1->v,$1->l); ! 1155: icc->splitdns_len = $1->l; ! 1156: } ! 1157: else ! 1158: { ! 1159: int len = icc->splitdns_len + $1->l + 1; ! 1160: icc->splitdns_list = racoon_realloc(icc->splitdns_list,len); ! 1161: if(icc->splitdns_list == NULL) { ! 1162: yyerror("error allocating splitdns list buffer"); ! 1163: return -1; ! 1164: } ! 1165: icc->splitdns_list[icc->splitdns_len] = ','; ! 1166: memcpy(icc->splitdns_list + icc->splitdns_len + 1, $1->v, $1->l); ! 1167: icc->splitdns_len = len; ! 1168: } ! 1169: vfree($1); ! 1170: #else ! 1171: yyerror("racoon not configured with --enable-hybrid"); ! 1172: #endif ! 1173: } ! 1174: ; ! 1175: ! 1176: ! 1177: /* timer */ ! 1178: timer_statement ! 1179: : RETRY BOC timer_stmts EOC ! 1180: ; ! 1181: timer_stmts ! 1182: : /* nothing */ ! 1183: | timer_stmts timer_stmt ! 1184: ; ! 1185: timer_stmt ! 1186: : RETRY_COUNTER NUMBER ! 1187: { ! 1188: lcconf->retry_counter = $2; ! 1189: } ! 1190: EOS ! 1191: | RETRY_INTERVAL NUMBER unittype_time ! 1192: { ! 1193: lcconf->retry_interval = $2 * $3; ! 1194: } ! 1195: EOS ! 1196: | RETRY_PERSEND NUMBER ! 1197: { ! 1198: lcconf->count_persend = $2; ! 1199: } ! 1200: EOS ! 1201: | RETRY_PHASE1 NUMBER unittype_time ! 1202: { ! 1203: lcconf->retry_checkph1 = $2 * $3; ! 1204: } ! 1205: EOS ! 1206: | RETRY_PHASE2 NUMBER unittype_time ! 1207: { ! 1208: lcconf->wait_ph2complete = $2 * $3; ! 1209: } ! 1210: EOS ! 1211: | NATT_KA NUMBER unittype_time ! 1212: { ! 1213: #ifdef ENABLE_NATT ! 1214: if (libipsec_opt & LIBIPSEC_OPT_NATT) ! 1215: lcconf->natt_ka_interval = $2 * $3; ! 1216: else ! 1217: yyerror("libipsec lacks NAT-T support"); ! 1218: #else ! 1219: yyerror("NAT-T support not compiled in."); ! 1220: #endif ! 1221: } ! 1222: EOS ! 1223: ; ! 1224: ! 1225: /* sainfo */ ! 1226: sainfo_statement ! 1227: : SAINFO ! 1228: { ! 1229: cur_sainfo = newsainfo(); ! 1230: if (cur_sainfo == NULL) { ! 1231: yyerror("failed to allocate sainfo"); ! 1232: return -1; ! 1233: } ! 1234: } ! 1235: sainfo_name sainfo_param BOC sainfo_specs ! 1236: { ! 1237: struct sainfo *check; ! 1238: ! 1239: /* default */ ! 1240: if (cur_sainfo->algs[algclass_ipsec_enc] == 0) { ! 1241: yyerror("no encryption algorithm at %s", ! 1242: sainfo2str(cur_sainfo)); ! 1243: return -1; ! 1244: } ! 1245: if (cur_sainfo->algs[algclass_ipsec_auth] == 0) { ! 1246: yyerror("no authentication algorithm at %s", ! 1247: sainfo2str(cur_sainfo)); ! 1248: return -1; ! 1249: } ! 1250: if (cur_sainfo->algs[algclass_ipsec_comp] == 0) { ! 1251: yyerror("no compression algorithm at %s", ! 1252: sainfo2str(cur_sainfo)); ! 1253: return -1; ! 1254: } ! 1255: ! 1256: /* duplicate check */ ! 1257: check = getsainfo(cur_sainfo->idsrc, ! 1258: cur_sainfo->iddst, ! 1259: cur_sainfo->id_i, ! 1260: NULL, ! 1261: cur_sainfo->remoteid); ! 1262: ! 1263: if (check && ((check->idsrc != SAINFO_ANONYMOUS) && ! 1264: (cur_sainfo->idsrc != SAINFO_ANONYMOUS))) { ! 1265: yyerror("duplicated sainfo: %s", ! 1266: sainfo2str(cur_sainfo)); ! 1267: return -1; ! 1268: } ! 1269: ! 1270: inssainfo(cur_sainfo); ! 1271: } ! 1272: EOC ! 1273: ; ! 1274: sainfo_name ! 1275: : ANONYMOUS ! 1276: { ! 1277: cur_sainfo->idsrc = SAINFO_ANONYMOUS; ! 1278: cur_sainfo->iddst = SAINFO_ANONYMOUS; ! 1279: } ! 1280: | ANONYMOUS CLIENTADDR ! 1281: { ! 1282: cur_sainfo->idsrc = SAINFO_ANONYMOUS; ! 1283: cur_sainfo->iddst = SAINFO_CLIENTADDR; ! 1284: } ! 1285: | ANONYMOUS sainfo_id ! 1286: { ! 1287: cur_sainfo->idsrc = SAINFO_ANONYMOUS; ! 1288: cur_sainfo->iddst = $2; ! 1289: } ! 1290: | sainfo_id ANONYMOUS ! 1291: { ! 1292: cur_sainfo->idsrc = $1; ! 1293: cur_sainfo->iddst = SAINFO_ANONYMOUS; ! 1294: } ! 1295: | sainfo_id CLIENTADDR ! 1296: { ! 1297: cur_sainfo->idsrc = $1; ! 1298: cur_sainfo->iddst = SAINFO_CLIENTADDR; ! 1299: } ! 1300: | sainfo_id sainfo_id ! 1301: { ! 1302: cur_sainfo->idsrc = $1; ! 1303: cur_sainfo->iddst = $2; ! 1304: } ! 1305: ; ! 1306: sainfo_id ! 1307: : IDENTIFIERTYPE ADDRSTRING prefix port ul_proto ! 1308: { ! 1309: char portbuf[10]; ! 1310: struct sockaddr *saddr; ! 1311: ! 1312: if (($5 == IPPROTO_ICMP || $5 == IPPROTO_ICMPV6) ! 1313: && ($4 != IPSEC_PORT_ANY || $4 != IPSEC_PORT_ANY)) { ! 1314: yyerror("port number must be \"any\"."); ! 1315: return -1; ! 1316: } ! 1317: ! 1318: snprintf(portbuf, sizeof(portbuf), "%lu", $4); ! 1319: saddr = str2saddr($2->v, portbuf); ! 1320: vfree($2); ! 1321: if (saddr == NULL) ! 1322: return -1; ! 1323: ! 1324: switch (saddr->sa_family) { ! 1325: case AF_INET: ! 1326: if ($5 == IPPROTO_ICMPV6) { ! 1327: yyerror("upper layer protocol mismatched.\n"); ! 1328: racoon_free(saddr); ! 1329: return -1; ! 1330: } ! 1331: $$ = ipsecdoi_sockaddr2id(saddr, ! 1332: $3 == ~0 ? (sizeof(struct in_addr) << 3): $3, ! 1333: $5); ! 1334: break; ! 1335: #ifdef INET6 ! 1336: case AF_INET6: ! 1337: if ($5 == IPPROTO_ICMP) { ! 1338: yyerror("upper layer protocol mismatched.\n"); ! 1339: racoon_free(saddr); ! 1340: return -1; ! 1341: } ! 1342: $$ = ipsecdoi_sockaddr2id(saddr, ! 1343: $3 == ~0 ? (sizeof(struct in6_addr) << 3): $3, ! 1344: $5); ! 1345: break; ! 1346: #endif ! 1347: default: ! 1348: yyerror("invalid family: %d", saddr->sa_family); ! 1349: $$ = NULL; ! 1350: break; ! 1351: } ! 1352: racoon_free(saddr); ! 1353: if ($$ == NULL) ! 1354: return -1; ! 1355: } ! 1356: | IDENTIFIERTYPE ADDRSTRING ADDRRANGE prefix port ul_proto ! 1357: { ! 1358: char portbuf[10]; ! 1359: struct sockaddr *laddr = NULL, *haddr = NULL; ! 1360: char *cur = NULL; ! 1361: ! 1362: if (($6 == IPPROTO_ICMP || $6 == IPPROTO_ICMPV6) ! 1363: && ($5 != IPSEC_PORT_ANY || $5 != IPSEC_PORT_ANY)) { ! 1364: yyerror("port number must be \"any\"."); ! 1365: return -1; ! 1366: } ! 1367: ! 1368: snprintf(portbuf, sizeof(portbuf), "%lu", $5); ! 1369: ! 1370: laddr = str2saddr($2->v, portbuf); ! 1371: if (laddr == NULL) { ! 1372: return -1; ! 1373: } ! 1374: vfree($2); ! 1375: haddr = str2saddr($3->v, portbuf); ! 1376: if (haddr == NULL) { ! 1377: racoon_free(laddr); ! 1378: return -1; ! 1379: } ! 1380: vfree($3); ! 1381: ! 1382: switch (laddr->sa_family) { ! 1383: case AF_INET: ! 1384: if ($6 == IPPROTO_ICMPV6) { ! 1385: yyerror("upper layer protocol mismatched.\n"); ! 1386: if (laddr) ! 1387: racoon_free(laddr); ! 1388: if (haddr) ! 1389: racoon_free(haddr); ! 1390: return -1; ! 1391: } ! 1392: $$ = ipsecdoi_sockrange2id(laddr, haddr, ! 1393: $6); ! 1394: break; ! 1395: #ifdef INET6 ! 1396: case AF_INET6: ! 1397: if ($6 == IPPROTO_ICMP) { ! 1398: yyerror("upper layer protocol mismatched.\n"); ! 1399: if (laddr) ! 1400: racoon_free(laddr); ! 1401: if (haddr) ! 1402: racoon_free(haddr); ! 1403: return -1; ! 1404: } ! 1405: $$ = ipsecdoi_sockrange2id(laddr, haddr, ! 1406: $6); ! 1407: break; ! 1408: #endif ! 1409: default: ! 1410: yyerror("invalid family: %d", laddr->sa_family); ! 1411: $$ = NULL; ! 1412: break; ! 1413: } ! 1414: if (laddr) ! 1415: racoon_free(laddr); ! 1416: if (haddr) ! 1417: racoon_free(haddr); ! 1418: if ($$ == NULL) ! 1419: return -1; ! 1420: } ! 1421: | IDENTIFIERTYPE QUOTEDSTRING ! 1422: { ! 1423: struct ipsecdoi_id_b *id_b; ! 1424: ! 1425: if ($1 == IDTYPE_ASN1DN) { ! 1426: yyerror("id type forbidden: %d", $1); ! 1427: $$ = NULL; ! 1428: return -1; ! 1429: } ! 1430: ! 1431: $2->l--; ! 1432: ! 1433: $$ = vmalloc(sizeof(*id_b) + $2->l); ! 1434: if ($$ == NULL) { ! 1435: yyerror("failed to allocate identifier"); ! 1436: return -1; ! 1437: } ! 1438: ! 1439: id_b = (struct ipsecdoi_id_b *)$$->v; ! 1440: id_b->type = idtype2doi($1); ! 1441: ! 1442: id_b->proto_id = 0; ! 1443: id_b->port = 0; ! 1444: ! 1445: memcpy($$->v + sizeof(*id_b), $2->v, $2->l); ! 1446: } ! 1447: ; ! 1448: sainfo_param ! 1449: : /* nothing */ ! 1450: { ! 1451: cur_sainfo->id_i = NULL; ! 1452: } ! 1453: | FROM IDENTIFIERTYPE identifierstring ! 1454: { ! 1455: struct ipsecdoi_id_b *id_b; ! 1456: vchar_t *idv; ! 1457: ! 1458: if (set_identifier(&idv, $2, $3) != 0) { ! 1459: yyerror("failed to set identifer.\n"); ! 1460: return -1; ! 1461: } ! 1462: cur_sainfo->id_i = vmalloc(sizeof(*id_b) + idv->l); ! 1463: if (cur_sainfo->id_i == NULL) { ! 1464: yyerror("failed to allocate identifier"); ! 1465: return -1; ! 1466: } ! 1467: ! 1468: id_b = (struct ipsecdoi_id_b *)cur_sainfo->id_i->v; ! 1469: id_b->type = idtype2doi($2); ! 1470: ! 1471: id_b->proto_id = 0; ! 1472: id_b->port = 0; ! 1473: ! 1474: memcpy(cur_sainfo->id_i->v + sizeof(*id_b), ! 1475: idv->v, idv->l); ! 1476: vfree(idv); ! 1477: } ! 1478: | GROUP QUOTEDSTRING ! 1479: { ! 1480: #ifdef ENABLE_HYBRID ! 1481: if ((cur_sainfo->group = vdup($2)) == NULL) { ! 1482: yyerror("failed to set sainfo xauth group.\n"); ! 1483: return -1; ! 1484: } ! 1485: #else ! 1486: yyerror("racoon not configured with --enable-hybrid"); ! 1487: return -1; ! 1488: #endif ! 1489: } ! 1490: ; ! 1491: sainfo_specs ! 1492: : /* nothing */ ! 1493: | sainfo_specs sainfo_spec ! 1494: ; ! 1495: sainfo_spec ! 1496: : PFS_GROUP dh_group_num ! 1497: { ! 1498: cur_sainfo->pfs_group = $2; ! 1499: } ! 1500: EOS ! 1501: | REMOTEID NUMBER ! 1502: { ! 1503: cur_sainfo->remoteid = $2; ! 1504: } ! 1505: EOS ! 1506: | LIFETIME LIFETYPE_TIME NUMBER unittype_time ! 1507: { ! 1508: cur_sainfo->lifetime = $3 * $4; ! 1509: } ! 1510: EOS ! 1511: | LIFETIME LIFETYPE_BYTE NUMBER unittype_byte ! 1512: { ! 1513: #if 1 ! 1514: yyerror("byte lifetime support is deprecated"); ! 1515: return -1; ! 1516: #else ! 1517: cur_sainfo->lifebyte = fix_lifebyte($3 * $4); ! 1518: if (cur_sainfo->lifebyte == 0) ! 1519: return -1; ! 1520: #endif ! 1521: } ! 1522: EOS ! 1523: | ALGORITHM_CLASS { ! 1524: cur_algclass = $1; ! 1525: } ! 1526: algorithms EOS ! 1527: ; ! 1528: ! 1529: algorithms ! 1530: : algorithm ! 1531: { ! 1532: inssainfoalg(&cur_sainfo->algs[cur_algclass], $1); ! 1533: } ! 1534: | algorithm ! 1535: { ! 1536: inssainfoalg(&cur_sainfo->algs[cur_algclass], $1); ! 1537: } ! 1538: COMMA algorithms ! 1539: ; ! 1540: algorithm ! 1541: : ALGORITHMTYPE keylength ! 1542: { ! 1543: int defklen; ! 1544: ! 1545: $$ = newsainfoalg(); ! 1546: if ($$ == NULL) { ! 1547: yyerror("failed to get algorithm allocation"); ! 1548: return -1; ! 1549: } ! 1550: ! 1551: $$->alg = algtype2doi(cur_algclass, $1); ! 1552: if ($$->alg == -1) { ! 1553: yyerror("algorithm mismatched"); ! 1554: racoon_free($$); ! 1555: $$ = NULL; ! 1556: return -1; ! 1557: } ! 1558: ! 1559: defklen = default_keylen(cur_algclass, $1); ! 1560: if (defklen == 0) { ! 1561: if ($2) { ! 1562: yyerror("keylen not allowed"); ! 1563: racoon_free($$); ! 1564: $$ = NULL; ! 1565: return -1; ! 1566: } ! 1567: } else { ! 1568: if ($2 && check_keylen(cur_algclass, $1, $2) < 0) { ! 1569: yyerror("invalid keylen %d", $2); ! 1570: racoon_free($$); ! 1571: $$ = NULL; ! 1572: return -1; ! 1573: } ! 1574: } ! 1575: ! 1576: if ($2) ! 1577: $$->encklen = $2; ! 1578: else ! 1579: $$->encklen = defklen; ! 1580: ! 1581: /* check if it's supported algorithm by kernel */ ! 1582: if (!(cur_algclass == algclass_ipsec_auth && $1 == algtype_non_auth) ! 1583: && pk_checkalg(cur_algclass, $1, $$->encklen)) { ! 1584: int a = algclass2doi(cur_algclass); ! 1585: int b = algtype2doi(cur_algclass, $1); ! 1586: if (a == IPSECDOI_ATTR_AUTH) ! 1587: a = IPSECDOI_PROTO_IPSEC_AH; ! 1588: yyerror("algorithm %s not supported by the kernel (missing module?)", ! 1589: s_ipsecdoi_trns(a, b)); ! 1590: racoon_free($$); ! 1591: $$ = NULL; ! 1592: return -1; ! 1593: } ! 1594: } ! 1595: ; ! 1596: prefix ! 1597: : /* nothing */ { $$ = ~0; } ! 1598: | PREFIX { $$ = $1; } ! 1599: ; ! 1600: port ! 1601: : /* nothing */ { $$ = IPSEC_PORT_ANY; } ! 1602: | PORT { $$ = $1; } ! 1603: | PORTANY { $$ = IPSEC_PORT_ANY; } ! 1604: ; ! 1605: ul_proto ! 1606: : NUMBER { $$ = $1; } ! 1607: | UL_PROTO { $$ = $1; } ! 1608: | ANY { $$ = IPSEC_ULPROTO_ANY; } ! 1609: ; ! 1610: keylength ! 1611: : /* nothing */ { $$ = 0; } ! 1612: | NUMBER { $$ = $1; } ! 1613: ; ! 1614: ! 1615: /* remote */ ! 1616: remote_statement ! 1617: : REMOTE QUOTEDSTRING INHERIT QUOTEDSTRING ! 1618: { ! 1619: struct remoteconf *from, *new; ! 1620: ! 1621: if (getrmconf_by_name($2->v) != NULL) { ! 1622: yyerror("named remoteconf \"%s\" already exists."); ! 1623: return -1; ! 1624: } ! 1625: ! 1626: from = getrmconf_by_name($4->v); ! 1627: if (from == NULL) { ! 1628: yyerror("named parent remoteconf \"%s\" does not exist.", ! 1629: $4->v); ! 1630: return -1; ! 1631: } ! 1632: ! 1633: new = duprmconf_shallow(from); ! 1634: if (new == NULL) { ! 1635: yyerror("failed to duplicate remoteconf from \"%s\".", ! 1636: $4->v); ! 1637: return -1; ! 1638: } ! 1639: ! 1640: new->name = racoon_strdup($2->v); ! 1641: cur_rmconf = new; ! 1642: ! 1643: vfree($2); ! 1644: vfree($4); ! 1645: } ! 1646: remote_specs_block ! 1647: | REMOTE QUOTEDSTRING ! 1648: { ! 1649: struct remoteconf *new; ! 1650: ! 1651: if (getrmconf_by_name($2->v) != NULL) { ! 1652: yyerror("Named remoteconf \"%s\" already exists."); ! 1653: return -1; ! 1654: } ! 1655: ! 1656: new = newrmconf(); ! 1657: if (new == NULL) { ! 1658: yyerror("failed to get new remoteconf."); ! 1659: return -1; ! 1660: } ! 1661: new->name = racoon_strdup($2->v); ! 1662: cur_rmconf = new; ! 1663: ! 1664: vfree($2); ! 1665: } ! 1666: remote_specs_block ! 1667: | REMOTE remote_index INHERIT remote_index ! 1668: { ! 1669: struct remoteconf *from, *new; ! 1670: ! 1671: from = getrmconf($4, GETRMCONF_F_NO_ANONYMOUS); ! 1672: if (from == NULL) { ! 1673: yyerror("failed to get remoteconf for %s.", ! 1674: saddr2str($4)); ! 1675: return -1; ! 1676: } ! 1677: ! 1678: new = duprmconf_shallow(from); ! 1679: if (new == NULL) { ! 1680: yyerror("failed to duplicate remoteconf from %s.", ! 1681: saddr2str($4)); ! 1682: return -1; ! 1683: } ! 1684: ! 1685: racoon_free($4); ! 1686: new->remote = $2; ! 1687: cur_rmconf = new; ! 1688: } ! 1689: remote_specs_block ! 1690: | REMOTE remote_index ! 1691: { ! 1692: struct remoteconf *new; ! 1693: ! 1694: new = newrmconf(); ! 1695: if (new == NULL) { ! 1696: yyerror("failed to get new remoteconf."); ! 1697: return -1; ! 1698: } ! 1699: ! 1700: new->remote = $2; ! 1701: cur_rmconf = new; ! 1702: } ! 1703: remote_specs_block ! 1704: ; ! 1705: ! 1706: remote_specs_block ! 1707: : BOC remote_specs EOC ! 1708: { ! 1709: /* check a exchange mode */ ! 1710: if (cur_rmconf->etypes == NULL) { ! 1711: yyerror("no exchange mode specified.\n"); ! 1712: return -1; ! 1713: } ! 1714: ! 1715: if (cur_rmconf->idvtype == IDTYPE_UNDEFINED) ! 1716: cur_rmconf->idvtype = IDTYPE_ADDRESS; ! 1717: ! 1718: if (cur_rmconf->idvtype == IDTYPE_ASN1DN) { ! 1719: if (cur_rmconf->mycertfile) { ! 1720: if (cur_rmconf->idv) ! 1721: yywarn("Both CERT and ASN1 ID " ! 1722: "are set. Hope this is OK.\n"); ! 1723: /* TODO: Preparse the DN here */ ! 1724: } else if (cur_rmconf->idv) { ! 1725: /* OK, using asn1dn without X.509. */ ! 1726: } else { ! 1727: yyerror("ASN1 ID not specified " ! 1728: "and no CERT defined!\n"); ! 1729: return -1; ! 1730: } ! 1731: } ! 1732: ! 1733: if (duprmconf_finish(cur_rmconf)) ! 1734: return -1; ! 1735: ! 1736: #if 0 ! 1737: /* this pointer copy will never happen, because duprmconf_shallow ! 1738: * already copied all pointers. ! 1739: */ ! 1740: if (cur_rmconf->spspec == NULL && ! 1741: cur_rmconf->inherited_from != NULL) { ! 1742: cur_rmconf->spspec = cur_rmconf->inherited_from->spspec; ! 1743: } ! 1744: #endif ! 1745: if (set_isakmp_proposal(cur_rmconf) != 0) ! 1746: return -1; ! 1747: ! 1748: /* DH group settting if aggressive mode is there. */ ! 1749: if (check_etypeok(cur_rmconf, (void*) ISAKMP_ETYPE_AGG)) { ! 1750: struct isakmpsa *p; ! 1751: int b = 0; ! 1752: ! 1753: /* DH group */ ! 1754: for (p = cur_rmconf->proposal; p; p = p->next) { ! 1755: if (b == 0 || (b && b == p->dh_group)) { ! 1756: b = p->dh_group; ! 1757: continue; ! 1758: } ! 1759: yyerror("DH group must be equal " ! 1760: "in all proposals " ! 1761: "when aggressive mode is " ! 1762: "used.\n"); ! 1763: return -1; ! 1764: } ! 1765: cur_rmconf->dh_group = b; ! 1766: ! 1767: if (cur_rmconf->dh_group == 0) { ! 1768: yyerror("DH group must be set in the proposal.\n"); ! 1769: return -1; ! 1770: } ! 1771: ! 1772: /* DH group settting if PFS is required. */ ! 1773: if (oakley_setdhgroup(cur_rmconf->dh_group, ! 1774: &cur_rmconf->dhgrp) < 0) { ! 1775: yyerror("failed to set DH value.\n"); ! 1776: return -1; ! 1777: } ! 1778: } ! 1779: ! 1780: insrmconf(cur_rmconf); ! 1781: } ! 1782: ; ! 1783: remote_index ! 1784: : ANONYMOUS ike_port ! 1785: { ! 1786: $$ = newsaddr(sizeof(struct sockaddr)); ! 1787: $$->sa_family = AF_UNSPEC; ! 1788: ((struct sockaddr_in *)$$)->sin_port = htons($2); ! 1789: } ! 1790: | ike_addrinfo_port ! 1791: { ! 1792: $$ = $1; ! 1793: if ($$ == NULL) { ! 1794: yyerror("failed to allocate sockaddr"); ! 1795: return -1; ! 1796: } ! 1797: } ! 1798: ; ! 1799: remote_specs ! 1800: : /* nothing */ ! 1801: | remote_specs remote_spec ! 1802: ; ! 1803: remote_spec ! 1804: : REMOTE_ADDRESS ike_addrinfo_port ! 1805: { ! 1806: if (cur_rmconf->remote != NULL) { ! 1807: yyerror("remote_address already specified"); ! 1808: return -1; ! 1809: } ! 1810: cur_rmconf->remote = $2; ! 1811: } ! 1812: EOS ! 1813: | EXCHANGE_MODE ! 1814: { ! 1815: cur_rmconf->etypes = NULL; ! 1816: } ! 1817: exchange_types EOS ! 1818: | DOI DOITYPE { cur_rmconf->doitype = $2; } EOS ! 1819: | SITUATION SITUATIONTYPE { cur_rmconf->sittype = $2; } EOS ! 1820: | CERTIFICATE_TYPE cert_spec ! 1821: | PEERS_CERTFILE QUOTEDSTRING ! 1822: { ! 1823: yywarn("This directive without certtype will be removed!\n"); ! 1824: yywarn("Please use 'peers_certfile x509 \"%s\";' instead\n", $2->v); ! 1825: ! 1826: if (cur_rmconf->peerscert != NULL) { ! 1827: yyerror("peers_certfile already defined\n"); ! 1828: return -1; ! 1829: } ! 1830: ! 1831: if (load_x509($2->v, &cur_rmconf->peerscertfile, ! 1832: &cur_rmconf->peerscert)) { ! 1833: yyerror("failed to load certificate \"%s\"\n", ! 1834: $2->v); ! 1835: return -1; ! 1836: } ! 1837: ! 1838: vfree($2); ! 1839: } ! 1840: EOS ! 1841: | PEERS_CERTFILE CERT_X509 QUOTEDSTRING ! 1842: { ! 1843: if (cur_rmconf->peerscert != NULL) { ! 1844: yyerror("peers_certfile already defined\n"); ! 1845: return -1; ! 1846: } ! 1847: ! 1848: if (load_x509($3->v, &cur_rmconf->peerscertfile, ! 1849: &cur_rmconf->peerscert)) { ! 1850: yyerror("failed to load certificate \"%s\"\n", ! 1851: $3->v); ! 1852: return -1; ! 1853: } ! 1854: ! 1855: vfree($3); ! 1856: } ! 1857: EOS ! 1858: | PEERS_CERTFILE CERT_PLAINRSA QUOTEDSTRING ! 1859: { ! 1860: char path[MAXPATHLEN]; ! 1861: int ret = 0; ! 1862: ! 1863: if (cur_rmconf->peerscert != NULL) { ! 1864: yyerror("peers_certfile already defined\n"); ! 1865: return -1; ! 1866: } ! 1867: ! 1868: cur_rmconf->peerscert = vmalloc(1); ! 1869: if (cur_rmconf->peerscert == NULL) { ! 1870: yyerror("failed to allocate peerscert"); ! 1871: return -1; ! 1872: } ! 1873: cur_rmconf->peerscert->v[0] = ISAKMP_CERT_PLAINRSA; ! 1874: ! 1875: getpathname(path, sizeof(path), ! 1876: LC_PATHTYPE_CERT, $3->v); ! 1877: if (rsa_parse_file(cur_rmconf->rsa_public, path, ! 1878: RSA_TYPE_PUBLIC)) { ! 1879: yyerror("Couldn't parse keyfile.\n", path); ! 1880: return -1; ! 1881: } ! 1882: plog(LLV_DEBUG, LOCATION, NULL, ! 1883: "Public PlainRSA keyfile parsed: %s\n", path); ! 1884: ! 1885: vfree($3); ! 1886: } ! 1887: EOS ! 1888: | PEERS_CERTFILE DNSSEC ! 1889: { ! 1890: if (cur_rmconf->peerscert != NULL) { ! 1891: yyerror("peers_certfile already defined\n"); ! 1892: return -1; ! 1893: } ! 1894: cur_rmconf->peerscert = vmalloc(1); ! 1895: if (cur_rmconf->peerscert == NULL) { ! 1896: yyerror("failed to allocate peerscert"); ! 1897: return -1; ! 1898: } ! 1899: cur_rmconf->peerscert->v[0] = ISAKMP_CERT_DNS; ! 1900: } ! 1901: EOS ! 1902: | CA_TYPE CERT_X509 QUOTEDSTRING ! 1903: { ! 1904: if (cur_rmconf->cacert != NULL) { ! 1905: yyerror("ca_type already defined\n"); ! 1906: return -1; ! 1907: } ! 1908: ! 1909: if (load_x509($3->v, &cur_rmconf->cacertfile, ! 1910: &cur_rmconf->cacert)) { ! 1911: yyerror("failed to load certificate \"%s\"\n", ! 1912: $3->v); ! 1913: return -1; ! 1914: } ! 1915: ! 1916: vfree($3); ! 1917: } ! 1918: EOS ! 1919: | VERIFY_CERT SWITCH { cur_rmconf->verify_cert = $2; } EOS ! 1920: | SEND_CERT SWITCH { cur_rmconf->send_cert = $2; } EOS ! 1921: | SEND_CR SWITCH { cur_rmconf->send_cr = $2; } EOS ! 1922: | MATCH_EMPTY_CR SWITCH { cur_rmconf->match_empty_cr = $2; } EOS ! 1923: | MY_IDENTIFIER IDENTIFIERTYPE identifierstring ! 1924: { ! 1925: if (set_identifier(&cur_rmconf->idv, $2, $3) != 0) { ! 1926: yyerror("failed to set identifer.\n"); ! 1927: return -1; ! 1928: } ! 1929: cur_rmconf->idvtype = $2; ! 1930: } ! 1931: EOS ! 1932: | MY_IDENTIFIER IDENTIFIERTYPE IDENTIFIERQUAL identifierstring ! 1933: { ! 1934: if (set_identifier_qual(&cur_rmconf->idv, $2, $4, $3) != 0) { ! 1935: yyerror("failed to set identifer.\n"); ! 1936: return -1; ! 1937: } ! 1938: cur_rmconf->idvtype = $2; ! 1939: } ! 1940: EOS ! 1941: | XAUTH_LOGIN identifierstring ! 1942: { ! 1943: #ifdef ENABLE_HYBRID ! 1944: /* formerly identifier type login */ ! 1945: if (xauth_rmconf_used(&cur_rmconf->xauth) == -1) { ! 1946: yyerror("failed to allocate xauth state\n"); ! 1947: return -1; ! 1948: } ! 1949: if ((cur_rmconf->xauth->login = vdup($2)) == NULL) { ! 1950: yyerror("failed to set identifer.\n"); ! 1951: return -1; ! 1952: } ! 1953: #else ! 1954: yyerror("racoon not configured with --enable-hybrid"); ! 1955: #endif ! 1956: } ! 1957: EOS ! 1958: | PEERS_IDENTIFIER IDENTIFIERTYPE identifierstring ! 1959: { ! 1960: struct idspec *id; ! 1961: id = newidspec(); ! 1962: if (id == NULL) { ! 1963: yyerror("failed to allocate idspec"); ! 1964: return -1; ! 1965: } ! 1966: if (set_identifier(&id->id, $2, $3) != 0) { ! 1967: yyerror("failed to set identifer.\n"); ! 1968: racoon_free(id); ! 1969: return -1; ! 1970: } ! 1971: id->idtype = $2; ! 1972: genlist_append (cur_rmconf->idvl_p, id); ! 1973: } ! 1974: EOS ! 1975: | PEERS_IDENTIFIER IDENTIFIERTYPE IDENTIFIERQUAL identifierstring ! 1976: { ! 1977: struct idspec *id; ! 1978: id = newidspec(); ! 1979: if (id == NULL) { ! 1980: yyerror("failed to allocate idspec"); ! 1981: return -1; ! 1982: } ! 1983: if (set_identifier_qual(&id->id, $2, $4, $3) != 0) { ! 1984: yyerror("failed to set identifer.\n"); ! 1985: racoon_free(id); ! 1986: return -1; ! 1987: } ! 1988: id->idtype = $2; ! 1989: genlist_append (cur_rmconf->idvl_p, id); ! 1990: } ! 1991: EOS ! 1992: | VERIFY_IDENTIFIER SWITCH { cur_rmconf->verify_identifier = $2; } EOS ! 1993: | NONCE_SIZE NUMBER { cur_rmconf->nonce_size = $2; } EOS ! 1994: | DH_GROUP ! 1995: { ! 1996: yyerror("dh_group cannot be defined here."); ! 1997: return -1; ! 1998: } ! 1999: dh_group_num EOS ! 2000: | PASSIVE SWITCH { cur_rmconf->passive = $2; } EOS ! 2001: | IKE_FRAG SWITCH { cur_rmconf->ike_frag = $2; } EOS ! 2002: | IKE_FRAG REMOTE_FORCE_LEVEL { cur_rmconf->ike_frag = ISAKMP_FRAG_FORCE; } EOS ! 2003: | ESP_FRAG NUMBER { ! 2004: #ifdef SADB_X_EXT_NAT_T_FRAG ! 2005: if (libipsec_opt & LIBIPSEC_OPT_FRAG) ! 2006: cur_rmconf->esp_frag = $2; ! 2007: else ! 2008: yywarn("libipsec lacks IKE frag support"); ! 2009: #else ! 2010: yywarn("Your kernel does not support esp_frag"); ! 2011: #endif ! 2012: } EOS ! 2013: | SCRIPT QUOTEDSTRING PHASE1_UP { ! 2014: if (cur_rmconf->script[SCRIPT_PHASE1_UP] != NULL) ! 2015: vfree(cur_rmconf->script[SCRIPT_PHASE1_UP]); ! 2016: ! 2017: cur_rmconf->script[SCRIPT_PHASE1_UP] = ! 2018: script_path_add(vdup($2)); ! 2019: } EOS ! 2020: | SCRIPT QUOTEDSTRING PHASE1_DOWN { ! 2021: if (cur_rmconf->script[SCRIPT_PHASE1_DOWN] != NULL) ! 2022: vfree(cur_rmconf->script[SCRIPT_PHASE1_DOWN]); ! 2023: ! 2024: cur_rmconf->script[SCRIPT_PHASE1_DOWN] = ! 2025: script_path_add(vdup($2)); ! 2026: } EOS ! 2027: | SCRIPT QUOTEDSTRING PHASE1_DEAD { ! 2028: if (cur_rmconf->script[SCRIPT_PHASE1_DEAD] != NULL) ! 2029: vfree(cur_rmconf->script[SCRIPT_PHASE1_DEAD]); ! 2030: ! 2031: cur_rmconf->script[SCRIPT_PHASE1_DEAD] = ! 2032: script_path_add(vdup($2)); ! 2033: } EOS ! 2034: | MODE_CFG SWITCH { cur_rmconf->mode_cfg = $2; } EOS ! 2035: | WEAK_PHASE1_CHECK SWITCH { ! 2036: cur_rmconf->weak_phase1_check = $2; ! 2037: } EOS ! 2038: | GENERATE_POLICY SWITCH { cur_rmconf->gen_policy = $2; } EOS ! 2039: | GENERATE_POLICY GENERATE_LEVEL { cur_rmconf->gen_policy = $2; } EOS ! 2040: | SUPPORT_PROXY SWITCH { cur_rmconf->support_proxy = $2; } EOS ! 2041: | INITIAL_CONTACT SWITCH { cur_rmconf->ini_contact = $2; } EOS ! 2042: | NAT_TRAVERSAL SWITCH ! 2043: { ! 2044: #ifdef ENABLE_NATT ! 2045: if (libipsec_opt & LIBIPSEC_OPT_NATT) ! 2046: cur_rmconf->nat_traversal = $2; ! 2047: else ! 2048: yyerror("libipsec lacks NAT-T support"); ! 2049: #else ! 2050: yyerror("NAT-T support not compiled in."); ! 2051: #endif ! 2052: } EOS ! 2053: | NAT_TRAVERSAL REMOTE_FORCE_LEVEL ! 2054: { ! 2055: #ifdef ENABLE_NATT ! 2056: if (libipsec_opt & LIBIPSEC_OPT_NATT) ! 2057: cur_rmconf->nat_traversal = NATT_FORCE; ! 2058: else ! 2059: yyerror("libipsec lacks NAT-T support"); ! 2060: #else ! 2061: yyerror("NAT-T support not compiled in."); ! 2062: #endif ! 2063: } EOS ! 2064: | DPD SWITCH ! 2065: { ! 2066: #ifdef ENABLE_DPD ! 2067: cur_rmconf->dpd = $2; ! 2068: #else ! 2069: yyerror("DPD support not compiled in."); ! 2070: #endif ! 2071: } EOS ! 2072: | DPD_DELAY NUMBER ! 2073: { ! 2074: #ifdef ENABLE_DPD ! 2075: cur_rmconf->dpd_interval = $2; ! 2076: #else ! 2077: yyerror("DPD support not compiled in."); ! 2078: #endif ! 2079: } ! 2080: EOS ! 2081: | DPD_RETRY NUMBER ! 2082: { ! 2083: #ifdef ENABLE_DPD ! 2084: cur_rmconf->dpd_retry = $2; ! 2085: #else ! 2086: yyerror("DPD support not compiled in."); ! 2087: #endif ! 2088: } ! 2089: EOS ! 2090: | DPD_MAXFAIL NUMBER ! 2091: { ! 2092: #ifdef ENABLE_DPD ! 2093: cur_rmconf->dpd_maxfails = $2; ! 2094: #else ! 2095: yyerror("DPD support not compiled in."); ! 2096: #endif ! 2097: } ! 2098: EOS ! 2099: | REKEY SWITCH { cur_rmconf->rekey = $2; } EOS ! 2100: | REKEY REMOTE_FORCE_LEVEL { cur_rmconf->rekey = REKEY_FORCE; } EOS ! 2101: | PH1ID NUMBER ! 2102: { ! 2103: cur_rmconf->ph1id = $2; ! 2104: } ! 2105: EOS ! 2106: | LIFETIME LIFETYPE_TIME NUMBER unittype_time ! 2107: { ! 2108: cur_rmconf->lifetime = $3 * $4; ! 2109: } ! 2110: EOS ! 2111: | PROPOSAL_CHECK PROPOSAL_CHECK_LEVEL { cur_rmconf->pcheck_level = $2; } EOS ! 2112: | LIFETIME LIFETYPE_BYTE NUMBER unittype_byte ! 2113: { ! 2114: #if 1 ! 2115: yyerror("byte lifetime support is deprecated in Phase1"); ! 2116: return -1; ! 2117: #else ! 2118: yywarn("the lifetime of bytes in phase 1 " ! 2119: "will be ignored at the moment."); ! 2120: cur_rmconf->lifebyte = fix_lifebyte($3 * $4); ! 2121: if (cur_rmconf->lifebyte == 0) ! 2122: return -1; ! 2123: #endif ! 2124: } ! 2125: EOS ! 2126: | PROPOSAL ! 2127: { ! 2128: struct secprotospec *spspec; ! 2129: ! 2130: spspec = newspspec(); ! 2131: if (spspec == NULL) ! 2132: return -1; ! 2133: insspspec(cur_rmconf, spspec); ! 2134: } ! 2135: BOC isakmpproposal_specs EOC ! 2136: ; ! 2137: exchange_types ! 2138: : /* nothing */ ! 2139: | exchange_types EXCHANGETYPE ! 2140: { ! 2141: struct etypes *new; ! 2142: new = racoon_malloc(sizeof(struct etypes)); ! 2143: if (new == NULL) { ! 2144: yyerror("failed to allocate etypes"); ! 2145: return -1; ! 2146: } ! 2147: new->type = $2; ! 2148: new->next = NULL; ! 2149: if (cur_rmconf->etypes == NULL) ! 2150: cur_rmconf->etypes = new; ! 2151: else { ! 2152: struct etypes *p; ! 2153: for (p = cur_rmconf->etypes; ! 2154: p->next != NULL; ! 2155: p = p->next) ! 2156: ; ! 2157: p->next = new; ! 2158: } ! 2159: } ! 2160: ; ! 2161: cert_spec ! 2162: : CERT_X509 QUOTEDSTRING QUOTEDSTRING ! 2163: { ! 2164: if (cur_rmconf->mycert != NULL) { ! 2165: yyerror("certificate_type already defined\n"); ! 2166: return -1; ! 2167: } ! 2168: ! 2169: if (load_x509($2->v, &cur_rmconf->mycertfile, ! 2170: &cur_rmconf->mycert)) { ! 2171: yyerror("failed to load certificate \"%s\"\n", ! 2172: $2->v); ! 2173: return -1; ! 2174: } ! 2175: ! 2176: cur_rmconf->myprivfile = racoon_strdup($3->v); ! 2177: STRDUP_FATAL(cur_rmconf->myprivfile); ! 2178: ! 2179: vfree($2); ! 2180: vfree($3); ! 2181: } ! 2182: EOS ! 2183: | CERT_PLAINRSA QUOTEDSTRING ! 2184: { ! 2185: char path[MAXPATHLEN]; ! 2186: int ret = 0; ! 2187: ! 2188: if (cur_rmconf->mycert != NULL) { ! 2189: yyerror("certificate_type already defined\n"); ! 2190: return -1; ! 2191: } ! 2192: ! 2193: cur_rmconf->mycert = vmalloc(1); ! 2194: if (cur_rmconf->mycert == NULL) { ! 2195: yyerror("failed to allocate mycert"); ! 2196: return -1; ! 2197: } ! 2198: cur_rmconf->mycert->v[0] = ISAKMP_CERT_PLAINRSA; ! 2199: ! 2200: getpathname(path, sizeof(path), ! 2201: LC_PATHTYPE_CERT, $2->v); ! 2202: cur_rmconf->send_cr = FALSE; ! 2203: cur_rmconf->send_cert = FALSE; ! 2204: cur_rmconf->verify_cert = FALSE; ! 2205: if (rsa_parse_file(cur_rmconf->rsa_private, path, ! 2206: RSA_TYPE_PRIVATE)) { ! 2207: yyerror("Couldn't parse keyfile.\n", path); ! 2208: return -1; ! 2209: } ! 2210: plog(LLV_DEBUG, LOCATION, NULL, ! 2211: "Private PlainRSA keyfile parsed: %s\n", path); ! 2212: vfree($2); ! 2213: } ! 2214: EOS ! 2215: ; ! 2216: dh_group_num ! 2217: : ALGORITHMTYPE ! 2218: { ! 2219: $$ = algtype2doi(algclass_isakmp_dh, $1); ! 2220: if ($$ == -1) { ! 2221: yyerror("must be DH group"); ! 2222: return -1; ! 2223: } ! 2224: } ! 2225: | NUMBER ! 2226: { ! 2227: if (ARRAYLEN(num2dhgroup) > $1 && num2dhgroup[$1] != 0) { ! 2228: $$ = num2dhgroup[$1]; ! 2229: } else { ! 2230: yyerror("must be DH group"); ! 2231: $$ = 0; ! 2232: return -1; ! 2233: } ! 2234: } ! 2235: ; ! 2236: identifierstring ! 2237: : /* nothing */ { $$ = NULL; } ! 2238: | ADDRSTRING { $$ = $1; } ! 2239: | QUOTEDSTRING { $$ = $1; } ! 2240: ; ! 2241: isakmpproposal_specs ! 2242: : /* nothing */ ! 2243: | isakmpproposal_specs isakmpproposal_spec ! 2244: ; ! 2245: isakmpproposal_spec ! 2246: : LIFETIME LIFETYPE_TIME NUMBER unittype_time ! 2247: { ! 2248: cur_rmconf->spspec->lifetime = $3 * $4; ! 2249: } ! 2250: EOS ! 2251: | LIFETIME LIFETYPE_BYTE NUMBER unittype_byte ! 2252: { ! 2253: #if 1 ! 2254: yyerror("byte lifetime support is deprecated"); ! 2255: return -1; ! 2256: #else ! 2257: cur_rmconf->spspec->lifebyte = fix_lifebyte($3 * $4); ! 2258: if (cur_rmconf->spspec->lifebyte == 0) ! 2259: return -1; ! 2260: #endif ! 2261: } ! 2262: EOS ! 2263: | DH_GROUP dh_group_num ! 2264: { ! 2265: cur_rmconf->spspec->algclass[algclass_isakmp_dh] = $2; ! 2266: } ! 2267: EOS ! 2268: | GSS_ID QUOTEDSTRING ! 2269: { ! 2270: if (cur_rmconf->spspec->vendorid != VENDORID_GSSAPI) { ! 2271: yyerror("wrong Vendor ID for gssapi_id"); ! 2272: return -1; ! 2273: } ! 2274: if (cur_rmconf->spspec->gssid != NULL) ! 2275: racoon_free(cur_rmconf->spspec->gssid); ! 2276: cur_rmconf->spspec->gssid = ! 2277: racoon_strdup($2->v); ! 2278: STRDUP_FATAL(cur_rmconf->spspec->gssid); ! 2279: } ! 2280: EOS ! 2281: | ALGORITHM_CLASS ALGORITHMTYPE keylength ! 2282: { ! 2283: int doi; ! 2284: int defklen; ! 2285: ! 2286: doi = algtype2doi($1, $2); ! 2287: if (doi == -1) { ! 2288: yyerror("algorithm mismatched 1"); ! 2289: return -1; ! 2290: } ! 2291: ! 2292: switch ($1) { ! 2293: case algclass_isakmp_enc: ! 2294: /* reject suppressed algorithms */ ! 2295: #ifndef HAVE_OPENSSL_RC5_H ! 2296: if ($2 == algtype_rc5) { ! 2297: yyerror("algorithm %s not supported", ! 2298: s_attr_isakmp_enc(doi)); ! 2299: return -1; ! 2300: } ! 2301: #endif ! 2302: #ifndef HAVE_OPENSSL_IDEA_H ! 2303: if ($2 == algtype_idea) { ! 2304: yyerror("algorithm %s not supported", ! 2305: s_attr_isakmp_enc(doi)); ! 2306: return -1; ! 2307: } ! 2308: #endif ! 2309: ! 2310: cur_rmconf->spspec->algclass[algclass_isakmp_enc] = doi; ! 2311: defklen = default_keylen($1, $2); ! 2312: if (defklen == 0) { ! 2313: if ($3) { ! 2314: yyerror("keylen not allowed"); ! 2315: return -1; ! 2316: } ! 2317: } else { ! 2318: if ($3 && check_keylen($1, $2, $3) < 0) { ! 2319: yyerror("invalid keylen %d", $3); ! 2320: return -1; ! 2321: } ! 2322: } ! 2323: if ($3) ! 2324: cur_rmconf->spspec->encklen = $3; ! 2325: else ! 2326: cur_rmconf->spspec->encklen = defklen; ! 2327: break; ! 2328: case algclass_isakmp_hash: ! 2329: cur_rmconf->spspec->algclass[algclass_isakmp_hash] = doi; ! 2330: break; ! 2331: case algclass_isakmp_ameth: ! 2332: cur_rmconf->spspec->algclass[algclass_isakmp_ameth] = doi; ! 2333: /* ! 2334: * We may have to set the Vendor ID for the ! 2335: * authentication method we're using. ! 2336: */ ! 2337: switch ($2) { ! 2338: case algtype_gssapikrb: ! 2339: if (cur_rmconf->spspec->vendorid != ! 2340: VENDORID_UNKNOWN) { ! 2341: yyerror("Vendor ID mismatch " ! 2342: "for auth method"); ! 2343: return -1; ! 2344: } ! 2345: /* ! 2346: * For interoperability with Win2k, ! 2347: * we set the Vendor ID to "GSSAPI". ! 2348: */ ! 2349: cur_rmconf->spspec->vendorid = ! 2350: VENDORID_GSSAPI; ! 2351: break; ! 2352: case algtype_rsasig: ! 2353: if (oakley_get_certtype(cur_rmconf->peerscert) == ISAKMP_CERT_PLAINRSA) { ! 2354: if (rsa_list_count(cur_rmconf->rsa_private) == 0) { ! 2355: yyerror ("Private PlainRSA key not set. " ! 2356: "Use directive 'certificate_type plainrsa ...'\n"); ! 2357: return -1; ! 2358: } ! 2359: if (rsa_list_count(cur_rmconf->rsa_public) == 0) { ! 2360: yyerror ("Public PlainRSA keys not set. " ! 2361: "Use directive 'peers_certfile plainrsa ...'\n"); ! 2362: return -1; ! 2363: } ! 2364: } ! 2365: break; ! 2366: default: ! 2367: break; ! 2368: } ! 2369: break; ! 2370: default: ! 2371: yyerror("algorithm mismatched 2"); ! 2372: return -1; ! 2373: } ! 2374: } ! 2375: EOS ! 2376: ; ! 2377: ! 2378: unittype_time ! 2379: : UNITTYPE_SEC { $$ = 1; } ! 2380: | UNITTYPE_MIN { $$ = 60; } ! 2381: | UNITTYPE_HOUR { $$ = (60 * 60); } ! 2382: ; ! 2383: unittype_byte ! 2384: : UNITTYPE_BYTE { $$ = 1; } ! 2385: | UNITTYPE_KBYTES { $$ = 1024; } ! 2386: | UNITTYPE_MBYTES { $$ = (1024 * 1024); } ! 2387: | UNITTYPE_TBYTES { $$ = (1024 * 1024 * 1024); } ! 2388: ; ! 2389: %% ! 2390: ! 2391: static struct secprotospec * ! 2392: newspspec() ! 2393: { ! 2394: struct secprotospec *new; ! 2395: ! 2396: new = racoon_calloc(1, sizeof(*new)); ! 2397: if (new == NULL) { ! 2398: yyerror("failed to allocate spproto"); ! 2399: return NULL; ! 2400: } ! 2401: ! 2402: new->encklen = 0; /*XXX*/ ! 2403: ! 2404: /* ! 2405: * Default to "uknown" vendor -- we will override this ! 2406: * as necessary. When we send a Vendor ID payload, an ! 2407: * "unknown" will be translated to a KAME/racoon ID. ! 2408: */ ! 2409: new->vendorid = VENDORID_UNKNOWN; ! 2410: ! 2411: return new; ! 2412: } ! 2413: ! 2414: /* ! 2415: * insert into head of list. ! 2416: */ ! 2417: static void ! 2418: insspspec(rmconf, spspec) ! 2419: struct remoteconf *rmconf; ! 2420: struct secprotospec *spspec; ! 2421: { ! 2422: if (rmconf->spspec != NULL) ! 2423: rmconf->spspec->prev = spspec; ! 2424: spspec->next = rmconf->spspec; ! 2425: rmconf->spspec = spspec; ! 2426: } ! 2427: ! 2428: static struct secprotospec * ! 2429: dupspspec(spspec) ! 2430: struct secprotospec *spspec; ! 2431: { ! 2432: struct secprotospec *new; ! 2433: ! 2434: new = newspspec(); ! 2435: if (new == NULL) { ! 2436: plog(LLV_ERROR, LOCATION, NULL, ! 2437: "dupspspec: malloc failed\n"); ! 2438: return NULL; ! 2439: } ! 2440: memcpy(new, spspec, sizeof(*new)); ! 2441: ! 2442: if (spspec->gssid) { ! 2443: new->gssid = racoon_strdup(spspec->gssid); ! 2444: STRDUP_FATAL(new->gssid); ! 2445: } ! 2446: if (spspec->remote) { ! 2447: new->remote = racoon_malloc(sizeof(*new->remote)); ! 2448: if (new->remote == NULL) { ! 2449: plog(LLV_ERROR, LOCATION, NULL, ! 2450: "dupspspec: malloc failed (remote)\n"); ! 2451: return NULL; ! 2452: } ! 2453: memcpy(new->remote, spspec->remote, sizeof(*new->remote)); ! 2454: } ! 2455: ! 2456: return new; ! 2457: } ! 2458: ! 2459: /* ! 2460: * copy the whole list ! 2461: */ ! 2462: void ! 2463: dupspspec_list(dst, src) ! 2464: struct remoteconf *dst, *src; ! 2465: { ! 2466: struct secprotospec *p, *new, *last; ! 2467: ! 2468: for(p = src->spspec, last = NULL; p; p = p->next, last = new) { ! 2469: new = dupspspec(p); ! 2470: if (new == NULL) ! 2471: exit(1); ! 2472: ! 2473: new->prev = last; ! 2474: new->next = NULL; /* not necessary but clean */ ! 2475: ! 2476: if (last) ! 2477: last->next = new; ! 2478: else /* first element */ ! 2479: dst->spspec = new; ! 2480: ! 2481: } ! 2482: } ! 2483: ! 2484: /* ! 2485: * delete the whole list ! 2486: */ ! 2487: void ! 2488: flushspspec(rmconf) ! 2489: struct remoteconf *rmconf; ! 2490: { ! 2491: struct secprotospec *p; ! 2492: ! 2493: while(rmconf->spspec != NULL) { ! 2494: p = rmconf->spspec; ! 2495: rmconf->spspec = p->next; ! 2496: if (p->next != NULL) ! 2497: p->next->prev = NULL; /* not necessary but clean */ ! 2498: ! 2499: if (p->gssid) ! 2500: racoon_free(p->gssid); ! 2501: if (p->remote) ! 2502: racoon_free(p->remote); ! 2503: racoon_free(p); ! 2504: } ! 2505: rmconf->spspec = NULL; ! 2506: } ! 2507: ! 2508: /* set final acceptable proposal */ ! 2509: static int ! 2510: set_isakmp_proposal(rmconf) ! 2511: struct remoteconf *rmconf; ! 2512: { ! 2513: struct secprotospec *s; ! 2514: int prop_no = 1; ! 2515: int trns_no = 1; ! 2516: int32_t types[MAXALGCLASS]; ! 2517: ! 2518: /* mandatory check */ ! 2519: if (rmconf->spspec == NULL) { ! 2520: yyerror("no remote specification found: %s.\n", ! 2521: saddr2str(rmconf->remote)); ! 2522: return -1; ! 2523: } ! 2524: for (s = rmconf->spspec; s != NULL; s = s->next) { ! 2525: /* XXX need more to check */ ! 2526: if (s->algclass[algclass_isakmp_enc] == 0) { ! 2527: yyerror("encryption algorithm required."); ! 2528: return -1; ! 2529: } ! 2530: if (s->algclass[algclass_isakmp_hash] == 0) { ! 2531: yyerror("hash algorithm required."); ! 2532: return -1; ! 2533: } ! 2534: if (s->algclass[algclass_isakmp_dh] == 0) { ! 2535: yyerror("DH group required."); ! 2536: return -1; ! 2537: } ! 2538: if (s->algclass[algclass_isakmp_ameth] == 0) { ! 2539: yyerror("authentication method required."); ! 2540: return -1; ! 2541: } ! 2542: } ! 2543: ! 2544: /* skip to last part */ ! 2545: for (s = rmconf->spspec; s->next != NULL; s = s->next) ! 2546: ; ! 2547: ! 2548: while (s != NULL) { ! 2549: plog(LLV_DEBUG2, LOCATION, NULL, ! 2550: "lifetime = %ld\n", (long) ! 2551: (s->lifetime ? s->lifetime : rmconf->lifetime)); ! 2552: plog(LLV_DEBUG2, LOCATION, NULL, ! 2553: "lifebyte = %d\n", ! 2554: s->lifebyte ? s->lifebyte : rmconf->lifebyte); ! 2555: plog(LLV_DEBUG2, LOCATION, NULL, ! 2556: "encklen=%d\n", s->encklen); ! 2557: ! 2558: memset(types, 0, ARRAYLEN(types)); ! 2559: types[algclass_isakmp_enc] = s->algclass[algclass_isakmp_enc]; ! 2560: types[algclass_isakmp_hash] = s->algclass[algclass_isakmp_hash]; ! 2561: types[algclass_isakmp_dh] = s->algclass[algclass_isakmp_dh]; ! 2562: types[algclass_isakmp_ameth] = ! 2563: s->algclass[algclass_isakmp_ameth]; ! 2564: ! 2565: /* expanding spspec */ ! 2566: clean_tmpalgtype(); ! 2567: trns_no = expand_isakmpspec(prop_no, trns_no, types, ! 2568: algclass_isakmp_enc, algclass_isakmp_ameth + 1, ! 2569: s->lifetime ? s->lifetime : rmconf->lifetime, ! 2570: s->lifebyte ? s->lifebyte : rmconf->lifebyte, ! 2571: s->encklen, s->vendorid, s->gssid, ! 2572: rmconf); ! 2573: if (trns_no == -1) { ! 2574: plog(LLV_ERROR, LOCATION, NULL, ! 2575: "failed to expand isakmp proposal.\n"); ! 2576: return -1; ! 2577: } ! 2578: ! 2579: s = s->prev; ! 2580: } ! 2581: ! 2582: if (rmconf->proposal == NULL) { ! 2583: plog(LLV_ERROR, LOCATION, NULL, ! 2584: "no proposal found.\n"); ! 2585: return -1; ! 2586: } ! 2587: ! 2588: return 0; ! 2589: } ! 2590: ! 2591: static void ! 2592: clean_tmpalgtype() ! 2593: { ! 2594: int i; ! 2595: for (i = 0; i < MAXALGCLASS; i++) ! 2596: tmpalgtype[i] = 0; /* means algorithm undefined. */ ! 2597: } ! 2598: ! 2599: static int ! 2600: expand_isakmpspec(prop_no, trns_no, types, ! 2601: class, last, lifetime, lifebyte, encklen, vendorid, gssid, ! 2602: rmconf) ! 2603: int prop_no, trns_no; ! 2604: int *types, class, last; ! 2605: time_t lifetime; ! 2606: int lifebyte; ! 2607: int encklen; ! 2608: int vendorid; ! 2609: char *gssid; ! 2610: struct remoteconf *rmconf; ! 2611: { ! 2612: struct isakmpsa *new; ! 2613: ! 2614: /* debugging */ ! 2615: { ! 2616: int j; ! 2617: char tb[10]; ! 2618: plog(LLV_DEBUG2, LOCATION, NULL, ! 2619: "p:%d t:%d\n", prop_no, trns_no); ! 2620: for (j = class; j < MAXALGCLASS; j++) { ! 2621: snprintf(tb, sizeof(tb), "%d", types[j]); ! 2622: plog(LLV_DEBUG2, LOCATION, NULL, ! 2623: "%s%s%s%s\n", ! 2624: s_algtype(j, types[j]), ! 2625: types[j] ? "(" : "", ! 2626: tb[0] == '0' ? "" : tb, ! 2627: types[j] ? ")" : ""); ! 2628: } ! 2629: plog(LLV_DEBUG2, LOCATION, NULL, "\n"); ! 2630: } ! 2631: ! 2632: #define TMPALGTYPE2STR(n) \ ! 2633: s_algtype(algclass_isakmp_##n, types[algclass_isakmp_##n]) ! 2634: /* check mandatory values */ ! 2635: if (types[algclass_isakmp_enc] == 0 ! 2636: || types[algclass_isakmp_ameth] == 0 ! 2637: || types[algclass_isakmp_hash] == 0 ! 2638: || types[algclass_isakmp_dh] == 0) { ! 2639: yyerror("few definition of algorithm " ! 2640: "enc=%s ameth=%s hash=%s dhgroup=%s.\n", ! 2641: TMPALGTYPE2STR(enc), ! 2642: TMPALGTYPE2STR(ameth), ! 2643: TMPALGTYPE2STR(hash), ! 2644: TMPALGTYPE2STR(dh)); ! 2645: return -1; ! 2646: } ! 2647: #undef TMPALGTYPE2STR ! 2648: ! 2649: /* set new sa */ ! 2650: new = newisakmpsa(); ! 2651: if (new == NULL) { ! 2652: yyerror("failed to allocate isakmp sa"); ! 2653: return -1; ! 2654: } ! 2655: new->prop_no = prop_no; ! 2656: new->trns_no = trns_no++; ! 2657: new->lifetime = lifetime; ! 2658: new->lifebyte = lifebyte; ! 2659: new->enctype = types[algclass_isakmp_enc]; ! 2660: new->encklen = encklen; ! 2661: new->authmethod = types[algclass_isakmp_ameth]; ! 2662: new->hashtype = types[algclass_isakmp_hash]; ! 2663: new->dh_group = types[algclass_isakmp_dh]; ! 2664: new->vendorid = vendorid; ! 2665: #ifdef HAVE_GSSAPI ! 2666: if (new->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) { ! 2667: if (gssid != NULL) { ! 2668: if ((new->gssid = vmalloc(strlen(gssid))) == NULL) { ! 2669: racoon_free(new); ! 2670: yyerror("failed to allocate gssid"); ! 2671: return -1; ! 2672: } ! 2673: memcpy(new->gssid->v, gssid, new->gssid->l); ! 2674: racoon_free(gssid); ! 2675: } else { ! 2676: /* ! 2677: * Allocate the default ID so that it gets put ! 2678: * into a GSS ID attribute during the Phase 1 ! 2679: * exchange. ! 2680: */ ! 2681: new->gssid = gssapi_get_default_gss_id(); ! 2682: } ! 2683: } ! 2684: #endif ! 2685: insisakmpsa(new, rmconf); ! 2686: ! 2687: return trns_no; ! 2688: } ! 2689: ! 2690: #if 0 ! 2691: /* ! 2692: * fix lifebyte. ! 2693: * Must be more than 1024B because its unit is kilobytes. ! 2694: * That is defined RFC2407. ! 2695: */ ! 2696: static int ! 2697: fix_lifebyte(t) ! 2698: unsigned long t; ! 2699: { ! 2700: if (t < 1024) { ! 2701: yyerror("byte size should be more than 1024B."); ! 2702: return 0; ! 2703: } ! 2704: ! 2705: return(t / 1024); ! 2706: } ! 2707: #endif ! 2708: ! 2709: int ! 2710: cfparse() ! 2711: { ! 2712: int error; ! 2713: ! 2714: yyerrorcount = 0; ! 2715: yycf_init_buffer(); ! 2716: ! 2717: if (yycf_switch_buffer(lcconf->racoon_conf) != 0) { ! 2718: plog(LLV_ERROR, LOCATION, NULL, ! 2719: "could not read configuration file \"%s\"\n", ! 2720: lcconf->racoon_conf); ! 2721: return -1; ! 2722: } ! 2723: ! 2724: error = yyparse(); ! 2725: if (error != 0) { ! 2726: if (yyerrorcount) { ! 2727: plog(LLV_ERROR, LOCATION, NULL, ! 2728: "fatal parse failure (%d errors)\n", ! 2729: yyerrorcount); ! 2730: } else { ! 2731: plog(LLV_ERROR, LOCATION, NULL, ! 2732: "fatal parse failure.\n"); ! 2733: } ! 2734: return -1; ! 2735: } ! 2736: ! 2737: if (error == 0 && yyerrorcount) { ! 2738: plog(LLV_ERROR, LOCATION, NULL, ! 2739: "parse error is nothing, but yyerrorcount is %d.\n", ! 2740: yyerrorcount); ! 2741: exit(1); ! 2742: } ! 2743: ! 2744: yycf_clean_buffer(); ! 2745: ! 2746: plog(LLV_DEBUG2, LOCATION, NULL, "parse successed.\n"); ! 2747: ! 2748: return 0; ! 2749: } ! 2750: ! 2751: int ! 2752: cfreparse() ! 2753: { ! 2754: flushph2(); ! 2755: flushph1(); ! 2756: flushrmconf(); ! 2757: flushsainfo(); ! 2758: clean_tmpalgtype(); ! 2759: return(cfparse()); ! 2760: } ! 2761: ! 2762: #ifdef ENABLE_ADMINPORT ! 2763: static void ! 2764: adminsock_conf(path, owner, group, mode_dec) ! 2765: vchar_t *path; ! 2766: vchar_t *owner; ! 2767: vchar_t *group; ! 2768: int mode_dec; ! 2769: { ! 2770: struct passwd *pw = NULL; ! 2771: struct group *gr = NULL; ! 2772: mode_t mode = 0; ! 2773: uid_t uid; ! 2774: gid_t gid; ! 2775: int isnum; ! 2776: ! 2777: adminsock_path = path->v; ! 2778: ! 2779: if (owner == NULL) ! 2780: return; ! 2781: ! 2782: errno = 0; ! 2783: uid = atoi(owner->v); ! 2784: isnum = !errno; ! 2785: if (((pw = getpwnam(owner->v)) == NULL) && !isnum) ! 2786: yyerror("User \"%s\" does not exist", owner->v); ! 2787: ! 2788: if (pw) ! 2789: adminsock_owner = pw->pw_uid; ! 2790: else ! 2791: adminsock_owner = uid; ! 2792: ! 2793: if (group == NULL) ! 2794: return; ! 2795: ! 2796: errno = 0; ! 2797: gid = atoi(group->v); ! 2798: isnum = !errno; ! 2799: if (((gr = getgrnam(group->v)) == NULL) && !isnum) ! 2800: yyerror("Group \"%s\" does not exist", group->v); ! 2801: ! 2802: if (gr) ! 2803: adminsock_group = gr->gr_gid; ! 2804: else ! 2805: adminsock_group = gid; ! 2806: ! 2807: if (mode_dec == -1) ! 2808: return; ! 2809: ! 2810: if (mode_dec > 777) ! 2811: yyerror("Mode 0%03o is invalid", mode_dec); ! 2812: if (mode_dec >= 400) { mode += 0400; mode_dec -= 400; } ! 2813: if (mode_dec >= 200) { mode += 0200; mode_dec -= 200; } ! 2814: if (mode_dec >= 100) { mode += 0200; mode_dec -= 100; } ! 2815: ! 2816: if (mode_dec > 77) ! 2817: yyerror("Mode 0%03o is invalid", mode_dec); ! 2818: if (mode_dec >= 40) { mode += 040; mode_dec -= 40; } ! 2819: if (mode_dec >= 20) { mode += 020; mode_dec -= 20; } ! 2820: if (mode_dec >= 10) { mode += 020; mode_dec -= 10; } ! 2821: ! 2822: if (mode_dec > 7) ! 2823: yyerror("Mode 0%03o is invalid", mode_dec); ! 2824: if (mode_dec >= 4) { mode += 04; mode_dec -= 4; } ! 2825: if (mode_dec >= 2) { mode += 02; mode_dec -= 2; } ! 2826: if (mode_dec >= 1) { mode += 02; mode_dec -= 1; } ! 2827: ! 2828: adminsock_mode = mode; ! 2829: ! 2830: return; ! 2831: } ! 2832: #endif