opensecret 0.0.962 → 0.0.988

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +16 -10
  3. data/bin/opensecret +3 -4
  4. data/bin/ops +5 -0
  5. data/lib/extension/string.rb +114 -0
  6. data/lib/factbase/facts.opensecret.io.ini +9 -21
  7. data/lib/interprete/begin.rb +232 -0
  8. data/lib/interprete/cmd.rb +621 -0
  9. data/lib/{plugins/usecases/unlock.rb → interprete/export.rb} +25 -70
  10. data/lib/interprete/init.rb +205 -0
  11. data/lib/interprete/key.rb +119 -0
  12. data/lib/interprete/open.rb +148 -0
  13. data/lib/{plugins/usecases → interprete}/put.rb +19 -6
  14. data/lib/{plugins/usecases → interprete}/safe.rb +2 -1
  15. data/lib/{plugins/usecases/lock.rb → interprete/seal.rb} +24 -34
  16. data/lib/interprete/set.rb +46 -0
  17. data/lib/interprete/use.rb +43 -0
  18. data/lib/interpreter.rb +165 -0
  19. data/lib/keytools/binary.map.rb +245 -0
  20. data/lib/keytools/digester.rb +245 -0
  21. data/lib/keytools/doc.conversion.to.ones.and.zeroes.ruby +179 -0
  22. data/lib/keytools/doc.rsa.radix.binary-mapping.ruby +190 -0
  23. data/lib/keytools/doc.star.schema.strategy.txt +77 -0
  24. data/lib/keytools/doc.using.pbkdf2.kdf.ruby +95 -0
  25. data/lib/keytools/doc.using.pbkdf2.pkcs.ruby +266 -0
  26. data/lib/keytools/kdf.bcrypt.rb +180 -0
  27. data/lib/keytools/kdf.pbkdf2.rb +164 -0
  28. data/lib/keytools/key.data.rb +227 -0
  29. data/lib/keytools/key.derivation.rb +341 -0
  30. data/lib/keytools/key.module.rb +140 -0
  31. data/lib/keytools/key.rb +481 -0
  32. data/lib/logging/gem.logging.rb +1 -2
  33. data/lib/modules/cryptology.md +43 -0
  34. data/lib/{plugins/ciphers → modules/cryptology}/aes-256.rb +6 -0
  35. data/lib/{crypto → modules/cryptology}/amalgam.rb +6 -0
  36. data/lib/modules/cryptology/blowfish.rb +130 -0
  37. data/lib/modules/cryptology/cipher.rb +207 -0
  38. data/lib/modules/cryptology/collect.rb +118 -0
  39. data/lib/{plugins → modules/cryptology}/crypt.io.rb +5 -0
  40. data/lib/{crypto → modules/cryptology}/engineer.rb +7 -1
  41. data/lib/{crypto → modules/cryptology}/open.bcrypt.rb +0 -0
  42. data/lib/modules/mappers/collateral.rb +282 -0
  43. data/lib/modules/mappers/dictionary.rb +288 -0
  44. data/lib/modules/mappers/envelope.rb +127 -0
  45. data/lib/modules/mappers/settings.rb +170 -0
  46. data/lib/modules/storage/coldstore.rb +186 -0
  47. data/lib/{opensecret/plugins.io/git/git.flow.rb → modules/storage/git.store.rb} +11 -0
  48. data/lib/notepad/scratch.pad.rb +17 -0
  49. data/lib/session/fact.finder.rb +13 -0
  50. data/lib/session/require.gem.rb +5 -0
  51. data/lib/store-commands.txt +180 -0
  52. data/lib/version.rb +1 -1
  53. data/opensecret.gemspec +5 -6
  54. metadata +74 -29
  55. data/lib/crypto/blowfish.rb +0 -85
  56. data/lib/crypto/collect.rb +0 -140
  57. data/lib/crypto/verify.rb +0 -33
  58. data/lib/opensecret.rb +0 -236
  59. data/lib/plugins/cipher.rb +0 -203
  60. data/lib/plugins/ciphers/blowfish.rb +0 -126
  61. data/lib/plugins/coldstore.rb +0 -181
  62. data/lib/plugins/envelope.rb +0 -116
  63. data/lib/plugins/secrets.uc.rb +0 -94
  64. data/lib/plugins/usecase.rb +0 -239
  65. data/lib/plugins/usecases/init.rb +0 -145
  66. data/lib/plugins/usecases/open.rb +0 -108
  67. data/lib/session/attributes.rb +0 -279
  68. data/lib/session/dictionary.rb +0 -191
  69. data/lib/session/file.path.rb +0 -53
  70. data/lib/session/session.rb +0 -80
