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 +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
|
-
|