cap2 0.2.0 → 0.2.1

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.
data/README.md CHANGED
@@ -49,25 +49,26 @@ Capabilities are referenced using lower cased symbols, and without the CAP_ pref
49
49
 
50
50
  ### Querying Capabilities
51
51
 
52
- There are three methods - `permitted?`, `enabled?` and `inheritable?` - defined on both `Cap2::Process` and `Cap2::File` for querying capabilities. Each of these methods, Cap2::File#enabled? being the exception, take a capability symbol and return true / false if the capability is in / not in the relevant set:
52
+ There are three methods - `permitted?`, `enabled?` and `inheritable?` - defined on both `Cap2::Process` and `Cap2::File` for querying capabilities. Each of these methods, Cap2::File#enabled? being the exception, take a list of capability symbols and return true / false if the capabilities are in / not in the relevant set:
53
53
 
54
54
  ```
55
55
  # the init daemon - all caps permitted & enabled but not inheritable
56
- init = Cap2.process(1) # => #<Cap2::Process @pid=1>
56
+ init = Cap2.process(1) # => #<Cap2::Process @pid=1>
57
57
 
58
- init.permitted?(:kill) # => true
59
- init.permitted?(:chown) # => true
58
+ init.permitted?(:kill) # => true
59
+ init.permitted?(:chown, :fowner) # => true
60
60
 
61
- init.enabled?(:fowner) # => true
61
+ init.enabled?(:fowner) # => true
62
+ init.enabled?(:kill, :chown) # => true
62
63
 
63
- init.inheritable?(:kill) # => false
64
- init.inheritable?(:fowner) # => false
64
+ init.inheritable?(:chown) # => false
65
+ init.inheritable?(:fowner, :kill) # => false
65
66
 
66
67
  # assume /bin/ping is using file capabilities to enable CAP_NET_RAW on exec
67
68
  ping = Cap2.file('/bin/ping') # => #<Cap2::File @filename="/bin/ping">
68
69
 
69
70
  ping.permitted?(:net_raw) # => true
70
- ping.permitted?(:mknod) # => false
71
+ ping.permitted?(:mknod, :chown) # => false
71
72
 
72
73
  ping.enabled? # => true
73
74
 
@@ -87,17 +88,19 @@ Cap2 provides different levels of control over process and file capabilities.
87
88
  To modify the permitted capabilities of a file (i.e. the capabilities which will be permitted in any process that exec's the file), use `Cap2::File#permit` and `Cap2::File#unpermit`:
88
89
 
89
90
  ```
90
- Cap2.process.enabled?(:setfcap) # => true - needed to set file capabilities
91
+ Cap2.process.enabled?(:setfcap) # => true - needed to set file capabilities
91
92
 
92
- file = Cap2.file('/tmp/file') # => #<Cap2::File @filename="/tmp/file">
93
+ file = Cap2.file('/tmp/file') # => #<Cap2::File @filename="/tmp/file">
93
94
 
94
- file.permitted?(:mknod) # => false
95
+ file.permitted?(:mknod, :chown, :fowner) # => false
95
96
 
96
- file.permit(:mknod) # => true
97
- file.permitted?(:mknod) # => true
97
+ file.permit(:mknod) # => true
98
+ file.permit(:chown, :fowner) # => true
99
+ file.permitted?(:mknod, :chown, :fowner) # => true
98
100
 
99
- file.unpermit(:mknod) # => true
100
- file.permitted?(:mknod) # => false
101
+ file.unpermit(:mknod) # => true
102
+ file.unpermit(:chown, :fowner) # => true
103
+ file.permitted?(:mknod, :chown, :fowner) # => false
101
104
  ```
102
105
 
103
106
  To modify the effective bit of a file (i.e. whether the resulting permitted capabilities of any process that exec's the file will also be enabled in it's effective set), use `Cap2::File#enable` and `Cap2::File#disable`:
@@ -133,6 +136,28 @@ file.disallow_inherit(:fowner) # => true
133
136
  file.inheritable?(:fowner) # => false