@@ -0,0 +1,148 @@
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, change
8
+ # (update) and list the secrets within an envelope (outer path) at a given
9
+ # position (inner path), whether that envelope exists or not.
10
+ #
11
+ # Also see the <b>reopen</b> command which only differs from open in that it
12
+ # fails if the path specified does not exist in either the sealed or session
13
+ # envelopes.
14
+ #
15
+ # == The Open Path Parameter
16
+ #
17
+ # Open must be called with a single <b>path</b> parameter with an optional
18
+ # single colon separating the outer (path to envelope) from the inner (path
19
+ # within envelope).
20
+ #
21
+ # ops open aws.credentials:s3reader
22
+ #
23
+ # The outer and inner paths can contain forward slashes that segment the path.
24
+ #
25
+ # ops open production/aws.credentials:s3/s3reader
26
+ # ops put access_key ABCD1234
27
+ # ops put secret_key FGHIJ56789
28
+ # ops put region_key eu-central-1
29
+ # ops seal
30
+ #
31
+ #
32
+ # == Before Opening a Path
33
+ #
34
+ # To open a path these conditions must be true.
35
+ #
36
+ # - the OPS_KEY environment variable must have been set for the session
37
+ # - either <tt>ops begin</tt> or <tt>ops init</tt> must have been issued
38
+ # - the external drive (eg usb key) must be configured and accessible
39
+ #
40
+ #
41
+ # == After Opening a Path
42
+ #
43
+ # After a path is opened we can
44
+ #
45
+ # - <tt>open</tt> to relative or absolutely change the path
46
+ # - <tt>put</tt> key/value data
47
+ # - <tt>add</tt> a single value
48
+ # - <tt>drop</tt> the value at the opened path
49
+ # - <tt>mod</tt> change (modify) value at path
50
+ # - <tt>seal</tt> to permanently write opened envelopes
51
+ #
52
+ # == Observable Value
53
+ #
54
+ # $ opensecret open home/wifi
55
+ #
56
+ # The observable value delivered by +[open]+ boils down to
57
+ #
58
+ # - an openkey (eg asdfx1234) and corresponding open encryption key
59
+ # - open encryption key written to <tt>~/.opensecret/open.keys/asdfx1234.x.txt</tt>
60
+ # - the opened path (ending in filename) written to session.cache base in [safe]
61
+ # - the INI string (were the file to be decrypted) would look like the below
62
+ #
63
+ # [session]
64
+ # base.path = home/wifi
65
+ #
66
+ class Open < Command
67
+
68
+ attr_writer :open_path
69
+
70
+ # The activities performed by the executing open use case is to
71
+ #
72
+ def execute
73
+
74
+ instantiate_collateral
75
+ @domain_name = @collateral.domain_name
76
+
77
+ param_outer_path = @open_path.split(":").first
78
+ param_inner_path = @open_path.split(":").last
79
+
80
+ index = get_session_dictionary
81
+ index.put OUTER_PATH, param_outer_path
82
+ index.put INNER_PATH, param_inner_path
83
+
84
+ index.write( create_session_dict_lock )
85
+
86
+ puts ""
87
+ puts index.to_s
88
+ puts ""
89
+
90
+ exit
91
+
92
+
93
+
94
+ last_fwdslash_index = param_outer_path.rindex "/"
95
+ folder_path = param_outer_path[0 .. last_fwdslash_index]
96
+ file_word = param_outer_path[last_fwdslash_index .. -1]
97
+
98
+ session_tree_dir = @collateral.session_envelopes_path
99
+ session_folder_path = File.join session_tree_dir, folder_path
100
+
101
+ FileUtils.mkdir_p session_folder_path
102
+ open_id = ToolBelt::Engineer.strong_key @p[:open_idlen]
103
+ open_key = ToolBelt::Engineer.strong_key @p[:open_keylen]
104
+
105
+ file_name = file_word + ".#{open_id}.os.txt"
106
+ file_key = File.join folder_path, file_name
107
+
108
+ Mapper::Settings.write @p[:open_name], @p[:open_idname], open_id
109
+ Mapper::Settings.write @p[:open_name], @p[:open_keyname], open_key
110
+ Mapper::Settings.write @p[:open_name], @p[:open_pathname], file_key
111
+
112
+ puts ""
113
+ puts "---------------------------"
114
+ puts "success | envelope opened"
115
+ puts "---------------------------"
116
+ puts ""
117
+ puts "envelope path => #{param_outer_path}"
118
+ puts "envelope file => #{nickname file_key}"
119
+ puts "time [opened] => #{@c[:global][:stamp_23]}"
120
+ puts ""
121
+ puts "------------------"
122
+ puts "now put secrets"
123
+ puts "------------------"
124
+ puts ""
125
+ puts "ops put virgin/ssid VM68256973"
126
+ puts "ops put virgin/password Wn5lsfixjfy"
127
+ puts ""
128
+
129
+
130
+ end
131
+
132
+
133
+ # Perform pre-conditional validations in preparation to executing the main flow
134
+ # of events for this use case. This method may throw the below exceptions.
135
+ #
136
+ # @raise [SafeDirNotConfigured] if the safe's url has not been configured
137
+ # @raise [EmailAddrNotConfigured] if the email address has not been configured
138
+ # @raise [StoreUrlNotConfigured] if the crypt store url is not configured
139
+ def pre_validation
140
+
141
+
142
+ end
143
+
144
+
145
+ end
146
+
147
+
148
+ end
@@ -71,10 +71,9 @@ module OpenSecret
71
71
  # - <b>look</b>
