capng_c 0.1.1 → 0.1.6

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: 31b53b59b57445d79f742beb25910e6bb62270673d6c171ffea029938d5f35ee
4
- data.tar.gz: 62c157b61e3cc5e1bfd144effb8370a3de756e63a7cfccfb3012d236ceecd2d9
3
+ metadata.gz: eea2ca339ebb678c88b6c3ee7726878a46c2bdef9a8756daca982bb22bc009a5
4
+ data.tar.gz: 6b792b28771206844c5daac503ad2003c443799ebbf64b27f2f4cc616694a5e7
5
5
  SHA512:
6
- metadata.gz: a3b0b2deda2fb0c46fcce53f54097659a4d7fddd34e1bc4ce01fd27dea02a220263cf668deb048542009dc92b885753938f753af37e7a87500b806111330e552
7
- data.tar.gz: b2968668551f8b397d7f5da73d38004215cef706e2d8e2ecf09453a6ca4ef14ed4b8e550296767a5f38dba9e87edcb669b4edaf2cf8433e3f92c7c9a27591c0a
6
+ metadata.gz: 3071407d369065ac165ed2e1c4c8c9962205f9e67601152c884dc0d76bed6720e8c95ebd28b951029ed752f74a82b734876fbfed102e66325dd548b7a23a85b2
7
+ data.tar.gz: f1d1728a2b9de22433383cfeae38d7682f43af05995ef4c26fb4dcf89df58398525a3c8f10cc688ce11e847a55109811add8398c02a6b976d70b2210440c659c
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- # Specify your gem's dependencies in ioext.gemspec
3
+ # Specify your gem's dependencies in capng_c.gemspec
4
4
  gemspec
data/README.md CHANGED
@@ -20,6 +20,10 @@ Or install it yourself as:
20
20
 
21
21
  $ gem install capng_c
22
22
 
23
+ ## Usage
24
+
25
+ The usage examples are put in [example directory](example).
26
+
23
27
  ## Development
24
28
 
25
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
@@ -83,7 +83,7 @@ rb_capng_capability_from_name(VALUE self, VALUE rb_capability_name_or_symbol)
83
83
  void
84
84
  Init_capng_capability(VALUE rb_cCapNG)
85
85
  {
86
- rb_cCapability = rb_define_class_under(rb_cCapNG, "Capability", rb_cObject);
86
+ VALUE rb_cCapability = rb_define_class_under(rb_cCapNG, "Capability", rb_cObject);
87
87
 
88
88
  rb_define_alloc_func(rb_cCapability, rb_capng_capability_alloc);
89
89
 
@@ -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
+ }
58
104
 
59
- capng_clear(NUM2INT(rb_action_set));
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
+ }
123
+
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;
133
+
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
+ }
68
147
 
69
- capng_fill(NUM2INT(rb_action_set));
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;
183
+
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
+ }
101
197
 
102
- Check_Type(rb_action_set, T_FIXNUM);
103
- Check_Type(rb_update_type, T_FIXNUM);
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;
@@ -166,20 +286,49 @@ rb_capng_change_id(VALUE self, VALUE rb_uid, VALUE rb_gid, VALUE rb_flags)
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;
@@ -250,11 +399,12 @@ rb_capng_apply_caps_file(VALUE self, VALUE rb_file)
250
399
  void
251
400
  Init_capng(void)
252
401
  {
253
- rb_cCapNG = rb_define_class("CapNG", rb_cObject);
402
+ VALUE rb_cCapNG = rb_define_class("CapNG", rb_cObject);
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,17 +20,25 @@
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
- VALUE rb_cCapNG;
25
- VALUE rb_cCapNGPrint;
26
- VALUE rb_cCapability;
27
- VALUE rb_cState;
28
- VALUE rb_mAction;
29
- VALUE rb_mSelect;
30
- VALUE rb_mType;
31
- VALUE rb_mResult;
32
- VALUE rb_mPrint;
33
- VALUE rb_mFlags;
27
+ extern VALUE rb_cCapNG;
28
+ extern VALUE rb_cCapNGPrint;
29
+ extern VALUE rb_cCapability;
30
+ extern VALUE rb_cState;
31
+ extern VALUE rb_mAction;
32
+ extern VALUE rb_mSelect;
33
+ extern VALUE rb_mType;
34
+ extern VALUE rb_mResult;
35
+ extern VALUE rb_mPrint;
36
+ extern VALUE rb_mFlags;
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);
34
42
 
