shhh 1.6.5 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f0dbd7d3e5bcbeafe77c1b0c1bc9b65a43cd1e5e
4
- data.tar.gz: 0826054665ac7542bf8fb8db7c2c6266e04723e1
3
+ metadata.gz: bdb6b7b759d1eb7c94e0fe9cb51c51bfb0668fde
4
+ data.tar.gz: 9bdfa75a4c43d67b4cd3c2ec4fa724793760c60e
5
5
  SHA512:
6
- metadata.gz: f726a8afd274a478fd3c439a5758c810db1ca28aeef380d9961ee670a822284f72b7b836c5e0b743a9be83f871d3c281f276e71157f8b0ec636f30dd00bd34cc
7
- data.tar.gz: 417a3995ac55bc82a00d3398d37be3202c85a41c19dfcffbf5c3801c094db74e02a09bc3052f8a9f293371e23d2abae24f5b3729e2cc47e00eef05f068427364
6
+ metadata.gz: 9997274e437d55c7477a8c57d490b7fc67c4272150c4f98af7a3c146b45950e3253cfb638daebc76ee9de16f71256588ccadbcf3f6ffff7257a52ae60ac2fa0e
7
+ data.tar.gz: e641b7bbc34c1ff95e3240a1e52bfca023735478080193fd59c8e22e6c94c5aa65467ad496c751d14d188a041c7f8729f935d2e0942aa1d73493ef646bfb4be6
data/exe/shhh CHANGED
@@ -4,6 +4,7 @@ lib_path = File.expand_path(File.dirname(__FILE__) + '/../lib')
4
4
  $LOAD_PATH << lib_path if File.exist?(lib_path) && !$LOAD_PATH.include?(lib_path)
5
5
 
6
6
  require 'shhh'
7
+ require 'shhh/app'
7
8
 
8
9
  #ARGV.any?{ |a| a =~ /^-/ } ?
9
10
  begin
@@ -1,6 +1,6 @@
1
- require 'require_dir'
2
1
  require 'colored2'
3
2
  require 'zlib'
3
+ require 'coin'
4
4
 
5
5
  require_relative 'shhh/configuration'
6
6
 
@@ -10,7 +10,6 @@ Shhh::Configuration.configure do |config|
10
10
  config.private_key_cipher = config.data_cipher
11
11
  config.compression_enabled = true
12
12
  config.compression_level = Zlib::BEST_COMPRESSION
13
- config.password_cache = { provider: :drb, timeout: 30 }
14
13
  end
15
14
 
16
15
  #
@@ -78,12 +77,18 @@ end
78
77
  #
79
78
  #
80
79
 
81
- module Shhh
82
- extend RequireDir
83
- init(__FILE__)
80
+ module Kernel
81
+ def require_dir(___dir)
82
+ @___dir ||= File.dirname(__FILE__)
83
+ # require files using a consistent order based on the dir/file name.
84
+ # this should be OS-neutral
85
+ Dir["#{@___dir}/#{___dir}/*.rb"].sort.each do |___file|
86
+ require(___file)
87
+ end
88
+ end
84
89
  end
85
90
 
86
- Shhh.dir 'shhh/extensions'
91
+ require_dir 'shhh/extensions'
87
92
 
88
93
  module Shhh
89
94
  def self.included(klass)
@@ -106,5 +111,3 @@ module Shhh
106
111
  end
107
112
  end
108
113
 
109
- Shhh.dir 'shhh'
110
- Shhh.dir 'shhh/app/commands'
@@ -1,9 +1,12 @@
1
- require 'shhh/data'
1
+ require 'shhh'
2
2
  require 'active_support/inflector'
3
+
3
4
  module Shhh
4
5
 
5
6
  # The {Shhh::App} Module is responsible for handing user input and executing commands.
6
- # Central class in this module is the {Shhh::App::CLI} class.
7
+ # Central class in this module is the {Shhh::App::CLI} class. However, it is
8
+ # recommended that ruby integration with the {Shhh::App} module functionality
9
+ # is done via the {Shhh::Application} class.
7
10
  #
8
11
  # Methods in this module are responsible for reporting errors and
9
12
  # maintaining the future exit code class-global variable.
@@ -48,4 +51,6 @@ module Shhh
48
51
  end
49
52
  end
50
53
 
