|
@@ -108,6 +108,14 @@ struct rend_service_port_config_s {
|
|
|
* rendezvous point before giving up? */
|
|
|
#define MAX_REND_TIMEOUT 30
|
|
|
|
|
|
+
|
|
|
+ * new file names should be added to rend_service_add_filenames_to_list()
|
|
|
+ * for sandboxing purposes. */
|
|
|
+static const char *private_key_fname = "private_key";
|
|
|
+static const char *hostname_fname = "hostname";
|
|
|
+static const char *client_keys_fname = "client_keys";
|
|
|
+static const char *sos_poison_fname = "onion_service_non_anonymous";
|
|
|
+
|
|
|
|
|
|
*/
|
|
|
static const char *
|
|
@@ -950,23 +958,32 @@ rend_service_update_descriptor(rend_service_t *service)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static const char *sos_poison_fname = "non_anonymous_hidden_service";
|
|
|
-
|
|
|
-
|
|
|
- * poison file in service.
|
|
|
- * The caller must free this path.
|
|
|
- * Returns NULL if there is no directory for service. */
|
|
|
+
|
|
|
+ * service->directory. Asserts that service has a directory.
|
|
|
+ * This function will never return NULL.
|
|
|
+ * The caller must free this path. */
|
|
|
static char *
|
|
|
-sos_poison_path(const rend_service_t *service)
|
|
|
+rend_service_path(const rend_service_t *service, const char *file_name)
|
|
|
{
|
|
|
- char *poison_path;
|
|
|
+ char *file_path = NULL;
|
|
|
|
|
|
tor_assert(service->directory);
|
|
|
|
|
|
- tor_asprintf(&poison_path, "%s%s%s",
|
|
|
- service->directory, PATH_SEPARATOR, sos_poison_fname);
|
|
|
+
|
|
|
+ tor_asprintf(&file_path, "%s%s%s",
|
|
|
+ service->directory, PATH_SEPARATOR, file_name);
|
|
|
+
|
|
|
+ return file_path;
|
|
|
+}
|
|
|
|
|
|
- return poison_path;
|
|
|
+
|
|
|
+ * service poison file in service->directory. Asserts that service has a
|
|
|
+ * directory.
|
|
|
+ * The caller must free this path. */
|
|
|
+STATIC char *
|
|
|
+rend_service_sos_poison_path(const rend_service_t *service)
|
|
|
+{
|
|
|
+ return rend_service_path(service, sos_poison_fname);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -981,8 +998,7 @@ service_is_single_onion_poisoned(const rend_service_t *service)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- poison_fname = sos_poison_path(service);
|
|
|
- tor_assert(poison_fname);
|
|
|
+ poison_fname = rend_service_sos_poison_path(service);
|
|
|
|
|
|
fstatus = file_status(poison_fname);
|
|
|
tor_free(poison_fname);
|
|
@@ -1076,7 +1092,7 @@ poison_new_single_onion_hidden_service_dir(const rend_service_t *service)
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
- poison_fname = sos_poison_path(service);
|
|
|
+ poison_fname = rend_service_sos_poison_path(service);
|
|
|
|
|
|
switch (file_status(poison_fname)) {
|
|
|
case FN_DIR:
|
|
@@ -1190,12 +1206,10 @@ rend_service_add_filenames_to_list(smartlist_t *lst, const rend_service_t *s)
|
|
|
tor_assert(lst);
|
|
|
tor_assert(s);
|
|
|
tor_assert(s->directory);
|
|
|
- smartlist_add_asprintf(lst, "%s"PATH_SEPARATOR"private_key",
|
|
|
- s->directory);
|
|
|
- smartlist_add_asprintf(lst, "%s"PATH_SEPARATOR"hostname",
|
|
|
- s->directory);
|
|
|
- smartlist_add_asprintf(lst, "%s"PATH_SEPARATOR"client_keys",
|
|
|
- s->directory);
|
|
|
+ smartlist_add(lst, rend_service_path(s, private_key_fname));
|
|
|
+ smartlist_add(lst, rend_service_path(s, hostname_fname));
|
|
|
+ smartlist_add(lst, rend_service_path(s, client_keys_fname));
|
|
|
+ smartlist_add(lst, rend_service_sos_poison_path(s));
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1239,7 +1253,7 @@ rend_service_derive_key_digests(struct rend_service_t *s)
|
|
|
static int
|
|
|
rend_service_load_keys(rend_service_t *s)
|
|
|
{
|
|
|
- char fname[512];
|
|
|
+ char *fname = NULL;
|
|
|
char buf[128];
|
|
|
cpd_check_t check_opts = CPD_CREATE;
|
|
|
|
|
@@ -1248,7 +1262,7 @@ rend_service_load_keys(rend_service_t *s)
|
|
|
}
|
|
|
|
|
|
if (check_private_dir(s->directory, check_opts, get_options()->User) < 0) {
|
|
|
- return -1;
|
|
|
+ goto err;
|
|
|
}
|
|
|
#ifndef _WIN32
|
|
|
if (s->dir_group_readable) {
|
|
@@ -1260,34 +1274,23 @@ rend_service_load_keys(rend_service_t *s)
|
|
|
#endif
|
|
|
|
|
|
|
|
|
- if (strlcpy(fname,s->directory,sizeof(fname)) >= sizeof(fname) ||
|
|
|
- strlcat(fname,PATH_SEPARATOR"private_key",sizeof(fname))
|
|
|
- >= sizeof(fname)) {
|
|
|
- log_warn(LD_CONFIG, "Directory name too long to store key file: \"%s\".",
|
|
|
- s->directory);
|
|
|
- return -1;
|
|
|
- }
|
|
|
+ fname = rend_service_path(s, private_key_fname);
|
|
|
s->private_key = init_key_from_file(fname, 1, LOG_ERR, 0);
|
|
|
+
|
|
|
if (!s->private_key)
|
|
|
- return -1;
|
|
|
+ goto err;
|
|
|
|
|
|
if (rend_service_derive_key_digests(s) < 0)
|
|
|
- return -1;
|
|
|
+ goto err;
|
|
|
|
|
|
+ tor_free(fname);
|
|
|
|
|
|
- if (strlcpy(fname,s->directory,sizeof(fname)) >= sizeof(fname) ||
|
|
|
- strlcat(fname,PATH_SEPARATOR"hostname",sizeof(fname))
|
|
|
- >= sizeof(fname)) {
|
|
|
- log_warn(LD_CONFIG, "Directory name too long to store hostname file:"
|
|
|
- " \"%s\".", s->directory);
|
|
|
- return -1;
|
|
|
- }
|
|
|
+ fname = rend_service_path(s, hostname_fname);
|
|
|
|
|
|
tor_snprintf(buf, sizeof(buf),"%s.onion\n", s->service_id);
|
|
|
if (write_str_to_file(fname,buf,0)<0) {
|
|
|
log_warn(LD_CONFIG, "Could not write onion address to hostname file.");
|
|
|
- memwipe(buf, 0, sizeof(buf));
|
|
|
- return -1;
|
|
|
+ goto err;
|
|
|
}
|
|
|
#ifndef _WIN32
|
|
|
if (s->dir_group_readable) {
|
|
@@ -1298,15 +1301,21 @@ rend_service_load_keys(rend_service_t *s)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
- memwipe(buf, 0, sizeof(buf));
|
|
|
-
|
|
|
|
|
|
if (s->auth_type != REND_NO_AUTH) {
|
|
|
- if (rend_service_load_auth_keys(s, fname) < 0)
|
|
|
- return -1;
|
|
|
+ if (rend_service_load_auth_keys(s, fname) < 0) {
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- return 0;
|
|
|
+ int r = 0;
|
|
|
+ goto done;
|
|
|
+ err:
|
|
|
+ r = -1;
|
|
|
+ done:
|
|
|
+ memwipe(buf, 0, sizeof(buf));
|
|
|
+ tor_free(fname);
|
|
|
+ return r;
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1316,7 +1325,7 @@ static int
|
|
|
rend_service_load_auth_keys(rend_service_t *s, const char *hfname)
|
|
|
{
|
|
|
int r = 0;
|
|
|
- char cfname[512];
|
|
|
+ char *cfname = NULL;
|
|
|
char *client_keys_str = NULL;
|
|
|
strmap_t *parsed_clients = strmap_new();
|
|
|
FILE *cfile, *hfile;
|
|
@@ -1326,12 +1335,7 @@ rend_service_load_auth_keys(rend_service_t *s, const char *hfname)
|
|
|
char buf[1500];
|
|
|
|
|
|
|
|
|
- if (tor_snprintf(cfname, sizeof(cfname), "%s"PATH_SEPARATOR"client_keys",
|
|
|
- s->directory)<0) {
|
|
|
- log_warn(LD_CONFIG, "Directory name too long to store client keys "
|
|
|
- "file: \"%s\".", s->directory);
|
|
|
- goto err;
|
|
|
- }
|
|
|
+ cfname = rend_service_path(s, client_keys_fname);
|
|
|
client_keys_str = read_file_to_str(cfname, RFTS_IGNORE_MISSING, NULL);
|
|
|
if (client_keys_str) {
|
|
|
if (rend_parse_client_keys(parsed_clients, client_keys_str) < 0) {
|
|
@@ -1485,7 +1489,10 @@ rend_service_load_auth_keys(rend_service_t *s, const char *hfname)
|
|
|
}
|
|
|
strmap_free(parsed_clients, rend_authorized_client_strmap_item_free);
|
|
|
|
|
|
- memwipe(cfname, 0, sizeof(cfname));
|
|
|
+ if (cfname) {
|
|
|
+ memwipe(cfname, 0, sizeof(cfname));
|
|
|
+ tor_free(cfname);
|
|
|
+ }
|
|
|
|
|
|
|
|
|
memwipe(buf, 0, sizeof(buf));
|