bsdcapsicum.rb 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5d83ead7ffc798a1957614930e629c867be433fc59a7138327ccae20e2bb35d4
4
- data.tar.gz: 9b91b67471e6cd11ebc3eced51face9e8cae9f96136763666e110b175c4a8f55
3
+ metadata.gz: 68cc91e740a2c2e8586db3884729be9c4fcefe8de403876ff805ac2bdaa3575b
4
+ data.tar.gz: d71319a3f9a56b63faef409ea27647ea93796eedda15658ad28bf9a9cd395066
5
5
  SHA512:
6
- metadata.gz: 315f60aad74e7db220c09cedc03fa4072fbd483de4cf851c6351f0df599249fc7752d892fc304636f4ca08d80735c88f7bc366854d4323f582d7406760c9c40a
7
- data.tar.gz: ab6a6c0b337f9ddcbf98e97053379bba9c585d51ecc02b1cd72f55ef9add3be5bcf26d3d0da310d939230a9fb2bf66a483f3accefe94e3d4ad8c729efdefbc76
6
+ metadata.gz: 94b898fee6872449599545d87fd4d52e9231b6e6d7424d58d3bfc7b22e97c84d5b10719821581bc590822e49464703503a284d9205def2ccba65670d300f97d6
7
+ data.tar.gz: d3d0649cf733bd07ed0e66ee9bf223dbdee5c89a54b609e35583964a216bbd3136f2bfdf0d1988edc705c004ac1a2781a00316f08fd23f639054d83a56637318
data/README.md CHANGED
@@ -20,9 +20,9 @@ manual page for more details:
20
20
  #!/usr/bin/env ruby
21
21
  require "bsd/capsicum"
22
22
 
23
- print "In capability mode: ", BSD::Capsicum.in_capability_mode? ? "yes" : "no", "\n"
24
- print "Enter capability mode: ", BSD::Capsicum.enter! ? "ok" : "error", "\n"
25
- print "In capability mode: ", BSD::Capsicum.in_capability_mode? ? "yes" : "no", "\n"
23
+ print "In capability mode: ", (BSD::Capsicum.in_capability_mode? ? "yes" : "no"), "\n"
24
+ print "Enter capability mode: ", (BSD::Capsicum.enter! ? "ok" : "error"), "\n"
25
+ print "In capability mode: ", (BSD::Capsicum.in_capability_mode? ? "yes" : "no"), "\n"
26
26
 
27
27
  begin
28
28
  File.new(File::NULL)
@@ -37,7 +37,7 @@ end
37
37
  # Error: Not permitted in capability mode @ rb_sysopen - /dev/null (Errno::ECAPMODE)
38
38
  ```
39
39
 
40
- __IPC__
40
+ __Child process__
41
41
 
42
42
  By spawning a child process and then entering capability mode, restrictions can be
43
43
  limited to a child process (and its child processes, if any). This can be helpful in
@@ -48,15 +48,15 @@ certain tasks but with restrictions in place:
48
48
  #!/usr/bin/env ruby
49
49
  require "bsd/capsicum"
50
50
 
51
- print "[parent] In capability mode: ", BSD::Capsicum.in_capability_mode? ? "yes" : "no", "\n"
51
+ print "[parent] In capability mode: ", (BSD::Capsicum.in_capability_mode? ? "yes" : "no"), "\n"
52
52
  fork do
53
- print "[subprocess] Enter capability mode: ", BSD::Capsicum.enter! ? "ok" : "error", "\n"
54
- print "[subprocess] In capability mode: ", BSD::Capsicum.in_capability_mode? ? "yes" : "no", "\n"
53
+ print "[subprocess] Enter capability mode: ", (BSD::Capsicum.enter! ? "ok" : "error"), "\n"
54
+ print "[subprocess] In capability mode: ", (BSD::Capsicum.in_capability_mode? ? "yes" : "no"), "\n"
55
55
  print "[subprocess] Exit", "\n"
56
56
  exit 42
57
57
  end
58
58
  Process.wait
59
- print "[parent] In capability mode: ", BSD::Capsicum.in_capability_mode? ? "yes" : "no", "\n"
59
+ print "[parent] In capability mode: ", (BSD::Capsicum.in_capability_mode? ? "yes" : "no"), "\n"
60
60
 
61
61
  ##
62
62
  # [parent] In capability mode: no
@@ -71,8 +71,8 @@ __Rights__
71
71
  The
72
72
  [BSD::Capsicum.set_rights!](http://0x1eef.github.io/x/bsdcapsicum.rb/BSD/Capsicum.html#set_rights!-instance_method)
73
73
  method can reduce the capabilities of a file descriptor. The following
74
- example obtains a file descriptor in a parent process (with both read and
75
- write permissions), then limits the capabilities of the file descriptor
74
+ example obtains a file descriptor in a parent process (with full capabilities),
75
+ then limits the capabilities of the file descriptor
76
76
  in a child process to allow only read operations. See the
77
77
  [rights(4)](https://man.freebsd.org/cgi/man.cgi?query=rights&apropos=0&sektion=4&format=html)
78
78
  man page for a full list of capabilities:
@@ -84,13 +84,13 @@ require "bsd/capsicum"
84
84
  path = File.join(Dir.home, "bsdcapsicum.txt")
85
85
  file = File.open(path, File::CREAT | File::TRUNC | File::RDWR)
86
86
  file.sync = true
87
- print "[parent] obtain file descriptor (with read+write permissions)", "\n"
87
+ print "[parent] Obtain file descriptor (with all capabilities)", "\n"
88
88
  fork do
89
89
  BSD::Capsicum.set_rights!(file, %i[CAP_READ])
90
- print "[subprocess] reduce rights to read-only", "\n"
90
+ print "[subprocess] Reduce capabilities to read", "\n"
91
91
 
92
92
  file.gets
93
- print "[subprocess] read successful", "\n"
93
+ print "[subprocess] Read OK", "\n"
94
94
 
95
95
  begin
96
96
  file.write "foo"
@@ -100,14 +100,14 @@ fork do
100
100
  end
101
101
  Process.wait
102
102
  file.write "[parent] Hello from #{Process.pid}", "\n"
103
- print "[parent] write successful", "\n"
103
+ print "[parent] Write OK", "\n"
104
104
 
105
105
  ##
106
- # [parent] obtain file descriptor (with read+write permissions)
107
- # [subprocess] reduce rights to read-only
108
- # [subprocess] read successful
106
+ # [parent] Obtain file descriptor (with all capabilities)
107
+ # [subprocess] Reduce capabilities to read
108
+ # [subprocess] Read OK
109
109
  # [subprocess] Error: Capabilities insufficient @ io_write - /home/user/bsdcapsicum.txt (Errno::ENOTCAPABLE)
110
- # [parent] write successful
110
+ # [parent] Write OK
111
111
  ```
