capng_c 0.1.0 → 0.1.5
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/.github/workflows/linux.yml +30 -0
- data/README.md +6 -0
- data/capng_c.gemspec +1 -1
- data/example/file_capability.rb +36 -0
- data/example/process_capability.rb +59 -0
- data/example/process_capability_without_root.rb +36 -0
- data/ext/capng/capng.c +170 -20
- data/ext/capng/capng.h +8 -0
- data/ext/capng/enum.c +3 -0
- data/ext/capng/extconf.rb +1 -1
- data/ext/capng/print.c +70 -10
- data/ext/capng/utils.c +80 -0
- data/lib/capng.rb +29 -1
- data/lib/capng/version.rb +1 -1
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46ab5a21fef03d5b25db0124526add7f625acc865ae10da0f8614b6290b5aec0
|
4
|
+
data.tar.gz: cae7565475f00217336124b3c1d0bad6fd3772470e3c8e2605ebac09bac87829
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 90fab6a90550512222604afee7896c75b766559d39f3288cad6191fb5b1192f080efc4bec6deef2c00377da4f7e8d129ec928191d67fa9277aac505652064b59
|
7
|
+
data.tar.gz: eee3466a6e594b8b5d4fa1835c7650a6d7669cb20be1410c32c8e0b2d878d197263848ec2f1ea7923088428611a78400569f9be55ea16a4c0115ee3b6cd8547d
|
@@ -0,0 +1,30 @@
|
|
1
|
+
name: Linux testing
|
2
|
+
on:
|
3
|
+
- push
|
4
|
+
- pull_request
|
5
|
+
jobs:
|
6
|
+
build:
|
7
|
+
runs-on: ${{ matrix.os }}
|
8
|
+
strategy:
|
9
|
+
fail-fast: false
|
10
|
+
matrix:
|
11
|
+
ruby: [ '2.4', '2.5', '2.6' , '2.7' ]
|
12
|
+
os:
|
13
|
+
- ubuntu-latest
|
14
|
+
name: Ruby ${{ matrix.ruby }} unit testing on ${{ matrix.os }}
|
15
|
+
steps:
|
16
|
+
- uses: actions/checkout@v2
|
17
|
+
- name: Install dependencies
|
18
|
+
run: |
|
19
|
+
sudo apt update
|
20
|
+
sudo apt -V install libcap-ng-dev
|
21
|
+
- uses: ruby/setup-ruby@v1
|
22
|
+
with:
|
23
|
+
ruby-version: ${{ matrix.ruby }}
|
24
|
+
- name: unit testing
|
25
|
+
env:
|
26
|
+
CI: true
|
27
|
+
run: |
|
28
|
+
gem install bundler rake
|
29
|
+
bundle install --jobs 4 --retry 3
|
30
|
+
bundle exec rake
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Capng_c
|
2
2
|
|
3
|
+