51
- Shhh.dir_r 'shhh/app'
54
+ require 'shhh/app/short_name'
55
+ require 'shhh/version'
56
+ require_dir 'shhh/app'
@@ -3,8 +3,8 @@ module Shhh
3
3
 
4
4
  class Args
5
5
 
6
- OPTIONS_MODE_SELECTED = %i(encrypt decrypt generate edit keychain)
7
6
  OPTIONS_REQUIRE_KEY = %i(encrypt decrypt edit)
7
+ OPTIONS_KEY_CREATED = %i(generate)
8
8
  OPTIONS_SPECIFY_KEY = %i(private_key interactive keyfile keychain)
9
9
  OPTIONS_SPECIFY_OUTPUT = %i(output quiet)
10
10
 
@@ -15,19 +15,18 @@ module Shhh
15
15
  self.selected_options = opts.keys.reject { |k| !opts[k] }
16
16
  end
17
17
 
18
- # TODO: generate these methods dynamically
19
- def do_options_specify_mode?
20
- do?(OPTIONS_MODE_SELECTED)
21
- end
22
-
23
- def do_options_specify_key?
18
+ def specify_key?
24
19
  do?(OPTIONS_SPECIFY_KEY)
25
20
  end
26
21
 
27
- def do_options_require_key?
22
+ def require_key?
28
23
  do?(OPTIONS_REQUIRE_KEY)
29
24
  end
30
25
 
26
+ def generate_key?
27
+ do?(OPTIONS_KEY_CREATED)
28
+ end
29
+
31
30
  def output_class
32
31
  output_type = OPTIONS_SPECIFY_OUTPUT.find { |o| opts[o] } # includes nil
33
32
  Shhh::App::Output.outputs[output_type]
@@ -70,7 +70,7 @@ module Shhh
70
70
  self.opts = parse(argv_copy)
71
71
  if dict
72
72
  options = opts.parser.unused_options + opts.parser.used_options
73
- puts options.map{|o| o.to_s.gsub(/.*(--[\w-]+).*/, '\1') }.sort.join(' ')
73
+ puts options.map { |o| o.to_s.gsub(/.*(--[\w-]+).*/, '\1') }.sort.join(' ')
74
74
  exit 0
75
75
  end
76
76
  rescue StandardError => e
@@ -81,9 +81,7 @@ module Shhh
81
81
  configure_color(argv)
82
82
 
83
83
  self.application = ::Shhh::Application.new(opts)
84
-
85
84
  select_output_stream
86
-
87
85
  end
88
86
 
89
87
  def execute
@@ -126,31 +124,40 @@ module Shhh
126
124
  o.banner = "Shhh (#{Shhh::VERSION}) – encrypt/decrypt data with a private key\n".bold.white
127
125
  o.separator 'Usage:'.yellow
128
126
  o.separator ' # Generate a new key:'.dark
129
- o.separator ' shhh -g '.green.bold +
130
- '[ -c ] [ -p ] [ -x keychain ] [ -o keyfile | -q | ] '.green
127
+ o.separator ' shhh -g '.green.bold + '[ -c ] [ -p ] [ -x keychain ] [ -o keyfile | -q | ] '.green
131
128
  o.separator ''
132
129
  o.separator ' # Encrypt/Decrypt '.dark
133
- o.separator ' shhh [ -d | -e ] '.green.bold +
134
- '[ -f <file> | -s <string> ] '.green
130
+ o.separator ' shhh [ -d | -e ] '.green.bold + '[ -f <file> | -s <string> ] '.green
135
131
  o.separator ' [ -k key | -K keyfile | -x keychain | -i ] '.green
136
132
  o.separator ' [ -o <output file> ] '.green
137
133
  o.separator ' '
138
134
  o.separator ' # Edit an encrypted file in $EDITOR '.dark
139
- o.separator ' shhh -t -f <file> [ -b ]'.green.bold +
140
- '[ -k key | -K keyfile | -x keychain | -i ] '.green
135
+ o.separator ' shhh -t -f <file> [ -b ]'.green.bold + '[ -k key | -K keyfile | -x keychain | -i ] '.green
136
+
141
137
  o.separator ' '
142
138
  o.separator 'Modes:'.yellow
139
+
143
140
  o.bool '-e', '--encrypt', ' encrypt mode'
144
141
  o.bool '-d', '--decrypt', ' decrypt mode'
