key_control 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- MmI3Yjk3YjQwODc1ZDcxZjVmYzBhZDgzYmY0MmE3NDAwZWZkNjBiNg==
5
- data.tar.gz: !binary |-
6
- ZDcxNmJmYWFiMjE0MThjZTFkY2ViZTk1Y2Q5YjA0N2NhYjEyNDVkMA==
2
+ SHA1:
3
+ metadata.gz: ff77033d493fe7d5c4d3efce964e1a01500cc24e
4
+ data.tar.gz: c6d31ad1d873ac69378ffb75c5033373904e5286
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- NzNlMjRhOGNlOTdjODRkYjE1ZTQ4NjhmZTM2Y2RjYTc2ZGQzNDMzYThhMzcx
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 for sharing information among several grouped processes):
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 treat it like you would a hash:
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 comes from the ability to use your kernel's
49
- built-in key management mechanism to share information between Ruby processes
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
- ## Future Enhancements
54
+ ### Key Deletion/Expiration
53
55
 
54
- - Non-default keyring management (creation, specifically)
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/<my-github-username>/key_control/fork )
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.
@@ -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
@@ -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 keyctl_read system call.
113
+ # Private: Get a proc representing the keyctl_set_timeout system call.
87
114
  #
88
115
  # Returns a Fiddle::Function.
89
- def read
90
- @read ||= Fiddle::Function.new(
91
- keyutils["keyctl_read"],
116
+ def set_timeout
117
+ @set_timeout ||= Fiddle::Function.new(
118
+ keyutils["keyctl_set_timeout"],
92
119
  [ Fiddle::TYPE_INT,
93
- Fiddle::ALIGN_CHAR,
94
- Fiddle::TYPE_SIZE_T ],
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
@@ -1,3 +1,3 @@
1
1
  module KeyControl
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
@@ -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 = "multi-thread-test"
30
+ Thread.new { ring[key] = secret }.join
31
+
21
32
  ring[key].must_equal nil
33
+ end
22
34
 
23
- Thread.new { ring[key] = secret }.join
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.5
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-04-14 00:00:00.000000000 Z
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: ! " Provides a Hash-like syntax for storing and retrieving data from
42
- the\n system's keyctl utility.\n"
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: []