Loading src/or/hs_common.c +34 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,40 @@ #include "hs_common.h" #include "rendcommon.h" /* Make sure that the directory for <b>service</b> is private, using the config * <b>username</b>. * If <b>create</b> is true: * - if the directory exists, change permissions if needed, * - if the directory does not exist, create it with the correct permissions. * If <b>create</b> is false: * - if the directory exists, check permissions, * - if the directory does not exist, check if we think we can create it. * Return 0 on success, -1 on failure. */ int hs_check_service_private_dir(const char *username, const char *path, unsigned int dir_group_readable, unsigned int create) { cpd_check_t check_opts = CPD_NONE; tor_assert(path); if (create) { check_opts |= CPD_CREATE; } else { check_opts |= CPD_CHECK_MODE_ONLY; check_opts |= CPD_CHECK; } if (dir_group_readable) { check_opts |= CPD_GROUP_READ; } /* Check/create directory */ if (check_private_dir(path, check_opts, username) < 0) { return -1; } return 0; } /* Create a new rend_data_t for a specific given <b>version</b>. * Return a pointer to the newly allocated data structure. */ static rend_data_t * Loading src/or/hs_common.h +23 −2 Original line number Diff line number Diff line Loading @@ -17,12 +17,33 @@ /* Version 3 of the protocol (prop224). */ #define HS_VERSION_THREE 3 /* Denotes ed25519 authentication key on ESTABLISH_INTRO cell. */ #define AUTH_KEY_ED25519 0x02 /** Try to maintain this many intro points per service by default. */ #define NUM_INTRO_POINTS_DEFAULT 3 /** Maximum number of intro points per service. */ #define NUM_INTRO_POINTS_MAX 10 /** Number of extra intro points we launch if our set of intro nodes is empty. * See proposal 155, section 4. */ #define NUM_INTRO_POINTS_EXTRA 2 /** If we can't build our intro circuits, don't retry for this long. */ #define INTRO_CIRC_RETRY_PERIOD (60*5) /** Don't try to build more than this many circuits before giving up for a * while.*/ #define MAX_INTRO_CIRCS_PER_PERIOD 10 /** How many times will a hidden service operator attempt to connect to a * requested rendezvous point before giving up? */ #define MAX_REND_FAILURES 1 /** How many seconds should we spend trying to connect to a requested * rendezvous point before giving up? */ #define MAX_REND_TIMEOUT 30 /* String prefix for the signature of ESTABLISH_INTRO */ #define ESTABLISH_INTRO_SIG_PREFIX "Tor establish-intro cell v1" int hs_check_service_private_dir(const char *username, const char *path, unsigned int dir_group_readable, unsigned int create); void rend_data_free(rend_data_t *data); rend_data_t *rend_data_dup(const rend_data_t *data); rend_data_t *rend_data_client_create(const char *onion_address, Loading src/or/hs_intropoint.c +2 −2 Original line number Diff line number Diff line Loading @@ -73,9 +73,9 @@ verify_establish_intro_cell(const trn_cell_establish_intro_t *cell, size_t circuit_key_material_len) { /* We only reach this function if the first byte of the cell is 0x02 which * means that auth_key_type is AUTH_KEY_ED25519, hence this check should * means that auth_key_type is of ed25519 type, hence this check should * always pass. See hs_intro_received_establish_intro(). */ if (BUG(cell->auth_key_type != AUTH_KEY_ED25519)) { if (BUG(cell->auth_key_type != HS_INTRO_AUTH_KEY_TYPE_ED25519)) { return -1; } Loading src/or/hs_service.c +3 −1 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ #include "circuitlist.h" #include "circpathbias.h" #include "hs_intropoint.h" #include "hs_service.h" #include "hs_common.h" Loading Loading @@ -75,7 +76,8 @@ generate_establish_intro_cell(const uint8_t *circuit_key_material, cell = trn_cell_establish_intro_new(); /* Set AUTH_KEY_TYPE: 2 means ed25519 */ trn_cell_establish_intro_set_auth_key_type(cell, AUTH_KEY_ED25519); trn_cell_establish_intro_set_auth_key_type(cell, HS_INTRO_AUTH_KEY_TYPE_ED25519); /* Set AUTH_KEY_LEN field */ /* Must also set byte-length of AUTH_KEY to match */ Loading src/or/rendservice.c +87 −87 Original line number Diff line number Diff line Loading @@ -76,9 +76,6 @@ static ssize_t rend_service_parse_intro_for_v3( static int rend_service_check_private_dir(const or_options_t *options, const rend_service_t *s, int create); static int rend_service_check_private_dir_impl(const or_options_t *options, const rend_service_t *s, int create); static const smartlist_t* rend_get_service_list( const smartlist_t* substitute_service_list); static smartlist_t* rend_get_service_list_mutable( Loading @@ -101,23 +98,6 @@ struct rend_service_port_config_s { char unix_addr[FLEXIBLE_ARRAY_MEMBER]; }; /** Try to maintain this many intro points per service by default. */ #define NUM_INTRO_POINTS_DEFAULT 3 /** Maximum number of intro points per service. */ #define NUM_INTRO_POINTS_MAX 10 /** Number of extra intro points we launch if our set of intro nodes is * empty. See proposal 155, section 4. */ #define NUM_INTRO_POINTS_EXTRA 2 /** If we can't build our intro circuits, don't retry for this long. */ #define INTRO_CIRC_RETRY_PERIOD (60*5) /** How many times will a hidden service operator attempt to connect to * a requested rendezvous point before giving up? */ #define MAX_REND_FAILURES 1 /** How many seconds should we spend trying to connect to a requested * rendezvous point before giving up? */ #define MAX_REND_TIMEOUT 30 /* Hidden service directory file names: * new file names should be added to rend_service_add_filenames_to_list() * for sandboxing purposes. */ Loading @@ -126,9 +106,12 @@ static const char *hostname_fname = "hostname"; static const char *client_keys_fname = "client_keys"; static const char *sos_poison_fname = "onion_service_non_anonymous"; /** A list of rend_service_t's for services run on this OP. */ /** A list of rend_service_t's for services run on this OP. */ static smartlist_t *rend_service_list = NULL; /** A list of rend_service_t's for services run on this OP which is used as a * staging area before they are put in the main list in order to prune dying * service on config reload. */ static smartlist_t *rend_service_staging_list = NULL; /* Like rend_get_service_list_mutable, but returns a read-only list. */ static const smartlist_t* Loading Loading @@ -540,18 +523,34 @@ rend_service_check_dir_and_add(smartlist_t *service_list, return rend_add_service(s_list, service); } /* If this is a reload and there were hidden services configured before, * keep the introduction points that are still needed and close the * other ones. */ /* Helper: Actual implementation of the pruning on reload which we've * decoupled in order to make the unit test workeable without ugly hacks. * Furthermore, this function does NOT free any memory but will nullify the * temporary list pointer whatever happens. */ STATIC void prune_services_on_reload(smartlist_t *old_service_list, smartlist_t *new_service_list) rend_service_prune_list_impl_(void) { origin_circuit_t *ocirc = NULL; smartlist_t *surviving_services = NULL; smartlist_t *surviving_services, *old_service_list, *new_service_list; tor_assert(old_service_list); tor_assert(new_service_list); /* When pruning our current service list, we must have a staging list that * contains what we want to check else it's a code flow error. */ tor_assert(rend_service_staging_list); /* We are about to prune the current list of its dead service so set the * semantic for that list to be the "old" one. */ old_service_list = rend_service_list; /* The staging list is now the "new" list so set this semantic. */ new_service_list = rend_service_staging_list; /* After this, whatever happens, we'll use our new list. */ rend_service_list = new_service_list; /* Finally, nullify the staging list pointer as we don't need it anymore * and it needs to be NULL before the next reload. */ rend_service_staging_list = NULL; /* Nothing to prune if we have no service list so stop right away. */ if (!old_service_list) { return; } /* This contains all _existing_ services that survives the relaod that is * that haven't been removed from the configuration. The difference between Loading Loading @@ -629,6 +628,27 @@ prune_services_on_reload(smartlist_t *old_service_list, smartlist_free(surviving_services); } /* Try to prune our main service list using the temporary one that we just * loaded and parsed successfully. The pruning process decides which onion * services to keep and which to discard after a reload. */ void rend_service_prune_list(void) { smartlist_t *old_service_list = rend_service_list; /* Don't try to prune anything if we have no staging list. */ if (!rend_service_staging_list) { return; } rend_service_prune_list_impl_(); if (old_service_list) { /* Every remaining service in the old list have been removed from the * configuration so clean them up safely. */ SMARTLIST_FOREACH(old_service_list, rend_service_t *, s, rend_service_free(s)); smartlist_free(old_service_list); } } /** Set up rend_service_list, based on the values of HiddenServiceDir and * HiddenServicePort in <b>options</b>. Return 0 on success and -1 on * failure. (If <b>validate_only</b> is set, parse, warn and return as Loading @@ -640,22 +660,22 @@ rend_config_services(const or_options_t *options, int validate_only) config_line_t *line; rend_service_t *service = NULL; rend_service_port_config_t *portcfg; smartlist_t *old_service_list = NULL; smartlist_t *temp_service_list = NULL; int ok = 0; int rv = -1; /* Use a temporary service list, so that we can check the new services' * consistency with each other */ temp_service_list = smartlist_new(); /* Use the staging service list so that we can check then do the pruning * process using the main list at the end. */ if (rend_service_staging_list == NULL) { rend_service_staging_list = smartlist_new(); } for (line = options->RendConfigLines; line; line = line->next) { if (!strcasecmp(line->key, "HiddenServiceDir")) { /* register the service we just finished parsing * this code registers every service except the last one parsed, * which is registered below the loop */ if (rend_service_check_dir_and_add(temp_service_list, options, service, validate_only) < 0) { if (rend_service_check_dir_and_add(rend_service_staging_list, options, service, validate_only) < 0) { service = NULL; goto free_and_return; } Loading Loading @@ -855,8 +875,8 @@ rend_config_services(const or_options_t *options, int validate_only) /* register the final service after we have finished parsing all services * this code only registers the last service, other services are registered * within the loop. It is ok for this service to be NULL, it is ignored. */ if (rend_service_check_dir_and_add(temp_service_list, options, service, validate_only) < 0) { if (rend_service_check_dir_and_add(rend_service_staging_list, options, service, validate_only) < 0) { service = NULL; goto free_and_return; } Loading @@ -868,31 +888,19 @@ rend_config_services(const or_options_t *options, int validate_only) goto free_and_return; } /* Otherwise, use the newly added services as the new service list * Since we have now replaced the global service list, from this point on we * must succeed, or die trying. */ old_service_list = rend_service_list; rend_service_list = temp_service_list; temp_service_list = NULL; /* If this is a reload and there were hidden services configured before, * keep the introduction points that are still needed and close the * other ones. */ if (old_service_list && !validate_only) { prune_services_on_reload(old_service_list, rend_service_list); /* Every remaining service in the old list have been removed from the * configuration so clean them up safely. */ SMARTLIST_FOREACH(old_service_list, rend_service_t *, s, rend_service_free(s)); smartlist_free(old_service_list); } /* This could be a reload of configuration so try to prune the main list * using the staging one. And we know we are not in validate mode here. * After this, the main and staging list will point to the right place and * be in a quiescent usable state. */ rend_service_prune_list(); return 0; free_and_return: rend_service_free(service); SMARTLIST_FOREACH(temp_service_list, rend_service_t *, ptr, SMARTLIST_FOREACH(rend_service_staging_list, rend_service_t *, ptr, rend_service_free(ptr)); smartlist_free(temp_service_list); smartlist_free(rend_service_staging_list); rend_service_staging_list = NULL; return rv; } Loading Loading @@ -1294,7 +1302,8 @@ poison_new_single_onion_hidden_service_dir_impl(const rend_service_t *service, } /* Make sure the directory was created before calling this function. */ if (BUG(rend_service_check_private_dir_impl(options, service, 0) < 0)) if (BUG(hs_check_service_private_dir(options->User, service->directory, service->dir_group_readable, 0) < 0)) return -1; poison_fname = rend_service_sos_poison_path(service); Loading Loading @@ -1444,32 +1453,6 @@ rend_service_derive_key_digests(struct rend_service_t *s) return 0; } /* Implements the directory check from rend_service_check_private_dir, * without doing the single onion poison checks. */ static int rend_service_check_private_dir_impl(const or_options_t *options, const rend_service_t *s, int create) { cpd_check_t check_opts = CPD_NONE; if (create) { check_opts |= CPD_CREATE; } else { check_opts |= CPD_CHECK_MODE_ONLY; check_opts |= CPD_CHECK; } if (s->dir_group_readable) { check_opts |= CPD_GROUP_READ; } /* Check/create directory */ if (check_private_dir(s->directory, check_opts, options->User) < 0) { log_warn(LD_REND, "Checking service directory %s failed.", s->directory); return -1; } return 0; } /** Make sure that the directory for <b>s</b> is private, using the config in * <b>options</b>. * If <b>create</b> is true: Loading @@ -1490,7 +1473,8 @@ rend_service_check_private_dir(const or_options_t *options, } /* Check/create directory */ if (rend_service_check_private_dir_impl(options, s, create) < 0) { if (hs_check_service_private_dir(options->User, s->directory, s->dir_group_readable, create) < 0) { return -1; } Loading Loading @@ -4595,3 +4579,19 @@ rend_service_non_anonymous_mode_enabled(const or_options_t *options) return options->HiddenServiceNonAnonymousMode ? 1 : 0; } #ifdef TOR_UNIT_TESTS STATIC void set_rend_service_list(smartlist_t *new_list) { rend_service_list = new_list; } STATIC void set_rend_rend_service_staging_list(smartlist_t *new_list) { rend_service_staging_list = new_list; } #endif /* TOR_UNIT_TESTS */ Loading
src/or/hs_common.c +34 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,40 @@ #include "hs_common.h" #include "rendcommon.h" /* Make sure that the directory for <b>service</b> is private, using the config * <b>username</b>. * If <b>create</b> is true: * - if the directory exists, change permissions if needed, * - if the directory does not exist, create it with the correct permissions. * If <b>create</b> is false: * - if the directory exists, check permissions, * - if the directory does not exist, check if we think we can create it. * Return 0 on success, -1 on failure. */ int hs_check_service_private_dir(const char *username, const char *path, unsigned int dir_group_readable, unsigned int create) { cpd_check_t check_opts = CPD_NONE; tor_assert(path); if (create) { check_opts |= CPD_CREATE; } else { check_opts |= CPD_CHECK_MODE_ONLY; check_opts |= CPD_CHECK; } if (dir_group_readable) { check_opts |= CPD_GROUP_READ; } /* Check/create directory */ if (check_private_dir(path, check_opts, username) < 0) { return -1; } return 0; } /* Create a new rend_data_t for a specific given <b>version</b>. * Return a pointer to the newly allocated data structure. */ static rend_data_t * Loading
src/or/hs_common.h +23 −2 Original line number Diff line number Diff line Loading @@ -17,12 +17,33 @@ /* Version 3 of the protocol (prop224). */ #define HS_VERSION_THREE 3 /* Denotes ed25519 authentication key on ESTABLISH_INTRO cell. */ #define AUTH_KEY_ED25519 0x02 /** Try to maintain this many intro points per service by default. */ #define NUM_INTRO_POINTS_DEFAULT 3 /** Maximum number of intro points per service. */ #define NUM_INTRO_POINTS_MAX 10 /** Number of extra intro points we launch if our set of intro nodes is empty. * See proposal 155, section 4. */ #define NUM_INTRO_POINTS_EXTRA 2 /** If we can't build our intro circuits, don't retry for this long. */ #define INTRO_CIRC_RETRY_PERIOD (60*5) /** Don't try to build more than this many circuits before giving up for a * while.*/ #define MAX_INTRO_CIRCS_PER_PERIOD 10 /** How many times will a hidden service operator attempt to connect to a * requested rendezvous point before giving up? */ #define MAX_REND_FAILURES 1 /** How many seconds should we spend trying to connect to a requested * rendezvous point before giving up? */ #define MAX_REND_TIMEOUT 30 /* String prefix for the signature of ESTABLISH_INTRO */ #define ESTABLISH_INTRO_SIG_PREFIX "Tor establish-intro cell v1" int hs_check_service_private_dir(const char *username, const char *path, unsigned int dir_group_readable, unsigned int create); void rend_data_free(rend_data_t *data); rend_data_t *rend_data_dup(const rend_data_t *data); rend_data_t *rend_data_client_create(const char *onion_address, Loading
src/or/hs_intropoint.c +2 −2 Original line number Diff line number Diff line Loading @@ -73,9 +73,9 @@ verify_establish_intro_cell(const trn_cell_establish_intro_t *cell, size_t circuit_key_material_len) { /* We only reach this function if the first byte of the cell is 0x02 which * means that auth_key_type is AUTH_KEY_ED25519, hence this check should * means that auth_key_type is of ed25519 type, hence this check should * always pass. See hs_intro_received_establish_intro(). */ if (BUG(cell->auth_key_type != AUTH_KEY_ED25519)) { if (BUG(cell->auth_key_type != HS_INTRO_AUTH_KEY_TYPE_ED25519)) { return -1; } Loading
src/or/hs_service.c +3 −1 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ #include "circuitlist.h" #include "circpathbias.h" #include "hs_intropoint.h" #include "hs_service.h" #include "hs_common.h" Loading Loading @@ -75,7 +76,8 @@ generate_establish_intro_cell(const uint8_t *circuit_key_material, cell = trn_cell_establish_intro_new(); /* Set AUTH_KEY_TYPE: 2 means ed25519 */ trn_cell_establish_intro_set_auth_key_type(cell, AUTH_KEY_ED25519); trn_cell_establish_intro_set_auth_key_type(cell, HS_INTRO_AUTH_KEY_TYPE_ED25519); /* Set AUTH_KEY_LEN field */ /* Must also set byte-length of AUTH_KEY to match */ Loading
src/or/rendservice.c +87 −87 Original line number Diff line number Diff line Loading @@ -76,9 +76,6 @@ static ssize_t rend_service_parse_intro_for_v3( static int rend_service_check_private_dir(const or_options_t *options, const rend_service_t *s, int create); static int rend_service_check_private_dir_impl(const or_options_t *options, const rend_service_t *s, int create); static const smartlist_t* rend_get_service_list( const smartlist_t* substitute_service_list); static smartlist_t* rend_get_service_list_mutable( Loading @@ -101,23 +98,6 @@ struct rend_service_port_config_s { char unix_addr[FLEXIBLE_ARRAY_MEMBER]; }; /** Try to maintain this many intro points per service by default. */ #define NUM_INTRO_POINTS_DEFAULT 3 /** Maximum number of intro points per service. */ #define NUM_INTRO_POINTS_MAX 10 /** Number of extra intro points we launch if our set of intro nodes is * empty. See proposal 155, section 4. */ #define NUM_INTRO_POINTS_EXTRA 2 /** If we can't build our intro circuits, don't retry for this long. */ #define INTRO_CIRC_RETRY_PERIOD (60*5) /** How many times will a hidden service operator attempt to connect to * a requested rendezvous point before giving up? */ #define MAX_REND_FAILURES 1 /** How many seconds should we spend trying to connect to a requested * rendezvous point before giving up? */ #define MAX_REND_TIMEOUT 30 /* Hidden service directory file names: * new file names should be added to rend_service_add_filenames_to_list() * for sandboxing purposes. */ Loading @@ -126,9 +106,12 @@ static const char *hostname_fname = "hostname"; static const char *client_keys_fname = "client_keys"; static const char *sos_poison_fname = "onion_service_non_anonymous"; /** A list of rend_service_t's for services run on this OP. */ /** A list of rend_service_t's for services run on this OP. */ static smartlist_t *rend_service_list = NULL; /** A list of rend_service_t's for services run on this OP which is used as a * staging area before they are put in the main list in order to prune dying * service on config reload. */ static smartlist_t *rend_service_staging_list = NULL; /* Like rend_get_service_list_mutable, but returns a read-only list. */ static const smartlist_t* Loading Loading @@ -540,18 +523,34 @@ rend_service_check_dir_and_add(smartlist_t *service_list, return rend_add_service(s_list, service); } /* If this is a reload and there were hidden services configured before, * keep the introduction points that are still needed and close the * other ones. */ /* Helper: Actual implementation of the pruning on reload which we've * decoupled in order to make the unit test workeable without ugly hacks. * Furthermore, this function does NOT free any memory but will nullify the * temporary list pointer whatever happens. */ STATIC void prune_services_on_reload(smartlist_t *old_service_list, smartlist_t *new_service_list) rend_service_prune_list_impl_(void) { origin_circuit_t *ocirc = NULL; smartlist_t *surviving_services = NULL; smartlist_t *surviving_services, *old_service_list, *new_service_list; tor_assert(old_service_list); tor_assert(new_service_list); /* When pruning our current service list, we must have a staging list that * contains what we want to check else it's a code flow error. */ tor_assert(rend_service_staging_list); /* We are about to prune the current list of its dead service so set the * semantic for that list to be the "old" one. */ old_service_list = rend_service_list; /* The staging list is now the "new" list so set this semantic. */ new_service_list = rend_service_staging_list; /* After this, whatever happens, we'll use our new list. */ rend_service_list = new_service_list; /* Finally, nullify the staging list pointer as we don't need it anymore * and it needs to be NULL before the next reload. */ rend_service_staging_list = NULL; /* Nothing to prune if we have no service list so stop right away. */ if (!old_service_list) { return; } /* This contains all _existing_ services that survives the relaod that is * that haven't been removed from the configuration. The difference between Loading Loading @@ -629,6 +628,27 @@ prune_services_on_reload(smartlist_t *old_service_list, smartlist_free(surviving_services); } /* Try to prune our main service list using the temporary one that we just * loaded and parsed successfully. The pruning process decides which onion * services to keep and which to discard after a reload. */ void rend_service_prune_list(void) { smartlist_t *old_service_list = rend_service_list; /* Don't try to prune anything if we have no staging list. */ if (!rend_service_staging_list) { return; } rend_service_prune_list_impl_(); if (old_service_list) { /* Every remaining service in the old list have been removed from the * configuration so clean them up safely. */ SMARTLIST_FOREACH(old_service_list, rend_service_t *, s, rend_service_free(s)); smartlist_free(old_service_list); } } /** Set up rend_service_list, based on the values of HiddenServiceDir and * HiddenServicePort in <b>options</b>. Return 0 on success and -1 on * failure. (If <b>validate_only</b> is set, parse, warn and return as Loading @@ -640,22 +660,22 @@ rend_config_services(const or_options_t *options, int validate_only) config_line_t *line; rend_service_t *service = NULL; rend_service_port_config_t *portcfg; smartlist_t *old_service_list = NULL; smartlist_t *temp_service_list = NULL; int ok = 0; int rv = -1; /* Use a temporary service list, so that we can check the new services' * consistency with each other */ temp_service_list = smartlist_new(); /* Use the staging service list so that we can check then do the pruning * process using the main list at the end. */ if (rend_service_staging_list == NULL) { rend_service_staging_list = smartlist_new(); } for (line = options->RendConfigLines; line; line = line->next) { if (!strcasecmp(line->key, "HiddenServiceDir")) { /* register the service we just finished parsing * this code registers every service except the last one parsed, * which is registered below the loop */ if (rend_service_check_dir_and_add(temp_service_list, options, service, validate_only) < 0) { if (rend_service_check_dir_and_add(rend_service_staging_list, options, service, validate_only) < 0) { service = NULL; goto free_and_return; } Loading Loading @@ -855,8 +875,8 @@ rend_config_services(const or_options_t *options, int validate_only) /* register the final service after we have finished parsing all services * this code only registers the last service, other services are registered * within the loop. It is ok for this service to be NULL, it is ignored. */ if (rend_service_check_dir_and_add(temp_service_list, options, service, validate_only) < 0) { if (rend_service_check_dir_and_add(rend_service_staging_list, options, service, validate_only) < 0) { service = NULL; goto free_and_return; } Loading @@ -868,31 +888,19 @@ rend_config_services(const or_options_t *options, int validate_only) goto free_and_return; } /* Otherwise, use the newly added services as the new service list * Since we have now replaced the global service list, from this point on we * must succeed, or die trying. */ old_service_list = rend_service_list; rend_service_list = temp_service_list; temp_service_list = NULL; /* If this is a reload and there were hidden services configured before, * keep the introduction points that are still needed and close the * other ones. */ if (old_service_list && !validate_only) { prune_services_on_reload(old_service_list, rend_service_list); /* Every remaining service in the old list have been removed from the * configuration so clean them up safely. */ SMARTLIST_FOREACH(old_service_list, rend_service_t *, s, rend_service_free(s)); smartlist_free(old_service_list); } /* This could be a reload of configuration so try to prune the main list * using the staging one. And we know we are not in validate mode here. * After this, the main and staging list will point to the right place and * be in a quiescent usable state. */ rend_service_prune_list(); return 0; free_and_return: rend_service_free(service); SMARTLIST_FOREACH(temp_service_list, rend_service_t *, ptr, SMARTLIST_FOREACH(rend_service_staging_list, rend_service_t *, ptr, rend_service_free(ptr)); smartlist_free(temp_service_list); smartlist_free(rend_service_staging_list); rend_service_staging_list = NULL; return rv; } Loading Loading @@ -1294,7 +1302,8 @@ poison_new_single_onion_hidden_service_dir_impl(const rend_service_t *service, } /* Make sure the directory was created before calling this function. */ if (BUG(rend_service_check_private_dir_impl(options, service, 0) < 0)) if (BUG(hs_check_service_private_dir(options->User, service->directory, service->dir_group_readable, 0) < 0)) return -1; poison_fname = rend_service_sos_poison_path(service); Loading Loading @@ -1444,32 +1453,6 @@ rend_service_derive_key_digests(struct rend_service_t *s) return 0; } /* Implements the directory check from rend_service_check_private_dir, * without doing the single onion poison checks. */ static int rend_service_check_private_dir_impl(const or_options_t *options, const rend_service_t *s, int create) { cpd_check_t check_opts = CPD_NONE; if (create) { check_opts |= CPD_CREATE; } else { check_opts |= CPD_CHECK_MODE_ONLY; check_opts |= CPD_CHECK; } if (s->dir_group_readable) { check_opts |= CPD_GROUP_READ; } /* Check/create directory */ if (check_private_dir(s->directory, check_opts, options->User) < 0) { log_warn(LD_REND, "Checking service directory %s failed.", s->directory); return -1; } return 0; } /** Make sure that the directory for <b>s</b> is private, using the config in * <b>options</b>. * If <b>create</b> is true: Loading @@ -1490,7 +1473,8 @@ rend_service_check_private_dir(const or_options_t *options, } /* Check/create directory */ if (rend_service_check_private_dir_impl(options, s, create) < 0) { if (hs_check_service_private_dir(options->User, s->directory, s->dir_group_readable, create) < 0) { return -1; } Loading Loading @@ -4595,3 +4579,19 @@ rend_service_non_anonymous_mode_enabled(const or_options_t *options) return options->HiddenServiceNonAnonymousMode ? 1 : 0; } #ifdef TOR_UNIT_TESTS STATIC void set_rend_service_list(smartlist_t *new_list) { rend_service_list = new_list; } STATIC void set_rend_rend_service_staging_list(smartlist_t *new_list) { rend_service_staging_list = new_list; } #endif /* TOR_UNIT_TESTS */