pledge 1.1.0 → 1.3.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 +4 -4
- data/CHANGELOG +8 -0
- data/README.rdoc +73 -12
- data/Rakefile +10 -9
- data/ext/pledge/extconf.rb +3 -1
- data/ext/pledge/pledge.c +42 -0
- data/lib/unveil.rb +71 -0
- data/spec/pledge_spec.rb +8 -15
- metadata +45 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f794b6f397a93e9eaabdfff4928f49537fb0a45b55c042c7dc27c46d27918f5a
|
4
|
+
data.tar.gz: a0291c2d672594938292c7a6a83cc111d3c54679ea412c679e28087b8a870a89
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9242a1de3c01334a60cb13ab98410dbe533e089228cf1a7a7cfdbb55a6d1ca7614aacbb306974ff85db1165b02a68e292ee9704038e41e9fab5100cccc7b68dc
|
7
|
+
data.tar.gz: e51bf3d1b375e5eba599052423fce0438cb21b3810b8dd38d6a26d7543bba2db8e8547edd0b53bbab99c999dfdead8b6f68e88620cfd9368a0c67bfcdf1c3d37
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
=== 1.3.0 (2022-12-19)
|
2
|
+
|
3
|
+
* Allow installation on platforms not supporting pledge, raising NotImplementedError when calling pledge/unveil methods in that case (jcs) (#3)
|
4
|
+
|
5
|
+
=== 1.2.0 (2019-07-07)
|
6
|
+
|
7
|
+
* Add unveil library and Pledge.unveil for access to unveil(2) to control file system access (jeremyevans)
|
8
|
+
|
1
9
|
=== 1.1.0 (2019-04-25)
|
2
10
|
|
3
11
|
* Support execpromises as optional second argument to Pledge.pledge (jeremyevans)
|
data/README.rdoc
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
= pledge
|
2
2
|
|
3
|
-
pledge exposes OpenBSD's pledge(2)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
pledge exposes OpenBSD's pledge(2) and unveil(2) system
|
4
|
+
calls to ruby. pledge(2) allows a program to restrict the
|
5
|
+
types of operations the program can do, and unveil(2)
|
6
|
+
restricts access to the file system.
|
7
|
+
|
8
|
+
Unlike other similar systems, pledge and unveil are
|
9
|
+
designed for programs that need to use a wide variety of
|
10
|
+
operations and file access on initialization, but
|
8
11
|
a fewer number after initialization (when user input will
|
9
12
|
be accepted).
|
10
13
|
|
11
|
-
|
12
|
-
argument for execpromises on OpenBSD 6.3+.
|
13
|
-
|
14
|
-
== Usage
|
14
|
+
== pledge
|
15
15
|
|
16
16
|
First, you need to require the library
|
17
17
|
|
@@ -53,8 +53,6 @@ in other classes:
|
|
53
53
|
Object.send(:include, Pledge)
|
54
54
|
pledge("rpath")
|
55
55
|
|
56
|
-
== Options
|
57
|
-
|
58
56
|
See the pledge(2) man page for a description of the allowed
|
59
57
|
promises in the strings passed to +Pledge.pledge+.
|
60
58
|
|
@@ -63,6 +61,69 @@ promise is added automatically to the current process's promises,
|
|
63
61
|
as ruby does not function without it, but it is not added to
|
64
62
|
the execpromises (as you can execute non-ruby programs).
|
65
63
|
|
64
|
+
== unveil
|
65
|
+
|
66
|
+
First, you need to require the library
|
67
|
+
|
68
|
+
require 'unveil'
|
69
|
+
|
70
|
+
Then you can use +Pledge.unveil+ as the interface to the unveil(2)
|
71
|
+
system call. You pass +Pledge.unveil+ a hash of paths and permissions,
|
72
|
+
for those paths, and it calls unveil(2) with the path and permissions
|
73
|
+
for each entry.
|
74
|
+
|
75
|
+
The permissions should be a string with the following characters:
|
76
|
+
|
77
|
+
r :: Allow read access to existing files and directories
|
78
|
+
w :: Allow write access to existing files and directories
|
79
|
+
x :: Allow execute access to programs
|
80
|
+
c :: Allow create access for new files and directories
|
81
|
+
|
82
|
+
You can use the empty string as permissions if you want to allow no access
|
83
|
+
to the given path, even if you have granted some access to a folder above
|
84
|
+
the given folder. You can use a value of +:gem+ to allow read access to
|
85
|
+
the directory for the gem specified by the key.
|
86
|
+
|
87
|
+
+Pledge.unveil+ locks the file system access to the specified paths. If
|
88
|
+
you want to specify which paths to allow in multiple places in your
|
89
|
+
program, use +Pledge.unveil_without_lock+ for the initial calls and
|
90
|
+
+Pledge.unveil+ for the final call.
|
91
|
+
|
92
|
+
If +Pledge.unveil+ is called with an empty hash, it adds an unveil of +/+
|
93
|
+
with no permissions, which denies all access to the file system if
|
94
|
+
+unveil_without_lock+ was not called previously with paths.
|
95
|
+
|
96
|
+
Example:
|
97
|
+
|
98
|
+
Pledge.unveil(
|
99
|
+
'/home/foo/bar' => 'r',
|
100
|
+
'/home/foo/bar/data' => 'rwc',
|
101
|
+
'/bin' => 'x',
|
102
|
+
'/home/foo/bar/secret' => '',
|
103
|
+
'rack' => :gem
|
104
|
+
)
|
105
|
+
|
106
|
+
The value of :gem is mostly mostly needed if the gem uses autoload or
|
107
|
+
other forms of runtime requires. This allows read access to
|
108
|
+
all files in the gem's folder, not just the gem's require paths,
|
109
|
+
so it works correctly for gems that access data (e.g. templates)
|
110
|
+
outside of the gem's require paths.
|
111
|
+
|
112
|
+
If you plan to use pledge and unveil together, you should
|
113
|
+
unveil before pledging, unless you use the +unveil+
|
114
|
+
promise when pledging.
|
115
|
+
|
116
|
+
=== Issues with unveil and File.realpath
|
117
|
+
|
118
|
+
+Pledge.unveil+ does not work with +File.realpath+ on Ruby <2.7.
|
119
|
+
The Ruby ports officially supported by OpenBSD have had support to
|
120
|
+
allow them to work together backported, as long as you are running
|
121
|
+
OpenBSD 6.6+ (or 6.5-current after July 2019). As +require+ uses
|
122
|
+
+File.realpath+, this means in most cases where you would want to
|
123
|
+
use the +:gem+ support, it will not actually work correctly unless
|
124
|
+
you are using Ruby 2.7+ or an OpenBSD package with the backported
|
125
|
+
support.
|
126
|
+
|
66
127
|
== Reporting issues/bugs
|
67
128
|
|
68
129
|
This library uses GitHub Issues for tracking issues/bugs:
|
@@ -81,7 +142,7 @@ To get a copy:
|
|
81
142
|
|
82
143
|
== Requirements
|
83
144
|
|
84
|
-
* OpenBSD 5.9+
|
145
|
+
* OpenBSD 5.9+ (6.4+ for unveil, but 6.6+ recommended)
|
85
146
|
* ruby 1.8.7+
|
86
147
|
* rake-compiler (if compiling)
|
87
148
|
|
data/Rakefile
CHANGED
@@ -1,13 +1,6 @@
|
|
1
|
-
require "rake"
|
2
1
|
require "rake/clean"
|
3
2
|
|
4
|
-
CLEAN.include %w'
|
5
|
-
|
6
|
-
desc "Do a full cleaning"
|
7
|
-
task :distclean do
|
8
|
-
CLEAN.include %w'tmp pkg tame*.gem lib/*.so'
|
9
|
-
Rake::Task[:clean].invoke
|
10
|
-
end
|
3
|
+
CLEAN.include %w'lib/*.so tmp coverage'
|
11
4
|
|
12
5
|
desc "Build the gem"
|
13
6
|
task :package do
|
@@ -17,12 +10,20 @@ end
|
|
17
10
|
desc "Run specs"
|
18
11
|
task :spec => :compile do
|
19
12
|
ruby = ENV['RUBY'] ||= FileUtils::RUBY
|
20
|
-
sh %{#{ruby} spec/pledge_spec.rb}
|
13
|
+
sh %{#{ruby} #{"-w" if RUBY_VERSION >= '3'} spec/pledge_spec.rb}
|
21
14
|
end
|
22
15
|
|
23
16
|
desc "Run specs"
|
24
17
|
task :default => :spec
|
25
18
|
|
19
|
+
desc "Run specs with coverage"
|
20
|
+
task :spec_cov => [:compile] do
|
21
|
+
ruby = ENV['RUBY'] ||= FileUtils::RUBY
|
22
|
+
ENV['COVERAGE'] = '1'
|
23
|
+
FileUtils.rm_rf('coverage')
|
24
|
+
sh %{#{ruby} spec/unveil_spec.rb}
|
25
|
+
end
|
26
|
+
|
26
27
|
begin
|
27
28
|
require 'rake/extensiontask'
|
28
29
|
Rake::ExtensionTask.new('pledge')
|
data/ext/pledge/extconf.rb
CHANGED
data/ext/pledge/pledge.c
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
static VALUE ePledgeInvalidPromise;
|
6
6
|
static VALUE ePledgePermissionIncreaseAttempt;
|
7
7
|
static VALUE ePledgeError;
|
8
|
+
static VALUE ePledgeUnveilError;
|
8
9
|
|
9
10
|
static VALUE rb_pledge(int argc, VALUE* argv, VALUE pledge_class) {
|
10
11
|
VALUE promises = Qnil;
|
@@ -12,6 +13,7 @@ static VALUE rb_pledge(int argc, VALUE* argv, VALUE pledge_class) {
|
|
12
13
|
const char * prom = NULL;
|
13
14
|
const char * execprom = NULL;
|
14
15
|
|
16
|
+
#ifdef HAVE_PLEDGE
|
15
17
|
rb_scan_args(argc, argv, "11", &promises, &execpromises);
|
16
18
|
|
17
19
|
if (!NIL_P(promises)) {
|
@@ -40,10 +42,44 @@ static VALUE rb_pledge(int argc, VALUE* argv, VALUE pledge_class) {
|
|
40
42
|
rb_raise(ePledgeError, "pledge error");
|
41
43
|
}
|
42
44
|
}
|
45
|
+
#else
|
46
|
+
rb_raise(rb_eNotImpError, "pledge not supported");
|
47
|
+
#endif
|
43
48
|
|
44
49
|
return Qnil;
|
45
50
|
}
|
46
51
|
|
52
|
+
#ifdef HAVE_UNVEIL
|
53
|
+
static VALUE check_unveil(const char * path, const char * perm) {
|
54
|
+
if (unveil(path, perm) != 0) {
|
55
|
+
switch(errno) {
|
56
|
+
case EINVAL:
|
57
|
+
rb_raise(ePledgeUnveilError, "invalid permissions value");
|
58
|
+
case EPERM:
|
59
|
+
rb_raise(ePledgeUnveilError, "attempt to increase permissions, path not accessible, or unveil already locked");
|
60
|
+
case E2BIG:
|
61
|
+
rb_raise(ePledgeUnveilError, "per-process limit for unveiled paths reached");
|
62
|
+
case ENOENT:
|
63
|
+
rb_raise(ePledgeUnveilError, "directory in the path does not exist");
|
64
|
+
default:
|
65
|
+
rb_raise(ePledgeUnveilError, "unveil error");
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
69
|
+
return Qnil;
|
70
|
+
}
|
71
|
+
|
72
|
+
static VALUE rb_unveil(VALUE pledge_class, VALUE path, VALUE perm) {
|
73
|
+
SafeStringValue(path);
|
74
|
+
SafeStringValue(perm);
|
75
|
+
return check_unveil(RSTRING_PTR(path), RSTRING_PTR(perm));
|
76
|
+
}
|
77
|
+
|
78
|
+
static VALUE rb_finalize_unveil(VALUE pledge_class) {
|
79
|
+
return check_unveil(NULL, NULL);
|
80
|
+
}
|
81
|
+
#endif
|
82
|
+
|
47
83
|
void Init_pledge(void) {
|
48
84
|
VALUE cPledge;
|
49
85
|
cPledge = rb_define_module("Pledge");
|
@@ -52,4 +88,10 @@ void Init_pledge(void) {
|
|
52
88
|
ePledgeError = rb_define_class_under(cPledge, "Error", rb_eStandardError);
|
53
89
|
ePledgeInvalidPromise = rb_define_class_under(cPledge, "InvalidPromise", ePledgeError);
|
54
90
|
ePledgePermissionIncreaseAttempt = rb_define_class_under(cPledge, "PermissionIncreaseAttempt", ePledgeError);
|
91
|
+
|
92
|
+
#ifdef HAVE_UNVEIL
|
93
|
+
rb_define_private_method(cPledge, "_unveil", rb_unveil, 2);
|
94
|
+
rb_define_private_method(cPledge, "_finalize_unveil!", rb_finalize_unveil, 0);
|
95
|
+
ePledgeUnveilError = rb_define_class_under(cPledge, "UnveilError", rb_eStandardError);
|
96
|
+
#endif
|
55
97
|
}
|
data/lib/unveil.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
require_relative 'pledge'
|
4
|
+
|
5
|
+
module Pledge
|
6
|
+
# Limit access to the file system using unveil(2). +paths+ should be a hash
|
7
|
+
# where keys are paths and values are the access permissions for that path. Each
|
8
|
+
# value should be a string with the following characters specifying what
|
9
|
+
# permissions are allowed:
|
10
|
+
#
|
11
|
+
# r :: Allow read access to existing files and directories
|
12
|
+
# w :: Allow write access to existing files and directories
|
13
|
+
# c :: Allow create/delete access for new files and directories
|
14
|
+
# x :: Allow execute access to programs
|
15
|
+
#
|
16
|
+
# You can use the empty string as permissions if you want to allow no access
|
17
|
+
# to the given path, even if you have granted some access to a folder above
|
18
|
+
# the given folder. You can use a value of +:gem+ to allow read access to
|
19
|
+
# the directory for the gem specified by the key.
|
20
|
+
#
|
21
|
+
# If called with an empty hash, adds an unveil of +/+ with no permissions,
|
22
|
+
# which denies all access to the file system if +unveil_without_lock+
|
23
|
+
# was not called previously.
|
24
|
+
def unveil(paths)
|
25
|
+
# :nocov:
|
26
|
+
raise NotImplementedError, "unveil not supported" unless Pledge.respond_to?(:_unveil, true)
|
27
|
+
# :nocov:
|
28
|
+
|
29
|
+
if paths.empty?
|
30
|
+
paths = {'/'=>''}
|
31
|
+
end
|
32
|
+
|
33
|
+
unveil_without_lock(paths)
|
34
|
+
_finalize_unveil!
|
35
|
+
end
|
36
|
+
|
37
|
+
# Same as unveil, but allows for future calls to unveil or unveil_without_lock.
|
38
|
+
def unveil_without_lock(paths)
|
39
|
+
# :nocov:
|
40
|
+
raise NotImplementedError, "unveil not supported" unless Pledge.respond_to?(:_unveil, true)
|
41
|
+
# :nocov:
|
42
|
+
|
43
|
+
paths = Hash[paths]
|
44
|
+
|
45
|
+
paths.to_a.each do |path, perm|
|
46
|
+
unless path.is_a?(String)
|
47
|
+
raise UnveilError, "unveil path is not a string: #{path.inspect}"
|
48
|
+
end
|
49
|
+
|
50
|
+
case perm
|
51
|
+
when :gem
|
52
|
+
unless spec = Gem.loaded_specs[path]
|
53
|
+
raise UnveilError, "cannot unveil gem #{path} as it is not loaded"
|
54
|
+
end
|
55
|
+
|
56
|
+
paths.delete(path)
|
57
|
+
paths[spec.full_gem_path] = 'r'
|
58
|
+
when String
|
59
|
+
# nothing to do
|
60
|
+
else
|
61
|
+
raise UnveilError, "unveil permission is not a string: #{perm.inspect}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
paths.each do |path, perm|
|
66
|
+
_unveil(path, perm)
|
67
|
+
end
|
68
|
+
|
69
|
+
nil
|
70
|
+
end
|
71
|
+
end
|
data/spec/pledge_spec.rb
CHANGED
@@ -1,11 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require 'rubygems'
|
4
|
-
ENV['MT_NO_PLUGINS'] = '1' # Work around stupid autoloading of plugins
|
5
|
-
gem 'minitest'
|
6
|
-
require 'minitest/autorun'
|
7
|
-
|
8
|
-
RUBY = ENV['RUBY'] || 'ruby'
|
1
|
+
require_relative 'unveil_spec'
|
9
2
|
|
10
3
|
describe "Pledge.pledge" do
|
11
4
|
def execpledged(promises, execpromises, code)
|
@@ -41,7 +34,7 @@ describe "Pledge.pledge" do
|
|
41
34
|
proc{Pledge.pledge("foo")}.must_raise Pledge::InvalidPromise
|
42
35
|
end
|
43
36
|
|
44
|
-
it "should raise a Pledge::PermissionIncreaseAttempt if attempting to increase
|
37
|
+
it "should raise a Pledge::PermissionIncreaseAttempt if attempting to increase permissions" do
|
45
38
|
pledged("begin; Pledge.pledge('rpath'); rescue Pledge::PermissionIncreaseAttempt; exit 0; end; exit 1")
|
46
39
|
end
|
47
40
|
|
@@ -73,8 +66,8 @@ describe "Pledge.pledge" do
|
|
73
66
|
|
74
67
|
it "should allow dns lookups if dns is used" do
|
75
68
|
with_lib('socket') do
|
76
|
-
unpledged("
|
77
|
-
pledged("
|
69
|
+
unpledged("Addrinfo.getaddrinfo('google.com', nil)")
|
70
|
+
pledged("Addrinfo.getaddrinfo('google.com', nil)", "dns")
|
78
71
|
end
|
79
72
|
end
|
80
73
|
|
@@ -121,9 +114,9 @@ describe "Pledge.pledge" do
|
|
121
114
|
end
|
122
115
|
|
123
116
|
it "should handle both promises and execpromises arguments" do
|
124
|
-
execpledged("proc exec rpath", "stdio rpath", "exit(`cat MIT-LICENSE` == File.read('MIT-LICENSE')
|
125
|
-
execpledged("proc exec", "stdio rpath", "$stderr.reopen('/dev/null', 'w'); exit(`cat MIT-LICENSE` == File.read('MIT-LICENSE')
|
126
|
-
execpledged("proc exec rpath", "stdio", "$stderr.reopen('/dev/null', 'w'); exit(`cat MIT-LICENSE` == File.read('MIT-LICENSE')
|
117
|
+
execpledged("proc exec rpath", "stdio rpath", "exit(`cat MIT-LICENSE` == File.read('MIT-LICENSE'))").must_equal true
|
118
|
+
execpledged("proc exec", "stdio rpath", "$stderr.reopen('/dev/null', 'w'); exit(`cat MIT-LICENSE` == File.read('MIT-LICENSE'))").must_equal false
|
119
|
+
execpledged("proc exec rpath", "stdio", "$stderr.reopen('/dev/null', 'w'); exit(`cat MIT-LICENSE` == File.read('MIT-LICENSE'))").must_equal false
|
127
120
|
end
|
128
121
|
|
129
122
|
it "should handle nil arguments" do
|
@@ -133,6 +126,6 @@ describe "Pledge.pledge" do
|
|
133
126
|
execpledged("", nil, "`cat MIT-LICENSE`").must_equal false
|
134
127
|
execpledged(nil, "stdio rpath", "`cat MIT-LICENSE`").must_equal true
|
135
128
|
execpledged(nil, "stdio", "File.read('MIT-LICENSE')").must_equal true
|
136
|
-
execpledged(nil, "stdio", "$stderr.reopen('/dev/null', 'w'); exit(`cat MIT-LICENSE` == File.read('MIT-LICENSE')
|
129
|
+
execpledged(nil, "stdio", "$stderr.reopen('/dev/null', 'w'); exit(`cat MIT-LICENSE` == File.read('MIT-LICENSE'))").must_equal false
|
137
130
|
end
|
138
131
|
end
|
metadata
CHANGED
@@ -1,23 +1,50 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pledge
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Evans
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
11
|
+
date: 2022-12-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: minitest-global_expectations
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake-compiler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
13
41
|
description: |
|
14
|
-
pledge exposes OpenBSD's pledge(2) system
|
15
|
-
program to restrict the types of operations the program
|
16
|
-
|
17
|
-
pledge
|
18
|
-
use a wide variety of operations on initialization, but
|
19
|
-
|
20
|
-
be accepted).
|
42
|
+
pledge exposes OpenBSD's pledge(2) and unveil(2) system calls to Ruby, allowing
|
43
|
+
a program to restrict the types of operations the program can do, and the file
|
44
|
+
system access the program has, after the point of call. Unlike other similar
|
45
|
+
systems, pledge and unveil are specifically designed for programs that need to
|
46
|
+
use a wide variety of operations on initialization, but a fewer number after
|
47
|
+
initialization (when user input will be accepted).
|
21
48
|
email: code@jeremyevans.net
|
22
49
|
executables: []
|
23
50
|
extensions:
|
@@ -33,18 +60,19 @@ files:
|
|
33
60
|
- Rakefile
|
34
61
|
- ext/pledge/extconf.rb
|
35
62
|
- ext/pledge/pledge.c
|
63
|
+
- lib/unveil.rb
|
36
64
|
- spec/pledge_spec.rb
|
37
65
|
homepage: https://github.com/jeremyevans/ruby-pledge
|
38
66
|
licenses:
|
39
67
|
- MIT
|
40
68
|
metadata: {}
|
41
|
-
post_install_message:
|
69
|
+
post_install_message:
|
42
70
|
rdoc_options:
|
43
71
|
- "--quiet"
|
44
72
|
- "--line-numbers"
|
45
73
|
- "--inline-source"
|
46
74
|
- "--title"
|
47
|
-
- 'pledge: restrict system operations on OpenBSD'
|
75
|
+
- 'pledge: restrict system operations and file system access on OpenBSD'
|
48
76
|
- "--main"
|
49
77
|
- README.rdoc
|
50
78
|
require_paths:
|
@@ -53,15 +81,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
53
81
|
requirements:
|
54
82
|
- - ">="
|
55
83
|
- !ruby/object:Gem::Version
|
56
|
-
version: 1.
|
84
|
+
version: 1.9.2
|
57
85
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
86
|
requirements:
|
59
87
|
- - ">="
|
60
88
|
- !ruby/object:Gem::Version
|
61
89
|
version: '0'
|
62
90
|
requirements: []
|
63
|
-
rubygems_version: 3.
|
64
|
-
signing_key:
|
91
|
+
rubygems_version: 3.3.26
|
92
|
+
signing_key:
|
65
93
|
specification_version: 4
|
66
|
-
summary: Restrict system operations on OpenBSD
|
94
|
+
summary: Restrict system operations and file system access on OpenBSD
|
67
95
|
test_files: []
|