tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

hs_config.c (24384B)


      1 /* Copyright (c) 2017-2021, The Tor Project, Inc. */
      2 /* See LICENSE for licensing information */
      3 
      4 /**
      5 * \file hs_config.c
      6 * \brief Implement hidden service configuration subsystem.
      7 *
      8 * \details
      9 *
     10 * This file has basically one main entry point: hs_config_service_all(). It
     11 * takes the torrc options and configure hidden service from it. In validate
     12 * mode, nothing is added to the global service list or keys are not generated
     13 * nor loaded.
     14 *
     15 * A service is configured in two steps. It is first created using the tor
     16 * options and then put in a staging list. It will stay there until
     17 * hs_service_load_all_keys() is called. That function is responsible to
     18 * load/generate the keys for the service in the staging list and if
     19 * successful, transferred the service to the main global service list where
     20 * at that point it is ready to be used.
     21 *
     22 * Configuration functions are per-version and there is a main generic one for
     23 * every option that is common to all version (config_generic_service).
     24 **/
     25 
     26 #include "feature/hs/hs_common.h"
     27 #include "feature/hs/hs_config.h"
     28 #include "feature/hs/hs_client.h"
     29 #include "feature/hs/hs_ob.h"
     30 #include "feature/hs/hs_service.h"
     31 #include "lib/encoding/confline.h"
     32 #include "lib/conf/confdecl.h"
     33 #include "lib/confmgt/confmgt.h"
     34 
     35 #include "feature/hs/hs_opts_st.h"
     36 #include "app/config/or_options_st.h"
     37 
     38 /* Declare the table mapping hs options to hs_opts_t */
     39 #define CONF_CONTEXT TABLE
     40 #include "feature/hs/hs_options.inc"
     41 #undef CONF_CONTEXT
     42 
     43 /** Magic number for hs_opts_t. */
     44 #define HS_OPTS_MAGIC 0x6f6e796e
     45 
     46 static const config_format_t hs_opts_fmt = {
     47  .size = sizeof(hs_opts_t),
     48  .magic = { "hs_opts_t",
     49             HS_OPTS_MAGIC,
     50             offsetof(hs_opts_t, magic) },
     51  .vars = hs_opts_t_vars,
     52 };
     53 
     54 /** Global configuration manager to handle HS sections*/
     55 static config_mgr_t *hs_opts_mgr = NULL;
     56 
     57 /**
     58 * Return a configuration manager for the hs_opts_t configuration type.
     59 **/
     60 static const config_mgr_t *
     61 get_hs_opts_mgr(void)
     62 {
     63  if (PREDICT_UNLIKELY(hs_opts_mgr == NULL)) {
     64    hs_opts_mgr = config_mgr_new(&hs_opts_fmt);
     65    config_mgr_freeze(hs_opts_mgr);
     66  }
     67  return hs_opts_mgr;
     68 }
     69 
     70 /**
     71 * Allocate, initialize, and return a new hs_opts_t.
     72 **/
     73 static hs_opts_t *
     74 hs_opts_new(void)
     75 {
     76  const config_mgr_t *mgr = get_hs_opts_mgr();
     77  hs_opts_t *r = config_new(mgr);
     78  tor_assert(r);
     79  config_init(mgr, r);
     80  return r;
     81 }
     82 
     83 /**
     84 * Free an hs_opts_t.
     85 **/
     86 #define hs_opts_free(opts) \
     87  config_free(get_hs_opts_mgr(), (opts))
     88 
     89 /** Using the given list of services, stage them into our global state. Every
     90 * service version are handled. This function can remove entries in the given
     91 * service_list.
     92 *
     93 * Staging a service means that we take all services in service_list and we
     94 * put them in the staging list (global) which acts as a temporary list that
     95 * is used by the service loading key process. In other words, staging a
     96 * service puts it in a list to be considered when loading the keys and then
     97 * moved to the main global list. */
     98 static void
     99 stage_services(smartlist_t *service_list)
    100 {
    101  tor_assert(service_list);
    102 
    103  /* This is >= v3 specific. Using the newly configured service list, stage
    104   * them into our global state. Every object ownership is lost after. */
    105  hs_service_stage_services(service_list);
    106 }
    107 
    108 /** Validate the given service against all service in the given list. If the
    109 * service is ephemeral, this function ignores it. Services with the same
    110 * directory path aren't allowed and will return an error. If a duplicate is
    111 * found, 1 is returned else 0 if none found. */
    112 static int
    113 service_is_duplicate_in_list(const smartlist_t *service_list,
    114                             const hs_service_t *service)
    115 {
    116  int ret = 0;
    117 
    118  tor_assert(service_list);
    119  tor_assert(service);
    120 
    121  /* Ephemeral service don't have a directory configured so no need to check
    122   * for a service in the list having the same path. */
    123  if (service->config.is_ephemeral) {
    124    goto end;
    125  }
    126 
    127  /* XXX: Validate if we have any service that has the given service dir path.
    128   * This has two problems:
    129   *
    130   * a) It's O(n^2)
    131   *
    132   * b) We only compare directory paths as strings, so we can't
    133   *    detect two distinct paths that specify the same directory
    134   *    (which can arise from symlinks, case-insensitivity, bind
    135   *    mounts, etc.).
    136   *
    137   * It also can't detect that two separate Tor instances are trying
    138   * to use the same HiddenServiceDir; for that, we would need a
    139   * lock file.  But this is enough to detect a simple mistake that
    140   * at least one person has actually made. */
    141  SMARTLIST_FOREACH_BEGIN(service_list, const hs_service_t *, s) {
    142    if (!strcmp(s->config.directory_path, service->config.directory_path)) {
    143      log_warn(LD_REND, "Another hidden service is already configured "
    144                        "for directory %s",
    145               escaped(service->config.directory_path));
    146      ret = 1;
    147      goto end;
    148    }
    149  } SMARTLIST_FOREACH_END(s);
    150 
    151 end:
    152  return ret;
    153 }
    154 
    155 /** Check whether an integer <b>i</b> is out of bounds (not between <b>low</b>
    156 * and <b>high</b> incusive).  If it is, then log a warning about the option
    157 * <b>name</b>, and return true. Otherwise return false. */
    158 static bool
    159 check_value_oob(int i, const char *name, int low, int high)
    160 {
    161  if (i < low || i > high) {
    162    if (low == high) {
    163      log_warn(LD_CONFIG, "%s must be %d, not %d.", name, low, i);
    164    } else {
    165      log_warn(LD_CONFIG, "%s must be between %d and %d, not %d.",
    166               name, low, high, i);
    167    }
    168    return true;
    169  }
    170  return false;
    171 }
    172 
    173 /**
    174 * Helper: check whether the integer value called <b>name</b> in <b>opts</b>
    175 * is out-of-bounds.
    176 **/
    177 #define CHECK_OOB(opts, name, low, high)      \
    178  check_value_oob((opts)->name, #name, (low), (high))
    179 
    180 /** Helper function: Given a configuration option and its value, parse the
    181 * value as a hs_circuit_id_protocol_t. On success, ok is set to 1 and ret is
    182 * the parse value. On error, ok is set to 0 and the "none"
    183 * hs_circuit_id_protocol_t is returned. This function logs on error. */
    184 static hs_circuit_id_protocol_t
    185 helper_parse_circuit_id_protocol(const char *key, const char *value, int *ok)
    186 {
    187  tor_assert(value);
    188  tor_assert(ok);
    189 
    190  hs_circuit_id_protocol_t ret = HS_CIRCUIT_ID_PROTOCOL_NONE;
    191  *ok = 0;
    192 
    193  if (! strcasecmp(value, "haproxy")) {
    194    *ok = 1;
    195    ret = HS_CIRCUIT_ID_PROTOCOL_HAPROXY;
    196  } else if (! strcasecmp(value, "none")) {
    197    *ok = 1;
    198    ret = HS_CIRCUIT_ID_PROTOCOL_NONE;
    199  } else {
    200    log_warn(LD_CONFIG, "%s must be 'haproxy' or 'none'.", key);
    201    goto err;
    202  }
    203 
    204 err:
    205  return ret;
    206 }
    207 
    208 /** Return the service version by trying to learn it from the key on disk if
    209 * any. If nothing is found, the current service configured version is
    210 * returned. */
    211 static int
    212 config_learn_service_version(hs_service_t *service)
    213 {
    214  int version;
    215 
    216  tor_assert(service);
    217 
    218  version = hs_service_get_version_from_key(service);
    219  if (version < 0) {
    220    version = service->config.version;
    221  }
    222 
    223  return version;
    224 }
    225 
    226 /**
    227 * Header key indicating the start of a new hidden service configuration
    228 * block.
    229 **/
    230 static const char SECTION_HEADER[] = "HiddenServiceDir";
    231 
    232 /** Return true iff the given options starting at line_ for a hidden service
    233 * contains at least one invalid option. Each hidden service option don't
    234 * apply to all versions so this function can find out. The line_ MUST start
    235 * right after the HiddenServiceDir line of this service.
    236 *
    237 * This is mainly for usability so we can inform the user of any invalid
    238 * option for the hidden service version instead of silently ignoring. */
    239 static int
    240 config_has_invalid_options(const config_line_t *line_,
    241                           const hs_service_t *service)
    242 {
    243  int ret = 0;
    244  const char **optlist;
    245  const config_line_t *line;
    246 
    247  tor_assert(service);
    248  tor_assert(service->config.version <= HS_VERSION_MAX);
    249 
    250  /* List of options that a v3 service doesn't support thus must exclude from
    251   * its configuration. */
    252  const char *opts_exclude_v3[] = {
    253    "HiddenServiceAuthorizeClient",
    254    NULL /* End marker. */
    255  };
    256 
    257  /* Defining the size explicitly allows us to take advantage of the compiler
    258   * which warns us if we ever bump the max version but forget to grow this
    259   * array. The plus one is because we have a version 0 :). */
    260  struct {
    261    const char **list;
    262  } exclude_lists[HS_VERSION_MAX + 1] = {
    263    { NULL }, /* v0. */
    264    { NULL }, /* v1. */
    265    { NULL }, /* v2. */
    266    { opts_exclude_v3 }, /* v3. */
    267  };
    268 
    269  optlist = exclude_lists[service->config.version].list;
    270  if (optlist == NULL) {
    271    /* No exclude options to look at for this version. */
    272    goto end;
    273  }
    274  for (int i = 0; optlist[i]; i++) {
    275    const char *opt = optlist[i];
    276    for (line = line_; line; line = line->next) {
    277      if (!strcasecmp(line->key, SECTION_HEADER)) {
    278        /* We just hit the next hidden service, stop right now.
    279         * (This shouldn't be possible, now that we have partitioned the list
    280         * into sections.) */
    281        tor_assert_nonfatal_unreached();
    282        goto end;
    283      }
    284      if (!strcasecmp(line->key, opt)) {
    285        log_warn(LD_CONFIG, "Hidden service option %s is incompatible with "
    286                            "version %" PRIu32 " of service in %s",
    287                 opt, service->config.version,
    288                 service->config.directory_path);
    289        ret = 1;
    290        /* Continue the loop so we can find all possible options. */
    291        continue;
    292      }
    293    }
    294  }
    295 end:
    296  return ret;
    297 }
    298 
    299 /** Validate service configuration. This is used when loading the configuration
    300 * and once we've setup a service object, it's config object is passed to this
    301 * function for further validation. This does not validate service key
    302 * material. Return 0 if valid else -1 if invalid. */
    303 static int
    304 config_validate_service(const hs_service_config_t *config)
    305 {
    306  tor_assert(config);
    307 
    308  /* Amount of ports validation. */
    309  if (!config->ports || smartlist_len(config->ports) == 0) {
    310    log_warn(LD_CONFIG, "Hidden service (%s) with no ports configured.",
    311             escaped(config->directory_path));
    312    goto invalid;
    313  }
    314 
    315  /* DoS validation values. */
    316  if (config->has_dos_defense_enabled &&
    317      (config->intro_dos_burst_per_sec < config->intro_dos_rate_per_sec)) {
    318    log_warn(LD_CONFIG, "Hidden service DoS defenses burst (%" PRIu32 ") can "
    319                        "not be smaller than the rate value (%" PRIu32 ").",
    320             config->intro_dos_burst_per_sec, config->intro_dos_rate_per_sec);
    321    goto invalid;
    322  }
    323  if (config->has_pow_defenses_enabled &&
    324      (config->pow_queue_burst < config->pow_queue_rate)) {
    325    log_warn(LD_CONFIG, "Hidden service PoW queue burst (%" PRIu32 ") can "
    326                        "not be smaller than the rate value (%" PRIu32 ").",
    327             config->pow_queue_burst, config->pow_queue_rate);
    328    goto invalid;
    329  }
    330  if (config->has_pow_defenses_enabled && !have_module_pow()) {
    331    log_warn(LD_CONFIG, "Hidden service proof-of-work defenses are enabled "
    332                        "in our configuration but this build of tor does not "
    333                        "include the required 'pow' module.");
    334    goto invalid;
    335  }
    336 
    337  /* Valid. */
    338  return 0;
    339 invalid:
    340  return -1;
    341 }
    342 
    343 /** Configuration function for a version 3 service. The given service
    344 * object must be already allocated and passed through
    345 * config_generic_service() prior to calling this function.
    346 *
    347 * Return 0 on success else a negative value. */
    348 static int
    349 config_service_v3(const hs_opts_t *hs_opts,
    350                  hs_service_config_t *config)
    351 {
    352  tor_assert(config);
    353  tor_assert(hs_opts);
    354 
    355  /* Number of introduction points. */
    356  if (CHECK_OOB(hs_opts, HiddenServiceNumIntroductionPoints,
    357                NUM_INTRO_POINTS_DEFAULT,
    358                HS_CONFIG_V3_MAX_INTRO_POINTS)) {
    359    goto err;
    360  }
    361  config->num_intro_points = hs_opts->HiddenServiceNumIntroductionPoints;
    362 
    363  /* Circuit ID export setting. */
    364  if (hs_opts->HiddenServiceExportCircuitID) {
    365    int ok;
    366    config->circuit_id_protocol =
    367      helper_parse_circuit_id_protocol("HiddenServiceExportCircuitID",
    368                                       hs_opts->HiddenServiceExportCircuitID,
    369                                       &ok);
    370    if (!ok) {
    371      goto err;
    372    }
    373  }
    374 
    375  /* Is the DoS defense enabled? */
    376  config->has_dos_defense_enabled =
    377    hs_opts->HiddenServiceEnableIntroDoSDefense;
    378 
    379  /* Rate for DoS defense */
    380  if (CHECK_OOB(hs_opts, HiddenServiceEnableIntroDoSRatePerSec,
    381                 HS_CONFIG_V3_DOS_DEFENSE_RATE_PER_SEC_MIN,
    382                 HS_CONFIG_V3_DOS_DEFENSE_RATE_PER_SEC_MAX)) {
    383    goto err;
    384  }
    385  config->intro_dos_rate_per_sec =
    386    hs_opts->HiddenServiceEnableIntroDoSRatePerSec;
    387  log_info(LD_REND, "Service INTRO2 DoS defenses rate set to: %" PRIu32,
    388           config->intro_dos_rate_per_sec);
    389 
    390  if (CHECK_OOB(hs_opts, HiddenServiceEnableIntroDoSBurstPerSec,
    391                HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_MIN,
    392                HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_MAX)) {
    393    goto err;
    394  }
    395  config->intro_dos_burst_per_sec =
    396    hs_opts->HiddenServiceEnableIntroDoSBurstPerSec;
    397  log_info(LD_REND, "Service INTRO2 DoS defenses burst set to: %" PRIu32,
    398           config->intro_dos_burst_per_sec);
    399 
    400  /* Is this an onionbalance instance? */
    401  if (hs_opts->HiddenServiceOnionBalanceInstance) {
    402    /* Option is enabled, parse config file. */
    403    if (! hs_ob_parse_config_file(config)) {
    404      goto err;
    405    }
    406  }
    407 
    408  /* Are the PoW anti-DoS defenses enabled? */
    409  config->has_pow_defenses_enabled = hs_opts->HiddenServicePoWDefensesEnabled;
    410  config->pow_queue_rate = hs_opts->HiddenServicePoWQueueRate;
    411  config->pow_queue_burst = hs_opts->HiddenServicePoWQueueBurst;
    412 
    413  log_info(LD_REND, "Service PoW defenses are %s",
    414           config->has_pow_defenses_enabled ? "enabled" : "disabled");
    415  if (config->has_pow_defenses_enabled) {
    416    log_info(LD_REND, "Service PoW queue rate set to: %" PRIu32,
    417             config->pow_queue_rate);
    418    log_info(LD_REND, "Service PoW queue burst set to: %" PRIu32,
    419             config->pow_queue_burst);
    420  }
    421 
    422  /* We do not load the key material for the service at this stage. This is
    423   * done later once tor can confirm that it is in a running state. */
    424 
    425  /* We are about to return a fully configured service so do one last pass of
    426   * validation at it. */
    427  if (config_validate_service(config) < 0) {
    428    goto err;
    429  }
    430 
    431  return 0;
    432 err:
    433  return -1;
    434 }
    435 
    436 /** Configure a service using the given options in hs_opts and options. This is
    437 * called for any service regardless of its version which means that all
    438 * directives in this function are generic to any service version. This
    439 * function will also check the validity of the service directory path.
    440 *
    441 * The line_ must be pointing to the directive directly after a
    442 * HiddenServiceDir. That way, when hitting the next HiddenServiceDir line or
    443 * reaching the end of the list of lines, we know that we have to stop looking
    444 * for more options.
    445 *
    446 * Return 0 on success else -1. */
    447 static int
    448 config_generic_service(const hs_opts_t *hs_opts,
    449                       const or_options_t *options,
    450                       hs_service_t *service)
    451 {
    452  hs_service_config_t *config;
    453 
    454  tor_assert(hs_opts);
    455  tor_assert(options);
    456  tor_assert(service);
    457 
    458  /* Makes thing easier. */
    459  config = &service->config;
    460 
    461  /* Directory where the service's keys are stored. */
    462  tor_assert(hs_opts->HiddenServiceDir);
    463  config->directory_path = tor_strdup(hs_opts->HiddenServiceDir);
    464  log_info(LD_CONFIG, "%s=%s. Configuring...",
    465           SECTION_HEADER, escaped(config->directory_path));
    466 
    467  /* Protocol version for the service. */
    468  if (hs_opts->HiddenServiceVersion == -1) {
    469    /* No value was set; stay with the default. */
    470  } else if (hs_opts->HiddenServiceVersion == 2) {
    471    log_warn(LD_CONFIG, "Onion services version 2 are obsolete. Please see "
    472                        "https://blog.torproject.org/v2-deprecation-timeline "
    473                        "for more details and for instructions on how to "
    474                        "transition to version 3.");
    475    goto err;
    476  } else if (CHECK_OOB(hs_opts, HiddenServiceVersion,
    477                       HS_VERSION_MIN, HS_VERSION_MAX)) {
    478    goto err;
    479  } else {
    480    config->hs_version_explicitly_set = 1;
    481    config->version = hs_opts->HiddenServiceVersion;
    482  }
    483 
    484  /* Virtual port. */
    485  for (const config_line_t *portline = hs_opts->HiddenServicePort;
    486       portline; portline = portline->next) {
    487    char *err_msg = NULL;
    488    /* XXX: Can we rename this? */
    489    hs_port_config_t *portcfg =
    490      hs_parse_port_config(portline->value, " ", &err_msg);
    491    if (!portcfg) {
    492      if (err_msg) {
    493        log_warn(LD_CONFIG, "%s", err_msg);
    494      }
    495      tor_free(err_msg);
    496      goto err;
    497    }
    498    tor_assert(!err_msg);
    499    smartlist_add(config->ports, portcfg);
    500    log_info(LD_CONFIG, "HiddenServicePort=%s for %s",
    501             portline->value, escaped(config->directory_path));
    502  }
    503 
    504  /* Do we allow unknown ports? */
    505  config->allow_unknown_ports = hs_opts->HiddenServiceAllowUnknownPorts;
    506 
    507  /* Directory group readable. */
    508  config->dir_group_readable = hs_opts->HiddenServiceDirGroupReadable;
    509 
    510  /* Maximum streams per circuit. */
    511  if (CHECK_OOB(hs_opts, HiddenServiceMaxStreams,
    512                0, HS_CONFIG_MAX_STREAMS_PER_RDV_CIRCUIT)) {
    513    goto err;
    514  }
    515  config->max_streams_per_rdv_circuit = hs_opts->HiddenServiceMaxStreams;
    516 
    517  /* Maximum amount of streams before we close the circuit. */
    518  config->max_streams_close_circuit =
    519    hs_opts->HiddenServiceMaxStreamsCloseCircuit;
    520 
    521  /* Check if we are configured in non anonymous mode meaning every service
    522   * becomes a single onion service. */
    523  if (hs_service_non_anonymous_mode_enabled(options)) {
    524    config->is_single_onion = 1;
    525  }
    526 
    527  /* Success */
    528  return 0;
    529 err:
    530  return -1;
    531 }
    532 
    533 /** Configure a service using the given line and options. This function will
    534 * call the corresponding configuration function for a specific service
    535 * version and validate the service against the other ones. On success, add
    536 * the service to the given list and return 0. On error, nothing is added to
    537 * the list and a negative value is returned. */
    538 static int
    539 config_service(config_line_t *line, const or_options_t *options,
    540               smartlist_t *service_list)
    541 {
    542  int ret;
    543  hs_service_t *service = NULL;
    544  hs_opts_t *hs_opts = NULL;
    545  char *msg = NULL;
    546 
    547  tor_assert(line);
    548  tor_assert(options);
    549  tor_assert(service_list);
    550 
    551  /* We have a new hidden service. */
    552  service = hs_service_new(options);
    553 
    554  /* Try to validate and parse the configuration lines into 'hs_opts' */
    555  hs_opts = hs_opts_new();
    556  ret = config_assign(get_hs_opts_mgr(), hs_opts, line, 0, &msg);
    557  if (ret < 0) {
    558    log_warn(LD_REND, "Can't parse configuration for onion service: %s", msg);
    559    goto err;
    560  }
    561  tor_assert_nonfatal(msg == NULL);
    562  validation_status_t vs = config_validate(get_hs_opts_mgr(), NULL,
    563                                           hs_opts, &msg);
    564  if (vs < 0) {
    565    log_warn(LD_REND, "Bad configuration for onion service: %s", msg);
    566    goto err;
    567  }
    568  tor_assert_nonfatal(msg == NULL);
    569 
    570  /* We'll configure that service as a generic one and then pass it to a
    571   * specific function according to the configured version number. */
    572  if (config_generic_service(hs_opts, options, service) < 0) {
    573    goto err;
    574  }
    575 
    576  tor_assert(service->config.version <= HS_VERSION_MAX);
    577 
    578  /* If we're running with TestingTorNetwork enabled, we relax the permissions
    579   * check on the hs directory. */
    580  if (!options->TestingTorNetwork) {
    581    /* Check permission on service directory that was just parsed. And this
    582     * must be done regardless of the service version. Do not ask for the
    583     * directory to be created, this is done when the keys are loaded because
    584     * we could be in validation mode right now. */
    585    if (hs_check_service_private_dir(options->User,
    586                                     service->config.directory_path,
    587                                     service->config.dir_group_readable,
    588                                     0) < 0) {
    589      goto err;
    590    }
    591  }
    592 
    593  /* We'll try to learn the service version here by loading the key(s) if
    594   * present and we did not set HiddenServiceVersion. Depending on the key
    595   * format, we can figure out the service version. */
    596  if (!service->config.hs_version_explicitly_set) {
    597    service->config.version = config_learn_service_version(service);
    598  }
    599 
    600  /* We make sure that this set of options for a service are valid. */
    601  if (config_has_invalid_options(line->next, service)) {
    602    goto err;
    603  }
    604 
    605  /* Different functions are in charge of specific options for a version. We
    606   * start just after the service directory line so once we hit another
    607   * directory line, the function knows that it has to stop parsing. */
    608  switch (service->config.version) {
    609  case HS_VERSION_THREE:
    610    ret = config_service_v3(hs_opts, &service->config);
    611    break;
    612  default:
    613    /* We do validate before if we support the parsed version. */
    614    tor_assert_nonfatal_unreached();
    615    goto err;
    616  }
    617  if (ret < 0) {
    618    goto err;
    619  }
    620 
    621  /* We'll check if this service can be kept depending on the others
    622   * configured previously. */
    623  if (service_is_duplicate_in_list(service_list, service)) {
    624    goto err;
    625  }
    626 
    627  /* Passes, add it to the given list. */
    628  smartlist_add(service_list, service);
    629  hs_opts_free(hs_opts);
    630 
    631  return 0;
    632 
    633 err:
    634  hs_service_free(service);
    635  hs_opts_free(hs_opts);
    636  tor_free(msg);
    637  return -1;
    638 }
    639 
    640 /** From a set of <b>options</b>, setup every hidden service found. Return 0 on
    641 * success or -1 on failure. If <b>validate_only</b> is set, parse, warn and
    642 * return as normal, but don't actually change the configured services. */
    643 int
    644 hs_config_service_all(const or_options_t *options, int validate_only)
    645 {
    646  int ret = -1;
    647  config_line_t *remaining = NULL;
    648  smartlist_t *new_service_list = NULL;
    649 
    650  tor_assert(options);
    651 
    652  /* Newly configured service are put in that list which is then used for
    653   * validation and staging for >= v3. */
    654  new_service_list = smartlist_new();
    655 
    656  /* We need to start with a HiddenServiceDir line */
    657  if (options->RendConfigLines &&
    658      strcasecmp(options->RendConfigLines->key, SECTION_HEADER)) {
    659    log_warn(LD_CONFIG, "%s with no preceding %s directive",
    660             options->RendConfigLines->key, SECTION_HEADER);
    661    goto err;
    662  }
    663 
    664  remaining = config_lines_dup(options->RendConfigLines);
    665  while (remaining) {
    666    config_line_t *section = remaining;
    667    remaining = config_lines_partition(section, SECTION_HEADER);
    668 
    669    /* Try to configure this service now. On success, it will be added to the
    670     * list and validated against the service in that same list. */
    671    int rv = config_service(section, options, new_service_list);
    672    config_free_lines(section);
    673    if (rv < 0) {
    674      config_free_lines(remaining);
    675      goto err;
    676    }
    677  }
    678 
    679  /* In non validation mode, we'll stage those services we just successfully
    680   * configured. Service ownership is transferred from the list to the global
    681   * state. If any service is invalid, it will be removed from the list and
    682   * freed. All versions are handled in that function. */
    683  if (!validate_only) {
    684    stage_services(new_service_list);
    685  } else {
    686    /* We've just validated that we were able to build a clean working list of
    687     * services. We don't need those objects anymore. */
    688    SMARTLIST_FOREACH(new_service_list, hs_service_t *, s,
    689                      hs_service_free(s));
    690  }
    691 
    692  /* Success. Note that the service list has no ownership of its content. */
    693  ret = 0;
    694  goto end;
    695 
    696 err:
    697  SMARTLIST_FOREACH(new_service_list, hs_service_t *, s, hs_service_free(s));
    698 
    699 end:
    700  smartlist_free(new_service_list);
    701  /* Tor main should call the free all function on error. */
    702  return ret;
    703 }
    704 
    705 /** From a set of <b>options</b>, setup every client authorization found.
    706 * Return 0 on success or -1 on failure. If <b>validate_only</b> is set,
    707 * parse, warn and return as normal, but don't actually change the
    708 * configured state. */
    709 int
    710 hs_config_client_auth_all(const or_options_t *options, int validate_only)
    711 {
    712  int ret = -1;
    713 
    714  /* Configure v3 authorization. */
    715  if (hs_config_client_authorization(options, validate_only) < 0) {
    716    goto done;
    717  }
    718 
    719  /* Success. */
    720  ret = 0;
    721 done:
    722  return ret;
    723 }
    724 
    725 /**
    726 * Free all resources held by the hs_config.c module.
    727 **/
    728 void
    729 hs_config_free_all(void)
    730 {
    731  config_mgr_free(hs_opts_mgr);
    732 }