chroot.ck 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. /*++
  2. Copyright (c) 2017 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. chroot.ck
  9. Abstract:
  10. This module implements chroot-based container support.
  11. Author:
  12. Evan Green 25-May-2017
  13. Environment:
  14. Chalk
  15. --*/
  16. //
  17. // ------------------------------------------------------------------- Includes
  18. //
  19. from santa.build import shell;
  20. from santa.config import config;
  21. from santa.containment import Containment, ContainmentError;
  22. from santa.file import chdir, chmod, chroot, mkdir, path, rmtree;
  23. //
  24. // --------------------------------------------------------------------- Macros
  25. //
  26. //
  27. // ---------------------------------------------------------------- Definitions
  28. //
  29. //
  30. // ------------------------------------------------------ Data Type Definitions
  31. //
  32. //
  33. // ----------------------------------------------- Internal Function Prototypes
  34. //
  35. //
  36. // -------------------------------------------------------------------- Globals
  37. //
  38. //
  39. // ------------------------------------------------------------------ Functions
  40. //
  41. class ChrootContainment is Containment {
  42. var _parameters;
  43. function
  44. create (
  45. parameters
  46. )
  47. /*++
  48. Routine Description:
  49. This routine creates a new container and initializes this instance's
  50. internal variables to represent it.
  51. Arguments:
  52. parameters - Supplies a dictionary of creation parameters.
  53. Return Value:
  54. None.
  55. --*/
  56. {
  57. var rootpath;
  58. _parameters = parameters.copy();
  59. _parameters.type = "chroot";
  60. try {
  61. rootpath = parameters.path;
  62. } except KeyError {
  63. Core.raise(ContainmentError("Required parameter is missing"));
  64. }
  65. if ((rootpath == "") || (rootpath == "/")) {
  66. Core.raise(ContainmentError("Invalid chroot path"));
  67. }
  68. mkdir(rootpath + "/tmp");
  69. chmod(rootpath + "/tmp", 0777);
  70. mkdir(rootpath + "/dev");
  71. shell("set -e\n"
  72. "_world=%s\n"
  73. "for d in null full zero urandom tty; do\n"
  74. " touch $_world/dev/$d\n"
  75. " mount --bind /dev/$d $_world/dev/$d\n"
  76. "done" % path(rootpath));
  77. if (config.getKey("core.verbose")) {
  78. Core.print("Created chroot environment at %s" % rootpath);
  79. }
  80. return;
  81. }
  82. function
  83. destroy (
  84. )
  85. /*++
  86. Routine Description:
  87. This routine destroys the container represented by this instance.
  88. Arguments:
  89. None.
  90. Return Value:
  91. None.
  92. --*/
  93. {
  94. var rootpath = _parameters.path;
  95. var verbose = config.getKey("core.verbose");
  96. if (verbose) {
  97. Core.print("Destroying chroot environment at %s" % rootpath);
  98. }
  99. shell("_world=%s\n"
  100. "for d in null full zero urandom tty; do\n"
  101. " umount $_world/dev/$d\n"
  102. "done\n"
  103. "true" % path(rootpath));
  104. rmtree(rootpath);
  105. _parameters = null;
  106. if (verbose) {
  107. Core.print("Destroyed chroot environment at %s" % rootpath);
  108. }
  109. return;
  110. }
  111. function
  112. load (
  113. parameters
  114. )
  115. /*++
  116. Routine Description:
  117. This routine initializes this instance to reflect the container
  118. identified by the given parameters.
  119. Arguments:
  120. parameters - Supplies a dictionary of parameters.
  121. Return Value:
  122. None.
  123. --*/
  124. {
  125. _parameters = parameters;
  126. try {
  127. parameters.path;
  128. } except KeyError {
  129. Core.raise(ContainmentError("Required parameter is missing"));
  130. }
  131. return;
  132. }
  133. function
  134. save (
  135. )
  136. /*++
  137. Routine Description:
  138. This routine returns the dictionary of state and identification needed
  139. to restore information about this container by other instances of this
  140. class.
  141. Arguments:
  142. None.
  143. Return Value:
  144. Returns a dictionary of parameters to save describing this instance.
  145. --*/
  146. {
  147. return _parameters;
  148. }
  149. function
  150. enter (
  151. parameters
  152. )
  153. /*++
  154. Routine Description:
  155. This routine enters the given container environment.
  156. Arguments:
  157. parameters - Supplies an optional set of additional parameters
  158. specific to this entry into the environment.
  159. Return Value:
  160. None. Upon return, the current execution environment will be confined
  161. to the container.
  162. --*/
  163. {
  164. var path = _parameters.path;
  165. chdir(path);
  166. chroot(path);
  167. if (config.getKey("core.verbose")) {
  168. Core.print("Entered chroot environment at %s" % path);
  169. }
  170. }
  171. function
  172. outerPath (
  173. filepath
  174. )
  175. /*++
  176. Routine Description:
  177. This routine translates from a path within the container to a path
  178. outside of the container.
  179. Arguments:
  180. filepath - Supplies the path rooted from within the container.
  181. Return Value:
  182. Returns the path to the file from the perspective of an application
  183. not executing within the container.
  184. --*/
  185. {
  186. var rootpath = path(_parameters.path);
  187. if (filepath == "/") {
  188. return rootpath;
  189. }
  190. return "/".join([rootpath, filepath]);
  191. }
  192. function
  193. innerPath (
  194. filepath
  195. )
  196. /*++
  197. Routine Description:
  198. This routine translates from a path outside the container to a path
  199. within of the container.
  200. Arguments:
  201. filepath - Supplies the path rooted from outside the container.
  202. Return Value:
  203. Returns the path to the file from the perspective of an application
  204. executing within the container.
  205. --*/
  206. {
  207. var rootpath = _parameters.path;
  208. if (!filepath.startsWith(rootpath)) {
  209. rootpath = path(rootpath);
  210. if (!filepath.startsWith(rootpath)) {
  211. Core.raise(ValueError("Path '%s' does not start in container "
  212. "rooted at '%s'" % [filepath, rootpath]));
  213. }
  214. }
  215. filepath = filepath[rootpath.length()...-1];
  216. if (filepath == "") {
  217. return "/";
  218. }
  219. return filepath;
  220. }
  221. }
  222. //
  223. // Set the variables needed so that the module loader can enumerate this class.
  224. //
  225. var description = "Containment based on chroot.";
  226. var containment = ChrootContainment;
  227. //
  228. // --------------------------------------------------------- Internal Functions
  229. //