bsdcapsicum.rb 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5d83ead7ffc798a1957614930e629c867be433fc59a7138327ccae20e2bb35d4
4
+ data.tar.gz: 9b91b67471e6cd11ebc3eced51face9e8cae9f96136763666e110b175c4a8f55
5
+ SHA512:
6
+ metadata.gz: 315f60aad74e7db220c09cedc03fa4072fbd483de4cf851c6351f0df599249fc7752d892fc304636f4ca08d80735c88f7bc366854d4323f582d7406760c9c40a
7
+ data.tar.gz: ab6a6c0b337f9ddcbf98e97053379bba9c585d51ecc02b1cd72f55ef9add3be5bcf26d3d0da310d939230a9fb2bf66a483f3accefe94e3d4ad8c729efdefbc76
data/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ Copyright (C) 2023 by 0x1eef <0x1eef@protonmail.com>
2
+
3
+ Permission to use, copy, modify, and/or distribute this
4
+ software for any purpose with or without fee is hereby
5
+ granted.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS
8
+ ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
9
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
10
+ EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
12
+ RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
14
+ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
15
+ OF THIS SOFTWARE.
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Thomas Hurst
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,147 @@
1
+ ## About
2
+
3
+ bsdcapsicum.rb provides Ruby bindings for
4
+ [capsicum(4)](https://man.freebsd.org/cgi/man.cgi?query=capsicum&apropos=0&sektion=4&format=html).
5
+
6
+ ## Examples
7
+
8
+ __Capability mode__
9
+
10
+ A process can enter into capability mode by calling
11
+ [BSD::Capsicum.enter!](http://0x1eef.github.io/x/bsdcapsicum.rb/BSD/Capsicum.html#enter!-instance_method).
12
+ After entering capability mode, the process has limited
13
+ abilities. File descriptors acquired before entering into
14
+ capability mode remain accessible and unrestricted, but
15
+ their capabilites can be reduced. See the
16
+ [cap_enter(2)](https://man.freebsd.org/cgi/man.cgi?query=cap_enter&apropos=0&sektion=2&format=html)
17
+ manual page for more details:
18
+
19
+ ```ruby
20
+ #!/usr/bin/env ruby
21
+ require "bsd/capsicum"
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"
26
+
27
+ begin
28
+ File.new(File::NULL)
29
+ rescue Errno::ECAPMODE => ex
30
+ print "Error: #{ex.message} (#{ex.class})", "\n"
31
+ end
32
+
33
+ ##
34
+ # In capability mode: no
35
+ # Enter capability mode: ok
36
+ # In capability mode: yes
37
+ # Error: Not permitted in capability mode @ rb_sysopen - /dev/null (Errno::ECAPMODE)
38
+ ```
39
+
40
+ __IPC__
41
+
42
+ By spawning a child process and then entering capability mode, restrictions can be
43
+ limited to a child process (and its child processes, if any). This can be helpful in
44
+ an architecture where a parent process can spawn one or more child processes to handle
45
+ certain tasks but with restrictions in place:
46
+
47
+ ```ruby
48
+ #!/usr/bin/env ruby
49
+ require "bsd/capsicum"
50
+
51
+ print "[parent] In capability mode: ", BSD::Capsicum.in_capability_mode? ? "yes" : "no", "\n"
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"
55
+ print "[subprocess] Exit", "\n"
56
+ exit 42
57
+ end
58
+ Process.wait
59
+ print "[parent] In capability mode: ", BSD::Capsicum.in_capability_mode? ? "yes" : "no", "\n"
60
+
61
+ ##
62
+ # [parent] In capability mode: no
63
+ # [subprocess] Enter capability mode: ok
64
+ # [subprocess] In capability mode: yes
65
+ # [subprocess] Exit
66
+ # [parent] In capability mode: no
67
+ ```
68
+
69
+ __Rights__
70
+
71
+ The
72
+ [BSD::Capsicum.set_rights!](http://0x1eef.github.io/x/bsdcapsicum.rb/BSD/Capsicum.html#set_rights!-instance_method)
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
76
+ in a child process to allow only read operations. See the
77
+ [rights(4)](https://man.freebsd.org/cgi/man.cgi?query=rights&apropos=0&sektion=4&format=html)
78
+ man page for a full list of capabilities:
79
+
80
+ ``` ruby
81
+ #!/usr/bin/env ruby
82
+ require "bsd/capsicum"
83
+
84
+ path = File.join(Dir.home, "bsdcapsicum.txt")
85
+ file = File.open(path, File::CREAT | File::TRUNC | File::RDWR)
86
+ file.sync = true
87
+ print "[parent] obtain file descriptor (with read+write permissions)", "\n"
88
+ fork do
89
+ BSD::Capsicum.set_rights!(file, %i[CAP_READ])
90
+ print "[subprocess] reduce rights to read-only", "\n"
91
+
92
+ file.gets
93
+ print "[subprocess] read successful", "\n"
94
+
95
+ begin
96
+ file.write "foo"
97
+ rescue Errno::ENOTCAPABLE => ex
98
+ print "[subprocess] Error: #{ex.message} (#{ex.class})", "\n"
99
+ end
100
+ end
101
+ Process.wait
102
+ file.write "[parent] Hello from #{Process.pid}", "\n"
103
+ print "[parent] write successful", "\n"
104
+
105
+ ##
106
+ # [parent] obtain file descriptor (with read+write permissions)
107
+ # [subprocess] reduce rights to read-only
108
+ # [subprocess] read successful
109
+ # [subprocess] Error: Capabilities insufficient @ io_write - /home/user/bsdcapsicum.txt (Errno::ENOTCAPABLE)
110
+ # [parent] write successful
111
+ ```
112
+
113
+ ## Documentation
114
+
115
+ A complete API reference is available at [0x1eef.github.io/x/bsdcapsicum.rb](https://0x1eef.github.io/x/bsdcapsicum.rb)
116
+
117
+ ## Install
118
+
119
+ bsdcapsicum.rb is available via rubygems.org:
120
+
121
+ gem install bsdcapsicum.rb
122
+
123
+ ## Sources
124
+
125
+ * [GitHub](https://github.com/0x1eef/bsdcapsicum.rb#readme)
126
+ * [git.HardenedBSD.org](https://git.hardenedbsd.org/0x1eef/bsdcapsicum.rb#about)
127
+
128
+ ## See also
129
+
130
+ * [Freaky/ruby-capsicum](https://github.com/Freaky/ruby-capsicum) <br>
131
+ bsdcapsicum.rb is a fork of this project. It was a huge help both
132
+ in terms of code and documentation.
133
+
134
+ ## License
135
+
136
+ bsdcapsicum.rb
137
+ <br>
138
+ [BSD Zero Clause](https://choosealicense.com/licenses/0bsd/)
139
+ <br>
140
+ See [LICENSE](./LICENSE)
141
+ <br><br>
142
+ ruby-capsicum
143
+ <br>
144
+ [Freaky/ruby-capsicum](https://github.com/Freaky/ruby-capsicum) is released
145
+ under the terms of the MIT license
146
+ <br>
147
+ See [LICENSE.ruby-capsicum](/.LICENSE-ruby-capsicum)
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'bsd/capsicum/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "bsdcapsicum.rb"
8
+ spec.version = BSD::Capsicum::VERSION
9
+ spec.authors = ["Thomas Hurst", "0x1eef"]
10
+ spec.email = ["0x1eef@protonmail.com"]
11
+
12
+ spec.summary = "Ruby bindings for FreeBSD's capsicum(4)"
13
+ spec.homepage = "https://github.com/0x1eef/bsdcapsicum.rb"
14
+ spec.licenses = ["0BSD", "MIT"]
15
+ spec.files = Dir["lib/*.rb", "lib/**/*.rb", "README.md", "LICENSE", "LICENSE.ruby-capsicum", "*.gemspec"]
16
+ spec.require_paths = ["lib"]
17
+
18
+ spec.add_runtime_dependency "fiddle", "~> 1.1"
19
+ spec.add_development_dependency "bundler", "~> 2.5"
20
+ spec.add_development_dependency "rake", "~> 13.2"
21
+ spec.add_development_dependency "minitest", "~> 5.0"
22
+ spec.add_development_dependency "standard", "~> 1.38"
23
+ spec.add_development_dependency "test-cmd.rb", "~> 0.12"
24
+ spec.add_development_dependency "xchan.rb", "~> 0.17"
25
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BSD::Capsicum
4
+ ##
5
+ # The constants found in this module are defined
6
+ # by sys/capsicum.h and sys/caprights.h. Their
7
+ # documentation can be found in the
8
+ # [rights(4)](https://man.freebsd.org/cgi/man.cgi?query=rights&apropos=0&sektion=4&format=html)
9
+ # man page
10
+ module Constants
11
+ CAP_RIGHTS_VERSION = 0x0
12
+
13
+ ##
14
+ # @group File capabilties
15
+ CAP_READ = 0x200000000000001
16
+ CAP_WRITE = 0x200000000000002
17
+ CAP_SEEK = 0x20000000000000c
18
+ CAP_PREAD = 0x20000000000000d
19
+ CAP_PWRITE = 0x20000000000000e
20
+ CAP_MMAP = 0x200000000000010
21
+ CAP_CREATE = 0x200000000000040
22
+ CAP_FEXECVE = 0x200000000000080
23
+ CAP_FSYNC = 0x200000000000100
24
+ CAP_FTRUNCATE = 0x200000000000200
25
+ CAP_FCHFLAGS = 0x200000000001000
26
+ CAP_FCHMOD = 0x200000000002000
27
+ CAP_FCHMODAT = 0x200000000002400
28
+ CAP_FCHOWN = 0x200000000004000
29
+ CAP_FCHOWNAT = 0x200000000004400
30
+ CAP_FLOCK = 0x200000000010000
31
+ CAP_FPATHCONF = 0x200000000020000
32
+ CAP_FSTAT = 0x200000000080000
33
+ CAP_FSTATAT = 0x200000000080400
34
+ CAP_FSTATFS = 0x200000000100000
35
+ CAP_FUTIMES = 0x200000000200000
36
+ CAP_FUTIMESAT = 0x200000000200400
37
+ # @endgroup
38
+
39
+ ##
40
+ # @group Socket capabilities
41
+ CAP_ACCEPT = 0x200000020000000
42
+ CAP_BIND = 0x200000040000000
43
+ CAP_CONNECT = 0x200000080000000
44
+ CAP_GETPEERNAME = 0x200000100000000
45
+ CAP_GETSOCKNAME = 0x200000200000000
46
+ CAP_GETSOCKOPT = 0x200000400000000
47
+ CAP_LISTEN = 0x200000800000000
48
+ CAP_PEELOFF = 0x200001000000000
49
+ CAP_RECV = CAP_READ
50
+ CAP_SEND = CAP_WRITE
51
+ CAP_SETSOCKOPT = 0x200002000000000
52
+ CAP_SHUTDOWN = 0x200004000000000
53
+ CAP_BINDAT = 0x200008000000400
54
+ CAP_SOCK_CLIENT = 0x200007780000003
55
+ CAP_SOCK_SERVER = 0x200007f60000003
56
+ # @endgroup
57
+
58
+ ##
59
+ # @group ACL capabilities
60
+ CAP_ACL_CHECK = 0x400000000010000
61
+ CAP_ACL_DELETE = 0x400000000020000
62
+ CAP_ACL_GET = 0x400000000040000
63
+ CAP_ACL_SET = 0x400000000080000
64
+ # @endgroup
65
+
66
+ ##
67
+ # @group Process capabilities
68
+ CAP_PDGETPID = 0x400000000000200
69
+ CAP_PDKILL = 0x400000000000800
70
+ CAP_PDWAIT = 0x400000000000400
71
+ # @endgroup
72
+
73
+ ##
74
+ # @group Uncategorized capabilities
75
+ CAP_CHFLAGSAT = 0x200000000001400
76
+ CAP_EVENT = 0x400000000000020
77
+ CAP_IOCTL = 0x400000000000080
78
+ CAP_KQUEUE = 0x400000000100040
79
+ CAP_LOOKUP = 0x200000000000400
80
+ CAP_MAC_GET = 0x400000000000001
81
+ CAP_MAC_SET = 0x400000000000002
82
+ CAP_MKDIRAT = 0x200000000800400
83
+ CAP_MKFIFOAT = 0x200000001000400
84
+ CAP_MKNODAT = 0x200000002000400
85
+ CAP_SEM_GETVALUE = 0x400000000000004
86
+ CAP_SEM_POST = 0x400000000000008
87
+ CAP_SEM_WAIT = 0x400000000000010
88
+ CAP_TTYHOOK = 0x400000000000100
89
+ CAP_UNLINKAT = 0x200000010000400
90
+ CAP_FSCK = 0x200000000040000
91
+ CAP_FCHDIR = 0x200000000000800
92
+ CAP_FCNTL = 0x200000000008000
93
+ # @endgroup
94
+ end
95
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BSD::Capsicum
4
+ module FFI
5
+ require "fiddle"
6
+ include Fiddle::Types
7
+ include Constants
8
+
9
+ module_function
10
+
11
+ ##
12
+ # Provides a Ruby interface for cap_enter(2)
13
+ # @return [Integer]
14
+ def cap_enter
15
+ Fiddle::Function.new(
16
+ libc["cap_enter"],
17
+ [],
18
+ INT
19
+ ).call
20
+ end
21
+
22
+ ##
23
+ # Provides a Ruby interface for cap_getmode(2)
24
+ # @param [Fiddle::Pointer] uintp
25
+ # @return [Integer]
26
+ def cap_getmode(uintp)
27
+ Fiddle::Function.new(
28
+ libc["cap_getmode"],
29
+ [INTPTR_T],
30
+ INT
31
+ ).call(uintp)
32
+ end
33
+
34
+ ##
35
+ # Provides a Ruby interface for cap_rights_limit(2)
36
+ # @param [Integer] fd
37
+ # @param [Fiddle::Pointer] rights
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)
45
+ end
46
+
47
+ ##
48
+ # Provides a Ruby interface for cap_rights_init(2)
49
+ # @param [Array<Integer>] rights
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
60
+ end
61
+
62
+ ##
63
+ # @api private
64
+ def libc
65
+ @libc ||= Fiddle.dlopen Dir["/lib/libc.*"].first
66
+ end
67
+ end
68
+ private_constant :FFI
69
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BSD
4
+ end unless defined?(BSD)
5
+
6
+ module BSD::Capsicum
7
+ VERSION = "0.2.0"
8
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BSD
4
+ end unless defined?(BSD)
5
+
6
+ module BSD::Capsicum
7
+ require_relative "capsicum/version"
8
+ require_relative "capsicum/constants"
9
+ require_relative "capsicum/ffi"
10
+ extend self
11
+
12
+ ##
13
+ # Check if we're in capability mode
14
+ #
15
+ # @see https://man.freebsd.org/cgi/man.cgi?query=cap_getmode&apropos=0&sektion=2&format=html cap_getmode(2)
16
+ # @raise [SystemCallError]
17
+ # Might raise a subclass of SystemCallError
18
+ # @return [Boolean]
19
+ # Returns true when the current process is in capability mode
20
+ def in_capability_mode?
21
+ uintp = Fiddle::Pointer.malloc(Fiddle::SIZEOF_UINT)
22
+ if FFI.cap_getmode(uintp).zero?
23
+ uintp[0, Fiddle::SIZEOF_UINT].unpack("i") == [1]
24
+ else
25
+ raise SystemCallError.new("cap_getmode", Fiddle.last_error)
26
+ end
27
+ ensure
28
+ uintp.call_free
29
+ end
30
+ alias_method :capability_mode?, :in_capability_mode?
31
+
32
+ ##
33
+ # Enter a process into capability mode
34
+ #
35
+ # @see https://man.freebsd.org/cgi/man.cgi?query=cap_enter&apropos=0&sektion=2&format=html cap_enter(2)
36
+ # @raise [SystemCallError]
37
+ # Might raise a subclass of SystemCallError
38
+ # @return [Boolean]
39
+ # Returns true when successful
40
+ def enter!
41
+ FFI.cap_enter.zero? ||
42
+ raise(SystemCallError.new("cap_enter", Fiddle.last_error))
43
+ end
44
+ alias_method :enter_capability_mode!, :enter!
45
+
46
+ ##
47
+ # Restrict the capabilities of a file descriptor
48
+ #
49
+ # @see https://man.freebsd.org/cgi/man.cgi?query=cap_rights_limit&apropos=0&sektion=2&format=html cap_rights_limit(2)
50
+ # @see BSD::Capsicum::Constants See Constants for a full list of capabilities
51
+ # @example
52
+ # # Restrict capabilities of STDOUT to read / write
53
+ # BSD::Capsicum.set_rights!(STDOUT, %i[CAP_READ CAP_WRITE])
54
+ # @raise [SystemCallError]
55
+ # Might raise a subclass of SystemCallError
56
+ # @param [#to_i] io
57
+ # An IO object
58
+ # @param [Array<String>] rights
59
+ # An allowed set of capabilities
60
+ # @return [Boolean]
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? ||
65
+ raise(SystemCallError.new("cap_rights_limit", Fiddle.last_error))
66
+ ensure
67
+ voidp.call_free
68
+ end
69
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "bsd/capsicum"
metadata ADDED
@@ -0,0 +1,152 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bsdcapsicum.rb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Thomas Hurst
8
+ - '0x1eef'
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2024-06-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: fiddle
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.1'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1.1'
28
+ - !ruby/object:Gem::Dependency
29
+ name: bundler
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '2.5'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '2.5'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rake
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '13.2'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '13.2'
56
+ - !ruby/object:Gem::Dependency
57
+ name: minitest
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '5.0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '5.0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: standard
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '1.38'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '1.38'
84
+ - !ruby/object:Gem::Dependency
85
+ name: test-cmd.rb
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: '0.12'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '0.12'
98
+ - !ruby/object:Gem::Dependency
99
+ name: xchan.rb
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '0.17'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '0.17'
112
+ description:
113
+ email:
114
+ - 0x1eef@protonmail.com
115
+ executables: []
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - LICENSE
120
+ - LICENSE.ruby-capsicum
121
+ - README.md
122
+ - bsdcapsicum.rb.gemspec
123
+ - lib/bsd/capsicum.rb
124
+ - lib/bsd/capsicum/constants.rb
125
+ - lib/bsd/capsicum/ffi.rb
126
+ - lib/bsd/capsicum/version.rb
127
+ - lib/bsdcapsicum.rb
128
+ homepage: https://github.com/0x1eef/bsdcapsicum.rb
129
+ licenses:
130
+ - 0BSD
131
+ - MIT
132
+ metadata: {}
133
+ post_install_message:
134
+ rdoc_options: []
135
+ require_paths:
136
+ - lib
137
+ required_ruby_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ required_rubygems_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ requirements: []
148
+ rubygems_version: 3.5.11
149
+ signing_key:
150
+ specification_version: 4
151
+ summary: Ruby bindings for FreeBSD's capsicum(4)
152
+ test_files: []