145
- o.bool '-t', '--edit', ' decrypt, open an encr. file in an $EDITOR'
142
+ o.bool '-t', '--edit', ' decrypt, open an encr. file in an $EDITOR'
143
+
146
144
  o.separator ' '
147
145
  o.separator 'Create a private key:'.yellow
146
+
148
147
  o.bool '-g', '--generate', ' generate a new private key'
149
148
  o.bool '-p', '--password', ' encrypt the key with a password'
150
- o.bool '-c', '--copy', ' copy the new key to the clipboard'
149
+ o.bool '-c', '--copy', ' copy the new key to the clipboard'
150
+
151
151
  if Shhh::App.is_osx?
152
152
  o.string '-x', '--keychain', '[key-name] '.blue + 'add to (or read from) the OS-X Keychain'
153
153
  end
154
+
155
+ o.separator ' '
156
+ o.separator 'Password Caching:'.yellow
157
+
158
+ o.integer '-M', '--password-timeout', '[timeout]'.blue + ' when passwords expire (in seconds)'
159
+ o.bool '-P', '--no-password-cache', ' disables key password caching'
160
+
154
161
  o.separator ' '
155
162
  o.separator 'Provide a private key:'.yellow
156
163
  o.bool '-i', '--interactive', ' Paste or type the key interactively'
@@ -53,3 +53,4 @@ module Shhh
53
53
  end
54
54
  end
55
55
 
56
+ require_dir 'shhh/app/commands'
@@ -1,6 +1,8 @@
1
- require 'shhh/app/short_name'
2
- require 'shhh/app/commands'
1
+ require 'shhh'
2
+ require 'shhh/app'
3
+
3
4
  require 'active_support/inflector'
5
+
4
6
  module Shhh
5
7
  module App
6
8
  module Commands
@@ -11,17 +11,13 @@ module Shhh
11
11
  def execute
12
12
  retries ||= 0
13
13
  new_private_key = self.class.create_private_key
14
-
15
- if opts[:password]
16
- new_private_key = encr_password(new_private_key,
17
- application.input_handler.new_password)
18
- end
14
+ new_private_key = encr_password(new_private_key,
15
+ application.input_handler.new_password) if opts[:password]
19
16
 
20
17
  clipboard_copy(new_private_key) if opts[:copy]
21
18
 
22
- if opts[:keychain] && Shhh::App.is_osx?
23
- Shhh::App::KeyChain.new(opts[:keychain], opts).add(new_private_key)
24
- end
19
+ Shhh::App::KeyChain.new(opts[:keychain], opts).
20
+ add(new_private_key) if opts[:keychain] && Shhh::App.is_osx?
25
21
 
26
22
  new_private_key
27
23
  rescue Shhh::Errors::PasswordsDontMatch, Shhh::Errors::PasswordTooShort => e
@@ -22,6 +22,7 @@ module Shhh
22
22
  begin
23
23
  self.tempfile = ::Tempfile.new(::Base64.urlsafe_encode64(opts[:file]))
24
24
  decrypt_content(self.tempfile)
25
+
25
26
  result = process launch_editor
26
27
  ensure
27
28
  self.tempfile.close if tempfile
@@ -4,6 +4,7 @@ module Shhh
4
4
  module App
5
5
  module Input
6
6
  class Handler
7
+
7
8
  def ask
8
9
  retries ||= 0
9
10
  prompt('Password: ', :green)
@@ -22,7 +23,7 @@ module Shhh
22
23
  end
23
24
 
24
25
  def new_password
25
- password = prompt('New Password : ', :blue)
26
+ password = prompt('New Password : ', :blue)
26
27
 
27
28
  raise Shhh::Errors::PasswordTooShort.new(
28
29
  'Minimum length is 7 characters.') if password.length < 7
@@ -30,7 +31,7 @@ module Shhh
30
31
  password_confirm = prompt('Confirm Password : ', :blue)
31
32
 
32
33
  raise Shhh::Errors::PasswordsDontMatch.new(
33
- 'The passwords you entered do not match.') if password != password_confirm
34
+ 'The passwords you entered do not match.') if password != password_confirm
34
35
 
35
36
  password
36
37
  end
