opensecret 0.0.962 → 0.0.988
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +16 -10
- data/bin/opensecret +3 -4
- data/bin/ops +5 -0
- data/lib/extension/string.rb +114 -0
- data/lib/factbase/facts.opensecret.io.ini +9 -21
- data/lib/interprete/begin.rb +232 -0
- data/lib/interprete/cmd.rb +621 -0
- data/lib/{plugins/usecases/unlock.rb → interprete/export.rb} +25 -70
- data/lib/interprete/init.rb +205 -0
- data/lib/interprete/key.rb +119 -0
- data/lib/interprete/open.rb +148 -0
- data/lib/{plugins/usecases → interprete}/put.rb +19 -6
- data/lib/{plugins/usecases → interprete}/safe.rb +2 -1
- data/lib/{plugins/usecases/lock.rb → interprete/seal.rb} +24 -34
- data/lib/interprete/set.rb +46 -0
- data/lib/interprete/use.rb +43 -0
- data/lib/interpreter.rb +165 -0
- data/lib/keytools/binary.map.rb +245 -0
- data/lib/keytools/digester.rb +245 -0
- data/lib/keytools/doc.conversion.to.ones.and.zeroes.ruby +179 -0
- data/lib/keytools/doc.rsa.radix.binary-mapping.ruby +190 -0
- data/lib/keytools/doc.star.schema.strategy.txt +77 -0
- data/lib/keytools/doc.using.pbkdf2.kdf.ruby +95 -0
- data/lib/keytools/doc.using.pbkdf2.pkcs.ruby +266 -0
- data/lib/keytools/kdf.bcrypt.rb +180 -0
- data/lib/keytools/kdf.pbkdf2.rb +164 -0
- data/lib/keytools/key.data.rb +227 -0
- data/lib/keytools/key.derivation.rb +341 -0
- data/lib/keytools/key.module.rb +140 -0
- data/lib/keytools/key.rb +481 -0
- data/lib/logging/gem.logging.rb +1 -2
- data/lib/modules/cryptology.md +43 -0
- data/lib/{plugins/ciphers → modules/cryptology}/aes-256.rb +6 -0
- data/lib/{crypto → modules/cryptology}/amalgam.rb +6 -0
- data/lib/modules/cryptology/blowfish.rb +130 -0
- data/lib/modules/cryptology/cipher.rb +207 -0
- data/lib/modules/cryptology/collect.rb +118 -0
- data/lib/{plugins → modules/cryptology}/crypt.io.rb +5 -0
- data/lib/{crypto → modules/cryptology}/engineer.rb +7 -1
- data/lib/{crypto → modules/cryptology}/open.bcrypt.rb +0 -0
- data/lib/modules/mappers/collateral.rb +282 -0
- data/lib/modules/mappers/dictionary.rb +288 -0
- data/lib/modules/mappers/envelope.rb +127 -0
- data/lib/modules/mappers/settings.rb +170 -0
- data/lib/modules/storage/coldstore.rb +186 -0
- data/lib/{opensecret/plugins.io/git/git.flow.rb → modules/storage/git.store.rb} +11 -0
- data/lib/notepad/scratch.pad.rb +17 -0
- data/lib/session/fact.finder.rb +13 -0
- data/lib/session/require.gem.rb +5 -0
- data/lib/store-commands.txt +180 -0
- data/lib/version.rb +1 -1
- data/opensecret.gemspec +5 -6
- metadata +74 -29
- data/lib/crypto/blowfish.rb +0 -85
- data/lib/crypto/collect.rb +0 -140
- data/lib/crypto/verify.rb +0 -33
- data/lib/opensecret.rb +0 -236
- data/lib/plugins/cipher.rb +0 -203
- data/lib/plugins/ciphers/blowfish.rb +0 -126
- data/lib/plugins/coldstore.rb +0 -181
- data/lib/plugins/envelope.rb +0 -116
- data/lib/plugins/secrets.uc.rb +0 -94
- data/lib/plugins/usecase.rb +0 -239
- data/lib/plugins/usecases/init.rb +0 -145
- data/lib/plugins/usecases/open.rb +0 -108
- data/lib/session/attributes.rb +0 -279
- data/lib/session/dictionary.rb +0 -191
- data/lib/session/file.path.rb +0 -53
- data/lib/session/session.rb +0 -80
data/lib/plugins/usecase.rb
DELETED
@@ -1,239 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
# coding: utf-8
|
3
|
-
|
4
|
-
# opensession contains basic behaviour for managing a client only
|
5
|
-
# (serverless) session. Configuration directives are read and written
|
6
|
-
# from an INI off the home directory that is created when the session
|
7
|
-
# is first initiated.
|
8
|
-
#
|
9
|
-
# The session is expected to be formally closed down and that is
|
10
|
-
# reflected by explicitly deleting the configuration file. If this
|
11
|
-
# "session over" command is not issued a reasonable time limit is
|
12
|
-
# then invoked when the next session command is issued.
|
13
|
-
#
|
14
|
-
# This "session awakening" wipes the slate clean and starts afresh
|
15
|
-
# with regard to the two dimensional array of configuration directive
|
16
|
-
# pointers.
|
17
|
-
module OpenSession
|
18
|
-
|
19
|
-
|
20
|
-
# An opensession use case is designed to be extended and does preparatory
|
21
|
-
# work to create favourable and useful conditions to make use cases readable,
|
22
|
-
# less repetitive, simpler and concise.
|
23
|
-
class UseCase
|
24
|
-
|
25
|
-
|
26
|
-
# Execute the use cases's flow from beginning when
|
27
|
-
# you validate the input and parameters through the
|
28
|
-
# memorize, execute and the final cleanup.
|
29
|
-
def flow_of_events
|
30
|
-
|
31
|
-
check_pre_conditions
|
32
|
-
pre_memorize
|
33
|
-
execute
|
34
|
-
post_memorize
|
35
|
-
cleanup
|
36
|
-
check_post_conditions
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
# Validate the input parameters and check that the current
|
43
|
-
# state is perfect for executing the use case.
|
44
|
-
#
|
45
|
-
# If either of the above fail - the validation function should
|
46
|
-
# set a human readable string and then throw an exception.
|
47
|
-
def check_pre_conditions
|
48
|
-
|
49
|
-
|
50
|
-
begin
|
51
|
-
|
52
|
-
pre_validation
|
53
|
-
|
54
|
-
rescue OpenError::CliError => e
|
55
|
-
|
56
|
-
puts ""
|
57
|
-
puts "Your command did not complete successfully."
|
58
|
-
puts "Pre validation checks failed."
|
59
|
-
puts ""
|
60
|
-
puts " => #{e.message}"
|
61
|
-
puts ""
|
62
|
-
abort e.message
|
63
|
-
end
|
64
|
-
|
65
|
-
|
66
|
-
end
|
67
|
-
|
68
|
-
|
69
|
-
# After the main flow of events certain state conditions
|
70
|
-
# must hold true thus demonstrating that the observable
|
71
|
-
# value has indeed ben delivered.
|
72
|
-
#
|
73
|
-
# Child classes should subclass this method and place any
|
74
|
-
# post execution (post condition) checks in it and then
|
75
|
-
# make a call to this method through the "super" keyword.
|
76
|
-
def check_post_conditions
|
77
|
-
|
78
|
-
begin
|
79
|
-
|
80
|
-
post_validation
|
81
|
-
|
82
|
-
rescue OpenError::CliError => e
|
83
|
-
|
84
|
-
puts ""
|
85
|
-
puts "Your command did not complete successfully."
|
86
|
-
puts "Post validation checks failed."
|
87
|
-
puts ""
|
88
|
-
puts " => #{e.message}"
|
89
|
-
#### puts " => #{e.culprit}"
|
90
|
-
puts ""
|
91
|
-
abort e.message
|
92
|
-
end
|
93
|
-
|
94
|
-
end
|
95
|
-
|
96
|
-
|
97
|
-
# Child classes should subclass this method and place any
|
98
|
-
# post execution (post condition) checks in it and then
|
99
|
-
# make a call to this method through the "super" keyword if
|
100
|
-
# this method gets any global behaviour in it worth calling.
|
101
|
-
def post_validation
|
102
|
-
|
103
|
-
end
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
# (Pre) memorize adds to permanent storage a configuration
|
108
|
-
# directive and its value <tt>provided by the user</tt>
|
109
|
-
# primarily because it avoids repitition in subsequent
|
110
|
-
# use case commands.
|
111
|
-
def pre_memorize
|
112
|
-
|
113
|
-
end
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
# Execute the main flow of events of the use case. Any
|
118
|
-
# exceptions thrown are captured and if the instance
|
119
|
-
# variale [@human_readable_message] is set - tell the
|
120
|
-
# user about it. Without any message - just tell the
|
121
|
-
# user something went wrong and tell them where the logs
|
122
|
-
# are that might carry more information.
|
123
|
-
def execute
|
124
|
-
|
125
|
-
end
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
# (Post) memorize will add to permanent storage) any
|
130
|
-
# key/values that have been derived or looked up during
|
131
|
-
# use case execution. This allows subsequent use case
|
132
|
-
# commands to
|
133
|
-
#
|
134
|
-
# - capitalize on
|
135
|
-
# - take direction from
|
136
|
-
# - and/or simply use
|
137
|
-
#
|
138
|
-
# the value in later use cases or processing.
|
139
|
-
def post_memorize
|
140
|
-
|
141
|
-
end
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
# If the use case validation went well, the memorization
|
146
|
-
# went well the
|
147
|
-
def cleanup
|
148
|
-
|
149
|
-
end
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
# Resolve +two attached fact files+ with the first being general and
|
154
|
-
# relevant to every use case in the parameter specified domain, and
|
155
|
-
# the second being specific to this use case.
|
156
|
-
#
|
157
|
-
# The <b><em>general factfile</em></b> is expected to be on the class (load) path
|
158
|
-
# and below are paths for a generic domain name and for an example domain
|
159
|
-
# name of *openpost.io*
|
160
|
-
#
|
161
|
-
# - <tt>factbase/facts.<<domain>>.ini</tt>
|
162
|
-
# - <tt>factbase/facts.openpost.io.ini</tt>
|
163
|
-
#
|
164
|
-
# The <b><em>use case specific factfile</em></b> is also _expected_ to be on the class
|
165
|
-
# (load) path and below is a generic and a use case specific path using
|
166
|
-
# the example <tt>deliver</tt> use case.
|
167
|
-
#
|
168
|
-
# - <tt>factbase/facts.<<uc-name>>.usecase.ini</tt>
|
169
|
-
# - <tt>factbase/facts.deliver.usecase.ini</tt>
|
170
|
-
#
|
171
|
-
# The domain name is delivered in the parameter whilst the use case
|
172
|
-
# name is derived from the (extension) class name.
|
173
|
-
#
|
174
|
-
# @param fact_domain [String] domain of the general attached factfile
|
175
|
-
# @return [Hash] a 2d (two-dimensional) hash of keys and their corresponding values
|
176
|
-
def attached_facts fact_domain
|
177
|
-
|
178
|
-
end
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
### def path_to_resources
|
184
|
-
### File.join(File.dirname(File.expand_path(__FILE__)), '../path/to/resources')
|
185
|
-
### end
|
186
|
-
|
187
|
-
# This use case is initialized primary by resolving the configured
|
188
|
-
# +general and use case specific facts+. To access the general facts,
|
189
|
-
# a domain name is expected in the parameter delegated by the extension
|
190
|
-
# use case classes.
|
191
|
-
def initialize
|
192
|
-
|
193
|
-
|
194
|
-
class_name = self.class.name.downcase.split(":").last
|
195
|
-
is_pre_init_usecase = [ "safe", "store", "email" ].include? class_name
|
196
|
-
return if is_pre_init_usecase
|
197
|
-
|
198
|
-
@ucid_str = self.class.name.do_flatten
|
199
|
-
log.info(x) { "Usecase class [self.class.name] converted to => #{@ucid_str}" }
|
200
|
-
@ucid_sym = @ucid_str.gsub(".", "_").to_sym
|
201
|
-
|
202
|
-
OpenSession::FactFind.instance.instantiate @ucid_str
|
203
|
-
OpenSession::FactFind.instance.assimilate "facts.opensecret.io.ini"
|
204
|
-
|
205
|
-
@c = OpenSession::FactFind.instance.f
|
206
|
-
@i = OpenSession::FactFind.instance.i
|
207
|
-
@p = OpenSession::FactFind.instance.f[@ucid_sym]
|
208
|
-
|
209
|
-
log.info(x) { "assimilated [#{@p.length}] facts specific to the [#{@ucid_str}] use case." }
|
210
|
-
|
211
|
-
############ @time_stamp = OpenSession::Stamp.instance
|
212
|
-
|
213
|
-
=begin
|
214
|
-
@eco_id_str = SnapFlat.do self.class.name
|
215
|
-
@eco_id_sym = @eco_id_str.gsub(".", "_").to_sym
|
216
|
-
@plugin_path = plugin_src_dir
|
217
|
-
|
218
|
-
FactTree.instance.instantiate @eco_id_str, @plugin_path
|
219
|
-
FactTree.instance.assimilate_instance_facts
|
220
|
-
|
221
|
-
instantiate_runtime FactTree.instance.f
|
222
|
-
|
223
|
-
FactTree.instance.identify_my_workstation
|
224
|
-
FactTree.instance.assimilate_station_facts
|
225
|
-
FactTree.instance.assimilate_plugin_facts
|
226
|
-
FactTree.instance.assimilate_general_facts
|
227
|
-
|
228
|
-
@c = FactTree.instance.f
|
229
|
-
@i = FactTree.instance.i
|
230
|
-
@p = FactTree.instance.f[@eco_id_sym]
|
231
|
-
=end
|
232
|
-
|
233
|
-
end
|
234
|
-
|
235
|
-
|
236
|
-
end
|
237
|
-
|
238
|
-
|
239
|
-
end
|
@@ -1,145 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
|
3
|
-
module OpenSecret
|
4
|
-
|
5
|
-
require 'openssl'
|
6
|
-
|
7
|
-
# The <b>init use case</b> initializes opensecret thus preparing it
|
8
|
-
# for the ability to lock secrets, unlock them, transport their keys and
|
9
|
-
# much more.
|
10
|
-
#
|
11
|
-
# Like all use cases, +init+ validates to ensure that the pre-conditions
|
12
|
-
# have been met and then proceeds to execute its core offering and deliver
|
13
|
-
# observable value.
|
14
|
-
#
|
15
|
-
# == Observable Value
|
16
|
-
#
|
17
|
-
# The observable value from the <b>init use case</b> init boils down to
|
18
|
-
#
|
19
|
-
# - the public key and <b>8192 bit encrypted private key</b> in the safe
|
20
|
-
# - the <b>encrypted workstation key</b> in the user's configuration file
|
21
|
-
# - the <b>encrypted public key signature</b> in the user's configuration file
|
22
|
-
# - a robust password (for unlocking secrets) +stashed in a human brain+
|
23
|
-
# - successful test of the open, put, list, lock, read and tell use cases
|
24
|
-
#
|
25
|
-
# No cloud or other external access occurs as per the opensecret policy.
|
26
|
-
#
|
27
|
-
# == Thwart Public Key Switch Attacks
|
28
|
-
#
|
29
|
-
# A <b><em>public key switch attack</em></b> tries to access <b>future secrets</b>
|
30
|
-
# (not the ones already encrypted) via unwitting encryption using a public key
|
31
|
-
# the attacker controls.
|
32
|
-
#
|
33
|
-
# <b>opensecret</b> thwarts this by continual verification against an
|
34
|
-
# encrypted <em>public key signature</em> aboard the workstation.
|
35
|
-
class Init < SecretsUseCase
|
36
|
-
|
37
|
-
attr_writer :safe_path, :email_addr, :store_url
|
38
|
-
@@context_name = "opensecret"
|
39
|
-
|
40
|
-
|
41
|
-
# The init use case prepares <b>opensecret</b> so that you can <b>open</b> a packet,
|
42
|
-
# <b>put</b> secrets into it and then <b>lock</b> it, effectively writing the crypt
|
43
|
-
# material into the backend store.
|
44
|
-
#
|
45
|
-
# <b>Main Flow of Events</b>
|
46
|
-
#
|
47
|
-
# So to prepare for the <b><em>modus operandi</em></b> that encrypts, decrypts and if
|
48
|
-
# required transports secrets, we
|
49
|
-
#
|
50
|
-
# - collect the human password (twice) and verify its robustness
|
51
|
-
# - manufacture workstation key that will be encrypted b4 it rests on machine
|
52
|
-
# - create amalgamated human/workstation password for locking the private key
|
53
|
-
# - create a long cryptographically strong symmetric encryption key
|
54
|
-
# - encrypt workstation key and put crypt into the opensecret configuration file
|
55
|
-
# - create a super sized 8192 bit private key (and its asymmetric public key)
|
56
|
-
# - write the AES 256bit encrypted private key into safe-store's master keys
|
57
|
-
# - create a text bundle for signing composed of the keys, email and date/time
|
58
|
-
# - sign the bundle and save the signature in the master keys store
|
59
|
-
# - put the public key in the configuration file (off the homedirectory)
|
60
|
-
# - test the core open, put, list, lock, read and tell use case commands
|
61
|
-
#
|
62
|
-
# <b>Observable Value</b>
|
63
|
-
#
|
64
|
-
# The <tt>init use case</tt> observable value post-conditions are
|
65
|
-
#
|
66
|
-
# - the <b>8192 bit encrypted private key</b> in the master keys safe
|
67
|
-
# - the <b>public key</b>, time stamp and encrypted workstation key in config
|
68
|
-
# - the <b>encrypted workstation key</b> in the user's configuration file
|
69
|
-
# - the <b>asymmetric keys, time stamp and email</b> signature in master keys safe
|
70
|
-
# - a robust password (for unlocking secrets) +stashed in a human brain+
|
71
|
-
def execute
|
72
|
-
|
73
|
-
human_password = Collect.secret_text(
|
74
|
-
@c[:global][:min_passwd_len],
|
75
|
-
true,
|
76
|
-
@c[:global][:prompt_1],
|
77
|
-
@c[:global][:prompt_2]
|
78
|
-
)
|
79
|
-
|
80
|
-
machine_key = Engineer.machine_key human_password.length, @c[:global][:ratio]
|
81
|
-
amalgam_key = Amalgam.passwords human_password, machine_key, @c[:global][:ratio]
|
82
|
-
asymmetric_keys = OpenSSL::PKey::RSA.new @c[:global][:bit_key_size]
|
83
|
-
secured_keytext = asymmetric_keys.export @c[:global][:key_cipher], amalgam_key
|
84
|
-
|
85
|
-
crypt_key_segments = [ human_password, @c[:global][:separator_a], @email_addr, @c[:global][:separator_a], @c[:global][:stamp_23] ]
|
86
|
-
|
87
|
-
machine_key_crypt_key = crypt_key_segments.alphanumeric_union.concat_length
|
88
|
-
machine_key_x = Base64.urlsafe_encode64(
|
89
|
-
Blowfish.new.encryptor(machine_key, machine_key_crypt_key)
|
90
|
-
)
|
91
|
-
|
92
|
-
OpenSession::Attributes.stash @c[:global][:name], @c[:global][:name], @c[:global][:machine_key_x], machine_key_x
|
93
|
-
OpenSession::Attributes.stash @c[:global][:name], @c[:global][:name], @c[:global][:stamp_key], @c[:global][:stamp_23]
|
94
|
-
|
95
|
-
|
96
|
-
## Change and write the public key to own file (see paper notes for naming direction)
|
97
|
-
## Change and write the public key to own file (see paper notes for naming direction)
|
98
|
-
## Change and write the public key to own file (see paper notes for naming direction)
|
99
|
-
public_key_64 = Base64.urlsafe_encode64 asymmetric_keys.public_key.to_pem
|
100
|
-
OpenSession::Attributes.stash @c[:global][:name], @c[:global][:name], @c[:global][:publickey_id], public_key_64
|
101
|
-
|
102
|
-
## not needed - produce public key from private key then validate with key in configuration.
|
103
|
-
## not needed - produce public key from private key then validate with key in configuration.
|
104
|
-
## not needed - produce public key from private key then validate with key in configuration.
|
105
|
-
to_sign_segments = [ secured_keytext, public_key_64, @email_addr, @c[:global][:stamp_23] ]
|
106
|
-
to_sign_packet = to_sign_segments.alphanumeric_union.concat_length
|
107
|
-
signature_string = Base64.urlsafe_encode64( asymmetric_keys.sign( OpenSSL::Digest::SHA256.new, to_sign_packet ) )
|
108
|
-
|
109
|
-
FileUtils.mkdir_p @c[:global][:master_dirpath]
|
110
|
-
File.write @c[:global][:master_prv_key], secured_keytext
|
111
|
-
File.write @c[:global][:master_sig_path], signature_string
|
112
|
-
|
113
|
-
end
|
114
|
-
|
115
|
-
|
116
|
-
# Perform pre-conditional validations in preparation to executing the main flow
|
117
|
-
# of events for this use case. This method may throw the below exceptions.
|
118
|
-
#
|
119
|
-
# @raise [SafeDirNotConfigured] if the safe's url has not been configured
|
120
|
-
# @raise [EmailAddrNotConfigured] if the email address has not been configured
|
121
|
-
# @raise [StoreUrlNotConfigured] if the crypt store url is not configured
|
122
|
-
def pre_validation
|
123
|
-
|
124
|
-
@safe_path = OpenSession::Attributes.instance.get_value @@context_name, @@context_name, "safe"
|
125
|
-
safe_configured = File.exists?( @safe_path ) && File.directory?( @safe_path )
|
126
|
-
@err_msg = "[safe] storage not yet configured. Try =>] opensecret safe /folder/path"
|
127
|
-
raise SafeDirNotConfigured.new @err_msg, @safe_path unless safe_configured
|
128
|
-
|
129
|
-
@email_addr = OpenSession::Attributes.instance.get_value @@context_name, @@context_name, "email"
|
130
|
-
email_configured = !@email_addr.nil? && !@email_addr.empty? && @email_addr.length > 4
|
131
|
-
@err_msg = "viable [email address] not configured. Try =>] opensecret email joe@example.com"
|
132
|
-
raise EmailAddrNotConfigured.new @err_msg, @email_addr unless email_configured
|
133
|
-
|
134
|
-
@store_url = OpenSession::Attributes.instance.get_value @@context_name, @@context_name, "store"
|
135
|
-
store_configured = !@store_url.nil? && !@store_url.empty? && @store_url.length > 0
|
136
|
-
@err_msg = "crypt [store url] not configured. Try =>] opensecret store /path/to/crypt"
|
137
|
-
raise StoreUrlNotConfigured.new @err_msg, @store_url unless store_configured
|
138
|
-
|
139
|
-
end
|
140
|
-
|
141
|
-
|
142
|
-
end
|
143
|
-
|
144
|
-
|
145
|
-
end
|
@@ -1,108 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
|
3
|
-
module OpenSecret
|
4
|
-
|
5
|
-
require 'openssl'
|
6
|
-
|
7
|
-
# The <tt>open use case</tt> allows us to add (put), subtract (del)ete and list
|
8
|
-
# the secrets in a file (whether it exists or not). The file can then be locked.
|
9
|
-
# Lookout for the reopen command.
|
10
|
-
#
|
11
|
-
# If the file to open already exists a --with option (giving the master-secret)
|
12
|
-
# must be provided.
|
13
|
-
#
|
14
|
-
# == Observable Value
|
15
|
-
#
|
16
|
-
# $ opensecret open home/wifi
|
17
|
-
#
|
18
|
-
# The observable value delivered by +[open]+ boils down to
|
19
|
-
#
|
20
|
-
# - an openkey (eg asdfx1234) and corresponding open encryption key
|
21
|
-
# - open encryption key written to <tt>~/.opensecret/open.keys/asdfx1234.x.txt</tt>
|
22
|
-
# - the opened path (ending in filename) written to session.cache base in [safe]
|
23
|
-
# - the INI string (were the file to be decrypted) would look like the below
|
24
|
-
#
|
25
|
-
# [session]
|
26
|
-
# base.path = home/wifi
|
27
|
-
#
|
28
|
-
class Open < SecretsUseCase
|
29
|
-
|
30
|
-
attr_writer :outer_path
|
31
|
-
@@context_name = "opensecret"
|
32
|
-
|
33
|
-
# Execute the <tt>open use case</tt> activities which precedes the ability to
|
34
|
-
# to add (put), subtract (del)ete and list the secrets into the opened session file.
|
35
|
-
# The file can then be locked (committed and pushed to permanent crypted stores).
|
36
|
-
#
|
37
|
-
# If the file to open already exists a --with option (giving the master-secret)
|
38
|
-
# must be provided.
|
39
|
-
#
|
40
|
-
# <b>Observable Value [Open Use Case]</b>
|
41
|
-
#
|
42
|
-
# $ opensecret open home/wifi
|
43
|
-
#
|
44
|
-
# The observable value delivered by +[open]+ boils down to
|
45
|
-
#
|
46
|
-
# - a provisioned openkey (eg asdfx1234) and corresponding open encryption key
|
47
|
-
# - open encryption key written to <tt>~/.opensecret/open.keys/asdfx1234.x.txt</tt>
|
48
|
-
# - the opened path (ending in filename) written to session.cache base in [safe]
|
49
|
-
# - the INI string (were the file to be decrypted) would look like the below
|
50
|
-
#
|
51
|
-
# [session]
|
52
|
-
# session.key = EQFe4TKMWyrlyD59NRWWJYVue8xsTnKAnuXtsZ6NRoVXMeqFRj
|
53
|
-
# session.path = home/wifi.1vz16m5Zl47w.x.os.txt
|
54
|
-
#
|
55
|
-
# @example
|
56
|
-
# home/wifi can be simply populated like this.
|
57
|
-
#
|
58
|
-
# $ opensecret put bt/ssid g034gdf3455
|
59
|
-
# $ opensecret put bt/password HRAsyf324g4DF
|
60
|
-
#
|
61
|
-
# $ opensecret put virgin.media/ssid 345SDFS
|
62
|
-
# $ opensecret put virgin.media/password HlksHRd043NjPO
|
63
|
-
#
|
64
|
-
# $ opensecret file virgin.media/contract /home/joe/downloads/vm.contract.pdf
|
65
|
-
#
|
66
|
-
# To encrypt (lock-down) these secrets we simply issue
|
67
|
-
#
|
68
|
-
# $ opensecret close
|
69
|
-
#
|
70
|
-
def execute
|
71
|
-
|
72
|
-
last_fwdslash_index = @outer_path.rindex "/"
|
73
|
-
folder_path = @outer_path[0 .. last_fwdslash_index]
|
74
|
-
file_word = @outer_path[last_fwdslash_index .. -1]
|
75
|
-
|
76
|
-
session_folder_path = File.join @p[:open_dirpath], folder_path
|
77
|
-
|
78
|
-
FileUtils.mkdir_p session_folder_path
|
79
|
-
open_id = Engineer.strong_key @p[:open_idlen]
|
80
|
-
open_key = Engineer.strong_key @p[:open_keylen]
|
81
|
-
|
82
|
-
file_name = file_word + ".#{open_id}.os.txt"
|
83
|
-
####################### file_path = File.join session_folder_path, file_name
|
84
|
-
file_key = File.join folder_path, file_name
|
85
|
-
|
86
|
-
OpenSession::Attributes.stash @@context_name, @p[:open_name], @p[:open_idname], open_id
|
87
|
-
OpenSession::Attributes.stash @@context_name, @p[:open_name], @p[:open_keyname], open_key
|
88
|
-
OpenSession::Attributes.stash @@context_name, @p[:open_name], @p[:open_pathname], file_key
|
89
|
-
|
90
|
-
end
|
91
|
-
|
92
|
-
|
93
|
-
# Perform pre-conditional validations in preparation to executing the main flow
|
94
|
-
# of events for this use case. This method may throw the below exceptions.
|
95
|
-
#
|
96
|
-
# @raise [SafeDirNotConfigured] if the safe's url has not been configured
|
97
|
-
# @raise [EmailAddrNotConfigured] if the email address has not been configured
|
98
|
-
# @raise [StoreUrlNotConfigured] if the crypt store url is not configured
|
99
|
-
def pre_validation
|
100
|
-
|
101
|
-
|
102
|
-
end
|
103
|
-
|
104
|
-
|
105
|
-
end
|
106
|
-
|
107
|
-
|
108
|
-
end
|