test_checkdir.c 5.3 KB

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