@@ -0,0 +1,63 @@
1
+ require 'coin'
2
+ require 'digest'
3
+ require 'singleton'
4
+ require 'colored2'
5
+
6
+ module Shhh
7
+ module App
8
+ module Password
9
+ class Cache
10
+ URI = 'druby://127.0.0.1:24924'
11
+ DEFAULT_TIMEOUT = 300
12
+
13
+ include Singleton
14
+
15
+ attr_accessor :provider, :enabled, :timeout
16
+
17
+ def configure(provider: Coin, enabled: true, timeout: DEFAULT_TIMEOUT)
18
+ Coin.uri = URI if provider == Coin
19
+
20
+ self.provider = provider
21
+ self.enabled = enabled
22
+ self.timeout = timeout
23
+
24
+ self
25
+ end
26
+
27
+ TRIES = 2
28
+
29
+ def operation
30
+ retries ||= TRIES
31
+ yield if self.enabled
32
+ rescue StandardError => e
33
+ if retries == TRIES && Coin.remote_uri.nil?
34
+ Coin.remote_uri = URI if provider == Coin
35
+ retries -= 1
36
+ retry
37
+ end
38
+ puts 'WARNING: error reading from DRB server: ' + e.message.red
39
+ nil
40
+ end
41
+
42
+
43
+ def [] (key)
44
+ cache = self
45
+ operation do
46
+ cache.provider.read(cache.md5(key))
47
+ end
48
+ end
49
+
50
+ def []=(key, value)
51
+ cache = self
52
+ operation do
53
+ cache.provider.write(cache.md5(key), value, cache.timeout)
54
+ end
55
+ end
56
+
57
+ def md5(string)
58
+ Digest::MD5.base64digest(string)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -1,17 +1,18 @@
1
- require_relative 'decryptor'
2
- require 'shhh/app/cache'
1
+ require 'shhh/app/private_key/decryptor'
2
+ require 'shhh/app/password/cache'
3
3
  module Shhh
4
4
  module App
5
5
  module PrivateKey
6
6
  class Decryptor
7
7
  include Shhh
8
8
 
9
- attr_accessor :encrypted_key, :input_handler
9
+ attr_accessor :encrypted_key, :input_handler, :password_cache
10
10
 
11
- def initialize(encrypted_key, input_handler)
12
- self.encrypted_key = encrypted_key
13
- self.input_handler = input_handler
14
- @cache_checked = false
11
+ def initialize(encrypted_key, input_handler, password_cache)
12
+ self.encrypted_key = encrypted_key
13
+ self.input_handler = input_handler
14
+ self.password_cache = password_cache
15
+ @cache_checked = false
15
16
  end
16
17
 
17
18
  def key
@@ -19,16 +20,21 @@ module Shhh
19
20
  decrypted_key = nil
20
21
  if should_decrypt?
21
22
  begin
22
- retries ||= 0
23
+ retries ||= 0
24
+ p = determine_key_password
25
+ decrypted_key = decrypt(p)
23
26
 
24
- p = password
25
- decrypted_key = decrypt(p)
26
27
  # if the password is valid, let's add it to the cache.
27
- Shhh::App::Cache.instance[encrypted_key] = p
28
+ password_cache[encrypted_key] = p
28
29
 
29
30
  rescue ::OpenSSL::Cipher::CipherError => e
30
31
  input_handler.puts 'Invalid password. Please try again.'
31
- ((retries += 1) < 3) ? retry : raise(Shhh::Errors::InvalidPasswordPrivateKey.new('Invalid password.'))
32
+
33
+ if ((retries += 1) < 3)
34
+ retry
35
+ else
36
+ raise(Shhh::Errors::InvalidPasswordPrivateKey.new('Invalid password.'))
37
+ end
32
38
  end
33
39
  else
34
40
  decrypted_key = encrypted_key
@@ -46,7 +52,7 @@ module Shhh
46
52
  decr_password(encrypted_key, password)
47
53
  end
48
54
 
49
- def password
55
+ def determine_key_password
50
56
  check_cache || ask_user
51
57
  end
52
58
 
@@ -57,9 +63,8 @@ module Shhh
57
63
  def check_cache
58
64
  return nil if @cache_checked
59
65
  @cache_checked = true
60
- Shhh::App::Cache.instance[encrypted_key]
66
+ password_cache[encrypted_key]
61
67
  end
62
-
63
68
  end
64
69
  end
65
70
  end
@@ -26,7 +26,7 @@ module Shhh
26
26
  ->(*, detector) { detector.input_handler.prompt('Please paste your private key: ', :magenta) }
27
27
 
28
28
  Detector.register :keychain,
