key_control 0.0.5 → 0.0.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 +5 -13
- data/README.md +33 -7
- data/lib/key_control/key_ring.rb +21 -0
- data/lib/key_control/system.rb +43 -6
- data/lib/key_control/version.rb +1 -1
- data/test/key_control/key_ring_test.rb +29 -23
- metadata +12 -11
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
ZDcxNmJmYWFiMjE0MThjZTFkY2ViZTk1Y2Q5YjA0N2NhYjEyNDVkMA==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ff77033d493fe7d5c4d3efce964e1a01500cc24e
|
4
|
+
data.tar.gz: c6d31ad1d873ac69378ffb75c5033373904e5286
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
Y2RkNmI2Y2ZkMzhjNGNlYTllNWE2NGNkNTYwYmE0ZmY3NGEwMGUyZjI1OWEz
|
11
|
-
ZWQyOWVlYTAxYTJjMjIwM2VjNWE5NGMwMjBiYjlkNThmNGZkYmM=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
MjA2ZWYyMTgyM2Q1NDMwMGZiNWNhYzgwNjQxYTJhZWQ4ODQxOWU4MWE0NjFm
|
14
|
-
ZjAxNTM4NmM4ZWE1OTAyNWMxYjBhNTg4N2E1MThkNTU4MjdlNTg1MWRjZjIx
|
15
|
-
MWJiM2RlZjRhOTBjYTAyNTg2Y2IwMDAyMzNhYzNlMzRkMmNkMTA=
|
6
|
+
metadata.gz: 9b4d8dcd0de20f4ab26b6b333cd88ed8ba3fb0f6e7a00377fc58a8946d3fde3336af9578eac512fa9f32e03ce01b1c08b9ccd4b722890843f8d778f2ade51188
|
7
|
+
data.tar.gz: 5bd6485baefafc81a7f2224df367afb1c3247ed71fa5783f3fb5f485634bf742648b5db3adb0bd253dfe90621d09a3ae6572cd3026c1aa52a24f17af9943ed4f
|
data/README.md
CHANGED
@@ -33,30 +33,56 @@ initializer takes a single argument, the ID of the keyring you wish to store
|
|
33
33
|
your data in. There are several (very useful) [special keyrings](http://manpages.ubuntu.com/manpages/oneiric/man1/keyctl.1.html),
|
34
34
|
which are available for use as constants in the `KeyControl` module.
|
35
35
|
|
36
|
-
As an example, we'll create a basic accessor for the session keyring (useful
|
36
|
+
As an example, we'll create a basic accessor for the session keyring (useful
|
37
|
+
for sharing information among several grouped processes):
|
37
38
|
```ruby
|
38
39
|
keyring = KeyControl::KeyRing.new(KeyControl::SESSION)
|
39
40
|
```
|
40
41
|
|
41
|
-
Once you have your keyring instance, just
|
42
|
+
Once you have your keyring instance, just add and fetch values like you would
|
43
|
+
with any regular Hash:
|
42
44
|
```ruby
|
43
45
|
keyring["mykey"] = "my passphrase"
|
44
46
|
keyring["mykey"]
|
45
47
|
# => "my passphrase"
|
46
48
|
```
|
47
49
|
|
48
|
-
That's it! The power of this gem
|
49
|
-
|
50
|
+
That's it! The power of this gem is the ability to use your kernel's built-in
|
51
|
+
key management mechanism to share information between Ruby processes,
|
50
52
|
without exposing your data to the outside world.
|
51
53
|
|
52
|
-
|
54
|
+
### Key Deletion/Expiration
|
53
55
|
|
54
|
-
|
56
|
+
There are two options to remove values from the current keyring. You can
|
57
|
+
remove a piece of data immediately with `KeyRing#delete`:
|
58
|
+
```ruby
|
59
|
+
keyring.delete("mykey")
|
60
|
+
keyring["mykey"]
|
61
|
+
# => nil
|
62
|
+
```
|
63
|
+
|
64
|
+
Alternately, if you need temporary access to the key, but want to ensure that
|
65
|
+
it will be removed from the keyring at some point in the future,
|
66
|
+
`KeyRing#set_timeout` is available:
|
67
|
+
```ruby
|
68
|
+
keyring.set_timeout("mykey", 3)
|
69
|
+
keyring["mykey"]
|
70
|
+
# => "my passphrase"
|
71
|
+
sleep 4
|
72
|
+
keyring["mykey"]
|
73
|
+
# => nil
|
74
|
+
```
|
55
75
|
|
56
76
|
## Contributing
|
57
77
|
|
58
|
-
1. Fork it ( http://github.com
|
78
|
+
1. Fork it ( http://github.com/ahorner/key_control/fork )
|
59
79
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
60
80
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
61
81
|
4. Push to the branch (`git push origin my-new-feature`)
|
62
82
|
5. Create new Pull Request
|
83
|
+
|
84
|
+
### Thanks
|
85
|
+
|
86
|
+
- @gabrielg: For refactoring the library detection, and setting up a slick
|
87
|
+
vagrant test suite.
|
88
|
+
- @qfire: For contributing the handy `unlink` and `set_timeout` operations.
|
data/lib/key_control/key_ring.rb
CHANGED
@@ -36,5 +36,26 @@ module KeyControl
|
|
36
36
|
|
37
37
|
system.get(:read, handle)
|
38
38
|
end
|
39
|
+
|
40
|
+
# Public: Remove the data matching the passed description from the keychain.
|
41
|
+
#
|
42
|
+
# name - The description of the data to remove.
|
43
|
+
#
|
44
|
+
# Returns nothing.
|
45
|
+
def delete(name)
|
46
|
+
handle = system.run!(:search, "user", name, nil, @keyring)
|
47
|
+
system.run!(:unlink, handle, @keyring)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Public: Set a timeout for the data matching the passed description.
|
51
|
+
#
|
52
|
+
# name - The description of the data for which to set a timeout.
|
53
|
+
# timeout - The timeout to set in seconds.
|
54
|
+
#
|
55
|
+
# Returns nothing.
|
56
|
+
def set_timeout(name, timeout)
|
57
|
+
handle = system.run!(:search, "user", name, nil, @keyring)
|
58
|
+
system.run!(:set_timeout, handle, timeout)
|
59
|
+
end
|
39
60
|
end
|
40
61
|
end
|
data/lib/key_control/system.rb
CHANGED
@@ -14,6 +14,21 @@ module KeyControl
|
|
14
14
|
send(action).call(*args)
|
15
15
|
end
|
16
16
|
|
17
|
+
# Public: Execute the requested action in keyctl, raising an error on
|
18
|
+
# failure.
|
19
|
+
#
|
20
|
+
# action - The action to perform.
|
21
|
+
# args - A list of arguments which should be passed to the action.
|
22
|
+
#
|
23
|
+
# Returns the stdout value returned by the call.
|
24
|
+
# Raises a SystemCallError if the requested system call fails.
|
25
|
+
def run!(action, *args)
|
26
|
+
result = run(action, *args)
|
27
|
+
raise SystemCallError.new(action.to_s, Fiddle.last_error) if result == -1
|
28
|
+
|
29
|
+
result
|
30
|
+
end
|
31
|
+
|
17
32
|
# Public: Execute the requested keyctl action, buffering the output into a
|
18
33
|
# string in multiple passes.
|
19
34
|
#
|
@@ -70,6 +85,18 @@ module KeyControl
|
|
70
85
|
Fiddle::TYPE_INT )
|
71
86
|
end
|
72
87
|
|
88
|
+
# Private: Get a proc representing the keyctl_read system call.
|
89
|
+
#
|
90
|
+
# Returns a Fiddle::Function.
|
91
|
+
def read
|
92
|
+
@read ||= Fiddle::Function.new(
|
93
|
+
keyutils["keyctl_read"],
|
94
|
+
[ Fiddle::TYPE_INT,
|
95
|
+
Fiddle::ALIGN_CHAR,
|
96
|
+
Fiddle::TYPE_SIZE_T ],
|
97
|
+
Fiddle::TYPE_LONG )
|
98
|
+
end
|
99
|
+
|
73
100
|
# Private: Get a proc representing the request_key system call.
|
74
101
|
#
|
75
102
|
# Returns a Fiddle::Function.
|
@@ -83,15 +110,25 @@ module KeyControl
|
|
83
110
|
Fiddle::TYPE_INT )
|
84
111
|
end
|
85
112
|
|
86
|
-
# Private: Get a proc representing the
|
113
|
+
# Private: Get a proc representing the keyctl_set_timeout system call.
|
87
114
|
#
|
88
115
|
# Returns a Fiddle::Function.
|
89
|
-
def
|
90
|
-
@
|
91
|
-
keyutils["
|
116
|
+
def set_timeout
|
117
|
+
@set_timeout ||= Fiddle::Function.new(
|
118
|
+
keyutils["keyctl_set_timeout"],
|
92
119
|
[ Fiddle::TYPE_INT,
|
93
|
-
Fiddle::
|
94
|
-
|
120
|
+
Fiddle::TYPE_INT ],
|
121
|
+
Fiddle::TYPE_LONG )
|
122
|
+
end
|
123
|
+
|
124
|
+
# Private: Get a proc representing the keyctl_unlink system call.
|
125
|
+
#
|
126
|
+
# Returns a Fiddle::Function.
|
127
|
+
def unlink
|
128
|
+
@unlink ||= Fiddle::Function.new(
|
129
|
+
keyutils["keyctl_unlink"],
|
130
|
+
[ Fiddle::ALIGN_INT,
|
131
|
+
Fiddle::ALIGN_INT ],
|
95
132
|
Fiddle::TYPE_LONG )
|
96
133
|
end
|
97
134
|
end
|
data/lib/key_control/version.rb
CHANGED
@@ -2,6 +2,19 @@ require "test_helper"
|
|
2
2
|
|
3
3
|
describe KeyControl::KeyRing do
|
4
4
|
let(:secret) { "the secret time forgot" }
|
5
|
+
let(:key) { "my-key" }
|
6
|
+
|
7
|
+
before do
|
8
|
+
ring[key].must_equal nil
|
9
|
+
end
|
10
|
+
|
11
|
+
after do
|
12
|
+
begin
|
13
|
+
ring.delete(key)
|
14
|
+
rescue SystemCallError
|
15
|
+
# Ignore keys which aren't set
|
16
|
+
end
|
17
|
+
end
|
5
18
|
|
6
19
|
describe "thread keyring" do
|
7
20
|
let(:ring) do
|
@@ -9,19 +22,27 @@ describe KeyControl::KeyRing do
|
|
9
22
|
end
|
10
23
|
|
11
24
|
it "allows read/write for values in the same thread" do
|
12
|
-
key = "single-thread-test"
|
13
|
-
ring[key].must_equal nil
|
14
|
-
|
15
25
|
ring[key] = secret
|
16
26
|
ring[key].must_equal secret
|
17
27
|
end
|
18
28
|
|
19
29
|
it "uses a new keyring for new threads" do
|
20
|
-
key =
|
30
|
+
Thread.new { ring[key] = secret }.join
|
31
|
+
|
21
32
|
ring[key].must_equal nil
|
33
|
+
end
|
22
34
|
|
23
|
-
|
35
|
+
it "raises an exception when deleting a key which has not been set" do
|
36
|
+
-> { ring.delete key }.must_raise Errno::ENOKEY
|
37
|
+
end
|
38
|
+
|
39
|
+
it "allows an expiration timeout to be set on a key" do
|
40
|
+
timeout = 1
|
41
|
+
ring[key] = secret
|
42
|
+
ring.set_timeout(key, timeout)
|
24
43
|
|
44
|
+
ring[key].must_equal secret
|
45
|
+
sleep timeout + 0.1
|
25
46
|
ring[key].must_equal nil
|
26
47
|
end
|
27
48
|
end
|
@@ -32,26 +53,17 @@ describe KeyControl::KeyRing do
|
|
32
53
|
end
|
33
54
|
|
34
55
|
it "allows read/write of values in the same process" do
|
35
|
-
key = "single-process-test"
|
36
|
-
ring[key].must_equal nil
|
37
|
-
|
38
56
|
ring[key] = secret
|
39
57
|
ring[key].must_equal secret
|
40
58
|
end
|
41
59
|
|
42
60
|
it "allows read/write of values across threads in the same process" do
|
43
|
-
key = "process-thread-test"
|
44
|
-
ring[key].must_equal nil
|
45
|
-
|
46
61
|
Thread.new { ring[key] = secret }.join
|
47
62
|
|
48
63
|
ring[key].must_equal secret
|
49
64
|
end
|
50
65
|
|
51
66
|
it "uses a new keyring for new processes" do
|
52
|
-
key = "multi-process-test"
|
53
|
-
ring[key].must_equal nil
|
54
|
-
|
55
67
|
pid = fork { ring[key] = secret and exit }
|
56
68
|
Process.waitpid(pid)
|
57
69
|
|
@@ -65,30 +77,24 @@ describe KeyControl::KeyRing do
|
|
65
77
|
end
|
66
78
|
|
67
79
|
it "allows read/write of values in the same thread/process" do
|
68
|
-
key = "session-test"
|
69
|
-
ring[key].must_equal nil
|
70
|
-
|
71
80
|
ring[key] = secret
|
72
81
|
ring[key].must_equal secret
|
82
|
+
ring.delete key
|
73
83
|
end
|
74
84
|
|
75
85
|
it "allows read/write of values across threads in the same process" do
|
76
|
-
key = "session-thread-test"
|
77
|
-
ring[key].must_equal nil
|
78
|
-
|
79
86
|
Thread.new { ring[key] = secret }.join
|
80
87
|
|
81
88
|
ring[key].must_equal secret
|
89
|
+
ring.delete key
|
82
90
|
end
|
83
91
|
|
84
92
|
it "allows read/write of values across processes in the same session" do
|
85
|
-
key = "session-process-test"
|
86
|
-
ring[key].must_equal nil
|
87
|
-
|
88
93
|
pid = fork { ring[key] = secret and exit }
|
89
94
|
Process.waitpid(pid)
|
90
95
|
|
91
96
|
ring[key].must_equal secret
|
97
|
+
ring.delete key
|
92
98
|
end
|
93
99
|
end
|
94
100
|
end
|
metadata
CHANGED
@@ -1,52 +1,53 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: key_control
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Horner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.5'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.5'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
-
description:
|
42
|
-
|
41
|
+
description: |2
|
42
|
+
Provides a Hash-like syntax for storing and retrieving data from the
|
43
|
+
system's keyctl utility.
|
43
44
|
email:
|
44
45
|
- andrew@tablexi.com
|
45
46
|
executables: []
|
46
47
|
extensions: []
|
47
48
|
extra_rdoc_files: []
|
48
49
|
files:
|
49
|
-
- .gitignore
|
50
|
+
- ".gitignore"
|
50
51
|
- Gemfile
|
51
52
|
- LICENSE.txt
|
52
53
|
- README.md
|
@@ -70,12 +71,12 @@ require_paths:
|
|
70
71
|
- lib
|
71
72
|
required_ruby_version: !ruby/object:Gem::Requirement
|
72
73
|
requirements:
|
73
|
-
- -
|
74
|
+
- - ">="
|
74
75
|
- !ruby/object:Gem::Version
|
75
76
|
version: '0'
|
76
77
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
78
|
requirements:
|
78
|
-
- -
|
79
|
+
- - ">="
|
79
80
|
- !ruby/object:Gem::Version
|
80
81
|
version: '0'
|
81
82
|
requirements: []
|