Annotation of embedaddon/strongswan/src/starter/confread.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2014 Tobias Brunner
! 3: * HSR Hochschule fuer Technik Rapperswil
! 4: *
! 5: * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
! 6: *
! 7: * This program is free software; you can redistribute it and/or modify it
! 8: * under the terms of the GNU General Public License as published by the
! 9: * Free Software Foundation; either version 2 of the License, or (at your
! 10: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
! 11: *
! 12: * This program is distributed in the hope that it will be useful, but
! 13: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 14: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
! 15: * for more details.
! 16: */
! 17:
! 18: #include <sys/types.h>
! 19: #include <sys/stat.h>
! 20: #include <unistd.h>
! 21: #include <stddef.h>
! 22: #include <stdlib.h>
! 23: #include <string.h>
! 24: #include <assert.h>
! 25: #include <netdb.h>
! 26:
! 27: #include <library.h>
! 28: #include <utils/debug.h>
! 29:
! 30: #include "keywords.h"
! 31: #include "confread.h"
! 32: #include "args.h"
! 33: #include "files.h"
! 34: #include "parser/conf_parser.h"
! 35:
! 36: #define IKE_LIFETIME_DEFAULT 10800 /* 3 hours */
! 37: #define IPSEC_LIFETIME_DEFAULT 3600 /* 1 hour */
! 38: #define SA_REPLACEMENT_MARGIN_DEFAULT 540 /* 9 minutes */
! 39: #define SA_REPLACEMENT_FUZZ_DEFAULT 100 /* 100% of margin */
! 40: #define SA_REPLACEMENT_RETRIES_DEFAULT 3
! 41: #define SA_REPLAY_WINDOW_DEFAULT -1 /* use charon.replay_window */
! 42:
! 43: static const char firewall_defaults[] = IPSEC_SCRIPT " _updown iptables";
! 44:
! 45: /**
! 46: * Process deprecated keywords
! 47: */
! 48: static bool is_deprecated(kw_token_t token, char *name, char *conn)
! 49: {
! 50: switch (token)
! 51: {
! 52: case KW_SETUP_DEPRECATED:
! 53: case KW_PKCS11_DEPRECATED:
! 54: DBG1(DBG_APP, "# deprecated keyword '%s' in config setup", name);
! 55: break;
! 56: case KW_CONN_DEPRECATED:
! 57: case KW_END_DEPRECATED:
! 58: case KW_PFS_DEPRECATED:
! 59: DBG1(DBG_APP, "# deprecated keyword '%s' in conn '%s'", name, conn);
! 60: break;
! 61: case KW_CA_DEPRECATED:
! 62: DBG1(DBG_APP, "# deprecated keyword '%s' in ca '%s'", name, conn);
! 63: break;
! 64: default:
! 65: return FALSE;
! 66: }
! 67: /* additional messages for some */
! 68: switch (token)
! 69: {
! 70: case KW_PKCS11_DEPRECATED:
! 71: DBG1(DBG_APP, " use the 'pkcs11' plugin instead");
! 72: break;
! 73: case KW_PFS_DEPRECATED:
! 74: DBG1(DBG_APP, " PFS is enabled by specifying a DH group in the "
! 75: "'esp' cipher suite");
! 76: break;
! 77: default:
! 78: break;
! 79: }
! 80: return TRUE;
! 81: }
! 82:
! 83: /*
! 84: * parse config setup section
! 85: */
! 86: static void load_setup(starter_config_t *cfg, conf_parser_t *parser)
! 87: {
! 88: enumerator_t *enumerator;
! 89: dictionary_t *dict;
! 90: const kw_entry_t *entry;
! 91: char *key, *value;
! 92:
! 93: DBG2(DBG_APP, "Loading config setup");
! 94: dict = parser->get_section(parser, CONF_PARSER_CONFIG_SETUP, NULL);
! 95: if (!dict)
! 96: {
! 97: return;
! 98: }
! 99: enumerator = dict->create_enumerator(dict);
! 100: while (enumerator->enumerate(enumerator, &key, &value))
! 101: {
! 102: bool assigned = FALSE;
! 103:
! 104: entry = in_word_set(key, strlen(key));
! 105: if (!entry)
! 106: {
! 107: DBG1(DBG_APP, "# unknown keyword '%s'", key);
! 108: cfg->non_fatal_err++;
! 109: continue;
! 110: }
! 111: if ((int)entry->token < KW_SETUP_FIRST || entry->token > KW_SETUP_LAST)
! 112: {
! 113: DBG1(DBG_APP, "# unsupported keyword '%s' in config setup", key);
! 114: cfg->err++;
! 115: continue;
! 116: }
! 117: if (is_deprecated(entry->token, key, ""))
! 118: {
! 119: cfg->non_fatal_err++;
! 120: continue;
! 121: }
! 122: if (!assign_arg(entry->token, KW_SETUP_FIRST, key, value, cfg,
! 123: &assigned))
! 124: {
! 125: DBG1(DBG_APP, " bad argument value in config setup");
! 126: cfg->err++;
! 127: }
! 128: }
! 129: enumerator->destroy(enumerator);
! 130: dict->destroy(dict);
! 131: }
! 132:
! 133: /*
! 134: * parse a ca section
! 135: */
! 136: static void load_ca(starter_ca_t *ca, starter_config_t *cfg,
! 137: conf_parser_t *parser)
! 138: {
! 139: enumerator_t *enumerator;
! 140: dictionary_t *dict;
! 141: const kw_entry_t *entry;
! 142: kw_token_t token;
! 143: char *key, *value;
! 144:
! 145: DBG2(DBG_APP, "Loading ca '%s'", ca->name);
! 146: dict = parser->get_section(parser, CONF_PARSER_CA, ca->name);
! 147: if (!dict)
! 148: {
! 149: return;
! 150: }
! 151: enumerator = dict->create_enumerator(dict);
! 152: while (enumerator->enumerate(enumerator, &key, &value))
! 153: {
! 154: bool assigned = FALSE;
! 155:
! 156: entry = in_word_set(key, strlen(key));
! 157: if (!entry)
! 158: {
! 159: DBG1(DBG_APP, "# unknown keyword '%s'", key);
! 160: cfg->non_fatal_err++;
! 161: continue;
! 162: }
! 163: token = entry->token;
! 164: if (token == KW_AUTO)
! 165: {
! 166: token = KW_CA_SETUP;
! 167: }
! 168: if (token < KW_CA_FIRST || token > KW_CA_LAST)
! 169: {
! 170: DBG1(DBG_APP, "# unsupported keyword '%s' in ca '%s'",
! 171: key, ca->name);
! 172: cfg->err++;
! 173: continue;
! 174: }
! 175: if (is_deprecated(token, key, ca->name))
! 176: {
! 177: cfg->non_fatal_err++;
! 178: continue;
! 179: }
! 180: if (!assign_arg(token, KW_CA_FIRST, key, value, ca, &assigned))
! 181: {
! 182: DBG1(DBG_APP, " bad argument value in ca '%s'", ca->name);
! 183: cfg->err++;
! 184: }
! 185: }
! 186: enumerator->destroy(enumerator);
! 187: dict->destroy(dict);
! 188:
! 189: /* treat 'route' and 'start' as 'add' */
! 190: if (ca->startup != STARTUP_NO)
! 191: {
! 192: ca->startup = STARTUP_ADD;
! 193: }
! 194: }
! 195:
! 196: /*
! 197: * set some default values
! 198: */
! 199: static void conn_defaults(starter_conn_t *conn)
! 200: {
! 201: conn->startup = STARTUP_NO;
! 202: conn->state = STATE_IGNORE;
! 203: conn->mode = MODE_TUNNEL;
! 204: conn->options = SA_OPTION_MOBIKE;
! 205:
! 206: /* esp defaults are set after parsing the conn section */
! 207: conn->sa_ike_life_seconds = IKE_LIFETIME_DEFAULT;
! 208: conn->sa_ipsec_life_seconds = IPSEC_LIFETIME_DEFAULT;
! 209: conn->sa_rekey_margin = SA_REPLACEMENT_MARGIN_DEFAULT;
! 210: conn->sa_rekey_fuzz = SA_REPLACEMENT_FUZZ_DEFAULT;
! 211: conn->sa_keying_tries = SA_REPLACEMENT_RETRIES_DEFAULT;
! 212: conn->install_policy = TRUE;
! 213: conn->dpd_delay = 30; /* seconds */
! 214: conn->dpd_timeout = 150; /* seconds */
! 215: conn->replay_window = SA_REPLAY_WINDOW_DEFAULT;
! 216: conn->fragmentation = FRAGMENTATION_YES;
! 217:
! 218: conn->left.sendcert = CERT_SEND_IF_ASKED;
! 219: conn->right.sendcert = CERT_SEND_IF_ASKED;
! 220:
! 221: conn->left.ikeport = 500;
! 222: conn->right.ikeport = 500;
! 223:
! 224: conn->left.to_port = 0xffff;
! 225: conn->right.to_port = 0xffff;
! 226: }
! 227:
! 228: /*
! 229: * parse left|right specific options
! 230: */
! 231: static void kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token,
! 232: char *key, char *value, starter_config_t *cfg)
! 233: {
! 234: bool assigned = FALSE;
! 235:
! 236: if (is_deprecated(token, key, conn->name))
! 237: {
! 238: cfg->non_fatal_err++;
! 239: return;
! 240: }
! 241:
! 242: if (!assign_arg(token, KW_END_FIRST, key, value, end, &assigned))
! 243: {
! 244: goto err;
! 245: }
! 246:
! 247: /* post processing of some keywords that were assigned automatically */
! 248: switch (token)
! 249: {
! 250: case KW_HOST:
! 251: if (value && strlen(value) > 0 && value[0] == '%')
! 252: {
! 253: if (streq(value, "%defaultroute"))
! 254: {
! 255: value = "%any";
! 256: }
! 257: if (!streq(value, "%any") && !streq(value, "%any4") &&
! 258: !streq(value, "%any6"))
! 259: { /* allow_any prefix */
! 260: end->allow_any = TRUE;
! 261: value++;
! 262: }
! 263: }
! 264: free(end->host);
! 265: end->host = strdupnull(value);
! 266: break;
! 267: case KW_SOURCEIP:
! 268: conn->mode = MODE_TUNNEL;
! 269: conn->proxy_mode = FALSE;
! 270: break;
! 271: case KW_SENDCERT:
! 272: if (end->sendcert == CERT_YES_SEND)
! 273: {
! 274: end->sendcert = CERT_ALWAYS_SEND;
! 275: }
! 276: else if (end->sendcert == CERT_NO_SEND)
! 277: {
! 278: end->sendcert = CERT_NEVER_SEND;
! 279: }
! 280: break;
! 281: default:
! 282: break;
! 283: }
! 284:
! 285: if (assigned)
! 286: {
! 287: return;
! 288: }
! 289:
! 290: /* individual processing of keywords that were not assigned automatically */
! 291: switch (token)
! 292: {
! 293: case KW_PROTOPORT:
! 294: {
! 295: struct protoent *proto;
! 296: struct servent *svc;
! 297: char *sep, *port = "", *endptr;
! 298: long int p;
! 299:
! 300: sep = strchr(value, '/');
! 301: if (sep)
! 302: { /* protocol/port */
! 303: *sep = '\0';
! 304: port = sep + 1;
! 305: }
! 306:
! 307: if (streq(value, "%any"))
! 308: {
! 309: end->protocol = 0;
! 310: }
! 311: else
! 312: {
! 313: proto = getprotobyname(value);
! 314: if (proto)
! 315: {
! 316: end->protocol = proto->p_proto;
! 317: }
! 318: else
! 319: {
! 320: p = strtol(value, &endptr, 0);
! 321: if ((*value && *endptr) || p < 0 || p > 0xff)
! 322: {
! 323: DBG1(DBG_APP, "# bad protocol: %s=%s", key, value);
! 324: goto err;
! 325: }
! 326: end->protocol = (uint8_t)p;
! 327: }
! 328: }
! 329: if (streq(port, "%any"))
! 330: {
! 331: end->from_port = 0;
! 332: end->to_port = 0xffff;
! 333: }
! 334: else if (streq(port, "%opaque"))
! 335: {
! 336: end->from_port = 0xffff;
! 337: end->to_port = 0;
! 338: }
! 339: else if (*port)
! 340: {
! 341: svc = getservbyname(port, NULL);
! 342: if (svc)
! 343: {
! 344: end->from_port = end->to_port = ntohs(svc->s_port);
! 345: }
! 346: else
! 347: {
! 348: p = strtol(port, &endptr, 0);
! 349: if (p < 0 || p > 0xffff)
! 350: {
! 351: DBG1(DBG_APP, "# bad port: %s=%s", key, port);
! 352: goto err;
! 353: }
! 354: end->from_port = p;
! 355: if (*endptr == '-')
! 356: {
! 357: port = endptr + 1;
! 358: p = strtol(port, &endptr, 0);
! 359: if (p < 0 || p > 0xffff)
! 360: {
! 361: DBG1(DBG_APP, "# bad port: %s=%s", key, port);
! 362: goto err;
! 363: }
! 364: }
! 365: end->to_port = p;
! 366: if (*endptr)
! 367: {
! 368: DBG1(DBG_APP, "# bad port: %s=%s", key, port);
! 369: goto err;
! 370: }
! 371: }
! 372: }
! 373: if (sep)
! 374: { /* restore the original text in case also= is used */
! 375: *sep = '/';
! 376: }
! 377: break;
! 378: }
! 379: default:
! 380: break;
! 381: }
! 382: return;
! 383:
! 384: err:
! 385: DBG1(DBG_APP, " bad argument value in conn '%s'", conn->name);
! 386: cfg->err++;
! 387: }
! 388:
! 389: /*
! 390: * macro to handle simple flags
! 391: */
! 392: #define KW_SA_OPTION_FLAG(sy, sn, fl) \
! 393: if (streq(value, sy)) { conn->options |= fl; } \
! 394: else if (streq(value, sn)) { conn->options &= ~fl; } \
! 395: else { DBG1(DBG_APP, "# bad option value: %s=%s", key, value); cfg->err++; }
! 396:
! 397: /*
! 398: * parse settings not handled by the simple argument parser
! 399: */
! 400: static void handle_keyword(kw_token_t token, starter_conn_t *conn, char *key,
! 401: char *value, starter_config_t *cfg)
! 402: {
! 403: if ((token == KW_ESP && conn->ah) || (token == KW_AH && conn->esp))
! 404: {
! 405: DBG1(DBG_APP, "# can't have both 'ah' and 'esp' options");
! 406: cfg->err++;
! 407: return;
! 408: }
! 409: switch (token)
! 410: {
! 411: case KW_TYPE:
! 412: {
! 413: conn->mode = MODE_TRANSPORT;
! 414: conn->proxy_mode = FALSE;
! 415: if (streq(value, "tunnel"))
! 416: {
! 417: conn->mode = MODE_TUNNEL;
! 418: }
! 419: else if (streq(value, "beet"))
! 420: {
! 421: conn->mode = MODE_BEET;
! 422: }
! 423: else if (streq(value, "transport_proxy"))
! 424: {
! 425: conn->mode = MODE_TRANSPORT;
! 426: conn->proxy_mode = TRUE;
! 427: }
! 428: else if (streq(value, "passthrough") || streq(value, "pass"))
! 429: {
! 430: conn->mode = MODE_PASS;
! 431: }
! 432: else if (streq(value, "drop") || streq(value, "reject"))
! 433: {
! 434: conn->mode = MODE_DROP;
! 435: }
! 436: else if (!streq(value, "transport"))
! 437: {
! 438: DBG1(DBG_APP, "# bad policy value: %s=%s", key, value);
! 439: cfg->err++;
! 440: }
! 441: break;
! 442: }
! 443: case KW_COMPRESS:
! 444: KW_SA_OPTION_FLAG("yes", "no", SA_OPTION_COMPRESS)
! 445: break;
! 446: case KW_MARK:
! 447: if (!mark_from_string(value, MARK_OP_UNIQUE, &conn->mark_in))
! 448: {
! 449: cfg->err++;
! 450: break;
! 451: }
! 452: conn->mark_out = conn->mark_in;
! 453: break;
! 454: case KW_MARK_IN:
! 455: if (!mark_from_string(value, MARK_OP_UNIQUE, &conn->mark_in))
! 456: {
! 457: cfg->err++;
! 458: }
! 459: break;
! 460: case KW_MARK_OUT:
! 461: if (!mark_from_string(value, MARK_OP_UNIQUE, &conn->mark_out))
! 462: {
! 463: cfg->err++;
! 464: }
! 465: break;
! 466: case KW_TFC:
! 467: if (streq(value, "%mtu"))
! 468: {
! 469: conn->tfc = -1;
! 470: }
! 471: else
! 472: {
! 473: char *endptr;
! 474:
! 475: conn->tfc = strtoul(value, &endptr, 10);
! 476: if (*endptr != '\0')
! 477: {
! 478: DBG1(DBG_APP, "# bad integer value: %s=%s", key, value);
! 479: cfg->err++;
! 480: }
! 481: }
! 482: break;
! 483: case KW_KEYINGTRIES:
! 484: if (streq(value, "%forever"))
! 485: {
! 486: conn->sa_keying_tries = 0;
! 487: }
! 488: else
! 489: {
! 490: char *endptr;
! 491:
! 492: conn->sa_keying_tries = strtoul(value, &endptr, 10);
! 493: if (*endptr != '\0')
! 494: {
! 495: DBG1(DBG_APP, "# bad integer value: %s=%s", key, value);
! 496: cfg->err++;
! 497: }
! 498: }
! 499: break;
! 500: case KW_REKEY:
! 501: KW_SA_OPTION_FLAG("no", "yes", SA_OPTION_DONT_REKEY)
! 502: break;
! 503: case KW_REAUTH:
! 504: KW_SA_OPTION_FLAG("no", "yes", SA_OPTION_DONT_REAUTH)
! 505: break;
! 506: case KW_MOBIKE:
! 507: KW_SA_OPTION_FLAG("yes", "no", SA_OPTION_MOBIKE)
! 508: break;
! 509: case KW_FORCEENCAPS:
! 510: KW_SA_OPTION_FLAG("yes", "no", SA_OPTION_FORCE_ENCAP)
! 511: break;
! 512: case KW_MODECONFIG:
! 513: KW_SA_OPTION_FLAG("push", "pull", SA_OPTION_MODECFG_PUSH)
! 514: break;
! 515: case KW_XAUTH:
! 516: KW_SA_OPTION_FLAG("server", "client", SA_OPTION_XAUTH_SERVER)
! 517: break;
! 518: default:
! 519: break;
! 520: }
! 521: }
! 522:
! 523: /*
! 524: * handles left|rightfirewall and left|rightupdown parameters
! 525: */
! 526: static void handle_firewall(const char *label, starter_end_t *end,
! 527: starter_config_t *cfg)
! 528: {
! 529: if (end->firewall)
! 530: {
! 531: if (end->updown != NULL)
! 532: {
! 533: DBG1(DBG_APP, "# cannot have both %sfirewall and %supdown", label,
! 534: label);
! 535: cfg->err++;
! 536: }
! 537: else
! 538: {
! 539: end->updown = strdupnull(firewall_defaults);
! 540: end->firewall = FALSE;
! 541: }
! 542: }
! 543: }
! 544:
! 545: /*
! 546: * parse a conn section
! 547: */
! 548: static void load_conn(starter_conn_t *conn, starter_config_t *cfg,
! 549: conf_parser_t *parser)
! 550: {
! 551: enumerator_t *enumerator;
! 552: dictionary_t *dict;
! 553: const kw_entry_t *entry;
! 554: kw_token_t token;
! 555: char *key, *value;
! 556:
! 557: DBG2(DBG_APP, "Loading conn '%s'", conn->name);
! 558: dict = parser->get_section(parser, CONF_PARSER_CONN, conn->name);
! 559: if (!dict)
! 560: {
! 561: return;
! 562: }
! 563: enumerator = dict->create_enumerator(dict);
! 564: while (enumerator->enumerate(enumerator, &key, &value))
! 565: {
! 566: bool assigned = FALSE;
! 567:
! 568: entry = in_word_set(key, strlen(key));
! 569: if (!entry)
! 570: {
! 571: DBG1(DBG_APP, "# unknown keyword '%s'", key);
! 572: cfg->non_fatal_err++;
! 573: continue;
! 574: }
! 575: token = entry->token;
! 576: if (token >= KW_LEFT_FIRST && token <= KW_LEFT_LAST)
! 577: {
! 578: kw_end(conn, &conn->left, token - KW_LEFT_FIRST + KW_END_FIRST,
! 579: key, value, cfg);
! 580: continue;
! 581: }
! 582: else if (token >= KW_RIGHT_FIRST && token <= KW_RIGHT_LAST)
! 583: {
! 584: kw_end(conn, &conn->right, token - KW_RIGHT_FIRST + KW_END_FIRST,
! 585: key, value, cfg);
! 586: continue;
! 587: }
! 588: if (token == KW_AUTO)
! 589: {
! 590: token = KW_CONN_SETUP;
! 591: }
! 592: if (token < KW_CONN_FIRST || token > KW_CONN_LAST)
! 593: {
! 594: DBG1(DBG_APP, "# unsupported keyword '%s' in conn '%s'",
! 595: key, conn->name);
! 596: cfg->err++;
! 597: continue;
! 598: }
! 599: if (is_deprecated(token, key, conn->name))
! 600: {
! 601: cfg->non_fatal_err++;
! 602: continue;
! 603: }
! 604: if (!assign_arg(token, KW_CONN_FIRST, key, value, conn,
! 605: &assigned))
! 606: {
! 607: DBG1(DBG_APP, " bad argument value in conn '%s'", conn->name);
! 608: cfg->err++;
! 609: continue;
! 610: }
! 611: if (!assigned)
! 612: {
! 613: handle_keyword(token, conn, key, value, cfg);
! 614: }
! 615: }
! 616: enumerator->destroy(enumerator);
! 617: dict->destroy(dict);
! 618:
! 619: handle_firewall("left", &conn->left, cfg);
! 620: handle_firewall("right", &conn->right, cfg);
! 621: }
! 622:
! 623: /*
! 624: * free the memory used by a starter_ca_t object
! 625: */
! 626: static void confread_free_ca(starter_ca_t *ca)
! 627: {
! 628: free_args(KW_CA_NAME, KW_CA_LAST, (char *)ca);
! 629: free(ca);
! 630: }
! 631:
! 632: /*
! 633: * free the memory used by a starter_conn_t object
! 634: */
! 635: static void confread_free_conn(starter_conn_t *conn)
! 636: {
! 637: free_args(KW_END_FIRST, KW_END_LAST, (char *)&conn->left);
! 638: free_args(KW_END_FIRST, KW_END_LAST, (char *)&conn->right);
! 639: free_args(KW_CONN_NAME, KW_CONN_LAST, (char *)conn);
! 640: free(conn);
! 641: }
! 642:
! 643: /*
! 644: * free the memory used by a starter_config_t object
! 645: */
! 646: void confread_free(starter_config_t *cfg)
! 647: {
! 648: starter_conn_t *conn = cfg->conn_first;
! 649: starter_ca_t *ca = cfg->ca_first;
! 650:
! 651: free_args(KW_SETUP_FIRST, KW_SETUP_LAST, (char *)cfg);
! 652:
! 653: while (conn != NULL)
! 654: {
! 655: starter_conn_t *conn_aux = conn;
! 656:
! 657: conn = conn->next;
! 658: confread_free_conn(conn_aux);
! 659: }
! 660:
! 661: while (ca != NULL)
! 662: {
! 663: starter_ca_t *ca_aux = ca;
! 664:
! 665: ca = ca->next;
! 666: confread_free_ca(ca_aux);
! 667: }
! 668:
! 669: free(cfg);
! 670: }
! 671:
! 672: /*
! 673: * load and parse an IPsec configuration file
! 674: */
! 675: starter_config_t* confread_load(const char *file)
! 676: {
! 677: conf_parser_t *parser;
! 678: starter_config_t *cfg = NULL;
! 679: enumerator_t *enumerator;
! 680: u_int total_err;
! 681: char *name;
! 682:
! 683: parser = conf_parser_create(file);
! 684: if (!parser->parse(parser))
! 685: {
! 686: parser->destroy(parser);
! 687: return NULL;
! 688: }
! 689:
! 690: INIT(cfg,
! 691: .setup = {
! 692: .uniqueids = TRUE,
! 693: }
! 694: );
! 695:
! 696: /* load config setup section */
! 697: load_setup(cfg, parser);
! 698:
! 699: /* load ca sections */
! 700: enumerator = parser->get_sections(parser, CONF_PARSER_CA);
! 701: while (enumerator->enumerate(enumerator, &name))
! 702: {
! 703: u_int previous_err = cfg->err;
! 704: starter_ca_t *ca;
! 705:
! 706: INIT(ca,
! 707: .name = strdup(name),
! 708: );
! 709: load_ca(ca, cfg, parser);
! 710:
! 711: if (cfg->err > previous_err)
! 712: {
! 713: total_err = cfg->err - previous_err;
! 714: DBG1(DBG_APP, "# ignored ca '%s' due to %d parsing error%s", name,
! 715: total_err, (total_err > 1) ? "s" : "");
! 716: confread_free_ca(ca);
! 717: cfg->non_fatal_err += cfg->err - previous_err;
! 718: cfg->err = previous_err;
! 719: }
! 720: else
! 721: {
! 722: if (cfg->ca_last)
! 723: {
! 724: cfg->ca_last->next = ca;
! 725: }
! 726: cfg->ca_last = ca;
! 727: if (!cfg->ca_first)
! 728: {
! 729: cfg->ca_first = ca;
! 730: }
! 731: if (ca->startup != STARTUP_NO)
! 732: {
! 733: ca->state = STATE_TO_ADD;
! 734: }
! 735: }
! 736: }
! 737: enumerator->destroy(enumerator);
! 738:
! 739: /* load conn sections */
! 740: enumerator = parser->get_sections(parser, CONF_PARSER_CONN);
! 741: while (enumerator->enumerate(enumerator, &name))
! 742: {
! 743: u_int previous_err = cfg->err;
! 744: starter_conn_t *conn;
! 745:
! 746: INIT(conn,
! 747: .name = strdup(name),
! 748: );
! 749: conn_defaults(conn);
! 750: load_conn(conn, cfg, parser);
! 751:
! 752: if (cfg->err > previous_err)
! 753: {
! 754: total_err = cfg->err - previous_err;
! 755: DBG1(DBG_APP, "# ignored conn '%s' due to %d parsing error%s", name,
! 756: total_err, (total_err > 1) ? "s" : "");
! 757: confread_free_conn(conn);
! 758: cfg->non_fatal_err += cfg->err - previous_err;
! 759: cfg->err = previous_err;
! 760: }
! 761: else
! 762: {
! 763: if (cfg->conn_last)
! 764: {
! 765: cfg->conn_last->next = conn;
! 766: }
! 767: cfg->conn_last = conn;
! 768: if (!cfg->conn_first)
! 769: {
! 770: cfg->conn_first = conn;
! 771: }
! 772: if (conn->startup != STARTUP_NO)
! 773: {
! 774: conn->state = STATE_TO_ADD;
! 775: }
! 776: }
! 777: }
! 778: enumerator->destroy(enumerator);
! 779:
! 780: parser->destroy(parser);
! 781:
! 782: total_err = cfg->err + cfg->non_fatal_err;
! 783: if (total_err > 0)
! 784: {
! 785: DBG1(DBG_APP, "### %d parsing error%s (%d fatal) ###",
! 786: total_err, (total_err > 1)?"s":"", cfg->err);
! 787: }
! 788: return cfg;
! 789: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>