|
4
|
+
|
3
5
|
libcap-ng bindings for Ruby.
|
4
6
|
|
5
7
|
## Installation
|
@@ -18,6 +20,10 @@ Or install it yourself as:
|
|
18
20
|
|
19
21
|
$ gem install capng_c
|
20
22
|
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
The usage examples are put in [example directory](example).
|
26
|
+
|
21
27
|
## Development
|
22
28
|
|
23
29
|
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/capng_c.gemspec
CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
|
|
11
11
|
spec.summary = %q{libcap-ng bindings for Ruby.}
|
12
12
|
spec.description = spec.summary
|
13
13
|
spec.homepage = "https://github.com/cosmo0920/cap-ng_c"
|
14
|
-
|
14
|
+
spec.license = "Apache-2.0"
|
15
15
|
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
16
16
|
|
17
17
|
spec.metadata["homepage_uri"] = spec.homepage
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Copyright 2020- Hiroshi Hatake
|
2
|
+
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'capng'
|
16
|
+
|
17
|
+
if ARGV.size != 1
|
18
|
+
puts "specify file path on ARGV."
|
19
|
+
exit 1
|
20
|
+
end
|
21
|
+
|
22
|
+
if Process.uid != 0
|
23
|
+
puts "Needed to run as root!"
|
24
|
+
exit 2
|
25
|
+
end
|
26
|
+
|
27
|
+
path = ARGV[0]
|
28
|
+
capng = CapNG.new(:file, path)
|
29
|
+
print = CapNG::Print.new
|
30
|
+
puts "capability: #{print.caps_text(:buffer, :effective)}"
|
31
|
+
capng.clear(:caps)
|
32
|
+
ret = capng.update(:add, CapNG::Type::EFFECTIVE | CapNG::Type::INHERITABLE | CapNG::Type::PERMITTED,
|
33
|
+
[:dac_read_search, :dac_override])
|
34
|
+
puts "updating capability: #{ret ? "success" : "fail"}"
|
35
|
+
capng.apply_caps_file(path)
|
36
|
+
puts "updated capability: #{print.caps_text(:buffer, :effective)}"
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# Copyright 2020- Hiroshi Hatake
|
2
|
+
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'capng'
|
16
|
+
|
17
|
+
if Process.uid != 0
|
18
|
+
puts "Needed to run as root!"
|
19
|
+
exit 2
|
20
|
+
end
|
21
|
+
|
22
|
+
capng = CapNG.new(:current_process)
|
23
|
+
|
24
|
+
print = CapNG::Print.new
|
25
|
+
puts "capability: #{print.caps_text(:buffer, :effective)}"
|
26
|
+
target_file = ARGV[0] || "/var/log/syslog"
|
27
|
+
capng.clear(:caps)
|
28
|
+
|
29
|
+
puts "capability: #{print.caps_text(:buffer, :effective)}"
|
30
|
+
ret = capng.update(:add, CapNG::Type::EFFECTIVE | CapNG::Type::INHERITABLE | CapNG::Type::PERMITTED, :dac_read_search)
|
31
|
+
puts "CapNG#update: #{ret ? 'success' : 'fail'}"
|
32
|
+
|
33
|
+
ret = capng.apply(:caps)
|
34
|
+
puts "CapNG#apply(add): #{ret ? 'success' : 'fail'}"
|
35
|
+
puts "capability: #{print.caps_text(:buffer, :effective)}"
|
36
|
+
path = "/var/log/syslog"
|
37
|
+
unless File.readable?(path)
|
38
|
+
puts "-----unreadable!!!!-----\ntarget: #{target_file}"
|
39
|
+
end
|
40
|
+
contents = File.read(target_file)
|
41
|
+
if contents.length >= 0
|
42
|
+
puts "succeeded to read: #{target_file}"
|
43
|
+
end
|
44
|
+
|
45
|
+
ret = capng.update(:drop, CapNG::Type::EFFECTIVE | CapNG::Type::INHERITABLE | CapNG::Type::PERMITTED, :dac_read_search)
|
46
|
+
puts "CapNG#update(drop): #{ret ? 'success' : 'fail'}"
|
47
|
+
puts "capability: #{print.caps_text(:buffer, :effective)}"
|
48
|
+
|
49
|
+
ret = capng.apply(:caps)
|
50
|
+
puts "CapNG#apply(drop): #{ret ? 'success' : 'fail'}"
|
51
|
+
|
52
|
+
unless File.readable?(path)
|
53
|
+
puts "-----unreadable!!!!-----\ntarget: #{target_file}"
|
54
|
+
end
|
55
|
+
begin
|
56
|
+
File.read(target_file)
|
57
|
+
rescue Errno::EACCES
|
58
|
+
puts "permission denied even if run as root"
|
59
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Copyright 2020- Hiroshi Hatake
|
2
|
+
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'capng'
|
16
|
+
|
17
|
+
capng = CapNG.new(:current_process)
|
18
|
+
unless capng.have_capability?(:effective, :dac_read_search)
|
19
|
+
puts "This example needs to setup :dac_read_search capability on running Ruby executable."
|
20
|
+
exit 2
|
21
|
+
end
|
22
|
+
|
23
|
+
print = CapNG::Print.new
|
24
|
+
puts "capability: #{print.caps_text(:buffer, :effective)}"
|
25
|
+
target_file = ARGV[0] || "/var/log/syslog"
|
26
|
+
|
27
|
+
path = "/var/log/syslog"
|
28
|
+
unless File.readable?(path)
|
29
|
+
puts "-----unreadable!!!!-----\ntarget: #{target_file}"
|
30
|
+
end
|
31
|
+
if capng.have_capability?(:effective, :dac_read_search)
|
32
|
+
contents = File.read(target_file)
|
33
|
+
if contents.length >= 0
|
34
|
+
puts "succeeded to read: #{target_file} w/o root user"
|
35
|
+
end
|
36
|
+
end
|
data/ext/capng/capng.c
CHANGED
@@ -46,27 +46,106 @@ rb_capng_alloc(VALUE klass)
|
|
46
46
|
}
|
47
47
|
|
48
48
|
static VALUE
|
49
|
-
rb_capng_initialize(VALUE self)
|
49
|
+
rb_capng_initialize(int argc, VALUE *argv, VALUE self)
|
50
50
|
{
|
51
|
+
VALUE rb_target, rb_pid_or_file;
|
52
|
+
int result = 0;
|
53
|
+
char *target = NULL;
|
54
|
+
int pid = 0, fd = 0;
|
55
|
+
rb_io_t *fptr = NULL;
|
56
|
+
|
57
|
+
rb_scan_args(argc, argv, "02", &rb_target, &rb_pid_or_file);
|
58
|
+
|
59
|
+
if (NIL_P(rb_target)) {
|
60
|
+
return Qnil;
|
61
|
+
}
|
62
|
+
|
63
|
+
if (RB_TYPE_P(rb_target, T_SYMBOL)) {
|
64
|
+
target = RSTRING_PTR(rb_sym2str(rb_target));
|
65
|
+
} else if (RB_TYPE_P(rb_target, T_STRING)) {
|
66
|
+
target = StringValuePtr(rb_target);
|
67
|
+
} else {
|
68
|
+
rb_raise(rb_eArgError, "Expected a String or a Symbol instance for tagret argument");
|
69
|
+
}
|
70
|
+
|
71
|
+
if (strcmp(target, "current_process") == 0) {
|
72
|
+
result = capng_get_caps_process();
|
73
|
+
if (result != 0) {
|
74
|
+
rb_raise(rb_eRuntimeError, "Couldn't get current process' capability");
|
75
|
+
}
|
76
|
+
} else if (strcmp(target, "other_process") == 0) {
|
77
|
+
Check_Type(rb_pid_or_file, T_FIXNUM);
|
78
|
+
|
79
|
+
pid = NUM2INT(rb_pid_or_file);
|
80
|
+
capng_setpid(pid);
|
81
|
+
result = capng_get_caps_process();
|
82
|
+
if (result != 0) {
|
83
|
+
rb_raise(rb_eRuntimeError, "Couldn't get current process' capability");
|
84
|
+
}
|
85
|
+
} else if (strcmp(target, "file") == 0) {
|
86
|
+
Check_Type(rb_pid_or_file, T_FILE);
|
87
|
+
|
88
|
+
fptr = RFILE(rb_pid_or_file)->fptr;
|
89
|
+
fd = fptr->fd;
|
90
|
+
result = capng_get_caps_fd(fd);
|
91
|
+
/* Just store result into instance variable. */
|
92
|
+
/* This is because capng_get_caps_fd should return 0 if file cap is not set. */
|
93
|
+
rb_iv_set(self, "@return_code", INT2NUM(result));
|
94
|
+
}
|
95
|
+
|
51
96
|
return Qnil;
|
52
97
|
}
|
53
98
|
|
54
99
|
static VALUE
|
55
|
-
|
100
|
+
rb_capng_return_code(VALUE self)
|
56
101
|
{
|
57
|
-
|
102
|
+
return rb_iv_get(self, "@return_code");
|
103
|
+
}
|
104
|
+
|
105
|
+
static VALUE
|
106
|
+
rb_capng_clear(VALUE self, VALUE rb_select_name_or_enum)
|
107
|
+
{
|
108
|
+
capng_select_t select = 0;
|
109
|
+
|
110
|
+
switch (TYPE(rb_select_name_or_enum)) {
|
111
|
+
case T_SYMBOL:
|
112
|
+
select = select_name_to_select_type(RSTRING_PTR(rb_sym2str(rb_select_name_or_enum)));
|
113
|
+
break;
|
114
|
+
case T_STRING:
|
115
|
+
select = select_name_to_select_type(StringValuePtr(rb_select_name_or_enum));
|
116
|
+
break;
|
117
|
+
case T_FIXNUM:
|
118
|
+
select = NUM2INT(rb_select_name_or_enum);
|
119
|
+
break;
|
120
|
+
default:
|
121
|
+
rb_raise(rb_eArgError, "Expected a String or a Symbol instance, or a capability type constant");
|
122
|
+
}
|
58
123
|
|
59
|
-
capng_clear(
|
124
|
+
capng_clear(select);
|
60
125
|
|
61
126
|
return Qnil;
|
62
127
|
}
|
63
128
|
|
64
129
|
static VALUE
|
65
|
-
rb_capng_fill(VALUE self, VALUE
|
130
|
+
rb_capng_fill(VALUE self, VALUE rb_select_name_or_enum)
|
66
131
|
{
|
67
|
-
|
132
|
+
capng_select_t select = 0;
|
68
133
|
|
69
|
-
|
134
|
+
switch (TYPE(rb_select_name_or_enum)) {
|
135
|
+
case T_SYMBOL:
|
136
|
+
select = select_name_to_select_type(RSTRING_PTR(rb_sym2str(rb_select_name_or_enum)));
|
137
|
+
break;
|
138
|
+
case T_STRING:
|
139
|
+
select = select_name_to_select_type(StringValuePtr(rb_select_name_or_enum));
|
140
|
+
break;
|
141
|
+
case T_FIXNUM:
|
142
|
+
select = NUM2INT(rb_select_name_or_enum);
|
143
|
+
break;
|
144
|
+
default:
|
145
|
+
rb_raise(rb_eArgError, "Expected a String or a Symbol instance, or a capability type constant");
|
146
|
+
}
|
147
|
+
|
148
|
+
capng_fill(select);
|
70
149
|
|
71
150
|
return Qnil;
|
72
151
|
}
|
@@ -94,13 +173,41 @@ rb_capng_get_caps_process(VALUE self)
|
|
94
173
|
}
|
95
174
|
|
96
175
|
static VALUE
|
97
|
-
rb_capng_update(VALUE self,
|
176
|
+
rb_capng_update(VALUE self,
|
177
|
+
VALUE rb_action_name_or_action, VALUE rb_capability_name_or_type, VALUE rb_capability_or_name)
|
98
178
|
{
|
99
179
|
int result = 0;
|
100
180
|
unsigned int capability = 0;
|
181
|
+
capng_type_t capability_type = 0;
|
182
|
+
capng_act_t action = 0;
|
101
183
|
|
102
|
-
|
103
|
-
|
184
|
+
switch (TYPE(rb_action_name_or_action)) {
|
185
|
+
case T_SYMBOL:
|
186
|
+
action = action_name_to_action_type(RSTRING_PTR(rb_sym2str(rb_action_name_or_action)));
|
187
|
+
break;
|
188
|
+
case T_STRING:
|
189
|
+
action = action_name_to_action_type(StringValuePtr(rb_action_name_or_action));
|
190
|
+
break;
|
191
|
+
case T_FIXNUM:
|
192
|
+
action = NUM2INT(rb_action_name_or_action);
|
193
|
+
break;
|
194
|
+
default:
|
195
|
+
rb_raise(rb_eArgError, "Expected a String or a Symbol instance, or a capability type constant");
|
196
|
+
}
|
197
|
+
|
198
|
+
switch (TYPE(rb_capability_name_or_type)) {
|
199
|
+
case T_SYMBOL:
|
200
|
+
capability_type = capability_type_name_to_capability_type(RSTRING_PTR(rb_sym2str(rb_capability_name_or_type)));
|
201
|
+
break;
|
202
|
+
case T_STRING:
|
203
|
+
capability_type = capability_type_name_to_capability_type(StringValuePtr(rb_capability_name_or_type));
|
204
|
+
break;
|
205
|
+
case T_FIXNUM:
|
206
|
+
capability_type = NUM2INT(rb_capability_name_or_type);
|
207
|
+
break;
|
208
|
+
default:
|
209
|
+
rb_raise(rb_eArgError, "Expected a String or a Symbol instance, or a capability type constant");
|
210
|
+
}
|
104
211
|
|
105
212
|
switch (TYPE(rb_capability_or_name)) {
|
106
213
|
case T_SYMBOL:
|
@@ -116,7 +223,7 @@ rb_capng_update(VALUE self, VALUE rb_action_set, VALUE rb_update_type, VALUE rb_
|
|
116
223
|
rb_raise(rb_eArgError, "Expected a String or a Symbol instance, or a capability constant");
|
117
224
|
}
|
118
225
|
|
119
|
-
result = capng_update(
|
226
|
+
result = capng_update(action, capability_type, capability);
|
120
227
|
|
121
228
|
if (result == 0)
|
122
229
|
return Qtrue;
|
@@ -125,13 +232,26 @@ rb_capng_update(VALUE self, VALUE rb_action_set, VALUE rb_update_type, VALUE rb_
|
|
125
232
|
}
|
126
233
|
|
127
234
|
static VALUE
|
128
|
-
rb_capng_apply(VALUE self, VALUE
|
235
|
+
rb_capng_apply(VALUE self, VALUE rb_select_name_or_enum)
|
129
236
|
{
|
130
237
|
int result = 0;
|
238
|
+
capng_select_t select = 0;
|
131
239
|
|
132
|
-
|
240
|
+
switch (TYPE(rb_select_name_or_enum)) {
|
241
|
+
case T_SYMBOL:
|
242
|
+
select = select_name_to_select_type(RSTRING_PTR(rb_sym2str(rb_select_name_or_enum)));
|
243
|
+
break;
|
244
|
+
case T_STRING:
|
245
|
+
select = select_name_to_select_type(StringValuePtr(rb_select_name_or_enum));
|
246
|
+
break;
|
247
|
+
case T_FIXNUM:
|
248
|
+
select = NUM2INT(rb_select_name_or_enum);
|
249
|
+
break;
|
250
|
+
default:
|
251
|
+
rb_raise(rb_eArgError, "Expected a String or a Symbol instance, or a capability type constant");
|
252
|
+
}
|
133
253
|
|
134
|
-
result = capng_apply(
|
254
|
+
result = capng_apply(select);
|
135
255
|
|
136
256
|
if (result == 0)
|
137
257
|
return Qtrue;
|
@@ -162,24 +282,53 @@ rb_capng_change_id(VALUE self, VALUE rb_uid, VALUE rb_gid, VALUE rb_flags)
|
|
162
282
|
if (result == 0)
|
163
283
|
return Qtrue;
|
164
284
|
else
|
165
|
-
|
285
|
+
rb_raise(rb_eRuntimeError, "Calling capng_change_id is failed with: (exitcode: %d)\n", result);
|
166
286
|
}
|
167
287
|
|
168
288
|
static VALUE
|
169
|
-
rb_capng_have_capabilities_p(VALUE self, VALUE
|
289
|
+
rb_capng_have_capabilities_p(VALUE self, VALUE rb_select_name_or_enum)
|
170
290
|
{
|
171
291
|
int result = 0;
|
292
|
+
capng_select_t select = 0;
|
172
293
|
|
173
|
-
|
294
|
+
switch (TYPE(rb_select_name_or_enum)) {
|
295
|
+
case T_SYMBOL:
|
296
|
+
select = select_name_to_select_type(RSTRING_PTR(rb_sym2str(rb_select_name_or_enum)));
|
297
|
+
break;
|
298
|
+
case T_STRING:
|
299
|
+
select = select_name_to_select_type(StringValuePtr(rb_select_name_or_enum));
|
300
|
+
break;
|
301
|
+
case T_FIXNUM:
|
302
|
+
select = NUM2INT(rb_select_name_or_enum);
|
303
|
+
break;
|
304
|
+
default:
|
305
|
+
rb_raise(rb_eArgError, "Expected a String or a Symbol instance, or a capability type constant");
|
306
|
+
}
|
307
|
+
result = capng_have_capabilities(select);
|
174
308
|
|
175
309
|
return INT2NUM(result);
|
176
310
|
}
|
177
311
|
|
178
312
|
static VALUE
|
179
|
-
rb_capng_have_capability_p(VALUE self, VALUE
|
313
|
+
rb_capng_have_capability_p(VALUE self, VALUE rb_capability_name_or_type, VALUE rb_capability_or_name)
|
180
314
|
{
|
181
315
|
int result = 0;
|
182
316
|
unsigned int capability = 0;
|
317
|
+
capng_type_t capability_type = 0;
|
318
|
+
|
319
|
+
switch (TYPE(rb_capability_name_or_type)) {
|
320
|
+
case T_SYMBOL:
|
321
|
+
capability_type = capability_type_name_to_capability_type(RSTRING_PTR(rb_sym2str(rb_capability_name_or_type)));
|
322
|
+
break;
|
323
|
+
case T_STRING:
|
324
|
+
capability_type = capability_type_name_to_capability_type(StringValuePtr(rb_capability_name_or_type));
|
325
|
+
break;
|
326
|
+
case T_FIXNUM:
|
327
|
+
capability_type = NUM2INT(rb_capability_name_or_type);
|
328
|
+
break;
|
329
|
+
default:
|
330
|
+
rb_raise(rb_eArgError, "Expected a String or a Symbol instance, or a capability type constant");
|
331
|
+
}
|
183
332
|
|
184
333
|
switch (TYPE(rb_capability_or_name)) {
|
185
334
|
case T_SYMBOL:
|
@@ -195,7 +344,7 @@ rb_capng_have_capability_p(VALUE self, VALUE rb_update_type, VALUE rb_capability
|
|
195
344
|
rb_raise(rb_eArgError, "Expected a String or a Symbol instance, or a capability constant");
|
196
345
|
}
|
197
346
|
|
198
|
-
result = capng_have_capability(
|
347
|
+
result = capng_have_capability(capability_type, capability);
|
199
348
|
|
200
349
|
if (result == 1)
|
201
350
|
return Qtrue;
|
@@ -254,7 +403,8 @@ Init_capng(void)
|
|
254
403
|
|
255
404
|
rb_define_alloc_func(rb_cCapNG, rb_capng_alloc);
|
256
405
|
|
257
|
-
rb_define_method(rb_cCapNG, "initialize", rb_capng_initialize,
|
406
|
+
rb_define_method(rb_cCapNG, "initialize", rb_capng_initialize, -1);
|
407
|
+
rb_define_method(rb_cCapNG, "return_code", rb_capng_return_code, 0);
|
258
408
|
rb_define_method(rb_cCapNG, "clear", rb_capng_clear, 1);
|
259
409
|
rb_define_method(rb_cCapNG, "fill", rb_capng_fill, 1);
|
260
410
|
rb_define_method(rb_cCapNG, "setpid", rb_capng_setpid, 1);
|
data/ext/capng/capng.h
CHANGED
@@ -20,6 +20,9 @@
|
|
20
20
|
|
21
21
|
#include <cap-ng.h>
|
22
22
|
#include <stdio.h>
|
23
|
+
#include <sys/types.h>
|
24
|
+
#include <sys/stat.h>
|
25
|
+
#include <fcntl.h>
|
23
26
|
|
24
27
|
VALUE rb_cCapNG;
|
25
28
|
VALUE rb_cCapNGPrint;
|
@@ -32,6 +35,11 @@ VALUE rb_mResult;
|
|
32
35
|
VALUE rb_mPrint;
|
33
36
|
VALUE rb_mFlags;
|
34
37
|
|
38
|
+
capng_select_t select_name_to_select_type(char *select_name);
|
39
|
+
capng_act_t action_name_to_action_type(char *action_name);
|
40
|
+
capng_print_t print_name_to_print_type(char *print_name);
|
41
|
+
capng_type_t capability_type_name_to_capability_type(char *capability_name);
|
42
|
+
|
35
43
|
void Init_capng_capability(VALUE);
|
36
44
|
void Init_capng_enum(VALUE);
|
37
45
|
void Init_capng_print(VALUE);
|
data/ext/capng/enum.c
CHANGED
@@ -55,5 +55,8 @@ void Init_capng_enum(VALUE rb_cCapNG)
|
|
55
55
|
rb_define_const(rb_mFlags, "NO_FLAG", LONG2NUM(CAPNG_NO_FLAG));
|
56
56
|
rb_define_const(rb_mFlags, "DROP_SUPP_GRP", LONG2NUM(CAPNG_DROP_SUPP_GRP));
|
57
57
|
rb_define_const(rb_mFlags, "CLEAR_BOUNDING", LONG2NUM(CAPNG_CLEAR_BOUNDING));
|
58
|
+
#if defined(CAPNG_INIT_SUPP_GRP)
|
59
|
+
// Ubuntu Trusty's libcap-ng-dev doesn't have CAPNG_INIT_SUPP_GRP constant.
|
58
60
|
rb_define_const(rb_mFlags, "INIT_SUPP_GRP", LONG2NUM(CAPNG_INIT_SUPP_GRP));
|
61
|
+
#endif
|
59
62
|
}
|
data/ext/capng/extconf.rb
CHANGED
data/ext/capng/print.c
CHANGED
@@ -52,41 +52,101 @@ rb_capng_print_initialize(VALUE self)
|
|
52
52
|
}
|
53
53
|
|
54
54
|
static VALUE
|
55
|
-
rb_capng_print_caps_text(VALUE self, VALUE
|
55
|
+
rb_capng_print_caps_text(VALUE self, VALUE rb_where_name_or_type, VALUE rb_capability_name_or_type)
|
56
56
|
{
|
57
57
|
char *result = NULL;
|
58
|
+
capng_type_t capability_type = 0;
|
59
|
+
capng_print_t print_type = 0;
|
58
60
|
|
59
|
-
switch (
|
61
|
+
switch (TYPE(rb_capability_name_or_type)) {
|
62
|
+
case T_SYMBOL:
|
63
|
+
capability_type = capability_type_name_to_capability_type(RSTRING_PTR(rb_sym2str(rb_capability_name_or_type)));
|
64
|
+
break;
|
65
|
+
case T_STRING:
|
66
|
+
capability_type = capability_type_name_to_capability_type(StringValuePtr(rb_capability_name_or_type));
|
67
|
+
break;
|
68
|
+
case T_FIXNUM:
|
69
|
+
capability_type = NUM2INT(rb_capability_name_or_type);
|
70
|
+
break;
|
71
|
+
default:
|
72
|
+
rb_raise(rb_eArgError, "Expected a String or a Symbol instance, or a capability type constant");
|
73
|
+
}
|
74
|
+
|
75
|
+
switch (TYPE(rb_where_name_or_type)) {
|
76
|
+
case T_SYMBOL:
|
77
|
+
print_type = print_name_to_print_type(RSTRING_PTR(rb_sym2str(rb_where_name_or_type)));
|
78
|
+
break;
|
79
|
+
case T_STRING:
|
80
|
+
print_type = print_name_to_print_type(StringValuePtr(rb_where_name_or_type));
|
81
|
+
break;
|
82
|
+
case T_FIXNUM:
|
83
|
+
print_type = NUM2INT(rb_where_name_or_type);
|
84
|
+
break;
|
85
|
+
default:
|
86
|
+
rb_raise(rb_eArgError, "Expected a String or a Symbol instance, or a print type constant");
|
87
|
+
}
|
88
|
+
|
89
|
+
switch (print_type) {
|
60
90
|
case CAPNG_PRINT_STDOUT:
|
61
|
-
capng_print_caps_text(CAPNG_PRINT_STDOUT,
|
91
|
+
capng_print_caps_text(CAPNG_PRINT_STDOUT, capability_type);
|
62
92
|
break;
|
63
93
|
case CAPNG_PRINT_BUFFER:
|
64
|
-
result = capng_print_caps_text(CAPNG_PRINT_BUFFER,
|
94
|
+
result = capng_print_caps_text(CAPNG_PRINT_BUFFER, capability_type);
|
65
95
|
}
|
66
96
|
|
67
97
|
if (result)
|
68
98
|
return rb_str_new2(result);
|
69
99
|
else
|
70
|
-
return rb_str_new2("
|
100
|
+
return rb_str_new2("none");
|
71
101
|
}
|
72
102
|
|
73
103
|
static VALUE
|
74
|
-
rb_capng_print_caps_numeric(VALUE self, VALUE
|
104
|
+
rb_capng_print_caps_numeric(VALUE self, VALUE rb_where_name_or_type, VALUE rb_select_name_or_enum)
|
75
105
|
{
|
76
106
|
char *result = NULL;
|
107
|
+
capng_select_t select = 0;
|
108
|
+
capng_print_t print_type = 0;
|
109
|
+
|
110
|
+
switch (TYPE(rb_where_name_or_type)) {
|
111
|
+
case T_SYMBOL:
|
112
|
+
print_type = print_name_to_print_type(RSTRING_PTR(rb_sym2str(rb_where_name_or_type)));
|
113
|
+
break;
|
114
|
+
case T_STRING:
|
115
|
+
print_type = print_name_to_print_type(StringValuePtr(rb_where_name_or_type));
|
116
|
+
break;
|
117
|
+
case T_FIXNUM:
|
118
|
+
print_type = NUM2INT(rb_where_name_or_type);
|
119
|
+
break;
|
120
|
+
default:
|
121
|
+
rb_raise(rb_eArgError, "Expected a String or a Symbol instance, or a print type constant");
|
122
|
+
}
|
123
|
+
|
124
|
+
switch (TYPE(rb_select_name_or_enum)) {
|
125
|
+
case T_SYMBOL:
|
126
|
+
select = select_name_to_select_type(RSTRING_PTR(rb_sym2str(rb_select_name_or_enum)));
|
127
|
+
break;
|
128
|
+
case T_STRING:
|
129
|
+
select = select_name_to_select_type(StringValuePtr(rb_select_name_or_enum));
|
130
|
+
break;
|
131
|
+
case T_FIXNUM:
|
132
|
+
select = NUM2INT(rb_select_name_or_enum);
|
133
|
+
break;
|
134
|
+
default:
|
135
|
+
rb_raise(rb_eArgError, "Expected a String or a Symbol instance, or a capability type constant");
|
136
|
+
}
|
77
137
|
|
78
|
-
switch (
|
138
|
+
switch (print_type) {
|
79
139
|
case CAPNG_PRINT_STDOUT:
|
80
|
-
capng_print_caps_numeric(CAPNG_PRINT_STDOUT,
|
140
|
+
capng_print_caps_numeric(CAPNG_PRINT_STDOUT, select);
|
81
141
|
break;
|
82
142
|
case CAPNG_PRINT_BUFFER:
|
83
|
-
result = capng_print_caps_numeric(CAPNG_PRINT_BUFFER,
|
143
|
+
result = capng_print_caps_numeric(CAPNG_PRINT_BUFFER, select);
|
84
144
|
}
|
85
145
|
|
86
146
|
if (result)
|
87
147
|
return rb_str_new2(result);
|
88
148
|
else
|
89
|
-
return rb_str_new2("
|
149
|
+
return rb_str_new2("none");
|
90
150
|
}
|
91
151
|
|
92
152
|
void Init_capng_print(VALUE rb_cCapNG)
|
data/ext/capng/utils.c
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
/* capng_c */
|
2
|
+
/* Copyright 2020- Hiroshi Hatake*/
|
3
|
+
/* */
|
4
|
+
/* Licensed under the Apache License, Version 2.0 (the "License"); */
|
5
|
+
/* you may not use this file except in compliance with the License. */
|
6
|
+
/* You may obtain a copy of the License at */
|
7
|
+
/* http://www.apache.org/licenses/LICENSE-2.0 */
|
8
|
+
/* Unless required by applicable law or agreed to in writing, software */
|
9
|
+
/* distributed under the License is distributed on an "AS IS" BASIS, */
|
10
|
+
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
|
11
|
+
/* See the License for the specific language governing permissions and */
|
12
|
+
/* limitations under the License. */
|
13
|
+
|
14
|
+
#include <capng.h>
|
15
|
+
|
16
|
+
capng_select_t
|
17
|
+
select_name_to_select_type(char *select_name)
|
18
|
+
{
|
19
|
+
if (strcmp(select_name, "caps") == 0) {
|
20
|
+
return CAPNG_SELECT_CAPS;
|
21
|
+
} else if (strcmp(select_name, "bounds") == 0) {
|
22
|
+
return CAPNG_SELECT_BOUNDS;
|
23
|
+
} else if (strcmp(select_name, "both") == 0) {
|
24
|
+
return CAPNG_SELECT_BOTH;
|
25
|
+
#if defined(CAPNG_SELECT_AMBIENT)
|
26
|
+
} else if (strcmp(select_name, "ambient") == 0) {
|
27
|
+
return CAPNG_SELECT_AMBIENT;
|
28
|
+
#endif
|
29
|
+
#if defined(CAPNG_SELECT_ALL)
|
30
|
+
} else if (strcmp(select_name, "all") == 0) {
|
31
|
+
return CAPNG_SELECT_ALL;
|
32
|
+
#endif
|
33
|
+
} else {
|
34
|
+
rb_raise(rb_eArgError, "unknown select name %s", select_name);
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
capng_act_t
|
39
|
+
action_name_to_action_type(char *action_name)
|
40
|
+
{
|
41
|
+
if (strcmp(action_name, "drop") == 0) {
|
42
|
+
return CAPNG_DROP;
|
43
|
+
} else if (strcmp(action_name, "add") == 0) {
|
44
|
+
return CAPNG_ADD;
|
45
|
+
} else {
|
46
|
+
rb_raise(rb_eArgError, "unknown action name %s", action_name);
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
capng_print_t
|
51
|
+
print_name_to_print_type(char *print_name)
|
52
|
+
{
|
53
|
+
if (strcmp(print_name, "stdout") == 0) {
|
54
|
+
return CAPNG_PRINT_STDOUT;
|
55
|
+
} else if (strcmp(print_name, "buffer") == 0) {
|
56
|
+
return CAPNG_PRINT_BUFFER;
|
57
|
+
} else {
|
58
|
+
rb_raise(rb_eArgError, "unknown print name %s", print_name);
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
capng_type_t
|
63
|
+
capability_type_name_to_capability_type(char *capability_name)
|
64
|
+
{
|
65
|
+
if (strcmp(capability_name, "effective") == 0) {
|
66
|
+
return CAPNG_EFFECTIVE;
|
67
|
+
} else if (strcmp(capability_name, "permitted") == 0) {
|
68
|
+
return CAPNG_PERMITTED;
|
69
|
+
} else if (strcmp(capability_name, "inheritable") == 0) {
|
70
|
+
return CAPNG_INHERITABLE;
|
71
|
+
} else if (strcmp(capability_name, "bounding_set") == 0) {
|
72
|
+
return CAPNG_BOUNDING_SET;
|
73
|
+
#if defined(CAPNG_AMBIENT)
|
74
|
+
} else if (strcmp(capability_name, "ambient") == 0) {
|
75
|
+
return CAPNG_AMBIENT;
|
76
|
+
#endif
|
77
|
+
} else {
|
78
|
+
rb_raise(rb_eArgError, "unknown capability name: %s", capability_name);
|
79
|
+
}
|
80
|
+
}
|
data/lib/capng.rb
CHANGED
@@ -6,6 +6,20 @@ class CapNG
|
|
6
6
|
|
7
7
|
alias_method :caps_file_raw, :caps_file
|
8
8
|
alias_method :apply_caps_file_raw, :apply_caps_file
|
9
|
+
alias_method :update_raw, :update
|
10
|
+
alias_method :initialize_raw, :initialize
|
11
|
+
|
12
|
+
def initialize(target = nil, pid_or_path = nil)
|
13
|
+
if target && pid_or_path.is_a?(Integer)
|
14
|
+
initialize_raw(target, pid_or_path)
|
15
|
+
elsif target && pid_or_path.is_a?(String) && File.exist?(pid_or_path)
|
16
|
+
File.open(pid_or_path) do |file|
|
17
|
+
initialize_raw(target, file);
|
18
|
+
end
|
19
|
+
else
|
20
|
+
initialize_raw(target, pid_or_path)
|
21
|
+
end
|
22
|
+
end
|
9
23
|
|
10
24
|
def caps_file(file_or_string_path)
|
11
25
|
if file_or_string_path.is_a?(String) && File.exist?(file_or_string_path)
|
@@ -22,7 +36,7 @@ class CapNG
|
|
22
36
|
def apply_caps_file(file_or_string_path)
|
23
37
|
if file_or_string_path.is_a?(String) && File.exist?(file_or_string_path)
|
24
38
|
File.open(file_or_string_path) do |f|
|
25
|
-
|
39
|
+
apply_caps_file_raw(f)
|
26
40
|
end
|
27
41
|
elsif file_or_string_path.is_a?(File)
|
28
42
|
apply_caps_file_raw(file_or_string_path)
|
@@ -30,4 +44,18 @@ class CapNG
|
|
30
44
|
raise ArgumentError, "#{file_or_string_path} should be File class or String class instance."
|
31
45
|
end
|
32
46
|
end
|
47
|
+
|
48
|
+
def update(action, type, capability_or_capability_array)
|
49
|
+
if capability_or_capability_array.is_a?(Array) && !capability_or_capability_array.empty?
|
50
|
+
results = []
|
51
|
+
capability_or_capability_array.each do |capability|
|
52
|
+
result = update_raw(action, type, capability)
|
53
|
+
results << result
|
54
|
+
return results if !result
|
55
|
+
end
|
56
|
+
results
|
57
|
+
else
|
58
|
+
update_raw(action, type, capability_or_capability_array)
|
59
|
+
end
|
60
|
+
end
|
33
61
|
end
|
data/lib/capng/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capng_c
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hiroshi Hatake
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-11-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -80,6 +80,7 @@ extensions:
|
|
80
80
|
- ext/capng/extconf.rb
|
81
81
|
extra_rdoc_files: []
|
82
82
|
files:
|
83
|
+
- ".github/workflows/linux.yml"
|
83
84
|
- ".gitignore"
|
84
85
|
- Gemfile
|
85
86
|
- LICENSE
|
@@ -88,6 +89,9 @@ files:
|
|
88
89
|
- bin/console
|
89
90
|
- bin/setup
|
90
91
|
- capng_c.gemspec
|
92
|
+
- example/file_capability.rb
|
93
|
+
- example/process_capability.rb
|
94
|
+
- example/process_capability_without_root.rb
|
91
95
|
- ext/capng/capability.c
|
92
96
|
- ext/capng/capng.c
|
93
97
|
- ext/capng/capng.h
|
@@ -95,10 +99,12 @@ files:
|
|
95
99
|
- ext/capng/extconf.rb
|
96
100
|
- ext/capng/print.c
|
97
101
|
- ext/capng/state.c
|
102
|
+
- ext/capng/utils.c
|
98
103
|
- lib/capng.rb
|
99
104
|
- lib/capng/version.rb
|
100
105
|
homepage: https://github.com/cosmo0920/cap-ng_c
|
101
|
-
licenses:
|
106
|
+
licenses:
|
107
|
+
- Apache-2.0
|
102
108
|
metadata:
|
103
109
|
allowed_push_host: https://rubygems.org
|
104
110
|
homepage_uri: https://github.com/cosmo0920/cap-ng_c
|