test_checkdir.c 5.3 KB

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