/* Copyright (c) 2014, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" #include "or.h" #include #include "config.h" #include "test.h" #include "util.h" #ifdef _WIN32 #define mkdir(a,b) mkdir(a) #endif /** Run unit tests for private dir permission enforcement logic. */ static void test_checkdir_perms(void *testdata) { (void)testdata; or_options_t *options = get_options_mutable(); const char *subdir = "test_checkdir"; char *testdir; cpd_check_t cpd_chkopts; cpd_check_t unix_create_opts; cpd_check_t unix_verify_optsmask; struct stat st; /* setup data directory before tests. */ tor_free(options->DataDirectory); options->DataDirectory = tor_strdup(get_fname(subdir)); tt_int_op(mkdir(options->DataDirectory, 0750), ==, 0); /* test: create new dir, no flags. */ testdir = get_datadir_fname("checkdir_new_none"); cpd_chkopts = CPD_CREATE; unix_verify_optsmask = 0077; tt_int_op(0, ==, check_private_dir(testdir, cpd_chkopts, NULL)); tt_int_op(0, ==, stat(testdir, &st)); tt_int_op(0, ==, (st.st_mode & unix_verify_optsmask)); tor_free(testdir); /* test: create new dir, CPD_GROUP_OK option set. */ testdir = get_datadir_fname("checkdir_new_groupok"); cpd_chkopts = CPD_CREATE|CPD_GROUP_OK; unix_verify_optsmask = 0077; tt_int_op(0, ==, check_private_dir(testdir, cpd_chkopts, NULL)); tt_int_op(0, ==, stat(testdir, &st)); tt_int_op(0, ==, (st.st_mode & unix_verify_optsmask)); tor_free(testdir); /* test: should get an error on existing dir with wrong perms */ testdir = get_datadir_fname("checkdir_new_groupok_err"); tt_int_op(0, ==, mkdir(testdir, 027)); cpd_chkopts = CPD_CHECK_MODE_ONLY|CPD_CREATE|CPD_GROUP_OK; tt_int_op(-1, ==, check_private_dir(testdir, cpd_chkopts, NULL)); tor_free(testdir); /* test: create new dir, CPD_GROUP_READ option set. */ testdir = get_datadir_fname("checkdir_new_groupread"); cpd_chkopts = CPD_CREATE|CPD_GROUP_READ; unix_verify_optsmask = 0027; tt_int_op(0, ==, check_private_dir(testdir, cpd_chkopts, NULL)); tt_int_op(0, ==, stat(testdir, &st)); tt_int_op(0, ==, (st.st_mode & unix_verify_optsmask)); tor_free(testdir); /* test: check existing dir created with defaults, and verify with CPD_CREATE only. */ testdir = get_datadir_fname("checkdir_exists_none"); cpd_chkopts = CPD_CREATE; unix_create_opts = 0700; unix_verify_optsmask = 0077; tt_int_op(0, ==, mkdir(testdir, unix_create_opts)); tt_int_op(0, ==, check_private_dir(testdir, cpd_chkopts, NULL)); tt_int_op(0, ==, stat(testdir, &st)); tt_int_op(0, ==, (st.st_mode & unix_verify_optsmask)); tor_free(testdir); /* test: check existing dir created with defaults, and verify with CPD_GROUP_OK option set. */ testdir = get_datadir_fname("checkdir_exists_groupok"); cpd_chkopts = CPD_CREATE; unix_verify_optsmask = 0077; tt_int_op(0, ==, check_private_dir(testdir, cpd_chkopts, NULL)); cpd_chkopts = CPD_GROUP_OK; tt_int_op(0, ==, check_private_dir(testdir, cpd_chkopts, NULL)); tt_int_op(0, ==, stat(testdir, &st)); tt_int_op(0, ==, (st.st_mode & unix_verify_optsmask)); tor_free(testdir); /* test: check existing dir created with defaults, and verify with CPD_GROUP_READ option set. */ testdir = get_datadir_fname("checkdir_exists_groupread"); cpd_chkopts = CPD_CREATE; unix_verify_optsmask = 0027; tt_int_op(0, ==, check_private_dir(testdir, cpd_chkopts, NULL)); cpd_chkopts = CPD_GROUP_READ; tt_int_op(0, ==, check_private_dir(testdir, cpd_chkopts, NULL)); tt_int_op(0, ==, stat(testdir, &st)); tt_int_op(0, ==, (st.st_mode & unix_verify_optsmask)); tor_free(testdir); /* test: check existing dir created with CPD_GROUP_READ, and verify with CPD_GROUP_OK option set. */ testdir = get_datadir_fname("checkdir_existsread_groupok"); cpd_chkopts = CPD_CREATE|CPD_GROUP_READ; unix_verify_optsmask = 0027; tt_int_op(0, ==, check_private_dir(testdir, cpd_chkopts, NULL)); cpd_chkopts = CPD_GROUP_OK; tt_int_op(0, ==, check_private_dir(testdir, cpd_chkopts, NULL)); tt_int_op(0, ==, stat(testdir, &st)); tt_int_op(0, ==, (st.st_mode & unix_verify_optsmask)); tor_free(testdir); /* test: check existing dir created with CPD_GROUP_READ, and verify with CPD_GROUP_READ option set. */ testdir = get_datadir_fname("checkdir_existsread_groupread"); cpd_chkopts = CPD_CREATE|CPD_GROUP_READ; unix_verify_optsmask = 0027; tt_int_op(0, ==, check_private_dir(testdir, cpd_chkopts, NULL)); tt_int_op(0, ==, stat(testdir, &st)); tt_int_op(0, ==, (st.st_mode & unix_verify_optsmask)); tor_free(testdir); done: ; } #define CHECKDIR(name,flags) \ { #name, test_checkdir_##name, (flags), NULL, NULL } struct testcase_t checkdir_tests[] = { CHECKDIR(perms, 0), END_OF_TESTCASES };