35
43
  void Init_capng_capability(VALUE);
36
44
  void Init_capng_enum(VALUE);
@@ -15,11 +15,11 @@
15
15
 
16
16
  void Init_capng_enum(VALUE rb_cCapNG)
17
17
  {
18
- rb_mAction = rb_define_module_under(rb_cCapNG, "Action");
19
- rb_mSelect = rb_define_module_under(rb_cCapNG, "Select");
20
- rb_mType = rb_define_module_under(rb_cCapNG, "Type");
21
- rb_mResult = rb_define_module_under(rb_cCapNG, "Result");
22
- rb_mFlags = rb_define_module_under(rb_cCapNG, "Flags");
18
+ VALUE rb_mAction = rb_define_module_under(rb_cCapNG, "Action");
19
+ VALUE rb_mSelect = rb_define_module_under(rb_cCapNG, "Select");
20
+ VALUE rb_mType = rb_define_module_under(rb_cCapNG, "Type");
21
+ VALUE rb_mResult = rb_define_module_under(rb_cCapNG, "Result");
22
+ VALUE rb_mFlags = rb_define_module_under(rb_cCapNG, "Flags");
23
23
 
24
24
  // capng_cat_t enum constants
25
25
  rb_define_const(rb_mAction, "DROP", INT2NUM(CAPNG_DROP));
@@ -29,10 +29,10 @@ void Init_capng_enum(VALUE rb_cCapNG)
29
29
  rb_define_const(rb_mSelect, "CAPS", INT2NUM(CAPNG_SELECT_CAPS));
30
30
  rb_define_const(rb_mSelect, "BOUNDS", INT2NUM(CAPNG_SELECT_BOUNDS));
31
31
  rb_define_const(rb_mSelect, "BOTH", INT2NUM(CAPNG_SELECT_BOTH));
32
- #if defined(CAPNG_SELECT_AMBIENT)
32
+ #if defined(HAVE_CONST_CAPNG_SELECT_AMBIENT)
33
33
  rb_define_const(rb_mSelect, "AMBIENT", INT2NUM(CAPNG_SELECT_AMBIENT));
34
34
  #endif
35
- #if defined(CAPNG_SELECT_ALL)
35
+ #if defined(HAVE_CONST_CAPNG_SELECT_ALL)
36
36
  rb_define_const(rb_mSelect, "ALL", INT2NUM(CAPNG_SELECT_ALL));
37
37
  #endif
38
38
 
@@ -41,7 +41,7 @@ void Init_capng_enum(VALUE rb_cCapNG)
41
41
  rb_define_const(rb_mType, "PERMITTED", INT2NUM(CAPNG_PERMITTED));
42
42
  rb_define_const(rb_mType, "INHERITABLE", INT2NUM(CAPNG_INHERITABLE));
43
43
  rb_define_const(rb_mType, "BOUNDING_SET", INT2NUM(CAPNG_BOUNDING_SET));
44
- #if defined(CAPNG_AMBIENT)
44
+ #if defined(HAVE_CONST_CAPNG_AMBIENT)
45
45
  rb_define_const(rb_mType, "AMBIENT", INT2NUM(CAPNG_AMBIENT));
46
46
  #endif
47
47
 
@@ -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(HAVE_CONST_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
  }
@@ -24,6 +24,10 @@ pkg_config("libcap-ng")
24
24
  $CFLAGS << " -Wall -std=c99 -fPIC "
25
25
  # $CFLAGS << " -g -O0"
26
26
 
27
+ have_const("CAPNG_SELECT_AMBIENT", "cap-ng.h")
28
+ have_const("CAPNG_SELECT_ALL", "cap-ng.h")
29
+ have_const("CAPNG_AMBIENT", "cap-ng.h")
30
+ have_const("CAPNG_INIT_SUPP_GRP", "cap-ng.h")
27
31
  have_func("rb_sym2str", "ruby.h")
28
32
  have_func("capng_get_caps_fd", "cap-ng.h")
29
33
  create_makefile("capng/capng")
@@ -52,16 +52,46 @@ 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)
@@ -71,16 +101,46 @@ rb_capng_print_caps_text(VALUE self, VALUE rb_where, VALUE rb_select_set)
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)
@@ -91,7 +151,7 @@ rb_capng_print_caps_numeric(VALUE self, VALUE rb_where, VALUE rb_select_set)
91
151
 
