sandbox.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. #include "xs.h"
  2. #include "snac.h"
  3. #if defined(__OpenBSD__)
  4. void sbox_enter(const char *basedir)
  5. {
  6. const char *address = xs_dict_get(srv_config, "address");
  7. if (xs_is_true(xs_dict_get(srv_config, "disable_openbsd_security"))) {
  8. srv_log(xs_dup("OpenBSD security disabled by admin"));
  9. return;
  10. }
  11. srv_debug(1, xs_fmt("Calling unveil()"));
  12. unveil(basedir, "rwc");
  13. unveil("/tmp", "rwc");
  14. unveil("/etc/resolv.conf", "r");
  15. unveil("/etc/hosts", "r");
  16. unveil("/etc/ssl/openssl.cnf", "r");
  17. unveil("/etc/ssl/cert.pem", "r");
  18. unveil("/usr/share/zoneinfo", "r");
  19. if (*address == '/')
  20. unveil(address, "rwc");
  21. unveil(NULL, NULL);
  22. srv_debug(1, xs_fmt("Calling pledge()"));
  23. xs *p = xs_str_new("stdio rpath wpath cpath flock inet proc dns fattr");
  24. if (*address == '/')
  25. p = xs_str_cat(p, " unix");
  26. pledge(p, NULL);
  27. }
  28. #elif defined(__linux__)
  29. #if defined(WITH_LINUX_SANDBOX)
  30. #include <unistd.h>
  31. #define LL_PRINTERR(fmt, ...) srv_debug(0, xs_fmt(fmt, __VA_ARGS__))
  32. #include "landloc.h"
  33. static
  34. LL_BEGIN(sbox_enter_linux_, const char* basedir, const char *address, int smtp_port) {
  35. const unsigned long long
  36. rd = LANDLOCK_ACCESS_FS_READ_DIR,
  37. rf = LANDLOCK_ACCESS_FS_READ_FILE,
  38. w = LANDLOCK_ACCESS_FS_WRITE_FILE |
  39. LANDLOCK_ACCESS_FS_TRUNCATE_COMPAT,
  40. c = LANDLOCK_ACCESS_FS_MAKE_DIR |
  41. LANDLOCK_ACCESS_FS_MAKE_REG |
  42. LANDLOCK_ACCESS_FS_TRUNCATE_COMPAT |
  43. LANDLOCK_ACCESS_FS_MAKE_SYM |
  44. LANDLOCK_ACCESS_FS_REMOVE_DIR |
  45. LANDLOCK_ACCESS_FS_REMOVE_FILE |
  46. LANDLOCK_ACCESS_FS_REFER_COMPAT,
  47. s = LANDLOCK_ACCESS_FS_MAKE_SOCK,
  48. x = LANDLOCK_ACCESS_FS_EXECUTE;
  49. LL_PATH(basedir, rf|rd|w|c);
  50. LL_PATH("/tmp", rf|rd|w|c);
  51. #ifndef WITHOUT_SHM
  52. LL_PATH("/dev/shm", rf|w|c );
  53. #endif
  54. LL_PATH("/etc/resolv.conf", rf );
  55. LL_PATH("/etc/hosts", rf );
  56. LL_PATH("/etc/ssl", rf );
  57. LL_PATH("/usr/share/zoneinfo", rf );
  58. if (mtime("/etc/pki") > 0)
  59. LL_PATH("/etc/pki", rf );
  60. if (*address == '/') {
  61. /* the directory holding the socket must be allowed */
  62. xs *l = xs_split(address, "/");
  63. l = xs_list_del(l, -1);
  64. xs *sdir = xs_join(l, "/");
  65. LL_PATH(sdir, s);
  66. }
  67. if (*address != '/') {
  68. unsigned short listen_port = xs_number_get(xs_dict_get(srv_config, "port"));
  69. LL_PORT(listen_port, LANDLOCK_ACCESS_NET_BIND_TCP_COMPAT);
  70. }
  71. LL_PORT(80, LANDLOCK_ACCESS_NET_CONNECT_TCP_COMPAT);
  72. LL_PORT(443, LANDLOCK_ACCESS_NET_CONNECT_TCP_COMPAT);
  73. if (smtp_port > 0)
  74. LL_PORT((unsigned short)smtp_port, LANDLOCK_ACCESS_NET_CONNECT_TCP_COMPAT);
  75. } LL_END
  76. void sbox_enter(const char *basedir)
  77. {
  78. const xs_val *v;
  79. const char *errstr;
  80. const char *address = xs_dict_get(srv_config, "address");
  81. int smtp_port = -1;
  82. if (xs_is_true(xs_dict_get(srv_config, "disable_sandbox"))) {
  83. srv_debug(1, xs_dup("Linux sandbox disabled by admin"));
  84. return;
  85. }
  86. if ((v = xs_dict_get(srv_config, "email_notifications")) &&
  87. (v = xs_dict_get(v, "url"))) {
  88. smtp_port = parse_port((const char *)v, &errstr);
  89. if (errstr)
  90. srv_debug(0, xs_fmt("Couldn't determine port from '%s': %s", (const char *)v, errstr));
  91. }
  92. if (sbox_enter_linux_(basedir, address, smtp_port) == 0)
  93. srv_debug(1, xs_dup("Linux sandbox enabled"));
  94. else
  95. srv_debug(0, xs_dup("Linux sandbox failed"));
  96. }
  97. #else /* defined(WITH_LINUX_SANDBOX) */
  98. void sbox_enter(const char *basedir)
  99. {
  100. (void)basedir;
  101. srv_debug(1, xs_fmt("Linux sandbox not compiled in"));
  102. }
  103. #endif
  104. #else
  105. /* other OSs: dummy sbox_enter() */
  106. void sbox_enter(const char *basedir)
  107. {
  108. (void)basedir;
  109. }
  110. #endif /* __OpenBSD__ */