cap2 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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