92
152
  void Init_capng_print(VALUE rb_cCapNG)
93
153
  {
94
- rb_cCapNGPrint = rb_define_class_under(rb_cCapNG, "Print", rb_cObject);
154
+ VALUE rb_cCapNGPrint = rb_define_class_under(rb_cCapNG, "Print", rb_cObject);
95
155
 
96
156
  rb_define_alloc_func(rb_cCapNGPrint, rb_capng_print_alloc);
97
157
 
@@ -90,7 +90,7 @@ rb_capng_state_restore(VALUE self)
90
90
  void
91
91
  Init_capng_state(VALUE rb_cCapNG)
92
92
  {
93
- rb_cState = rb_define_class_under(rb_cCapNG, "State", rb_cObject);
93
+ VALUE rb_cState = rb_define_class_under(rb_cCapNG, "State", rb_cObject);
94
94
 
95
95
  rb_define_alloc_func(rb_cState, rb_capng_state_alloc);
96
96
 
@@ -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(HAVE_CONST_CAPNG_SELECT_AMBIENT)
26
+ } else if (strcmp(select_name, "ambient") == 0) {
27
+ return CAPNG_SELECT_AMBIENT;
28
+ #endif
29
+ #if defined(HAVE_CONST_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(HAVE_CONST_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
+ }
@@ -7,6 +7,19 @@ class CapNG
7
7
  alias_method :caps_file_raw, :caps_file
8
8
  alias_method :apply_caps_file_raw, :apply_caps_file
9
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
10
23
 
11
24
  def caps_file(file_or_string_path)
12
25
  if file_or_string_path.is_a?(String) && File.exist?(file_or_string_path)
@@ -23,7 +36,7 @@ class CapNG
23
36
  def apply_caps_file(file_or_string_path)
24
37
  if file_or_string_path.is_a?(String) && File.exist?(file_or_string_path)
25
38
  File.open(file_or_string_path) do |f|
26
- apply_cps_file_raw(f)
39
+ apply_caps_file_raw(f)
27
40
  end
28
41
  elsif file_or_string_path.is_a?(File)
29
42
  apply_caps_file_raw(file_or_string_path)
@@ -34,9 +47,13 @@ class CapNG
34
47
 
35
48
  def update(action, type, capability_or_capability_array)
36
49
  if capability_or_capability_array.is_a?(Array) && !capability_or_capability_array.empty?
50
+ results = []
37
51
  capability_or_capability_array.each do |capability|
38
- update_raw(action, type, capability)
52
+ result = update_raw(action, type, capability)
53
+ results << result
54
+ return results if !result
39
55
  end
56
+ results
40
57
  else
41
58
  update_raw(action, type, capability_or_capability_array)
42
59
  end
@@ -1,3 +1,3 @@
1
1
  class CapNG
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.6"
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.1
4
+ version: 0.1.6
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-27 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
@@ -89,6 +89,9 @@ files:
89
89
  - bin/console
90
90
  - bin/setup
91
91
  - capng_c.gemspec
92
+ - example/file_capability.rb
93
+ - example/process_capability.rb
94
+ - example/process_capability_without_root.rb
92
95
  - ext/capng/capability.c
93
96
  - ext/capng/capng.c
94
97
  - ext/capng/capng.h
@@ -96,10 +99,12 @@ files:
96
99
  - ext/capng/extconf.rb
97
100
  - ext/capng/print.c
98
101
  - ext/capng/state.c
102
+ - ext/capng/utils.c
99
103
  - lib/capng.rb
100
104
  - lib/capng/version.rb
101
105
  homepage: https://github.com/cosmo0920/cap-ng_c
102
- licenses: []
106
+ licenses:
107
+ - Apache-2.0
103
108
  metadata:
104
109
  allowed_push_host: https://rubygems.org
105
110
  homepage_uri: https://github.com/cosmo0920/cap-ng_c