Module: Chrooter
- Defined in:
- lib/chrooter.rb
Overview
Chrooter allows for testing programs in both chroot/unveil and non chroot modes.
Class Method Summary collapse
-
.chroot(user, pledge = nil, group = user, dir = Dir.pwd) ⇒ Object
If the current user is the super user, change to the given user/group, chroot to the given directory, and pledge the process with the given permissions (if given).
-
.unveil(user, pledge = nil, unveil = {}, group = user) ⇒ Object
If the current user is the super user, drop privileges to the given
user
first.
Class Method Details
.chroot(user, pledge = nil, group = user, dir = Dir.pwd) ⇒ Object
If the current user is the super user, change to the given user/group, chroot to the given directory, and pledge the process with the given permissions (if given).
If the current user is not the super user, freeze $LOADED_FEATURES to more easily detect problems with autoloaded constants, and just pledge the process with the given permissions (if given).
This will reference common autoloaded constants in the rack and mail libraries if they are defined. Other autoloaded constants should be referenced before calling this method.
In general this should be called inside an at_exit block after loading minitest/autorun, so it will run after all specs are loaded, but before running specs.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/chrooter.rb', line 70 def self.chroot(user, pledge=nil, group=user, dir=Dir.pwd) # Work around autoload issues in libraries. # autoload is problematic when chrooting because if the # constant is not referenced before chrooting, an # exception is raised if the constant is raised # after chrooting. # # The constants listed here are the autoloaded constants # known to be used by any applications. This list # may need to be updated when libraries are upgraded # and add new constants, or when applications start # using new features. if defined?(Rack) Rack::MockRequest if defined?(Rack::MockRequest) Rack::Auth::Digest::Params if defined?(Rack::Auth::Digest::Params) if defined?(Rack::Multipart) Rack::Multipart Rack::Multipart::Parser Rack::Multipart::Generator Rack::Multipart::UploadedFile end end if defined?(Mail) Mail::Address Mail::AddressList Mail::Parsers::AddressListsParser Mail::ContentTransferEncodingElement Mail::ContentDispositionElement Mail::MessageIdsElement Mail::MimeVersionElement Mail::OptionalField Mail::ContentTypeElement end if Process.euid == 0 _drop_privs(user, group) do Dir.chroot(dir) Dir.chdir('/') end puts "Chrooted to #{dir}, running as user #{user}" else # Load minitest plugins before freezing loaded features, # so they don't break. Minitest.load_plugins # Emulate chroot not working by freezing $LOADED_FEATURES # This allows to more easily catch bugs that only occur # when chrooted, such as referencing an autoloaded constant # that wasn't loaded before the chroot. $LOADED_FEATURES.freeze end _pledge(pledge) end |
.unveil(user, pledge = nil, unveil = {}, group = user) ⇒ Object
If the current user is the super user, drop privileges to the given user
first.
Use Pledge.unveil to limit access to the file system based on the unveil
option. Then pledge the process with the given pledge
permissions (if given).
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/chrooter.rb', line 32 def self.unveil(user, pledge=nil, unveil={}, group=user) require 'unveil' unveil = Hash[unveil] if defined?(Rack) unveil['rack'] = :gem end if defined?(Mail) unveil['mail'] = :gem end if Process.euid == 0 _drop_privs(user, group) puts "Unveiled, running as user #{user}" end Pledge.unveil(unveil) _pledge(pledge) end |