112
112
 
113
113
  ## Documentation
@@ -123,7 +123,9 @@ bsdcapsicum.rb is available via rubygems.org:
123
123
  ## Sources
124
124
 
125
125
  * [GitHub](https://github.com/0x1eef/bsdcapsicum.rb#readme)
126
- * [git.HardenedBSD.org](https://git.hardenedbsd.org/0x1eef/bsdcapsicum.rb#about)
126
+ * [GitLab](https://gitlab.com/0x1eef/bsdcapsicum.rb#about)
127
+ * [git.HardenedBSD.org/@0x1eef](https://git.hardenedbsd.org/0x1eef/bsdcapsicum.rb#about)
128
+ * [brew.bsd.cafe/@0x1eef](https://brew.bsd.cafe/0x1eef/bsdcapsicum.rb)
127
129
 
128
130
  ## See also
129
131
 
@@ -91,5 +91,9 @@ module BSD::Capsicum
91
91
  CAP_FCHDIR = 0x200000000000800
92
92
  CAP_FCNTL = 0x200000000008000
93
93
  # @endgroup
94
+
95
+ # @group Sizes
96
+ SIZEOF_CAP_RIGHTS_T = 16
97
+ # @endgroup
94
98
  end
95
99
  end
@@ -3,8 +3,16 @@
3
3
  module BSD::Capsicum
4
4
  module FFI
5
5
  require "fiddle"
6
+ require "fiddle/import"
6
7
  include Fiddle::Types
7
8
  include Constants
9
+ extend Fiddle::Importer
10
+ dlload Dir["/lib/libc.*"].first
11
+
12
+ extern "int cap_getmode(u_int*)"
13
+ extern "int cap_enter(void)"
14
+ extern "int cap_rights_limit(int, const cap_rights_t*)"
15
+ extern "cap_rights_t* __cap_rights_init(int version, cap_rights_t*, ...)"
8
16
 
9
17
  module_function
10
18
 
@@ -12,11 +20,7 @@ module BSD::Capsicum
12
20
  # Provides a Ruby interface for cap_enter(2)
13
21
  # @return [Integer]
14
22
  def cap_enter
15
- Fiddle::Function.new(
16
- libc["cap_enter"],
17
- [],
18
- INT
19
- ).call
23
+ self["cap_enter"].call
20
24
  end
21
25
 
22
26
  ##
@@ -24,45 +28,43 @@ module BSD::Capsicum
24
28
  # @param [Fiddle::Pointer] uintp
25
29
  # @return [Integer]
26
30
  def cap_getmode(uintp)
27
- Fiddle::Function.new(
28
- libc["cap_getmode"],
29
- [INTPTR_T],
30
- INT
31
- ).call(uintp)
31
+ self["cap_getmode"].call(uintp)
32
32
  end
33
33
 
34
34
  ##
35
35
  # Provides a Ruby interface for cap_rights_limit(2)
36
36
  # @param [Integer] fd
37
- # @param [Fiddle::Pointer] rights
37
+ # @param [Fiddle::Pointer] rightsp
38
38
  # @return [Integer]
39
- def cap_rights_limit(fd, rights)
40
- Fiddle::Function.new(
41
- libc["cap_rights_limit"],
42
- [INT, VOIDP],
43
- INT
44
- ).call(fd, rights)
39
+ def cap_rights_limit(fd, rightsp)
40
+ self["cap_rights_limit"].call(fd, rightsp)
45
41
  end
46
42
 
47
43
  ##
48
44
  # Provides a Ruby interface for cap_rights_init(2)
49
- # @param [Array<Integer>] rights
45
+ # @see BSD::Capsicum::Constants See Constants for a full list of capabilities
46
+ # @param [Fiddle::Pointer] rightsp
47
+ # A pointer to initialize the `cap_rights_t` structure
48
+ # @param [Array<Symbol, Integer>] capabilities
49
+ # An allowed set of capabilities
50
50
  # @return [Fiddle::Pointer]
51
- def cap_rights_init(*rights)
52
- voidp = Fiddle::Pointer.malloc(Fiddle::SIZEOF_VOIDP)
53
- varargs = rights.flat_map { [ULONG_LONG, (Symbol === _1) ? Constants.const_get(_1) : _1] }
54
- Fiddle::Function.new(
55
- libc["__cap_rights_init"],
56
- [INT, VOIDP, VARIADIC],
57
- VOIDP
58
- ).call(CAP_RIGHTS_VERSION, voidp, *varargs)
59
- voidp
51
+ # Returns a pointer to the structure `cap_rights_t`
52
+ def cap_rights_init(rightsp, *capabilities)
53
+ self["__cap_rights_init"].call(
54
+ CAP_RIGHTS_VERSION,
55
+ rightsp,
56
+ *capabilities.flat_map { |cap|
57
+ [ULONG_LONG, cap_all.include?(cap) ? const_get(cap) : cap]
58
+ }
59
+ )
60
60
  end
61
61
 
62
62
  ##
63
63
  # @api private
64
- def libc
65
- @libc ||= Fiddle.dlopen Dir["/lib/libc.*"].first
64
+ # @return [Array<Symbol>]
65
+ # Returns all known capabilities
66
+ def cap_all
67
+ @cap_all ||= Constants.constants.select { _1.to_s.start_with?("CAP_") }
66
68
  end
67
69
  end
68
70
  private_constant :FFI
@@ -4,5 +4,5 @@ module BSD
4
4
  end unless defined?(BSD)
5
5
 
6
6
  module BSD::Capsicum
7
- VERSION = "0.2.0"
7
+ VERSION = "0.3.0"
8
8
  end
data/lib/bsd/capsicum.rb CHANGED
@@ -44,26 +44,27 @@ module BSD::Capsicum
44
44
  alias_method :enter_capability_mode!, :enter!
45
45
 
46
46
  ##
47
- # Restrict the capabilities of a file descriptor
47
+ # Limit the capabilities of a file descriptor
48
48
  #
49
49
  # @see https://man.freebsd.org/cgi/man.cgi?query=cap_rights_limit&apropos=0&sektion=2&format=html cap_rights_limit(2)
50
50
  # @see BSD::Capsicum::Constants See Constants for a full list of capabilities
51
51
  # @example
52
- # # Restrict capabilities of STDOUT to read / write
52
+ # # Limit standard output capabilities to read and write
53
53
  # BSD::Capsicum.set_rights!(STDOUT, %i[CAP_READ CAP_WRITE])
54
54
  # @raise [SystemCallError]
55
55
  # Might raise a subclass of SystemCallError
56
56
  # @param [#to_i] io
57
57
  # An IO object
58
- # @param [Array<String>] rights
58
+ # @param [Array<Symbol, Integer>] capabilities
59
59
  # An allowed set of capabilities
60
60
  # @return [Boolean]
61
61
  # Returns true when successful
62
- def set_rights!(io, rights)
63
- voidp = FFI.cap_rights_init(*rights)
64
- FFI.cap_rights_limit(io.to_i, voidp).zero? ||
62
+ def set_rights!(io, capabilities)
63
+ rightsp = Fiddle::Pointer.malloc(Constants::SIZEOF_CAP_RIGHTS_T)
64
+ FFI.cap_rights_init(rightsp, *capabilities)
65
+ FFI.cap_rights_limit(io.to_i, rightsp).zero? ||
65
66
  raise(SystemCallError.new("cap_rights_limit", Fiddle.last_error))
66
67
  ensure
67
- voidp.call_free
68
+ rightsp.call_free
68
69
  end
69
70
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bsdcapsicum.rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Hurst
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-06-27 00:00:00.000000000 Z
12
+ date: 2024-07-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fiddle