29
- ->(key_name, * ) { KeyChain.new(key_name).find }
29
+ ->(key_name, * ) { KeyChain.new(key_name).find rescue nil }
30
30
 
31
31
  Detector.register :keyfile,
32
32
  ->(file, *) {
@@ -10,12 +10,13 @@ module Shhh
10
10
  class Handler
11
11
  include Shhh
12
12
 
13
- attr_accessor :opts, :input_handler
13
+ attr_accessor :opts, :input_handler, :password_cache
14
14
  attr_writer :key
15
15
 
16
- def initialize(opts, input_handler)
17
- self.opts = opts
18
- self.input_handler = input_handler
16
+ def initialize(opts, input_handler, password_cache)
17
+ self.opts = opts
18
+ self.input_handler = input_handler
19
+ self.password_cache = password_cache
19
20
  end
20
21
 
21
22
 
@@ -26,13 +27,13 @@ module Shhh
26
27
  @key = begin
27
28
  Detector.new(opts, input_handler).key
28
29
  rescue Shhh::Errors::Error => e
29
- if Shhh::App::Args.new(opts).do_options_specify_key? && key.nil?
30
+ if Shhh::App::Args.new(opts).specify_key? && key.nil?
30
31
  raise e
31
32
  end
32
33
  end
33
34
 
34
35
  if @key && @key.length > 45
35
- @key = Decryptor.new(Base64Decoder.new(key).key, input_handler).key
36
+ @key = Decryptor.new(Base64Decoder.new(key).key, input_handler, password_cache).key
36
37
  end
37
38
 
38
39
  @key
@@ -1,5 +1,7 @@
1
- require 'shhh'
2
1
  require 'colored2'
2
+ require 'shhh'
3
+ require_dir 'shhh/app'
4
+
3
5
  module Shhh
4
6
  class Application
5
7
 
@@ -10,12 +12,15 @@ module Shhh
10
12
  :key,
11
13
  :input_handler,
12
14
  :key_handler,
13
- :result
15
+ :result,
16
+ :password_cache
14
17
 
15
18
  def initialize(opts)
16
19
  self.opts = opts
17
20
  self.opts_hash = opts.respond_to?(:to_hash) ? opts.to_hash : opts
18
21
  self.args = ::Shhh::App::Args.new(opts_hash)
22
+
23
+ initialize_password_cache
19
24
  initialize_input_handler
20
25
  initialize_key_handler
21
26
  initialize_action
@@ -30,8 +35,9 @@ module Shhh
30
35
  end
31
36
 
32
37
  def execute!
33
- if args.do_options_require_key? || args.do_options_specify_key?
34
- self.key = Shhh::App::PrivateKey::Handler.new(opts, input_handler).key
38
+ if !args.generate_key? &&
39
+ (args.require_key? || args.specify_key?)
40
+ self.key = Shhh::App::PrivateKey::Handler.new(opts, input_handler, password_cache).key
35
41
  raise Shhh::Errors::NoPrivateKeyFound.new('Private key is required') unless self.key
36
42
  end
37
43
 
@@ -62,10 +68,26 @@ module Shhh
62
68
  def command
63
69
  @command_class ||= Shhh::App::Commands.find_command_class(opts)
64
70
  @command ||= @command_class.new(self) if @command_class
71
+ @command
65
72
  end
66
73
 
67
74
  def editor
68
- ENV['EDITOR'] || '/bin/vi'
75
+ editors_to_try.find { |editor| File.exist?(editor) }
76
+ end
77
+
78
+ def editors_to_try
79
+ [
80
+ ENV['EDITOR'],
81
+ '/usr/bin/vim',
82
+ '/usr/local/bin/vim',
83
+ '/bin/vim',
84
+ '/sbin/vim',
85
+ '/usr/sbin/vim',
86
+ '/usr/bin/vi',
87
+ '/usr/local/bin/vi',
88
+ '/bin/vi',
89
+ '/sbin/vi'
90
+ ]
69
91
  end
70
92
 
71
93
  def error(hash)
@@ -77,8 +99,16 @@ module Shhh
77
99
  end
78
100
 
79
101
  def initialize_key_handler
80
- self.key_handler = ::Shhh::App::PrivateKey::Handler.new(self.opts, input_handler)
102
+ self.key_handler = ::Shhh::App::PrivateKey::Handler.new(self.opts, input_handler, password_cache)
81
103
  end
82
104
 
105
+ def initialize_password_cache
106
+ args = {}
107
+ args[:provider] = Coin
108
+ args[:timeout] = opts[:password_timeout].to_i if opts[:password_timeout]
109
+ args[:enabled] = false if opts[:no_password_cache]
110
+
111
+ self.password_cache = Shhh::App::Password::Cache.instance.configure(args)
112
+ end
83
113
  end
84
114
  end
@@ -34,6 +34,6 @@ module Shhh
34
34
  end
35
35
 
36
36
  attr_accessor :data_cipher, :password_cipher, :private_key_cipher
37
- attr_accessor :compression_enabled, :compression_level, :password_cache
37
+ attr_accessor :compression_enabled, :compression_level
38
38
  end
39
39
  end
@@ -1,3 +1,3 @@
1
1
  module Shhh
2
- VERSION = '1.6.5'
2
+ VERSION = '1.7.0'
3
3
  end
@@ -29,7 +29,6 @@ Thank you for installing Shhh!
29
29
  -- KG (github.com/kigster)
30
30
  "
31
31
 
32
- spec.add_dependency 'require_dir', '~> 0.1'
33
32
  spec.add_dependency 'colored2', '~> 2.0'
34
33
  spec.add_dependency 'slop', '~> 4.3'
35
34
  spec.add_dependency 'activesupport'
@@ -42,4 +41,5 @@ Thank you for installing Shhh!
42
41
  spec.add_development_dependency 'rake', '~> 10.0'
43
42
  spec.add_development_dependency 'rspec', '~> 3.0'
44
43
  spec.add_development_dependency 'yard', '~> 0.9'
44
+ spec.add_development_dependency 'irbtools'
45
45
  end
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shhh
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.5
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Konstantin Gredeskoul
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-09-10 00:00:00.000000000 Z
11
+ date: 2016-10-17 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: require_dir
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '0.1'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '0.1'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: colored2
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -178,6 +164,20 @@ dependencies:
178
164
  - - "~>"
179
165
  - !ruby/object:Gem::Version
180
166
  version: '0.9'
167
+ - !ruby/object:Gem::Dependency
168
+ name: irbtools
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
181
  description: Store sensitive data safely as encrypted strings or entire files, using
182
182
  symmetric aes-256-cbc encryption/decryption with a secret key and an IV vector,
183
183
  and YAML-friendly base64-encoded encrypted result.
@@ -209,7 +209,6 @@ files:
209
209
  - lib/shhh.rb
210
210
  - lib/shhh/app.rb
211
211
  - lib/shhh/app/args.rb
212
- - lib/shhh/app/cache.rb
213
212
  - lib/shhh/app/cli.rb
214
213
  - lib/shhh/app/commands.rb
215
214
  - lib/shhh/app/commands/command.rb
@@ -233,6 +232,7 @@ files:
233
232
  - lib/shhh/app/output/file.rb
234
233
  - lib/shhh/app/output/noop.rb
235
234
  - lib/shhh/app/output/stdout.rb
235
+ - lib/shhh/app/password/cache.rb
236
236
  - lib/shhh/app/private_key/base64_decoder.rb
237
237
  - lib/shhh/app/private_key/decryptor.rb
238
238
  - lib/shhh/app/private_key/detector.rb
@@ -1,47 +0,0 @@
1
- require 'coin'
2
- require 'digest'
3
- require 'singleton'
4
-
5
- module Shhh
6
- module App
7
- #
8
- # +Cache+ looks like a hash, but is a singleton, and provides
9
- # access to the shared across processes Cache.
10
- #
11
- # The current implementation is based on DRb, which creates a
12
- # server process that then manages the data structure.
13
- #
14
- class Cache
15
- include Singleton
16
-
17
- class << self
18
- def cache
19
- self.instance
20
- end
21
-
22
- def configure
23
- # configure the URI that the DRb server runs on
24
- Coin.uri = 'druby://127.0.0.1:24924'
25
- end
26
- end
27
-
28
- self.configure
29
-
30
- def [] (key)
31
- Coin.read(md5(key))
32
- end
33
-
34
- def []=(key, value)
35
- Coin.write(md5(key), value)
36
- end
37
-
38
- private
39
-
40
- def md5(string)
41
- Digest::MD5.base64digest(string)
42
- end
43
-
44
- end
45
- end
46
- end
47
-