shhh 1.6.5 → 1.7.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.
- checksums.yaml +4 -4
- data/exe/shhh +1 -0
- data/lib/shhh.rb +11 -8
- data/lib/shhh/app.rb +8 -3
- data/lib/shhh/app/args.rb +7 -8
- data/lib/shhh/app/cli.rb +18 -11
- data/lib/shhh/app/commands.rb +1 -0
- data/lib/shhh/app/commands/command.rb +4 -2
- data/lib/shhh/app/commands/generate_key.rb +4 -8
- data/lib/shhh/app/commands/open_editor.rb +1 -0
- data/lib/shhh/app/input/handler.rb +3 -2
- data/lib/shhh/app/password/cache.rb +63 -0
- data/lib/shhh/app/private_key/decryptor.rb +20 -15
- data/lib/shhh/app/private_key/detector.rb +1 -1
- data/lib/shhh/app/private_key/handler.rb +7 -6
- data/lib/shhh/application.rb +36 -6
- data/lib/shhh/configuration.rb +1 -1
- data/lib/shhh/version.rb +1 -1
- data/shhh.gemspec +1 -1
- metadata +17 -17
- data/lib/shhh/app/cache.rb +0 -47
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bdb6b7b759d1eb7c94e0fe9cb51c51bfb0668fde
|
4
|
+
data.tar.gz: 9bdfa75a4c43d67b4cd3c2ec4fa724793760c60e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9997274e437d55c7477a8c57d490b7fc67c4272150c4f98af7a3c146b45950e3253cfb638daebc76ee9de16f71256588ccadbcf3f6ffff7257a52ae60ac2fa0e
|
7
|
+
data.tar.gz: e641b7bbc34c1ff95e3240a1e52bfca023735478080193fd59c8e22e6c94c5aa65467ad496c751d14d188a041c7f8729f935d2e0942aa1d73493ef646bfb4be6
|
data/exe/shhh
CHANGED
data/lib/shhh.rb
CHANGED
@@ -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
|
82
|
-
|
83
|
-
|
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
|
-
|
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'
|
data/lib/shhh/app.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
-
require 'shhh
|
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
|
-
|
54
|
+
require 'shhh/app/short_name'
|
55
|
+
require 'shhh/version'
|
56
|
+
require_dir 'shhh/app'
|
data/lib/shhh/app/args.rb
CHANGED
@@ -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
|
-
|
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
|
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]
|
data/lib/shhh/app/cli.rb
CHANGED
@@ -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
|
-
|
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',
|
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',
|
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'
|
data/lib/shhh/app/commands.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
23
|
-
|
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
|
@@ -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
|
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
|
-
|
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
|
-
|
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
|
13
|
-
self.input_handler
|
14
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
18
|
-
self.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).
|
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
|
data/lib/shhh/application.rb
CHANGED
@@ -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.
|
34
|
-
|
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
|
-
|
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
|
data/lib/shhh/configuration.rb
CHANGED
data/lib/shhh/version.rb
CHANGED
data/shhh.gemspec
CHANGED
@@ -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.
|
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-
|
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
|
data/lib/shhh/app/cache.rb
DELETED
@@ -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
|
-
|