2018-06-20 14:13:28 +02:00
|
|
|
/* Copyright (c) 2014-2018, The Tor Project, Inc. */
|
2014-08-28 20:10:21 +02:00
|
|
|
/* See LICENSE for licensing information */
|
|
|
|
|
|
|
|
#include "orconfig.h"
|
2018-06-20 15:35:05 +02:00
|
|
|
#include "or/or.h"
|
2015-07-23 18:01:57 +02:00
|
|
|
|
2015-08-25 17:46:29 +02:00
|
|
|
#ifdef _WIN32
|
|
|
|
#include <direct.h>
|
|
|
|
#else
|
2014-08-28 20:10:21 +02:00
|
|
|
#include <dirent.h>
|
2015-07-23 18:01:57 +02:00
|
|
|
#endif
|
|
|
|
|
2018-06-20 15:35:05 +02:00
|
|
|
#include "or/config.h"
|
|
|
|
#include "test/test.h"
|
|
|
|
#include "common/util.h"
|
2014-08-28 20:10:21 +02:00
|
|
|
|
2014-11-05 20:39:09 +01:00
|
|
|
#ifdef _WIN32
|
|
|
|
#define mkdir(a,b) mkdir(a)
|
2014-11-07 14:54:03 +01:00
|
|
|
#define tt_int_op_nowin(a,op,b) do { (void)(a); (void)(b); } while (0)
|
2015-01-15 16:24:27 +01:00
|
|
|
#define umask(mask) ((void)0)
|
2014-11-07 14:54:03 +01:00
|
|
|
#else
|
|
|
|
#define tt_int_op_nowin(a,op,b) tt_int_op((a),op,(b))
|
2017-09-15 22:24:44 +02:00
|
|
|
#endif /* defined(_WIN32) */
|
2014-11-05 20:39:09 +01:00
|
|
|
|
2014-08-28 20:10:21 +02:00
|
|
|
/** Run unit tests for private dir permission enforcement logic. */
|
|
|
|
static void
|
|
|
|
test_checkdir_perms(void *testdata)
|
|
|
|
{
|
2014-11-05 20:09:59 +01:00
|
|
|
(void)testdata;
|
2014-08-28 20:10:21 +02:00
|
|
|
or_options_t *options = get_options_mutable();
|
|
|
|
const char *subdir = "test_checkdir";
|
2014-11-07 14:54:03 +01:00
|
|
|
char *testdir = NULL;
|
2014-08-28 20:10:21 +02:00
|
|
|
cpd_check_t cpd_chkopts;
|
|
|
|
cpd_check_t unix_create_opts;
|
|
|
|
cpd_check_t unix_verify_optsmask;
|
|
|
|
struct stat st;
|
|
|
|
|
2015-01-15 16:24:27 +01:00
|
|
|
umask(022);
|
|
|
|
|
2014-08-29 07:58:53 +02:00
|
|
|
/* setup data directory before tests. */
|
2014-08-28 20:10:21 +02:00
|
|
|
tor_free(options->DataDirectory);
|
|
|
|
options->DataDirectory = tor_strdup(get_fname(subdir));
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(mkdir(options->DataDirectory, 0750), OP_EQ, 0);
|
2014-08-28 20:10:21 +02:00
|
|
|
|
2014-08-29 07:58:53 +02:00
|
|
|
/* test: create new dir, no flags. */
|
2014-08-28 20:10:21 +02:00
|
|
|
testdir = get_datadir_fname("checkdir_new_none");
|
|
|
|
cpd_chkopts = CPD_CREATE;
|
2014-08-29 07:58:53 +02:00
|
|
|
unix_verify_optsmask = 0077;
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL));
|
|
|
|
tt_int_op(0, OP_EQ, stat(testdir, &st));
|
|
|
|
tt_int_op_nowin(0, OP_EQ, (st.st_mode & unix_verify_optsmask));
|
2014-08-28 20:10:21 +02:00
|
|
|
tor_free(testdir);
|
|
|
|
|
2014-08-29 07:58:53 +02:00
|
|
|
/* test: create new dir, CPD_GROUP_OK option set. */
|
2014-08-28 20:10:21 +02:00
|
|
|
testdir = get_datadir_fname("checkdir_new_groupok");
|
|
|
|
cpd_chkopts = CPD_CREATE|CPD_GROUP_OK;
|
2014-08-29 07:58:53 +02:00
|
|
|
unix_verify_optsmask = 0077;
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL));
|
|
|
|
tt_int_op(0, OP_EQ, stat(testdir, &st));
|
|
|
|
tt_int_op_nowin(0, OP_EQ, (st.st_mode & unix_verify_optsmask));
|
2014-08-28 20:10:21 +02:00
|
|
|
tor_free(testdir);
|
2014-10-15 10:17:54 +02:00
|
|
|
|
|
|
|
/* test: should get an error on existing dir with
|
|
|
|
wrong perms */
|
|
|
|
testdir = get_datadir_fname("checkdir_new_groupok_err");
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, mkdir(testdir, 027));
|
2014-10-15 10:17:54 +02:00
|
|
|
cpd_chkopts = CPD_CHECK_MODE_ONLY|CPD_CREATE|CPD_GROUP_OK;
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op_nowin(-1, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL));
|
2014-10-15 10:17:54 +02:00
|
|
|
tor_free(testdir);
|
2014-08-28 20:10:21 +02:00
|
|
|
|
2014-08-29 07:58:53 +02:00
|
|
|
/* test: create new dir, CPD_GROUP_READ option set. */
|
2014-08-28 20:10:21 +02:00
|
|
|
testdir = get_datadir_fname("checkdir_new_groupread");
|
|
|
|
cpd_chkopts = CPD_CREATE|CPD_GROUP_READ;
|
2014-08-29 07:58:53 +02:00
|
|
|
unix_verify_optsmask = 0027;
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL));
|
|
|
|
tt_int_op(0, OP_EQ, stat(testdir, &st));
|
|
|
|
tt_int_op_nowin(0, OP_EQ, (st.st_mode & unix_verify_optsmask));
|
2014-08-28 20:10:21 +02:00
|
|
|
tor_free(testdir);
|
|
|
|
|
2014-08-29 07:58:53 +02:00
|
|
|
/* test: check existing dir created with defaults,
|
2014-08-28 20:10:21 +02:00
|
|
|
and verify with CPD_CREATE only. */
|
|
|
|
testdir = get_datadir_fname("checkdir_exists_none");
|
|
|
|
cpd_chkopts = CPD_CREATE;
|
2014-08-29 07:58:53 +02:00
|
|
|
unix_create_opts = 0700;
|
2014-11-05 20:51:17 +01:00
|
|
|
(void)unix_create_opts;
|
2014-08-29 07:58:53 +02:00
|
|
|
unix_verify_optsmask = 0077;
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, mkdir(testdir, unix_create_opts));
|
|
|
|
tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL));
|
|
|
|
tt_int_op(0, OP_EQ, stat(testdir, &st));
|
|
|
|
tt_int_op_nowin(0, OP_EQ, (st.st_mode & unix_verify_optsmask));
|
2014-08-28 20:10:21 +02:00
|
|
|
tor_free(testdir);
|
|
|
|
|
2014-08-29 07:58:53 +02:00
|
|
|
/* test: check existing dir created with defaults,
|
2014-08-28 20:10:21 +02:00
|
|
|
and verify with CPD_GROUP_OK option set. */
|
|
|
|
testdir = get_datadir_fname("checkdir_exists_groupok");
|
|
|
|
cpd_chkopts = CPD_CREATE;
|
2014-08-29 07:58:53 +02:00
|
|
|
unix_verify_optsmask = 0077;
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL));
|
2014-08-28 20:10:21 +02:00
|
|
|
cpd_chkopts = CPD_GROUP_OK;
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL));
|
|
|
|
tt_int_op(0, OP_EQ, stat(testdir, &st));
|
|
|
|
tt_int_op_nowin(0, OP_EQ, (st.st_mode & unix_verify_optsmask));
|
2014-08-28 20:10:21 +02:00
|
|
|
tor_free(testdir);
|
|
|
|
|
2014-08-29 07:58:53 +02:00
|
|
|
/* test: check existing dir created with defaults,
|
2014-08-28 20:10:21 +02:00
|
|
|
and verify with CPD_GROUP_READ option set. */
|
|
|
|
testdir = get_datadir_fname("checkdir_exists_groupread");
|
|
|
|
cpd_chkopts = CPD_CREATE;
|
2014-08-29 07:58:53 +02:00
|
|
|
unix_verify_optsmask = 0027;
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL));
|
2014-08-28 20:10:21 +02:00
|
|
|
cpd_chkopts = CPD_GROUP_READ;
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL));
|
|
|
|
tt_int_op(0, OP_EQ, stat(testdir, &st));
|
|
|
|
tt_int_op_nowin(0, OP_EQ, (st.st_mode & unix_verify_optsmask));
|
2014-08-28 20:10:21 +02:00
|
|
|
tor_free(testdir);
|
|
|
|
|
2014-08-29 07:58:53 +02:00
|
|
|
/* test: check existing dir created with CPD_GROUP_READ,
|
2014-08-28 20:10:21 +02:00
|
|
|
and verify with CPD_GROUP_OK option set. */
|
|
|
|
testdir = get_datadir_fname("checkdir_existsread_groupok");
|
|
|
|
cpd_chkopts = CPD_CREATE|CPD_GROUP_READ;
|
2014-08-29 07:58:53 +02:00
|
|
|
unix_verify_optsmask = 0027;
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL));
|
2014-08-28 20:10:21 +02:00
|
|
|
cpd_chkopts = CPD_GROUP_OK;
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL));
|
|
|
|
tt_int_op(0, OP_EQ, stat(testdir, &st));
|
|
|
|
tt_int_op_nowin(0, OP_EQ, (st.st_mode & unix_verify_optsmask));
|
2014-08-28 20:10:21 +02:00
|
|
|
tor_free(testdir);
|
|
|
|
|
2014-08-29 07:58:53 +02:00
|
|
|
/* test: check existing dir created with CPD_GROUP_READ,
|
2014-08-28 20:10:21 +02:00
|
|
|
and verify with CPD_GROUP_READ option set. */
|
|
|
|
testdir = get_datadir_fname("checkdir_existsread_groupread");
|
|
|
|
cpd_chkopts = CPD_CREATE|CPD_GROUP_READ;
|
2014-08-29 07:58:53 +02:00
|
|
|
unix_verify_optsmask = 0027;
|
2014-11-12 19:28:07 +01:00
|
|
|
tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL));
|
|
|
|
tt_int_op(0, OP_EQ, stat(testdir, &st));
|
|
|
|
tt_int_op_nowin(0, OP_EQ, (st.st_mode & unix_verify_optsmask));
|
2014-08-28 20:10:21 +02:00
|
|
|
|
2014-11-12 19:15:10 +01:00
|
|
|
done:
|
2014-11-07 14:54:03 +01:00
|
|
|
tor_free(testdir);
|
2014-08-28 20:10:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#define CHECKDIR(name,flags) \
|
|
|
|
{ #name, test_checkdir_##name, (flags), NULL, NULL }
|
|
|
|
|
|
|
|
struct testcase_t checkdir_tests[] = {
|
2015-01-15 16:24:27 +01:00
|
|
|
CHECKDIR(perms, TT_FORK),
|
2014-08-28 20:10:21 +02:00
|
|
|
END_OF_TESTCASES
|
|
|
|
};
|
|
|
|
|