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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 88da08aa05f1a6e84b2b57fb2fca90a1d0c0d4dde8585dbad9e2f848e286cef6
4
- data.tar.gz: 28a4762a3f921fbe0b06d1913d151d907b12a4558d1941fd7b9fed2440974eb6
3
+ metadata.gz: 46ab5a21fef03d5b25db0124526add7f625acc865ae10da0f8614b6290b5aec0
4
+ data.tar.gz: cae7565475f00217336124b3c1d0bad6fd3772470e3c8e2605ebac09bac87829
5
5
  SHA512:
6
- metadata.gz: d6880731ae31f78a4b8ff1734b8638c1eddb86ec0bf519f9a6a13fe1b3410d7f1488103548954ba17fd5fa6e834eacd94275c46bdb650cf70f15ab901ab8ac84
7
- data.tar.gz: 381f2a5abde2165d4f31513d3ae9086ae7d183747f53993ff492b7e255fbcfa9bbefdf9da8035027cc6cf0e330c9cf6efea69b260e329d685e4d95f81a25f988
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
+ ![Linux testing](https://github.com/cosmo0920/capng_c/workflows/Linux%20testing/badge.svg?branch=main)
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.
@@ -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
@@ -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
- rb_capng_clear(VALUE self, VALUE rb_action_set)
100
+ rb_capng_return_code(VALUE self)
56
101
  {
57
- Check_Type(rb_action_set, T_FIXNUM);
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(NUM2INT(rb_action_set));
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 rb_action_set)
130
+ rb_capng_fill(VALUE self, VALUE rb_select_name_or_enum)
66
131
  {
67
- Check_Type(rb_action_set, T_FIXNUM);
132
+ capng_select_t select = 0;
68
133
 
69
- capng_fill(NUM2INT(rb_action_set));
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, VALUE rb_action_set, VALUE rb_update_type, VALUE rb_capability_or_name)
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
- Check_Type(rb_action_set, T_FIXNUM);
103
- Check_Type(rb_update_type, T_FIXNUM);
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(NUM2UINT(rb_action_set), NUM2INT(rb_update_type), capability);
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 rb_action_set)
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
- Check_Type(rb_action_set, T_FIXNUM);
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(NUM2INT(rb_action_set));
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
- return Qfalse;
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 rb_select_enum)
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
- result = capng_have_capabilities(NUM2INT(rb_select_enum));
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 rb_update_type, VALUE rb_capability_or_name)
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(NUM2INT(rb_update_type), 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, 0);
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);
@@ -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);
@@ -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
  }
@@ -20,7 +20,7 @@ includedir = RbConfig::CONFIG["includedir"]
20
20
 
21
21
  dir_config("capng", includedir, libdir)
22
22
 
23
- $LDFLAGS << " -lcap-ng "
23
+ pkg_config("libcap-ng")
24
24
  $CFLAGS << " -Wall -std=c99 -fPIC "
25
25
  # $CFLAGS << " -g -O0"
26
26
 
@@ -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 rb_where, VALUE rb_select_set)
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 (NUM2LONG(rb_where)) {
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, NUM2LONG(rb_select_set));
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, NUM2INT(rb_select_set));
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("(NULL)");
100
+ return rb_str_new2("none");
71
101
  }
72
102
 
73
103
  static VALUE
74
- rb_capng_print_caps_numeric(VALUE self, VALUE rb_where, VALUE rb_select_set)
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 (NUM2LONG(rb_where)) {
138
+ switch (print_type) {
79
139
  case CAPNG_PRINT_STDOUT:
80
- capng_print_caps_numeric(CAPNG_PRINT_STDOUT, NUM2INT(rb_select_set));
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, NUM2LONG(rb_select_set));
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("(NULL)");
149
+ return rb_str_new2("none");
90
150
  }
91
151
 
92
152
  void Init_capng_print(VALUE rb_cCapNG)
@@ -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
+ }
@@ -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
- apply_cps_file_raw(f)
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
@@ -1,3 +1,3 @@
1
1
  class CapNG
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.5"
3
3
  end
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.0
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-10-26 00:00:00.000000000 Z
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