From 8841a9e396372771a170656ebfab4b4bf6b0c593 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 31 Oct 2016 14:53:30 -0400 Subject: [PATCH 01/13] Create single-onion-service directory before poisoning it, if needed (Also, refactor the code to create a hidden service directory into a separate funcion, so we don't have to duplicate it.) Fixes bug 20484; bugfix on 0.2.9.3-alpha. --- changes/bug20484 | 5 +++++ src/or/rendservice.c | 33 +++++++++++++++++++++++++-------- 2 files changed, 30 insertions(+), 8 deletions(-) create mode 100644 changes/bug20484 diff --git a/changes/bug20484 b/changes/bug20484 new file mode 100644 index 000000000..9a0b95cb3 --- /dev/null +++ b/changes/bug20484 @@ -0,0 +1,5 @@ + o Minor bugfixes (single onion services): + - Start correctly when creating a single onion service in a + directory that did not previously exist. Fixes bug 20484; bugfix on + 0.2.9.3-alpha. + diff --git a/src/or/rendservice.c b/src/or/rendservice.c index 3afe88055..1bf6ae94f 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -72,6 +72,8 @@ static ssize_t rend_service_parse_intro_for_v3( size_t plaintext_len, char **err_msg_out); +static int rend_service_check_and_create_private_dir(const rend_service_t *s); + /** Represents the mapping from a virtual port of a rendezvous service to * a real port on some IP. */ @@ -1090,6 +1092,10 @@ poison_new_single_onion_hidden_service_dir(const rend_service_t *service) return -1; } + /* Make sure the directory exists */ + if (rend_service_check_and_create_private_dir(service) < 0) + return -1; + poison_fname = rend_service_sos_poison_path(service); switch (file_status(poison_fname)) { @@ -1245,22 +1251,18 @@ rend_service_derive_key_digests(struct rend_service_t *s) return 0; } -/** Load and/or generate private keys for the hidden service s, - * possibly including keys for client authorization. Return 0 on success, -1 - * on failure. */ +/** Make sure that the directory for s is private, creating it + * if needed. Return 0 on success, -1 on failure. */ static int -rend_service_load_keys(rend_service_t *s) +rend_service_check_and_create_private_dir(const rend_service_t *s) { - char *fname = NULL; - char buf[128]; cpd_check_t check_opts = CPD_CREATE; - if (s->dir_group_readable) { check_opts |= CPD_GROUP_READ; } /* Check/create directory */ if (check_private_dir(s->directory, check_opts, get_options()->User) < 0) { - goto err; + return -1; } #ifndef _WIN32 if (s->dir_group_readable) { @@ -1271,6 +1273,21 @@ rend_service_load_keys(rend_service_t *s) } #endif + return 0; +} + +/** Load and/or generate private keys for the hidden service s, + * possibly including keys for client authorization. Return 0 on success, -1 + * on failure. */ +static int +rend_service_load_keys(rend_service_t *s) +{ + char *fname = NULL; + char buf[128]; + + if (rend_service_check_and_create_private_dir(s) < 0) + goto err; + /* Load key */ fname = rend_service_path(s, private_key_fname); s->private_key = init_key_from_file(fname, 1, LOG_ERR, 0); From c9db775243dc83c3300e7a88e0ad6afc74671825 Mon Sep 17 00:00:00 2001 From: teor Date: Wed, 2 Nov 2016 11:16:00 +1100 Subject: [PATCH 02/13] Refactor, adding a create argument to rend_service_check_private_dir It used to be rend_service_check_and_create_private_dir, which always created the directory. No behaviour change. --- src/or/rendservice.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/or/rendservice.c b/src/or/rendservice.c index 1bf6ae94f..610ed759a 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -72,7 +72,7 @@ static ssize_t rend_service_parse_intro_for_v3( size_t plaintext_len, char **err_msg_out); -static int rend_service_check_and_create_private_dir(const rend_service_t *s); +static int rend_service_check_private_dir(const rend_service_t *s, int create); /** Represents the mapping from a virtual port of a rendezvous service to * a real port on some IP. @@ -674,12 +674,7 @@ rend_config_services(const or_options_t *options, int validate_only) } } if (service) { - cpd_check_t check_opts = CPD_CHECK_MODE_ONLY|CPD_CHECK; - if (service->dir_group_readable) { - check_opts |= CPD_GROUP_READ; - } - - if (check_private_dir(service->directory, check_opts, options->User) < 0) { + if (rend_service_check_private_dir(service, 0) < 0) { rend_service_free(service); return -1; } @@ -1093,7 +1088,7 @@ poison_new_single_onion_hidden_service_dir(const rend_service_t *service) } /* Make sure the directory exists */ - if (rend_service_check_and_create_private_dir(service) < 0) + if (rend_service_check_private_dir(service, 1) < 0) return -1; poison_fname = rend_service_sos_poison_path(service); @@ -1251,12 +1246,18 @@ rend_service_derive_key_digests(struct rend_service_t *s) return 0; } -/** Make sure that the directory for s is private, creating it - * if needed. Return 0 on success, -1 on failure. */ +/** Make sure that the directory for s is private. If create is + * true, if it exists, change permissions if needed, otherwise, create it with + * the correct permissions. Otherwise, if create is false and the + * directory does not exist, check if we think we can create it. + * Return 0 on success, -1 on failure. */ static int -rend_service_check_and_create_private_dir(const rend_service_t *s) +rend_service_check_private_dir(const rend_service_t *s, int create) { cpd_check_t check_opts = CPD_CREATE; + if (!create) { + check_opts |= CPD_CHECK_MODE_ONLY; + } if (s->dir_group_readable) { check_opts |= CPD_GROUP_READ; } @@ -1265,7 +1266,7 @@ rend_service_check_and_create_private_dir(const rend_service_t *s) return -1; } #ifndef _WIN32 - if (s->dir_group_readable) { + if (s->dir_group_readable && create) { /* Only new dirs created get new opts, also enforce group read. */ if (chmod(s->directory, 0750)) { log_warn(LD_FS,"Unable to make %s group-readable.", s->directory); @@ -1285,7 +1286,7 @@ rend_service_load_keys(rend_service_t *s) char *fname = NULL; char buf[128]; - if (rend_service_check_and_create_private_dir(s) < 0) + if (rend_service_check_private_dir(s, 1) < 0) goto err; /* Load key */ From 6c541815592b76ecb7dc639123bce894bf47b67f Mon Sep 17 00:00:00 2001 From: teor Date: Wed, 2 Nov 2016 11:20:49 +1100 Subject: [PATCH 03/13] Remove redundant group permission code from rend_service_check_private_dir check_private_dir already does this for existing directories. --- src/or/rendservice.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/or/rendservice.c b/src/or/rendservice.c index 610ed759a..dca775e04 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -1265,15 +1265,6 @@ rend_service_check_private_dir(const rend_service_t *s, int create) if (check_private_dir(s->directory, check_opts, get_options()->User) < 0) { return -1; } -#ifndef _WIN32 - if (s->dir_group_readable && create) { - /* Only new dirs created get new opts, also enforce group read. */ - if (chmod(s->directory, 0750)) { - log_warn(LD_FS,"Unable to make %s group-readable.", s->directory); - } - } -#endif - return 0; } From fedafe7c0eb9eda0d11dd1b5ba37b7faff625c88 Mon Sep 17 00:00:00 2001 From: teor Date: Wed, 2 Nov 2016 11:37:05 +1100 Subject: [PATCH 04/13] Use check_private_dir in test_single_onion_poisoning This avoids Win32 conditionals for mkdir. --- src/test/test_hs.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/test/test_hs.c b/src/test/test_hs.c index fd5ab1564..39a2c914a 100644 --- a/src/test/test_hs.c +++ b/src/test/test_hs.c @@ -550,20 +550,11 @@ test_single_onion_poisoning(void *arg) tt_assert(ret == 0); /* Create directories for both services */ - -#ifdef _WIN32 - ret = mkdir(mock_options->DataDirectory); + ret = check_private_dir(mock_options->DataDirectory, CPD_CREATE, NULL); tt_assert(ret == 0); - ret = mkdir(dir1); + ret = check_private_dir(dir1, CPD_CREATE, NULL); tt_assert(ret == 0); - ret = mkdir(dir2); -#else - ret = mkdir(mock_options->DataDirectory, 0700); - tt_assert(ret == 0); - ret = mkdir(dir1, 0700); - tt_assert(ret == 0); - ret = mkdir(dir2, 0700); -#endif + ret = check_private_dir(dir2, CPD_CREATE, NULL); tt_assert(ret == 0); service_1->directory = dir1; @@ -694,7 +685,7 @@ test_single_onion_poisoning(void *arg) tt_assert(ret < 0); done: - /* TODO: should we delete the directories here? */ + /* The test harness deletes the directories at exit */ rend_service_free(service_1); rend_service_free(service_2); smartlist_free(services); From a906ff88a3660ff689a2bd630836b74d70a1ce6c Mon Sep 17 00:00:00 2001 From: teor Date: Wed, 2 Nov 2016 14:10:52 +1100 Subject: [PATCH 05/13] fixup! Refactor, adding a create argument to rend_service_check_private_dir --- src/or/rendservice.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/or/rendservice.c b/src/or/rendservice.c index dca775e04..6743d825b 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -1246,17 +1246,23 @@ rend_service_derive_key_digests(struct rend_service_t *s) return 0; } -/** Make sure that the directory for s is private. If create is - * true, if it exists, change permissions if needed, otherwise, create it with - * the correct permissions. Otherwise, if create is false and the - * directory does not exist, check if we think we can create it. +/** Make sure that the directory for s is private. + * If create is true: + * - if the directory exists, change permissions if needed, + * - if the directory does not exist, create it with the correct permissions. + * If create 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. */ static int rend_service_check_private_dir(const rend_service_t *s, int create) { - cpd_check_t check_opts = CPD_CREATE; - if (!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; From 2f48693663c3703e1015fd438fc585cd2857ba71 Mon Sep 17 00:00:00 2001 From: teor Date: Wed, 2 Nov 2016 14:11:26 +1100 Subject: [PATCH 06/13] Improve comments in check_private_dir and onion poisoning Comment changes only --- src/common/util.c | 12 +++++++----- src/or/rendservice.c | 8 ++++++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/common/util.c b/src/common/util.c index 916296790..a7bce2ea6 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -2191,11 +2191,13 @@ file_status(const char *fname) } } -/** Check whether dirname exists and is private. If yes return 0. If - * it does not exist, and check&CPD_CREATE is set, try to create it - * and return 0 on success. If it does not exist, and - * check&CPD_CHECK, and we think we can create it, return 0. Else - * return -1. If CPD_GROUP_OK is set, then it's okay if the directory +/** Check whether dirname exists and is private. If yes return 0. + * If dirname does not exist: + * - if check&CPD_CREATE, try to create it and return 0 on success. + * - if check&CPD_CHECK, and we think we can create it, return 0. + * - if check&CPD_CHECK is false, and the directory exists, return 0. + * - otherwise, return -1. + * If CPD_GROUP_OK is set, then it's okay if the directory * is group-readable, but in all cases we create the directory mode 0700. * If CPD_GROUP_READ is set, existing directory behaves as CPD_GROUP_OK and * if the directory is created it will use mode 0750 with group read diff --git a/src/or/rendservice.c b/src/or/rendservice.c index 6743d825b..7dbcf718f 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -998,7 +998,9 @@ service_is_single_onion_poisoned(const rend_service_t *service) fstatus = file_status(poison_fname); tor_free(poison_fname); - /* If this fname is occupied, the hidden service has been poisoned. */ + /* If this fname is occupied, the hidden service has been poisoned. + * fstatus can be FN_ERROR if the service directory does not exist, in that + * case, there is obviously no private key. */ if (fstatus == FN_FILE || fstatus == FN_EMPTY) { return 1; } @@ -1014,7 +1016,9 @@ rend_service_private_key_exists(const rend_service_t *service) char *private_key_path = rend_service_path(service, private_key_fname); const file_status_t private_key_status = file_status(private_key_path); tor_free(private_key_path); - /* Only non-empty regular private key files could have been used before. */ + /* Only non-empty regular private key files could have been used before. + * fstatus can be FN_ERROR if the service directory does not exist, in that + * case, there is obviously no private key. */ return private_key_status == FN_FILE; } From d7634dc5196801c5a3e6be9eb2167c2c96f48ab4 Mon Sep 17 00:00:00 2001 From: teor Date: Wed, 2 Nov 2016 14:13:34 +1100 Subject: [PATCH 07/13] Create get_fname_suffix, and refactor get_fname to use it --- src/test/testing_common.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/test/testing_common.c b/src/test/testing_common.c index fd7c4e707..e28e3dd45 100644 --- a/src/test/testing_common.c +++ b/src/test/testing_common.c @@ -102,18 +102,29 @@ setup_directory(void) temp_dir_setup_in_pid = getpid(); } -/** Return a filename relative to our testing temporary directory */ -const char * -get_fname(const char *name) +/** Return a filename relative to our testing temporary directory, based on + * name and suffix. If name is NULL, return the name of the testing temporary + * directory. */ +static const char * +get_fname_suffix(const char *name, const char *suffix) { static char buf[1024]; setup_directory(); if (!name) return temp_dir; - tor_snprintf(buf,sizeof(buf),"%s/%s",temp_dir,name); + tor_snprintf(buf,sizeof(buf),"%s/%s%s%s",temp_dir,name,suffix ? "_" : "", + suffix ? suffix : ""); return buf; } +/** Return a filename relative to our testing temporary directory. If name is + * NULL, return the name of the testing temporary directory. */ +const char * +get_fname(const char *name) +{ + return get_fname_suffix(name, NULL); +} + /* Remove a directory and all of its subdirectories */ static void rm_rf(const char *dir) From 77e1d660ee5b8e2beae12f3de543d19009aaa8ac Mon Sep 17 00:00:00 2001 From: teor Date: Wed, 2 Nov 2016 14:14:19 +1100 Subject: [PATCH 08/13] Add get_fname_rnd for unit tests that want a unique path every time --- src/test/test.h | 1 + src/test/testing_common.c | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/src/test/test.h b/src/test/test.h index 770f403ce..25336ac83 100644 --- a/src/test/test.h +++ b/src/test/test.h @@ -73,6 +73,7 @@ {print_ = (I64_PRINTF_TYPE) value_;}, {}, TT_EXIT_TEST_FUNCTION) const char *get_fname(const char *name); +const char *get_fname_rnd(const char *name); struct crypto_pk_t *pk_generate(int idx); #define US2_CONCAT_2__(a, b) a ## __ ## b diff --git a/src/test/testing_common.c b/src/test/testing_common.c index e28e3dd45..1eae07e45 100644 --- a/src/test/testing_common.c +++ b/src/test/testing_common.c @@ -125,6 +125,18 @@ get_fname(const char *name) return get_fname_suffix(name, NULL); } +/** Return a filename with a random suffix, relative to our testing temporary + * directory. If name is NULL, return the name of the testing temporary + * directory, without any suffix. */ +const char * +get_fname_rnd(const char *name) +{ + char rnd[256], rnd32[256]; + crypto_rand(rnd, RAND_PATH_BYTES); + base32_encode(rnd32, sizeof(rnd32), rnd, RAND_PATH_BYTES); + return get_fname_suffix(name, rnd32); +} + /* Remove a directory and all of its subdirectories */ static void rm_rf(const char *dir) From 13fbbe9cced6df027d2354f3c94f5312dfe60bf2 Mon Sep 17 00:00:00 2001 From: teor Date: Wed, 2 Nov 2016 14:16:14 +1100 Subject: [PATCH 09/13] Make sure passthrough_test_setup doesn't inadvertently fail or skip tests passthrough_test_setup doesn't pass through arguments if the argument is equal to 0 or TT_SKIP. Instead, it fails or skips the test. Assert on this, so we don't accidentally fail or skip tests. --- src/test/testing_common.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/testing_common.c b/src/test/testing_common.c index 1eae07e45..9c6580f78 100644 --- a/src/test/testing_common.c +++ b/src/test/testing_common.c @@ -240,6 +240,9 @@ free_pregenerated_keys(void) static void * passthrough_test_setup(const struct testcase_t *testcase) { + /* Make sure the passthrough doesn't unintentionally fail or skip tests */ + tor_assert(testcase->setup_data); + tor_assert(testcase->setup_data != (void*)TT_SKIP); return testcase->setup_data; } static int From 01fe039b78e6115615ff2e3c3341bcb03100a7f0 Mon Sep 17 00:00:00 2001 From: teor Date: Wed, 2 Nov 2016 14:17:52 +1100 Subject: [PATCH 10/13] Test single onion service configs where the directory does not exist Runs a test for each combination of create/don't create directories. Tests #20484. --- src/test/test_hs.c | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/src/test/test_hs.c b/src/test/test_hs.c index 39a2c914a..b42bc590c 100644 --- a/src/test/test_hs.c +++ b/src/test/test_hs.c @@ -518,6 +518,11 @@ mock_get_options(void) return mock_options; } +/* arg can't be 0 (the test fails) or 2 (the test is skipped) */ +#define CREATE_HS_DIR_NONE ((intptr_t)0x04) +#define CREATE_HS_DIR1 ((intptr_t)0x08) +#define CREATE_HS_DIR2 ((intptr_t)0x10) + /* Test that single onion poisoning works. */ static void test_single_onion_poisoning(void *arg) @@ -528,15 +533,15 @@ test_single_onion_poisoning(void *arg) MOCK(get_options, mock_get_options); int ret = -1; - mock_options->DataDirectory = tor_strdup(get_fname("test_data_dir")); + intptr_t create_dir_mask = (intptr_t)arg; + /* Get directories with a random suffix so we can repeat the tests */ + mock_options->DataDirectory = tor_strdup(get_fname_rnd("test_data_dir")); rend_service_t *service_1 = tor_malloc_zero(sizeof(rend_service_t)); - char *dir1 = tor_strdup(get_fname("test_hs_dir1")); + char *dir1 = tor_strdup(get_fname_rnd("test_hs_dir1")); rend_service_t *service_2 = tor_malloc_zero(sizeof(rend_service_t)); - char *dir2 = tor_strdup(get_fname("test_hs_dir2")); + char *dir2 = tor_strdup(get_fname_rnd("test_hs_dir2")); smartlist_t *services = smartlist_new(); - (void) arg; - /* No services, no problem! */ mock_options->HiddenServiceSingleHopMode = 0; mock_options->HiddenServiceNonAnonymousMode = 0; @@ -549,13 +554,20 @@ test_single_onion_poisoning(void *arg) ret = rend_service_list_verify_single_onion_poison(services, mock_options); tt_assert(ret == 0); - /* Create directories for both services */ + /* Create the data directory, and, if the correct bit in arg is set, + * create a directory for that service. + * The data directory is required for the lockfile, which is used when + * loading keys. */ ret = check_private_dir(mock_options->DataDirectory, CPD_CREATE, NULL); tt_assert(ret == 0); - ret = check_private_dir(dir1, CPD_CREATE, NULL); - tt_assert(ret == 0); - ret = check_private_dir(dir2, CPD_CREATE, NULL); - tt_assert(ret == 0); + if (create_dir_mask & CREATE_HS_DIR1) { + ret = check_private_dir(dir1, CPD_CREATE, NULL); + tt_assert(ret == 0); + } + if (create_dir_mask & CREATE_HS_DIR2) { + ret = check_private_dir(dir2, CPD_CREATE, NULL); + tt_assert(ret == 0); + } service_1->directory = dir1; service_2->directory = dir2; @@ -707,8 +719,14 @@ struct testcase_t hs_tests[] = { NULL, NULL }, { "hs_auth_cookies", test_hs_auth_cookies, TT_FORK, NULL, NULL }, - { "single_onion_poisoning", test_single_onion_poisoning, TT_FORK, - NULL, NULL }, + { "single_onion_poisoning_create_dir_none", test_single_onion_poisoning, + TT_FORK, &passthrough_setup, (void*)(CREATE_HS_DIR_NONE) }, + { "single_onion_poisoning_create_dir1", test_single_onion_poisoning, + TT_FORK, &passthrough_setup, (void*)(CREATE_HS_DIR1) }, + { "single_onion_poisoning_create_dir2", test_single_onion_poisoning, + TT_FORK, &passthrough_setup, (void*)(CREATE_HS_DIR2) }, + { "single_onion_poisoning_create_dir_both", test_single_onion_poisoning, + TT_FORK, &passthrough_setup, (void*)(CREATE_HS_DIR1 | CREATE_HS_DIR2) }, END_OF_TESTCASES }; From 1747f28861e1f5ce8fc5c8cb3eaad0c7f2297dc9 Mon Sep 17 00:00:00 2001 From: teor Date: Wed, 2 Nov 2016 14:32:04 +1100 Subject: [PATCH 11/13] Check every hidden service directory's permissions when configuring Previously, we would only check the last hidden service directory. Fixes #20529, bugfix on ticket 13942 commit 85bfad1 in 0.2.6.2-alpha. --- changes/bug20529 | 4 ++++ src/or/rendservice.c | 5 +++++ 2 files changed, 9 insertions(+) create mode 100644 changes/bug20529 diff --git a/changes/bug20529 b/changes/bug20529 new file mode 100644 index 000000000..276be5b2b --- /dev/null +++ b/changes/bug20529 @@ -0,0 +1,4 @@ + o Minor bugfixes (hidden services): + - When configuring hidden services, check every hidden service directory's + permissions. Previously, we only checked the last hidden service. + Fixes bug 20529; bugfix on 13942 commit 85bfad1 in 0.2.6.2-alpha. diff --git a/src/or/rendservice.c b/src/or/rendservice.c index 7dbcf718f..c62673a74 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -464,6 +464,11 @@ rend_config_services(const or_options_t *options, int validate_only) for (line = options->RendConfigLines; line; line = line->next) { if (!strcasecmp(line->key, "HiddenServiceDir")) { if (service) { /* register the one we just finished parsing */ + if (rend_service_check_private_dir(service, 0) < 0) { + rend_service_free(service); + return -1; + } + if (validate_only) rend_service_free(service); else From 0ee9049e947ec44b3d228e4bb74bcbc28d32ca95 Mon Sep 17 00:00:00 2001 From: teor Date: Wed, 2 Nov 2016 14:55:14 +1100 Subject: [PATCH 12/13] Use the latest options in rend_service_check_private_dir Fixup on both: * Refactor, adding a create argument... and * Check every hidden service directory's permissions... --- src/or/rendservice.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/or/rendservice.c b/src/or/rendservice.c index c62673a74..56dbacdaf 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -72,7 +72,9 @@ static ssize_t rend_service_parse_intro_for_v3( size_t plaintext_len, char **err_msg_out); -static int rend_service_check_private_dir(const rend_service_t *s, int create); +static int rend_service_check_private_dir(const or_options_t *options, + const rend_service_t *s, + int create); /** Represents the mapping from a virtual port of a rendezvous service to * a real port on some IP. @@ -464,7 +466,7 @@ rend_config_services(const or_options_t *options, int validate_only) for (line = options->RendConfigLines; line; line = line->next) { if (!strcasecmp(line->key, "HiddenServiceDir")) { if (service) { /* register the one we just finished parsing */ - if (rend_service_check_private_dir(service, 0) < 0) { + if (rend_service_check_private_dir(options, service, 0) < 0) { rend_service_free(service); return -1; } @@ -679,7 +681,7 @@ rend_config_services(const or_options_t *options, int validate_only) } } if (service) { - if (rend_service_check_private_dir(service, 0) < 0) { + if (rend_service_check_private_dir(options, service, 0) < 0) { rend_service_free(service); return -1; } @@ -1097,7 +1099,7 @@ poison_new_single_onion_hidden_service_dir(const rend_service_t *service) } /* Make sure the directory exists */ - if (rend_service_check_private_dir(service, 1) < 0) + if (rend_service_check_private_dir(get_options(), service, 1) < 0) return -1; poison_fname = rend_service_sos_poison_path(service); @@ -1255,7 +1257,8 @@ rend_service_derive_key_digests(struct rend_service_t *s) return 0; } -/** Make sure that the directory for s is private. +/** Make sure that the directory for s is private, using the config in + * options. * If create is true: * - if the directory exists, change permissions if needed, * - if the directory does not exist, create it with the correct permissions. @@ -1264,7 +1267,9 @@ rend_service_derive_key_digests(struct rend_service_t *s) * - if the directory does not exist, check if we think we can create it. * Return 0 on success, -1 on failure. */ static int -rend_service_check_private_dir(const rend_service_t *s, int create) +rend_service_check_private_dir(const or_options_t *options, + const rend_service_t *s, + int create) { cpd_check_t check_opts = CPD_NONE; if (create) { @@ -1277,7 +1282,7 @@ rend_service_check_private_dir(const rend_service_t *s, int create) check_opts |= CPD_GROUP_READ; } /* Check/create directory */ - if (check_private_dir(s->directory, check_opts, get_options()->User) < 0) { + if (check_private_dir(s->directory, check_opts, options->User) < 0) { return -1; } return 0; @@ -1292,7 +1297,7 @@ rend_service_load_keys(rend_service_t *s) char *fname = NULL; char buf[128]; - if (rend_service_check_private_dir(s, 1) < 0) + if (rend_service_check_private_dir(get_options(), s, 1) < 0) goto err; /* Load key */ From a77187a52c9594c0c168596eec856ee11c447fe0 Mon Sep 17 00:00:00 2001 From: teor Date: Fri, 4 Nov 2016 18:25:57 +1100 Subject: [PATCH 13/13] Add onion_service_non_anonymous file to man page --- doc/tor.1.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/tor.1.txt b/doc/tor.1.txt index 9d8b631e3..f4d061688 100644 --- a/doc/tor.1.txt +++ b/doc/tor.1.txt @@ -2896,6 +2896,10 @@ __HiddenServiceDirectory__**/client_keys**:: Authorization data for a hidden service that is only accessible by authorized clients. +__HiddenServiceDirectory__**/onion_service_non_anonymous**:: + This file is present if a hidden service key was created in + **HiddenServiceNonAnonymousMode**. + SEE ALSO -------- **torsocks**(1), **torify**(1) +