72
72
  # - <b>peep</b> and
73
73
  # - <b>peek</b>
74
- class Put < SecretsUseCase
74
+ class Put < Command
75
75
 
76
76
  attr_writer :secret_id, :secret_value
77
- @@context_name = "opensecret"
78
77
 
79
78
  # The <b>put use case</b> follows <b>open</b> and it adds secrets into an
80
79
  # <em>(encrypted at rest)</em> envelope. Put can be called many times to
@@ -101,6 +100,22 @@ module OpenSecret
101
100
  # - a new session id and encryption key is generated and used to re-encrypt
102
101
  def execute
103
102
 
103
+ #### is this needed
104
+ #### is this needed
105
+ #### is this needed
106
+ #### is this needed
107
+ #### is this needed
108
+ #### is this needed
109
+ #### is this needed
110
+ ######### instantiate_collateral
111
+ #### is this needed
112
+ #### is this needed
113
+ #### is this needed
114
+ #### is this needed
115
+ #### is this needed
116
+ #### is this needed
117
+
118
+
104
119
  envelope = get_envelope
105
120
 
106
121
  secret_ids = @secret_id.split("/")
@@ -110,8 +125,8 @@ module OpenSecret
110
125
  envelope[secret_ids.first] = { secret_ids.last => @secret_value }
111
126
  end
112
127
 
113
- new_encryption_key = Engineer.strong_key @c[:open][:open_keylen]
114
- OpenSession::Attributes.stash @@context_name, @c[:open][:open_name], @c[:open][:open_keyname], new_encryption_key
128
+ new_encryption_key = ToolBelt::Engineer.strong_key @c[:open][:open_keylen]
129
+ Mapper::Settings.write @c[:open][:open_name], @c[:open][:open_keyname], new_encryption_key
115
130
  envelope.write new_encryption_key
116
131
 
117
132
  end
@@ -133,5 +148,3 @@ module OpenSecret
133
148
 
134
149
 
135
150
  end
136
-
137
-
@@ -14,7 +14,7 @@ module OpenSecret
14
14
  # Stash the path into the host machine's configuration file and proceed
15
15
  # to create the path directory chain if it does not already exist.
16
16
  #
17
- class Safe < SecretsUseCase
17
+ class Safe < Command
18
18
 
19
19
  attr_writer :safe_path
20
20
  @@context_name = "opensecret"
@@ -85,6 +85,7 @@ module OpenSecret
85
85
 
86
86
  end
87
87
 
88
+
88
89
  end
89
90
 
90
91
 
@@ -26,13 +26,11 @@ module OpenSecret
26
26
  #
27
27
  # @example
28
28
  #
29
- # $ opensecret lock
29
+ # $ ops seal
30
30
  #
31
- class Lock < SecretsUseCase
32
-
33
- attr_writer :secret_id, :secret_value
34
- @@context_name = "opensecret"
31
+ class Seal < Command
35
32
 
33
+ attr_writer :envelope_path
36
34
 
37
35
  # The <tt>lock use case</tt> is called after {OpenSecret::Open} and {OpenSecret::Put}
38
36
  # and its effect is to dispatch the doubly encrypted materrial to the configured storage
