bsdcapsicum.rb 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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: []