test_checkdir.c (5407B)
1 /* Copyright (c) 2014-2021, The Tor Project, Inc. */ 2 /* See LICENSE for licensing information */ 3 4 #include "orconfig.h" 5 #include "core/or/or.h" 6 7 #ifdef _WIN32 8 #include <direct.h> 9 #else 10 #include <dirent.h> 11 #endif 12 13 #include "app/config/config.h" 14 #include "test/test.h" 15 16 #ifdef HAVE_SYS_STAT_H 17 #include <sys/stat.h> 18 #endif 19 20 #ifdef _WIN32 21 #define mkdir(a,b) mkdir(a) 22 #define tt_int_op_nowin(a,op,b) do { (void)(a); (void)(b); } while (0) 23 #define umask(mask) ((void)0) 24 #else 25 #define tt_int_op_nowin(a,op,b) tt_int_op((a),op,(b)) 26 #endif /* defined(_WIN32) */ 27 28 /** Run unit tests for private dir permission enforcement logic. */ 29 static void 30 test_checkdir_perms(void *testdata) 31 { 32 (void)testdata; 33 or_options_t *options = get_options_mutable(); 34 const char *subdir = "test_checkdir"; 35 char *testdir = NULL; 36 cpd_check_t cpd_chkopts; 37 cpd_check_t unix_create_opts; 38 cpd_check_t unix_verify_optsmask; 39 struct stat st; 40 41 umask(022); 42 43 /* setup data directory before tests. */ 44 tor_free(options->DataDirectory); 45 options->DataDirectory = tor_strdup(get_fname(subdir)); 46 tt_int_op(mkdir(options->DataDirectory, 0750), OP_EQ, 0); 47 48 /* test: create new dir, no flags. */ 49 testdir = get_datadir_fname("checkdir_new_none"); 50 cpd_chkopts = CPD_CREATE; 51 unix_verify_optsmask = 0077; 52 tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL)); 53 tt_int_op(0, OP_EQ, stat(testdir, &st)); 54 tt_int_op_nowin(0, OP_EQ, (st.st_mode & unix_verify_optsmask)); 55 tor_free(testdir); 56 57 /* test: create new dir, CPD_GROUP_OK option set. */ 58 testdir = get_datadir_fname("checkdir_new_groupok"); 59 cpd_chkopts = CPD_CREATE|CPD_GROUP_OK; 60 unix_verify_optsmask = 0077; 61 tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL)); 62 tt_int_op(0, OP_EQ, stat(testdir, &st)); 63 tt_int_op_nowin(0, OP_EQ, (st.st_mode & unix_verify_optsmask)); 64 tor_free(testdir); 65 66 /* test: should get an error on existing dir with 67 wrong perms */ 68 testdir = get_datadir_fname("checkdir_new_groupok_err"); 69 tt_int_op(0, OP_EQ, mkdir(testdir, 027)); 70 cpd_chkopts = CPD_CHECK_MODE_ONLY|CPD_CREATE|CPD_GROUP_OK; 71 tt_int_op_nowin(-1, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL)); 72 tor_free(testdir); 73 74 /* test: create new dir, CPD_GROUP_READ option set. */ 75 testdir = get_datadir_fname("checkdir_new_groupread"); 76 cpd_chkopts = CPD_CREATE|CPD_GROUP_READ; 77 unix_verify_optsmask = 0027; 78 tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL)); 79 tt_int_op(0, OP_EQ, stat(testdir, &st)); 80 tt_int_op_nowin(0, OP_EQ, (st.st_mode & unix_verify_optsmask)); 81 tor_free(testdir); 82 83 /* test: check existing dir created with defaults, 84 and verify with CPD_CREATE only. */ 85 testdir = get_datadir_fname("checkdir_exists_none"); 86 cpd_chkopts = CPD_CREATE; 87 unix_create_opts = 0700; 88 (void)unix_create_opts; 89 unix_verify_optsmask = 0077; 90 tt_int_op(0, OP_EQ, mkdir(testdir, unix_create_opts)); 91 tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL)); 92 tt_int_op(0, OP_EQ, stat(testdir, &st)); 93 tt_int_op_nowin(0, OP_EQ, (st.st_mode & unix_verify_optsmask)); 94 tor_free(testdir); 95 96 /* test: check existing dir created with defaults, 97 and verify with CPD_GROUP_OK option set. */ 98 testdir = get_datadir_fname("checkdir_exists_groupok"); 99 cpd_chkopts = CPD_CREATE; 100 unix_verify_optsmask = 0077; 101 tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL)); 102 cpd_chkopts = CPD_GROUP_OK; 103 tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL)); 104 tt_int_op(0, OP_EQ, stat(testdir, &st)); 105 tt_int_op_nowin(0, OP_EQ, (st.st_mode & unix_verify_optsmask)); 106 tor_free(testdir); 107 108 /* test: check existing dir created with defaults, 109 and verify with CPD_GROUP_READ option set. */ 110 testdir = get_datadir_fname("checkdir_exists_groupread"); 111 cpd_chkopts = CPD_CREATE; 112 unix_verify_optsmask = 0027; 113 tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL)); 114 cpd_chkopts = CPD_GROUP_READ; 115 tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL)); 116 tt_int_op(0, OP_EQ, stat(testdir, &st)); 117 tt_int_op_nowin(0, OP_EQ, (st.st_mode & unix_verify_optsmask)); 118 tor_free(testdir); 119 120 /* test: check existing dir created with CPD_GROUP_READ, 121 and verify with CPD_GROUP_OK option set. */ 122 testdir = get_datadir_fname("checkdir_existsread_groupok"); 123 cpd_chkopts = CPD_CREATE|CPD_GROUP_READ; 124 unix_verify_optsmask = 0027; 125 tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL)); 126 cpd_chkopts = CPD_GROUP_OK; 127 tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL)); 128 tt_int_op(0, OP_EQ, stat(testdir, &st)); 129 tt_int_op_nowin(0, OP_EQ, (st.st_mode & unix_verify_optsmask)); 130 tor_free(testdir); 131 132 /* test: check existing dir created with CPD_GROUP_READ, 133 and verify with CPD_GROUP_READ option set. */ 134 testdir = get_datadir_fname("checkdir_existsread_groupread"); 135 cpd_chkopts = CPD_CREATE|CPD_GROUP_READ; 136 unix_verify_optsmask = 0027; 137 tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL)); 138 tt_int_op(0, OP_EQ, stat(testdir, &st)); 139 tt_int_op_nowin(0, OP_EQ, (st.st_mode & unix_verify_optsmask)); 140 141 done: 142 tor_free(testdir); 143 } 144 145 #define CHECKDIR(name,flags) \ 146 { #name, test_checkdir_##name, (flags), NULL, NULL } 147 148 struct testcase_t checkdir_tests[] = { 149 CHECKDIR(perms, TT_FORK), 150 END_OF_TESTCASES 151 };