@@ -67,20 +65,22 @@ module OpenSecret
67
65
  # - deletion of {Open}ed session data to locate and decrypt envelope
68
66
  def execute
69
67
 
70
- rel_filepath = OpenSession::Attributes.instance.get_value @@context_name, @c[:open][:open_name], @c[:open][:open_pathname]
71
- master_public_key = OpenSSL::PKey::RSA.new ( Base64.urlsafe_decode64( OpenSession::Attributes.instance.get_value @c[:global][:name], @c[:global][:name], "public.key" ) )
68
+ instantiate_collateral
69
+
70
+ rel_filepath = Mapper::Settings.read @c[:open][:open_name], @c[:open][:open_pathname]
71
+ master_public_key = OpenSSL::PKey::RSA.new ( @collateral.read_public_key )
72
72
 
73
- main_store = ColdStore.new @c[:global][:store_mainpath]
74
- keys_store = ColdStore.new @c[:global][:store_keyspath]
73
+ keys_store = Store::ColdStore.new( @collateral.frontend_keystore_path )
74
+ main_store = Store::ColdStore.new( @collateral.backend_cryptstore_path )
75
75
 
76
76
  envelope = get_envelope
77
77
  asym_key = OpenSSL::PKey::RSA.new @c[:global][:bit_key_size]
78
- lockdown = Cipher.encrypt_it( asym_key.public_key, envelope.to_json )
79
- lockedup = Cipher.encrypt_it( master_public_key, asym_key.export )
78
+ lockdown = ToolBelt::Cipher.encrypt_it( asym_key.public_key, envelope.to_json )
79
+ lockedup = ToolBelt::Cipher.encrypt_it( master_public_key, asym_key.export )
80
80
 
81
81
  ##### ###################################### #####
82
82
  ##### ###################################### #####
83
- ### Now put the CRYPTS into [Cold] Storage ###
83
+ ### Now put the CRYPTS into [Cold] Storage ###
84
84
  ##### ###################################### #####
85
85
  ##### ###################################### #####
86
86
 
@@ -93,28 +93,6 @@ module OpenSecret
93
93
  puts "================================================================="
94
94
  puts ""
95
95
 
96
- #############################################################################################
97
- #############################################################################################
98
-
99
- =begin
100
- Crypto.print_secret_env_var @p[:env_var_name], machine_key
101
- GitFlow.do_clone_repo @p[:public_gitrepo], @p[:local_gitrepo]
102
- FileUtils.mkdir_p @p[:public_keydir]
103
- File.write @p[:public_keypath], public_key_text
104
- GitFlow.push @p[:local_gitrepo], @p[:public_keyname], @c[:time][:stamp]
105
- =end
106
-
107
-
108
- # key4_pem = File.read 'private.secure.pem'
109
- # pass_phrase = 'superduperpasswordistoBeENTEREDRIGHT1234HereandRightNOW'
110
- # key4 = OpenSSL::PKey::RSA.new key4_pem, pass_phrase
111
- # decrypted_text = key4.private_decrypt(Base64.urlsafe_decode64(encrypted_string))
112
-
113
- # print "\nHey we have done the decryption.\n", "\n"
114
- # print decrypted_text, "\n"
115
-
116
- #############################################################################################
117
- #############################################################################################
118
96
 
119
97
  end
120
98
 
@@ -137,3 +115,15 @@ module OpenSecret
137
115
  end
138
116
 
139
117
 
