keyring 0.1.0 → 0.2.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f67fb1efea2eb2eaa09bacafab9ef4e75fba84cd
4
+ data.tar.gz: 1a19d3f9507d0e606f08b0e60c9710d2e677432a
5
+ SHA512:
6
+ metadata.gz: 73ef48738d5a0193754a983abbce3d5d666ea619fe4d25044d0dfe7350ef4667847aa7085fe35c9bbc4dc6a777b4fb1f77f1c6296ec8bbde108e991f553056cb
7
+ data.tar.gz: af4063ca11ba35150b2a8697aa58a468e8fe86d773a94d2d8c4486eb2710980e886265b5acd9a9e20a41edc590b3432c08a91f37055d1b82506d176e1039d493
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ # keyring: System keyring abstraction library
2
+ # License: MIT (http://www.opensource.org/licenses/mit-license.php)
3
+
4
+ source 'https://rubygems.org'
5
+
6
+ # Specify your gem's dependencies in keyring.gemspec
7
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 Jason Heiss
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,70 +1,62 @@
1
- keyring
2
- ===========
3
-
4
- A simple framework for storing passwords in certain keyring systems.
5
- This gem is heavily inspired by python-keyring.
6
-
7
- Examples
8
- --------
9
-
10
- The simplest case is to use a single global keyring instance:
11
-
12
- require "keyring"
13
- Keyring.set_password("service", "user", "password")
14
- Keyring.get_password("service", "user") == "password"
15
-
16
- This instance parses ./.rbkeyringrc and ~/.rbkeyringrc (in that order)
17
- for a valid configuration. The configuration determines the default
18
- module to use along with some parameters, e.g., the following
19
- configuration uses the kwallet module (available as keyring-kwallet
20
- gem):
21
-
22
- ---
23
- module: keyring-kwallet
24
- params:
25
- folder: myfolder
26
- app: myapp
27
-
28
- Alternatively you can create instances of your favourite keyring module:
29
-
30
- simple = Keyring::SimpleKeyring.new
31
- kwallet = Keyring::KWalletKeyring.new folder: "myfolder", app: "myapp"
32
- simple.set_password("service", "user", kwallet.get_password("service", "user"))
33
-
34
- The concrete parameters depend on the backend type.
35
-
36
- Install
37
- -------
38
-
39
- gem install keyring
40
-
41
- Author
42
- ------
43
-
44
- Original author: Frank Fischer
45
-
46
- License
47
- -------
48
-
49
- (The MIT License) FIXME (different license?)
50
-
51
- Copyright (c) 2011 FIXME (author's name)
52
-
53
- Permission is hereby granted, free of charge, to any person obtaining
54
- a copy of this software and associated documentation files (the
55
- 'Software'), to deal in the Software without restriction, including
56
- without limitation the rights to use, copy, modify, merge, publish,
57
- distribute, sublicense, and/or sell copies of the Software, and to
58
- permit persons to whom the Software is furnished to do so, subject to
59
- the following conditions:
60
-
61
- The above copyright notice and this permission notice shall be
62
- included in all copies or substantial portions of the Software.
63
-
64
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
65
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
66
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
67
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
68
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
69
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
70
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ # Keyring
2
+
3
+ Store and access your passwords safely
4
+
5
+ This library provides a easy way to access the system keyring service from ruby.
6
+ It can be used in any application that needs safe password storage.
7
+
8
+ The keyring services supported by this library:
9
+ * Mac OS X Keychain: the Apple Keychain service in Mac OS X.
10
+ * In-memory keychain
11
+
12
+ Additional keyring services we'd like to support:
13
+ * KDE KWallet
14
+ * GNOME 2 Keyring
15
+ * SecretServiceKeyring: for newer GNOME and KDE environments.
16
+ * Windows Credential Manager
17
+
18
+ ## Installation
19
+
20
+ Add this line to your application's Gemfile:
21
+
22
+ gem 'keyring'
23
+
24
+ And then execute:
25
+
26
+ $ bundle
27
+
28
+ Or install it yourself as:
29
+
30
+ $ gem install keyring
31
+
32
+ ## Usage
33
+
34
+ The basic usage of keyring is simple: just call Keyring#set_password and
35
+ Keyring#get_password:
36
+
37
+ require 'keyring'
38
+ keyring = Keyring.new
39
+ keyring.set_password('service', 'username', 'password')
40
+ password = keyring.get_password('service', 'username')
41
+ keyring.delete_password('service', 'username')
42
+
43
+ 'service' is an arbitrary string identifying your application.
44
+
45
+ ## Credits
46
+
47
+ Copyright 2013, Jason Heiss
48
+
49
+ Inspired by the keyring library for Python:
50
+ https://bitbucket.org/kang/python-keyring-lib
51
+
52
+ ## License
53
+
54
+ MIT
55
+
56
+ ## Contributing
57
+
58
+ 1. Fork it
59
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
60
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
61
+ 4. Push to the branch (`git push origin my-new-feature`)
62
+ 5. Create new Pull Request
data/Rakefile CHANGED
@@ -1,17 +1,12 @@
1
+ # keyring: System keyring abstraction library
2
+ # License: MIT (http://www.opensource.org/licenses/mit-license.php)
1
3
 
2
- begin
3
- require 'bones'
4
- rescue LoadError
5
- abort '### Please install the "bones" gem ###'
6
- end
7
-
8
- task :default => 'spec:run'
9
- task 'gem:release' => 'spec:run'
10
-
11
- Bones {
12
- name 'keyring'
13
- authors 'Frank Fischer'
14
- email 'frank.fischer@mathematik.tu-chemnitz.de'
15
- url 'http://darcsden.com/lyro/keyring'
16
- }
4
+ require "bundler/gem_tasks"
5
+ require 'rake/testtask'
17
6
 
7
+ # Run a specific file: rake test TEST=test/make.rb
8
+ # Run a specific method:
9
+ # rake test TEST=test/test_make.rb TESTOPTS="--name=test_make_osarch_names"
10
+ Rake::TestTask.new do |t|
11
+ t.verbose = true
12
+ end
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+ # keyring: System keyring abstraction library
3
+ # License: MIT (http://www.opensource.org/licenses/mit-license.php)
4
+
5
+ # When run from the source repository or from an unpacked copy of the
6
+ # distribution we want to find the local library, even if there's a copy
7
+ # installed on the system.
8
+ $:.unshift(File.expand_path('../lib', File.dirname(__FILE__)))
9
+
10
+ require 'keyring/cli'
11
+
12
+ Keyring::CLI.new.main
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ # keyring: System keyring abstraction library
3
+ # License: MIT (http://www.opensource.org/licenses/mit-license.php)
4
+
5
+ lib = File.expand_path('../lib', __FILE__)
6
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
7
+ require 'keyring/version'
8
+
9
+ Gem::Specification.new do |spec|
10
+ spec.name = "keyring"
11
+ spec.version = Keyring::VERSION
12
+ spec.authors = ["Jason Heiss"]
13
+ spec.email = ["jheiss@aput.net"]
14
+ spec.description = %q{This library provides a easy way to access the system keyring service from ruby}
15
+ spec.summary = %q{Store and access your passwords safely}
16
+ spec.homepage = "https://github.com/jheiss/keyring"
17
+ spec.license = "MIT"
18
+
19
+ spec.files = `git ls-files`.split($/)
20
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
21
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.3"
25
+ spec.add_development_dependency "rake"
26
+ spec.add_development_dependency 'mocha'
27
+ spec.add_dependency 'slop'
28
+ end
@@ -1,15 +1,24 @@
1
+ # keyring: System keyring abstraction library
2
+ # License: MIT (http://www.opensource.org/licenses/mit-license.php)
1
3
 
2
- module Keyring
3
-
4
- # :stopdoc:
5
- LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
6
- PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
7
- VERSION = ::File.read(PATH + 'version.txt').strip
8
-
9
- %w(Keyring.rb SimpleKeyring.rb).each do |fname|
10
- require File.join(LIBPATH, "keyring", fname)
11
- end
12
-
13
- end # module Keyring
14
-
4
+ require "keyring/version"
15
5
 
6
+ class Keyring
7
+ require 'keyring/backend'
8
+
9
+ # If you want a particular backend then use, for example,
10
+ # Keyring.new(Keyring::Backend::Memory.new)
11
+ def initialize(backend=nil)
12
+ @backend = backend || Keyring::Backend.create
13
+ end
14
+
15
+ def get_password(service, username)
16
+ @backend.get_password(service, username)
17
+ end
18
+ def set_password(service, username, password)
19
+ @backend.set_password(service, username, password)
20
+ end
21
+ def delete_password(service, username)
22
+ @backend.delete_password(service, username)
23
+ end
24
+ end
@@ -0,0 +1,42 @@
1
+ # keyring: System keyring abstraction library
2
+ # License: MIT (http://www.opensource.org/licenses/mit-license.php)
3
+
4
+ class Keyring::Backend
5
+ @implementations = []
6
+ class << self
7
+ attr_accessor :implementations
8
+ end
9
+ def self.register_implementation(impl)
10
+ Keyring::Backend.implementations << impl
11
+ end
12
+ Dir.glob(File.expand_path('backends/*.rb', File.dirname(__FILE__))).each {|b| require b}
13
+ def self.create
14
+ supported = implementations.collect{|i| b = i.new; b.supported? ? b : nil}.compact
15
+ if supported.empty?
16
+ raise(NotImplementedError)
17
+ end
18
+ supported.max{|b| b.priority}
19
+ end
20
+
21
+ #
22
+ # Backend classes must implement these methods
23
+ #
24
+
25
+ def supported?
26
+ false
27
+ end
28
+ # Returns a number between 0 and 1 (inclusive) indicating the relative
29
+ # preference for this backend.
30
+ def priority
31
+ 0
32
+ end
33
+ def set_password(service, username, password)
34
+ raise NotImplementedError
35
+ end
36
+ def get_password(service, username)
37
+ raise NotImplementedError
38
+ end
39
+ def delete_password(service, username)
40
+ raise NotImplementedError
41
+ end
42
+ end
@@ -0,0 +1,91 @@
1
+ # keyring: System keyring abstraction library
2
+ # License: MIT (http://www.opensource.org/licenses/mit-license.php)
3
+
4
+ # This is a keyring backend for the Apple Keychain
5
+ # http://en.wikipedia.org/wiki/Keychain_(Apple)
6
+
7
+ require 'open3'
8
+
9
+ class Keyring::Backend::MacosxKeychain < Keyring::Backend
10
+ register_implementation(self)
11
+
12
+ attr_accessor :security
13
+ def initialize
14
+ @security = '/usr/bin/security'
15
+ end
16
+ def supported?
17
+ File.exist?(@security) && `#{@security} -h`.include?('find-generic-password')
18
+ end
19
+ def priority
20
+ 1
21
+ end
22
+
23
+ def security_command(operation)
24
+ "#{operation}-generic-password"
25
+ end
26
+
27
+ def set_password(service, username, password)
28
+ cmd = [
29
+ @security,
30
+ security_command('add'),
31
+ '-s', service,
32
+ '-a', username,
33
+ # FIXME: password in command line, sad panda!
34
+ '-w', password,
35
+ '-U',
36
+ ]
37
+ system(*cmd)
38
+ if !$?.success?
39
+ raise
40
+ end
41
+ end
42
+ def get_password(service, username)
43
+ password = nil
44
+ cmd = [
45
+ @security,
46
+ security_command('find'),
47
+ '-s', service,
48
+ '-a', username,
49
+ '-g',
50
+ # '-w',
51
+ ]
52
+ Open3.popen3(*cmd) do |stdin, stdout, stderr, wait_thr|
53
+ stderr.each do |line|
54
+ if line =~ /\Apassword: (.*)/
55
+ pw = $1
56
+ if pw == ''
57
+ password = pw
58
+ elsif pw =~ /\A"(.*)"\z/
59
+ password = $1
60
+ elsif pw =~ /\A0x(\h+)/
61
+ password = [$1].pack("H*")
62
+ end
63
+ end
64
+ end
65
+ # security exits with 44 if the entry does not exist. We just want to return
66
+ # nil rather than raise an exception in that case.
67
+ if ![0,44].include?(wait_thr.value.exitstatus)
68
+ raise
69
+ end
70
+ end
71
+ password
72
+ end
73
+ def delete_password(service, username)
74
+ cmd = [
75
+ @security,
76
+ security_command('delete'),
77
+ '-s', service,
78
+ '-a', username,
79
+ ]
80
+ Open3.popen3(*cmd) do |stdin, stdout, stderr, wait_thr|
81
+ case wait_thr.value.exitstatus
82
+ when 0
83
+ return true
84
+ when 44
85
+ return false
86
+ else
87
+ raise
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,29 @@
1
+ # keyring: System keyring abstraction library
2
+ # License: MIT (http://www.opensource.org/licenses/mit-license.php)
3
+
4
+ # Stores the keyring in-memory. Useful when you don't need permanant storage.
5
+
6
+ class Keyring::Backend::Memory < Keyring::Backend
7
+ register_implementation(self)
8
+
9
+ def initialize
10
+ @keyring = {}
11
+ end
12
+ def supported?
13
+ true
14
+ end
15
+ def priority
16
+ 0.1
17
+ end
18
+
19
+ def get_password(service, username)
20
+ @keyring[service] && @keyring[service][username]
21
+ end
22
+ def set_password(service, username, password)
23
+ @keyring[service] ||= {}
24
+ @keyring[service][username] = password
25
+ end
26
+ def delete_password(service, username)
27
+ @keyring[service] && @keyring[service].delete(username)
28
+ end
29
+ end