opensecret 0.0.959 → 0.0.960
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/extension/string.rb +30 -0
- data/lib/factbase/facts.opensecret.io.ini +4 -0
- data/lib/plugins/coldstore.rb +145 -0
- data/lib/plugins/envelope.rb +25 -25
- data/lib/plugins/usecases/lock.rb +17 -40
- data/lib/session/file.path.rb +53 -0
- data/lib/version.rb +1 -1
- metadata +4 -3
- data/lib/plugins/stores/store.rb +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b95962b0946200185b87257ef12fbfab9e689ecd
|
4
|
+
data.tar.gz: 40eb3bb6b0a401192e33a92b23053d35755f7c51
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8e6c1c61a35e114c6e20e5d8192c3d1a2b996fb6bb65ebd58858f268d2839d5d629824883b2efc8ef8e50faf064f13efcf77e850986313baa168fb0ea06caf10
|
7
|
+
data.tar.gz: 8f511f4f83d18d85a3891ef504bef7b60a8f8bcb59e427d86f24acf928315d765132be999a0aa63a2aec4cd818e7b96ab61df59346fc6753c94c30fa4bc14b66
|
data/lib/extension/string.rb
CHANGED
@@ -12,6 +12,36 @@
|
|
12
12
|
class String
|
13
13
|
|
14
14
|
|
15
|
+
# Overtly long file paths (eg in logs) can hamper readability so this
|
16
|
+
# <b>human readable filepath converter</b> counters the problem by
|
17
|
+
# returning (only) the 2 immediate ancestors of the filepath.
|
18
|
+
#
|
19
|
+
# So this method returns the name of the grandparent folder then parent folder
|
20
|
+
# and then the most significant file (or folder) name.
|
21
|
+
#
|
22
|
+
# When this is not possible due to the filepath being colisively near the
|
23
|
+
# filesystem's root, it returns the parameter name.
|
24
|
+
#
|
25
|
+
# @example
|
26
|
+
# A really long input like
|
27
|
+
# => /home/joe/project/degrees/math/2020
|
28
|
+
# is reduced to
|
29
|
+
# => degrees/math/2020
|
30
|
+
#
|
31
|
+
# @return [String] the segmented 3 most significant path name elements.
|
32
|
+
def hr_path
|
33
|
+
|
34
|
+
object_name = File.basename self
|
35
|
+
parent_folder = File.dirname self
|
36
|
+
parent_name = File.basename parent_folder
|
37
|
+
granny_folder = File.dirname parent_folder
|
38
|
+
granny_name = File.basename granny_folder
|
39
|
+
|
40
|
+
return [granny_name,parent_name,object_name].join("/")
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
|
15
45
|
# Return a new string matching this one with every non alpha-numeric
|
16
46
|
# character removed. This string is left unchanged.
|
17
47
|
#
|
@@ -24,6 +24,10 @@ stamp.key = stamp
|
|
24
24
|
stamp.14 = rb>> OpenSession::Stamp.yyjjj_hhmm_sst
|
25
25
|
stamp.23 = rb>> OpenSession::Stamp.yyjjj_hhmm_ss_nanosec
|
26
26
|
|
27
|
+
base.path = rb>> File.join FilePath.context_path(@s[:name]), @s[:email_address]
|
28
|
+
store.keyspath = rb>> File.join @s[:base_path], "coldstore.keys"
|
29
|
+
store.mainpath = rb>> File.join @s[:base_path], "coldstore.main"
|
30
|
+
|
27
31
|
machine.key.x = os.x
|
28
32
|
separator.a = %$os$%
|
29
33
|
publickey.id = public.key
|
@@ -0,0 +1,145 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
module OpenSecret
|
5
|
+
|
6
|
+
# Cold storage can sync repositories with a <b>bias during conflicts</b>
|
7
|
+
# either to the <em>remote repository</em> <b>when pulling</b>, and then
|
8
|
+
# conversely to the <em>local reposiory</em> <b>when pushing</b>.
|
9
|
+
#
|
10
|
+
# In between the sync operations a ColdStore can create, read, update and
|
11
|
+
# delete to and from the local mirror.
|
12
|
+
#
|
13
|
+
# == ColdStore | Use Cases
|
14
|
+
#
|
15
|
+
# Any <b>self-respecting coldstore</b> must, after initialization, provide
|
16
|
+
# some basic (and mandatory) behaviour.
|
17
|
+
#
|
18
|
+
# These include
|
19
|
+
#
|
20
|
+
# - <b>read</b> - reading text from a (possibly unavailable) frozen path
|
21
|
+
# - <b>write</b> - writing text (effectively freezing it) to a path
|
22
|
+
# - <b>pull</b> - sync with a <b>collision bias</b> that favours the remote mirror
|
23
|
+
# - <b>push</b> - sync with a <b>collision bias</b> that favours the local mirror
|
24
|
+
#
|
25
|
+
# <b>Cold Storage</b> is borrowed from BitCoin and represents offline storage
|
26
|
+
# for keys and crypts. opensecret separates keys and crypts so that you can
|
27
|
+
# transfer and share secrets by moving keys (not the crypts).
|
28
|
+
#
|
29
|
+
# == Houses and Gold Bullion
|
30
|
+
#
|
31
|
+
# You don't carry houses or gold bullion around to rent, share or transfer
|
32
|
+
# their ownership.
|
33
|
+
#
|
34
|
+
# You copy keys to rent secrets and when the tenure is up (or you change your
|
35
|
+
# mind) you revoke access with a metaphorical lock change.
|
36
|
+
#
|
37
|
+
# opensecret embodies concepts like an owner who rents as opposed to a change
|
38
|
+
# in ownership.
|
39
|
+
#
|
40
|
+
# == trade secrets | commoditizing secrets
|
41
|
+
#
|
42
|
+
# opensecret is a conduit through which secrets can be bought and sold.
|
43
|
+
#
|
44
|
+
# It commoditizes secrets so that they can be owned, traded, leased and
|
45
|
+
# auctioned. Options to acquire or relinquish them at set prices can easily
|
46
|
+
# be taken out.
|
47
|
+
class ColdStore
|
48
|
+
|
49
|
+
# @param base_path [String]
|
50
|
+
# path to the store's (mirror) base directory.
|
51
|
+
# If the denoted directory does not exist an attempt will be made to
|
52
|
+
# create it. If a file exists at this path an error will be thrown.
|
53
|
+
#
|
54
|
+
# @param domain [String]
|
55
|
+
# the domain is an identifier (and namespace) denoting which opensecret
|
56
|
+
# "account" is being accessed. opensecret allows the creation and use of
|
57
|
+
# multiple domains.
|
58
|
+
def initialize local_path
|
59
|
+
|
60
|
+
@store_path = local_path
|
61
|
+
FileUtils.mkdir_p @store_path
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
# Read the file frozen (in this store mirror) at this path and
|
67
|
+
# return its contents.
|
68
|
+
#
|
69
|
+
# Coldstores are usually frozen offline (offmachine) so for this
|
70
|
+
# to work the {ColdStore.pull} behaviour must have executed to
|
71
|
+
# create a local store mirror. This method reads from that mirror.
|
72
|
+
#
|
73
|
+
# @param from_path [String]
|
74
|
+
# read the file frozen at this path and return its contents
|
75
|
+
# so that the defreeze process can begin.
|
76
|
+
#
|
77
|
+
# This path is relative to the base of the store defined in
|
78
|
+
# the constructor.
|
79
|
+
#
|
80
|
+
# @return [String]
|
81
|
+
# return the text frozen in a file at the denoted local path
|
82
|
+
#
|
83
|
+
# nil is reurned if no file can be found in the local mirror
|
84
|
+
# at the configured path
|
85
|
+
def read from_path
|
86
|
+
|
87
|
+
frozen_filepath = File.join @store_path, from_path
|
88
|
+
return nil unless File.exists? frozen_filepath
|
89
|
+
return File.read frozen_filepath
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
# Write (freeze) the text into a file at the denoted path. The
|
95
|
+
# folder path will be created if need be.
|
96
|
+
#
|
97
|
+
# Coldstores are usually frozen offline (offmachine) so after
|
98
|
+
# this method completes the {ColdStore.push} behaviour must be
|
99
|
+
# executed to synchronize the local coldstore freezer with the
|
100
|
+
# remote mirror.
|
101
|
+
#
|
102
|
+
# @param this_text [String]
|
103
|
+
# this is the text that needs to be frozen into the local and
|
104
|
+
# subsequently the remote coldstore freezer.
|
105
|
+
#
|
106
|
+
# @param to_path [String]
|
107
|
+
# write the text (effectively freezing it) into the file at
|
108
|
+
# this path. An attempt will be made to put down the necessary
|
109
|
+
# directory structure.
|
110
|
+
#
|
111
|
+
# This path is relative to the base of the store defined in
|
112
|
+
# the constructor.
|
113
|
+
def write this_text, to_path
|
114
|
+
|
115
|
+
freeze_filepath = File.join @store_path, to_path
|
116
|
+
|
117
|
+
log.info(x) { "ColdStore freezing #{this_text.length} characters of worthless text."}
|
118
|
+
log.info(x) { "ColdStore freeze file path => #{freeze_filepath.hr_path}"}
|
119
|
+
|
120
|
+
FileUtils.mkdir_p(File.dirname(freeze_filepath))
|
121
|
+
File.write freeze_filepath, this_text
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
private
|
127
|
+
|
128
|
+
# @todo - write sync (with a local bias during conflicts)
|
129
|
+
# The open up to the public (published) api.
|
130
|
+
def push
|
131
|
+
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
# @todo - write sync (with a rmote bias during conflicts)
|
136
|
+
# The open up to the public (published) api.
|
137
|
+
def pull
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
|
145
|
+
end
|
data/lib/plugins/envelope.rb
CHANGED
@@ -40,31 +40,6 @@ module OpenSecret
|
|
40
40
|
class Envelope < Hash
|
41
41
|
|
42
42
|
|
43
|
-
# Write the data in this envelope hash map into a file-system
|
44
|
-
# backed mirror whose path was specified in the {self.read} method.
|
45
|
-
#
|
46
|
-
# Technology for encryption at rest is supported by this dictionary
|
47
|
-
# and to this aim, please endeavour to post a robust symmetric
|
48
|
-
# encryption key.
|
49
|
-
#
|
50
|
-
# Calling this {self.write} method when the file at the prescribed path
|
51
|
-
# does not exist results in the directory structure being created
|
52
|
-
# (if necessary) and then the encrypted file being written.
|
53
|
-
#
|
54
|
-
# @param encryption_key [String]
|
55
|
-
# encryption at rest is a given so this mandatory parameter must
|
56
|
-
# contain a robust symmetric encryption key. The symmetric key will
|
57
|
-
# be used for the decryption after the read. Note that the decryption
|
58
|
-
# key does not linger meaning it isn't cached in an instance variable.
|
59
|
-
def write encryption_key
|
60
|
-
|
61
|
-
FileUtils.mkdir_p(File.dirname(@filepath))
|
62
|
-
cipher_text = Base64.encode64 Blowfish.new.encryptor( self.to_json, encryption_key )
|
63
|
-
File.write @filepath, cipher_text
|
64
|
-
|
65
|
-
end
|
66
|
-
|
67
|
-
|
68
43
|
# Read and inject into this envelope, the data structure found in a
|
69
44
|
# file at the path specified in the first parameter.
|
70
45
|
#
|
@@ -110,6 +85,31 @@ module OpenSecret
|
|
110
85
|
end
|
111
86
|
|
112
87
|
|
88
|
+
# Write the data in this envelope hash map into a file-system
|
89
|
+
# backed mirror whose path was specified in the {self.read} method.
|
90
|
+
#
|
91
|
+
# Technology for encryption at rest is supported by this dictionary
|
92
|
+
# and to this aim, please endeavour to post a robust symmetric
|
93
|
+
# encryption key.
|
94
|
+
#
|
95
|
+
# Calling this {self.write} method when the file at the prescribed path
|
96
|
+
# does not exist results in the directory structure being created
|
97
|
+
# (if necessary) and then the encrypted file being written.
|
98
|
+
#
|
99
|
+
# @param encryption_key [String]
|
100
|
+
# encryption at rest is a given so this mandatory parameter must
|
101
|
+
# contain a robust symmetric encryption key. The symmetric key will
|
102
|
+
# be used for the decryption after the read. Note that the decryption
|
103
|
+
# key does not linger meaning it isn't cached in an instance variable.
|
104
|
+
def write encryption_key
|
105
|
+
|
106
|
+
FileUtils.mkdir_p(File.dirname(@filepath))
|
107
|
+
cipher_text = Base64.encode64 Blowfish.new.encryptor( self.to_json, encryption_key )
|
108
|
+
File.write @filepath, cipher_text
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
113
|
end
|
114
114
|
|
115
115
|
|
@@ -67,55 +67,35 @@ module OpenSecret
|
|
67
67
|
# - deletion of {Open}ed session data to locate and decrypt envelope
|
68
68
|
def execute
|
69
69
|
|
70
|
+
rel_filepath = OpenSession::Attributes.instance.get_value @@context_name, @c[:open][:open_name], @c[:open][:open_pathname]
|
71
|
+
master_public_key = Base64.urlsafe_decode64( OpenSession::Attributes.instance.get_value @c[:global][:name], @c[:global][:name], "public.key" )
|
72
|
+
|
73
|
+
main_store = ColdStore.new @c[:global][:store_mainpath]
|
74
|
+
keys_store = ColdStore.new @c[:global][:store_keyspath]
|
75
|
+
|
70
76
|
envelope = get_envelope
|
71
77
|
asym_key = OpenSSL::PKey::RSA.new @c[:global][:bit_key_size]
|
72
78
|
lockdown = Aes256.new.encrypt_it( asym_key.public_key.to_pem, envelope.to_json )
|
79
|
+
lockedup = Aes256.new.encrypt_it( master_public_key, asym_key.export )
|
73
80
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
81
|
+
##### ###################################### #####
|
82
|
+
##### ###################################### #####
|
83
|
+
### Now put the CRYPTS into [Cold] Storage ###
|
84
|
+
##### ###################################### #####
|
85
|
+
##### ###################################### #####
|
79
86
|
|
80
|
-
|
87
|
+
keys_store.write lockedup, rel_filepath
|
88
|
+
main_store.write lockdown, rel_filepath
|
81
89
|
|
82
|
-
lockedup = Aes256.new.encrypt_it( master_public_key, asym_key.export )
|
83
|
-
|
84
|
-
puts "#### #############################"
|
85
|
-
puts "#### The Crypt Store Suitcase"
|
86
|
-
puts "#### #############################"
|
87
|
-
puts ""
|
88
|
-
puts lockdown
|
89
|
-
puts ""
|
90
|
-
puts "#### #############################"
|
91
|
-
puts "#### The Key Store Suitcase"
|
92
|
-
puts "#### #############################"
|
93
90
|
puts ""
|
94
|
-
puts
|
91
|
+
puts "================================================================="
|
92
|
+
puts "[Lock] => Now DELETE the session files and configured variables."
|
93
|
+
puts "================================================================="
|
95
94
|
puts ""
|
96
|
-
puts "================================================================================================="
|
97
|
-
puts "Now Continue with Unencoding the public key and then locking down the above asym_key.export"
|
98
|
-
puts "================================================================================================="
|
99
|
-
puts ""
|
100
|
-
|
101
|
-
exit
|
102
|
-
|
103
|
-
|
104
|
-
locked_block = Aes256.new.encrypt_it( asym_key.public_key.to_pem, asym_key.export )
|
105
|
-
|
106
|
-
secured_keytext = asym_key.export
|
107
|
-
## public_key_text = asymmetric_keys.public_key.to_pem
|
108
|
-
|
109
|
-
|
110
|
-
Aes256.new.encrypt_it( "rubbish", secrets_dictionary.to_s )
|
111
|
-
|
112
|
-
the_encrypted_stuff = Aes256.new.encrypt_it( "rubbish", )
|
113
|
-
|
114
95
|
|
115
96
|
#############################################################################################
|
116
97
|
#############################################################################################
|
117
98
|
|
118
|
-
|
119
99
|
=begin
|
120
100
|
Crypto.print_secret_env_var @p[:env_var_name], machine_key
|
121
101
|
GitFlow.do_clone_repo @p[:public_gitrepo], @p[:local_gitrepo]
|
@@ -125,7 +105,6 @@ module OpenSecret
|
|
125
105
|
=end
|
126
106
|
|
127
107
|
|
128
|
-
# exit
|
129
108
|
# key4_pem = File.read 'private.secure.pem'
|
130
109
|
# pass_phrase = 'superduperpasswordistoBeENTEREDRIGHT1234HereandRightNOW'
|
131
110
|
# key4 = OpenSSL::PKey::RSA.new key4_pem, pass_phrase
|
@@ -134,8 +113,6 @@ module OpenSecret
|
|
134
113
|
# print "\nHey we have done the decryption.\n", "\n"
|
135
114
|
# print decrypted_text, "\n"
|
136
115
|
|
137
|
-
|
138
|
-
|
139
116
|
#############################################################################################
|
140
117
|
#############################################################################################
|
141
118
|
|
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
module OpenSession
|
5
|
+
|
6
|
+
require 'inifile'
|
7
|
+
require 'singleton'
|
8
|
+
|
9
|
+
class FilePath
|
10
|
+
|
11
|
+
# Get the directory that the session context file either does
|
12
|
+
# or will sit inside.
|
13
|
+
#
|
14
|
+
# The directory hangs off the home directory and is named simply
|
15
|
+
# as the dot prefixed context_name.
|
16
|
+
#
|
17
|
+
# @example ~/.openbox is the directory for context "openbox"
|
18
|
+
#
|
19
|
+
# @param context_name [String] name of program (or use case) context
|
20
|
+
# @return [String] path to directory holding context configuration file
|
21
|
+
def self.context_path context_name
|
22
|
+
|
23
|
+
return File.join home_directory, ".#{context_name}"
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
# On non-windows systems the home directory is defined
|
29
|
+
# perfectly by Ruby's Dir object.
|
30
|
+
#
|
31
|
+
# On Windows we sometimes get /AppData/Roaming appended
|
32
|
+
# onto the actual home directory. In these cases this
|
33
|
+
# method removes it.
|
34
|
+
#
|
35
|
+
# @return [String] the path to the machine user's home directory
|
36
|
+
def self.home_directory
|
37
|
+
|
38
|
+
return Dir.home unless Gem.win_platform?
|
39
|
+
|
40
|
+
extraneous_path = "/AppData/Roaming"
|
41
|
+
if Dir.home.end_with? extraneous_path then
|
42
|
+
return Dir.home.gsub( extraneous_path, "" )
|
43
|
+
end
|
44
|
+
|
45
|
+
return Dir.home
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
end
|
data/lib/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opensecret
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.960
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Apollo Akora
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-03-
|
11
|
+
date: 2018-03-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: inifile
|
@@ -99,9 +99,9 @@ files:
|
|
99
99
|
- lib/plugins/cipher.rb
|
100
100
|
- lib/plugins/ciphers/aes-256.rb
|
101
101
|
- lib/plugins/ciphers/blowfish.rb
|
102
|
+
- lib/plugins/coldstore.rb
|
102
103
|
- lib/plugins/envelope.rb
|
103
104
|
- lib/plugins/secrets.uc.rb
|
104
|
-
- lib/plugins/stores/store.rb
|
105
105
|
- lib/plugins/usecase.rb
|
106
106
|
- lib/plugins/usecases/init.rb
|
107
107
|
- lib/plugins/usecases/lock.rb
|
@@ -111,6 +111,7 @@ files:
|
|
111
111
|
- lib/session/attributes.rb
|
112
112
|
- lib/session/dictionary.rb
|
113
113
|
- lib/session/fact.finder.rb
|
114
|
+
- lib/session/file.path.rb
|
114
115
|
- lib/session/require.gem.rb
|
115
116
|
- lib/session/session.rb
|
116
117
|
- lib/session/time.stamp.rb
|
data/lib/plugins/stores/store.rb
DELETED