134
137
  ```
135
138
 
139
+ To clear all capabilities for a file, use Cap2::File#clear:
140
+
141
+ ```
142
+ Cap2.process.enabled?(:setfcap) # => true - needed to set file capabilities
143
+
144
+ file = Cap2.file('/tmp/file') # => #<Cap2::File @filename="/tmp/file">
145
+
146
+ file.permit(:kill, :mknod) # => true
147
+ file.allow_inherit(:kill, :mknod) # => true
148
+ file.enable # => true
149
+
150
+ file.permitted?(:kill, :mknod) # => true
151
+ file.inheritable?(:kill, :mknod) # => true
152
+ file.enabled? # => true
153
+
154
+ file.clear # => true
155
+
156
+ file.permitted?(:kill, :mknod) # => false
157
+ file.inheritable?(:kill, :mknod) # => false
158
+ file.enabled? # => false
159
+ ```
160
+
136
161
  #### Processes
137
162
 
138
163
  Cap2 can be used to enable / disable capabilities of the current Ruby process.
@@ -8,16 +8,16 @@ module Cap2
8
8
  @caps = getcaps
9
9
  end
10
10
 
11
- # Returns whether the given capability is permitted
12
- def permitted?(capability)
11
+ # Returns whether the given capabilities are permitted
12
+ def permitted?(*capabilities)
13
13
  reload
14
- @caps[:permitted].include? capability
14
+ @caps[:permitted].superset? Set[*capabilities]
15
15
  end
16
16
 
17
- # Returns whether the given capability is inheritable
18
- def inheritable?(capability)
17
+ # Returns whether the given capabilities are inheritable
18
+ def inheritable?(*capabilities)
19
19
  reload
20
- @caps[:inheritable].include? capability
20
+ @caps[:inheritable].superset? Set[*capabilities]
21
21
  end
22
22
 
23
23
  # Returns whether or not the file has any effective
@@ -28,26 +28,26 @@ module Cap2
28
28
  end
29
29
 
30
30
  # Permit processes executing this file to enable the given capability.
31
- def permit(capability)
32
- @caps[:permitted].add(capability)
31
+ def permit(*capabilities)
32
+ @caps[:permitted].merge(capabilities)
33
33
  save
34
34
  end
35
35
 
36
36
  # Dont permit processes executing this file to enable the given capability.
37
- def unpermit(capability)
38
- @caps[:permitted].delete(capability)
37
+ def unpermit(*capabilities)
38
+ @caps[:permitted].subtract(capabilities)
39
39
  save
40
40
  end
41
41
 
42
42
  # Allow processes executing this file to inherit the given capability.
43
- def allow_inherit(capability)
44
- @caps[:inheritable].add(capability)
43
+ def allow_inherit(*capabilities)
44
+ @caps[:inheritable].merge(capabilities)
45
45
  save
46
46
  end
47
47
 
48
48
  # Dont allow processes executing this file to inherit the given capability.
49
- def disallow_inherit(capability)
50
- @caps[:inheritable].delete(capability)
49
+ def disallow_inherit(*capabilities)
50
+ @caps[:inheritable].subtract(capabilities)
51
51
  save
52
52
  end
53
53
 
@@ -63,6 +63,12 @@ module Cap2
63
63
  save
64
64
  end
65
65
 
66
+ # Clear all capabilites
67
+ def clear
68
+ @caps.each_pair { |_, s| s.clear }
69
+ save
70
+ end
71
+
66
72
  private
67
73
  def reload
68
74
  @caps = getcaps
@@ -8,22 +8,22 @@ module Cap2
8
8
  @caps = getcaps
9
9
  end
10
10
 
11
- # Returns whether the given capability is permitted
12
- def permitted?(capability)
11
+ # Returns whether the given capabilities are permitted
12
+ def permitted?(*capabilities)
13
13
  reload
14
- @caps[:permitted].include? capability
14
+ @caps[:permitted].superset? Set[*capabilities]
15
15
  end
16
16
 
17
- # Returns whether the given capability is enabled
18
- def enabled?(capability)
17
+ # Returns whether the given capabilities are enabled
18
+ def enabled?(*capabilities)
19
19
  reload
20
- @caps[:effective].include? capability
20
+ @caps[:effective].superset? Set[*capabilities]
21
21
  end
22
22
 
23
- # Returns whether the given capability is inheritable
24
- def inheritable?(capability)
23
+ # Returns whether the given capabilities are inheritable
24
+ def inheritable?(capabilities)
25
25
  reload
26
- @caps[:inheritable].include? capability
26
+ @caps[:inheritable].superset? Set[*capabilities]
27
27
  end
28
28
 
29
29
  # Enable the given capability for this process.
@@ -44,7 +44,7 @@ module Cap2
44
44
  # Raises a RuntimeError if the process's pid is not the same as the current
45
45
  # pid (you cannot enable capabilities for other processes, that's their job).
46
46
  def check_pid
47
- unless @pid == Process.pid
47
+ unless @pid == ::Process.pid
48
48
  raise 'Cannot modify capabilities of other processes'
49
49
  end
50
50
  end
@@ -1,3 +1,3 @@
1
1
  module Cap2
2
- Version = '0.2.0'
2
+ Version = '0.2.1'
3
3
  end
@@ -5,17 +5,21 @@ describe Cap2::File do
5
5
 
6
6
  subject { Cap2::File.new(file.path) }
7
7
 
8
+ before(:each) do
9
+ run_as_root('clear')
10
+ end
11
+
8
12
  describe '#permitted?' do
9
- context "when the file doesn't have the given capability" do
10
- it { should_not be_permitted(:dac_override) }
13
+ context "when the file doesn't have the given capabilities" do
14
+ it { should_not be_permitted(:dac_override, :chown) }
11
15
  end
12
16
 
13
- context 'when the file does have the given capability' do
17
+ context 'when the file does have the given capabilities' do
14
18
  before(:each) do
15
- run_as_root('permit(:dac_override)')
19
+ run_as_root('permit(:dac_override, :chown)')
16
20
  end
17
21
 
18
- it { should be_permitted(:dac_override) }
22
+ it { should be_permitted(:dac_override, :chown) }
19
23
  end
20
24
  end
21
25
 
@@ -34,35 +38,45 @@ describe Cap2::File do
34
38
  end
35
39
 
36
40
  describe '#inheritable?' do
37
- context "when the file doesn't have the given capability" do
38
- it { should_not be_inheritable(:dac_override) }
41
+ context "when the file doesn't have the given capabilities" do
42
+ it { should_not be_inheritable(:dac_override, :chown) }
39
43
  end
40
44
 
41
- context 'when the file does have the given capability' do
45
+ context 'when the file does have the given capabilities' do
42
46
  before(:each) do
43
- run_as_root('allow_inherit(:dac_override)')
47
+ run_as_root('allow_inherit(:dac_override, :chown)')
44
48
  end
45
49
 
46
- it { should be_inheritable(:dac_override) }
50
+ it { should be_inheritable(:dac_override, :chown) }
47
51
  end
48
52
  end
49
53
 
50
54
  describe '#permit' do
51
55
  specify do
52
- expect { running_as_root('permit(:fowner)') }.to \
56
+ expect { running_as_root('permit(:fowner, :kill)') }.to \
53
57
  change { subject.permitted?(:fowner) }.from(false).to(true)
54
58
  end
59
+
60
+ specify do
61
+ expect { running_as_root('permit(:fowner, :kill)') }.to \
62
+ change { subject.permitted?(:kill) }.from(false).to(true)
63
+ end
55
64
  end
56
65
 
57
66
  describe '#unpermit' do
58
67
  before(:each) do
59
- run_as_root('permit(:fowner)')
68
+ run_as_root('permit(:fowner, :kill)')
60
69
  end
61
70
 
62
71
  specify do
63
- expect { running_as_root('unpermit(:fowner)') }.to \
72
+ expect { running_as_root('unpermit(:fowner, :kill)') }.to \
64
73
  change { subject.permitted?(:fowner) }.from(true).to(false)
65
74
  end
75
+
76
+ specify do
77
+ expect { running_as_root('unpermit(:fowner, :kill)') }.to \
78
+ change { subject.permitted?(:kill) }.from(true).to(false)
79
+ end
66
80
  end
67
81
 
68
82
  describe '#allow_inherit' do
@@ -129,6 +143,18 @@ describe Cap2::File do
129
143
  end
130
144
  end
131
145
 
146
+ describe '#clear' do
147
+ it 'should clear all capabilities' do
148
+ run_as_root('permit(:kill)', 'allow_inherit(:kill)', 'enable')
149
+
150
+ run_as_root('clear')
151
+
152
+ subject.should_not be_permitted(:kill)
153
+ subject.should_not be_inheritable(:kill)
154
+ subject.should_not be_enabled
155
+ end
156
+ end
157
+
132
158
  # FIXME: Would like to call the given code on subject directly (e.g.
133
159
  # `subject.permit(:fowner)`) but this would require the test
134
160
  # suite to be run as root?
@@ -2,30 +2,30 @@ require 'spec_helper'
2
2
 
3
3
  describe Cap2::Process do
4
4
  describe '#permitted?' do
5
- context "when the process doesn't have the given capability" do
5
+ context "when the process doesn't have the given capabilities" do
6
6
  subject { Cap2::Process.new(Process.pid) }
7
7
 
8
- it { should_not be_permitted(:dac_override) }
8
+ it { should_not be_permitted(:dac_override, :chown) }
9
9
  end
10
10
 
11
- context 'when the process does have the given capability' do
11
+ context 'when the process does have the given capabilities' do
12
12
  subject { Cap2::Process.new(1) }
13
13
 
14
- it { should be_permitted(:dac_override) }
14
+ it { should be_permitted(:dac_override, :chown) }
15
15
  end
16
16
  end
17
17
 
18
18
  describe '#enabled?' do
19
- context "when the process doesn't have the given capability" do
19
+ context "when the process doesn't have the given capabilities" do
20
20
  subject { Cap2::Process.new(Process.pid) }
21
21
 
22
- it { should_not be_enabled(:dac_override) }
22
+ it { should_not be_enabled(:dac_override, :chown) }
23
23
  end
24
24
 
25
- context 'when the process does have the given capability' do
25
+ context 'when the process does have the given capabilities' do
26
26
  subject { Cap2::Process.new(1) }
27
27
 
28
- it { should be_enabled(:dac_override) }
28
+ it { should be_enabled(:dac_override, :chown) }
29
29
  end
30
30
  end
31
31
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cap2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-07 00:00:00.000000000 Z
12
+ date: 2012-09-08 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: ! " Cap2 is a Ruby library for managing the POSIX 1003.1e capabilities\n
15
15
  \ available in Linux kernels.\n\n These capabilities are a partitioning of