118
+ #############################################################################################
119
+ #############################################################################################
120
+
121
+ =begin
122
+ GitFlow.do_clone_repo @p[:public_gitrepo], @p[:local_gitrepo]
123
+ FileUtils.mkdir_p @p[:public_keydir]
124
+ File.write @p[:public_keypath], public_key_text
125
+ GitFlow.push @p[:local_gitrepo], @p[:public_keyname], @c[:time][:stamp]
126
+ =end
127
+
128
+ #############################################################################################
129
+ #############################################################################################
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module OpenSecret
4
+
5
+ require 'openssl'
6
+
7
+ # The <b>set <em>use case</em></b> is the generic tool for setting configuration
8
+ # directives inside the ops workstation INI formatted file.
9
+ #
10
+ # The mirror of this use case is <b><em>unset</em></b>.
11
+ #
12
+ # == Observable Value
13
+ #
14
+ # The configuration directive will eithe be created (or will overwrite) an existing
15
+ # directive with the same path.
16
+ #
17
+ # The configuration file is printed to inform the user of the current state.
18
+ #
19
+ # == Alternative / Error Flows
20
+ #
21
+ # Error - if the directive path is not composed of two (fwd slash separated) parts
22
+ # Error - if the directive path and/or value contains (or not) unacceptable characters
23
+ #
24
+ class Set < Command
25
+
26
+ attr_writer :domain_name
27
+
28
+
29
+ # The <b>use <em>use case</em></b> is borrowed from the database world and it denotes
30
+ # the domain to be used <b>for now (and evermore)</b> for this workstation until another
31
+ # use command is issued.
32
+ #
33
+ # The parameter domain_name must be set after an object instance is acquired but
34
+ # before the execute method runs.
35
+ def execute
36
+ end
37
+
38
+
39
+ def pre_validation
40
+ end
41
+
42
+
43
+ end
44
+
45
+
46
+ end
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module OpenSecret
4
+
5
+ require 'openssl'
6
+
7
+ # The <b>use <em>use case</em></b> borrowed from the database world denotes which
8
+ # domain will be used <b>for now (and evermore)</b> on the workstation until another
9
+ # use command is issued.
10
+ #
11
+ # == Observable Value
12
+ #
13
+ # The workstation configuration file will point to the domain name specified
14
+ # marking it as the current and correct domain to use.
15
+ #
16
+ # == Alternative / Error Flows
17
+ #
18
+ # Error - if the domain name is not listed in the configuration file.
19
+ # Error - if the (dictionary) path to the domain's base does not exist
20
+ #
21
+ class Use < Command
22
+
23
+ attr_writer :domain_name
24
+
25
+
26
+ # The <b>use <em>use case</em></b> is borrowed from the database world and it denotes
27
+ # the domain to be used <b>for now (and evermore)</b> for this workstation until another
28
+ # use command is issued.
29
+ #
30
+ # The parameter domain_name must be set after an object instance is acquired but
31
+ # before the execute method runs.
32
+ def execute
33
+ end
34
+
35
+
36
+ def pre_validation
37
+ end
38
+
39
+
40
+ end
41
+
42
+
43
+ end
@@ -0,0 +1,165 @@
1
+ require "thor"
2
+ require "fileutils"
3
+
4
+ require "session/time.stamp"
5
+ require "logging/gem.logging"
6
+ require "session/require.gem"
7
+
8
+ # Include the logger mixins so that every class can enjoy "import free"
9
+ # logging through pointers to the (extended) log behaviour.
10
+ include OpenLogger
11
+
12
+ # This standard out sync command flushes text destined for STDOUT immediately,
13
+ # without waiting either for a full cache or script completion.
14
+ $stdout.sync = true
15
+
16
+ # Recursively require all gems that are either in or under the directory
17
+ # that this code is executing from. Only use this tool if your library is
18
+ # relatively small but highly interconnected. In these instances it raises
19
+ # productivity and reduces harassing "not found" exceptions.
20
+ OpenSession::RecursivelyRequire.now( __FILE__ )
21
+
22
+
23
+ # This command line processor extends the Thor gem CLI tools in order to
24
+ #
25
+ # - read the posted commands, options and switches
26
+ # - maps the incoming string data to objects
27
+ # - assert that the mandatory options exist
28
+ # - assert the type of each parameter
29
+ # - ensure that the parameter values are in range
30
+ # - delegate processing to the registered handlers
31
+ #
32
+ class Interpreter < Thor
33
+
34
+ log.info(x) {"opensecret session initiated at [#{OpenSession::Stamp.yyjjj_hhmm_sst}]." }
35
+
36
+ # This class option allows every CLI call the option to include
37
+ # a --debug boolean switch which will up the verbosity of the
38
+ # content logged to the file .opensecret/opensecret.log
39
+ class_option :debug, :type => :boolean
40
+
41
+ # Description of the init configuration call.
42
+ desc "init <domain_name>, <base_path>", "initialize domain with (optional) frontend path"
43
+
44
+ # If confident that command history cannot be exploited to gain the
45
+ # human password or if the agent running opensecret is itself a script,
46
+ # the <tt>with</tt> option can be used to convey the password.
47
+ option :with
48
+
49
+ # Initialize the credentials manager, collect the human password and
50
+ # manufacture the strong asymmetric public / private keypair.
51
+ #
52
+ # @param domain_name [String] the domain the software operates under
53
+ # @param base_path [String] the path to the base operating directory
54
+ def init domain_name, base_path = nil
55
+ init_uc = OpenSecret::Init.new
56
+ init_uc.master_p4ss = options[:with] if options[:with]
57
+ init_uc.domain_name = domain_name
58
+ init_uc.base_path = base_path unless base_path.nil?
59
+ init_uc.flow_of_events
60
+ end
61
+
62
+
63
+ # Description of the seal use case command line call.
64
+ desc "seal", "Seal away the (secret stuffed) envelope into key and crypt stores."
65
+
66
+ # Seal away the (secret stuffed) envelope into key and crypt stores.
67
+ def seal
68
+ OpenSecret::Seal.new.flow_of_events
69
+ end
70
+
71
+
72
+ # Description of the begin use case command line call.
73
+ desc "begin", "Begin interacting with your opensecret database."
74
+
75
+ # If confident that command history cannot be exploited to gain the
76
+ # human password or if the agent running opensecret is itself a script,
77
+ # the <tt>with</tt> option can be used to convey the password.
78
+ option :with
79
+
80
+ # Begin interacting with your opensecret database.
81
+ def begin
82
+ begin_uc = OpenSecret::Begin.new
83
+ begin_uc.master_p4ss = options[:with] if options[:with]
84
+ begin_uc.flow_of_events
85
+ end
86
+
87
+
88
+ # Description of the opensecret key use case.
89
+ desc "key", "Produce an encrypted session key tied to the workstation and shell environment."
90
+
91
+ # The<b>key</b> use cases prints out an encrypted session key tied
92
+ # to the workstation and shell environment.
93
+ def key
94
+ OpenSecret::Key.new.flow_of_events
95
+ end
96
+
97
+
98
+ # Description of the open use case command.
99
+ desc "open OPEN_PATH", "OPEN_PATH to envelope of secrets to stuff and then lock."
100
+
101
+ # Open up a conduit from which we can add, subtract, update and list secrets
102
+ # before they are committed (and pushed) into permanent locked storage.
103
+ #
104
+ # @param open_path [String] the path to USB key for storing encrypted keys
105
+ def open open_path
106
+
107
+ open_uc = OpenSecret::Open.new
108
+ open_uc.open_path = open_path
109
+ open_uc.flow_of_events
110
+
111
+ end
112
+
113
+
114
+ # Description of the export use case command.
115
+ desc "export OPEN_PATH", "OPEN_PATH to locked secrets to open for reading or stuffing."
116
+
117
+ # If confident that command history cannot be exploited to gain the human password
118
+ # or if the agent running opensecret is itself a script, the <tt>with</tt> option can
119
+ # be used to convey the password.
120
+ option :with
121
+
122
+ # Export a secrets envelope at the specified outer path so that we can read, put
123
+ # and discard secrets.
124
+ #
125
+ # This use case requires the human (agent) password unless the <tt>--no-human-password</tt>
126
+ # flag was posted along with the <tt>init</tt> command.
127
+ #
128
+ # There are two ways to provide the password (for the <b><em>my/gadgets</em></b> group)
129
+ #
130
+ # - <tt>opensecret export my/gadgets</tt> and respond to the password prompt (or)
131
+ # - <tt>opensecret export my/gadgets --with="hUM4n-0pen$3cr3t"</tt>
132
+ #
133
+ # If providing the password on the command line, one must be confident that the shell's
134
+ # command history cannot be exploited to capture it.
135
+ #
136
+ # @param open_path [String] the path to the (previously) locked secrets in frozen storage.
137
+ def export open_path
138
+
139
+ export_uc = OpenSecret::Export.new
140
+ export_uc.open_path = open_path
141
+ export_uc.master_p4ss = options[:with] if options[:with]
142
+ export_uc.flow_of_events
143
+
144
+ end
145
+
146
+
147
+ # Description of the put secret command.
148
+ desc "put <secret_id> <secret_value>", "put secret like login/username into opened context."
149
+
150
+ # Put a secret with an id like login/username and a value like joebloggs into the
151
+ # context (eg work/laptop) that was opened with the open command.
152
+ #
153
+ # @param secret_id [String] the id of the secret to put into the opened context
154
+ # @param secret_value [String] the value of the secret to put into the opened context
155
+ def put secret_id, secret_value
156
+
157
+ put_uc = OpenSecret::Put.new
158
+ put_uc.secret_id = secret_id
159
+ put_uc.secret_value = secret_value
160
+ put_uc.flow_of_events
161
+
162
+ end
163
+
164
+
165
+ end