bsdcapsicum.rb/README.md

138 lines
4.4 KiB
Markdown
Raw Normal View History

2024-06-25 08:25:53 +02:00
## About
2017-05-24 17:34:00 +02:00
2024-06-26 23:16:04 +02:00
bsdcapsicum.rb provides Ruby bindings for
2024-06-25 17:26:01 +02:00
[capsicum(4)](https://man.freebsd.org/cgi/man.cgi?query=capsicum&apropos=0&sektion=4&format=html).
2017-05-24 02:18:05 +02:00
2024-06-25 08:57:49 +02:00
## Examples
2017-05-24 02:18:05 +02:00
2024-06-25 08:57:49 +02:00
__Capability mode__
2017-05-24 17:34:00 +02:00
2024-06-25 08:57:49 +02:00
A process can enter into capability mode by calling
2024-06-25 09:10:31 +02:00
[BSD::Capsicum.enter!](http://0x1eef.github.io/x/bsdcapsicum.rb/BSD/Capsicum.html#enter!-instance_method).
2024-06-25 08:57:49 +02:00
After entering capability mode, the process has limited
2024-06-25 10:25:11 +02:00
abilities. File descriptors acquired before entering into
capability mode remain accessible and unrestricted, but
2024-06-25 10:46:50 +02:00
their capabilites can be reduced. See the
2024-06-25 08:57:49 +02:00
[cap_enter(2)](https://man.freebsd.org/cgi/man.cgi?query=cap_enter&apropos=0&sektion=2&format=html)
2024-06-25 09:04:08 +02:00
manual page for more details:
2017-05-24 02:18:47 +02:00
```ruby
2024-06-25 09:11:12 +02:00
#!/usr/bin/env ruby
2024-06-25 08:25:53 +02:00
require "bsd/capsicum"
2024-06-25 04:36:09 +02:00
2024-06-25 08:25:53 +02:00
print "In capability mode: ", BSD::Capsicum.in_capability_mode? ? "yes" : "no", "\n"
print "Enter capability mode: ", BSD::Capsicum.enter! ? "ok" : "error", "\n"
print "In capability mode: ", BSD::Capsicum.in_capability_mode? ? "yes" : "no", "\n"
2024-06-25 04:36:09 +02:00
begin
File.new(File::NULL)
rescue Errno::ECAPMODE => ex
print "Error: #{ex.message} (#{ex.class})", "\n"
end
##
# In capability mode: no
# Enter capability mode: ok
# In capability mode: yes
# Error: Not permitted in capability mode @ rb_sysopen - /dev/null (Errno::ECAPMODE)
2017-05-24 02:18:47 +02:00
```
2024-06-25 08:57:49 +02:00
__IPC__
2017-05-24 02:18:47 +02:00
2024-06-25 08:57:49 +02:00
By spawning a child process and then entering capability mode, restrictions can be
limited to a child process (and its child processes, if any). This can be helpful in
an architecture where a parent process can spawn one or more child processes to handle
certain tasks but with restrictions in place:
2017-05-24 02:18:47 +02:00
```ruby
2024-06-25 09:11:12 +02:00
#!/usr/bin/env ruby
2024-06-25 08:25:53 +02:00
require "bsd/capsicum"
2024-06-25 05:23:16 +02:00
2024-06-25 08:25:53 +02:00
print "[parent] In capability mode: ", BSD::Capsicum.in_capability_mode? ? "yes" : "no", "\n"
fork do
2024-06-25 08:25:53 +02:00
print "[subprocess] Enter capability mode: ", BSD::Capsicum.enter! ? "ok" : "error", "\n"
print "[subprocess] In capability mode: ", BSD::Capsicum.in_capability_mode? ? "yes" : "no", "\n"
2024-06-25 05:23:16 +02:00
print "[subprocess] Exit", "\n"
2017-05-24 02:18:47 +02:00
exit 42
end
Process.wait
2024-06-25 08:25:53 +02:00
print "[parent] In capability mode: ", BSD::Capsicum.in_capability_mode? ? "yes" : "no", "\n"
2017-05-24 02:18:47 +02:00
2024-06-25 05:23:16 +02:00
##
# [parent] In capability mode: no
# [subprocess] Enter capability mode: ok
# [subprocess] In capability mode: yes
# [subprocess] Exit
# [parent] In capability mode: no
2017-05-24 02:18:47 +02:00
```
__Rights__
The
[BSD::Capsicum.set_rights!](http://0x1eef.github.io/x/bsdcapsicum.rb/BSD/Capsicum.html#set_rights!-instance_method)
method can reduce the capabilities of a file descriptor. The following
example obtains a file descriptor in a parent process (with both read and
write permissions), then limits the capabilities of the file descriptor
in a child process to allow only read operations. See the
[rights(4)](https://man.freebsd.org/cgi/man.cgi?query=rights&apropos=0&sektion=4&format=html)
man page for a full list of capabilities:
``` ruby
#!/usr/bin/env ruby
require "bsd/capsicum"
path = File.join(Dir.home, "bsdcapsicum.txt")
file = File.open(path, File::CREAT | File::TRUNC | File::RDWR)
file.sync = true
print "[parent] obtain file descriptor (with read+write permissions)", "\n"
fork do
BSD::Capsicum.set_rights!(file, %i[CAP_READ])
print "[subprocess] reduce rights to read-only", "\n"
file.gets
print "[subprocess] read successful", "\n"
begin
file.write "foo"
rescue Errno::ENOTCAPABLE => ex
print "[subprocess] Error: #{ex.message} (#{ex.class})", "\n"
end
end
Process.wait
file.write "[parent] Hello from #{Process.pid}", "\n"
print "[parent] write successful", "\n"
##
# [parent] obtain file descriptor (with read+write permissions)
# [subprocess] reduce rights to read-only
# [subprocess] read successful
# [subprocess] Error: Capabilities insufficient @ io_write - /home/user/bsdcapsicum.txt (Errno::ENOTCAPABLE)
# [parent] write successful
```
2024-06-25 09:04:08 +02:00
## Documentation
A complete API reference is available at [0x1eef.github.io/x/bsdcapsicum.rb](https://0x1eef.github.io/x/bsdcapsicum.rb)
2017-05-24 02:18:05 +02:00
2024-06-25 08:57:49 +02:00
## Install
2017-05-24 02:18:05 +02:00
2024-06-25 08:57:49 +02:00
bsdcapsicum.rb is available via rubygems.org:
2017-05-24 17:34:00 +02:00
2024-06-25 08:57:49 +02:00
gem install bsdcapsicum.rb
2017-05-24 02:18:05 +02:00
2024-06-25 09:54:45 +02:00
## Sources
* [GitHub](https://github.com/0x1eef/bsdcapsicum.rb#readme)
* [git.HardenedBSD.org](https://git.hardenedbsd.org/0x1eef/bsdcapsicum.rb#about)
2024-06-25 08:57:49 +02:00
## See also
2017-05-24 02:18:05 +02:00
2024-06-25 09:04:08 +02:00
* [Freaky/ruby-capsicum](https://github.com/Freaky/ruby-capsicum) <br>
2024-06-25 08:57:49 +02:00
bsdcapsicum.rb is a fork of this project. It was a huge help both
in terms of code and documentation.
2017-05-24 02:18:05 +02:00
## License
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).