opensecret 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/config.openkey.ini +14 -0
- data/lib/opensecret/plugins.io/cipher/crypto.rb +152 -123
- data/lib/opensecret/version.rb +1 -1
- data/lib/opensecret.rb +63 -11
- metadata +2 -2
- data/lib/opensecret-domain.ini +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9bc4bfc60cbda290f4cac72f199f16c7edeee9f7
|
4
|
+
data.tar.gz: 5b901aaa8a3d2db04a48bb1244bf9e305e7ab2a6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2e246d8520e068d0dace4ec48221d0cc2a2fbd761e8c06924759912e24e1e9afbdb433e56b1a132983966c178b3ae79fa30ded31fa9e57d287c4d9cf50d844d3
|
7
|
+
data.tar.gz: 8b0cee1a18cb39cfce967b73dd091630d6f8ac923b7d60978a1d61970d157a41f67be672653c19798e25dd3a306002a385ba19a47940e193552665373cffcf5b
|
@@ -0,0 +1,14 @@
|
|
1
|
+
|
2
|
+
[joebloggs@openkey.com]
|
3
|
+
type=user
|
4
|
+
id=joe
|
5
|
+
keydir=/media/usb-key/secrets
|
6
|
+
fingerprint=23423x123123
|
7
|
+
public.key.signature=13242345dfg
|
8
|
+
|
9
|
+
[blues.band.bloggs]
|
10
|
+
type=domain
|
11
|
+
members = { pete => "peterpan@simple.com", fx => "admin@fortknox.com" }
|
12
|
+
fingerprints = { pete => "x1234ljsdf", fx => "asdfasd1234" }
|
13
|
+
store.url=https://www.github.com/joes.hub.account
|
14
|
+
|
@@ -1,174 +1,203 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
3
|
+
module OpenSecret
|
4
|
+
|
5
|
+
#
|
6
|
+
# Create dynamic secrets of various flavours including
|
7
|
+
#
|
8
|
+
# - ssh public/private key secrets
|
9
|
+
# - secret keys for internal database services
|
10
|
+
# - hashed SHA256 keys for Jenkins user auth
|
11
|
+
#
|
12
|
+
class Crypto
|
13
|
+
|
14
|
+
|
15
|
+
# Register two fundamental openkey crypt pointers
|
16
|
+
#
|
17
|
+
# - an openkey domain like » **lecturers@harvard**
|
18
|
+
# - the url to a backend store like Git, S3 or an SSH accessible drive.
|
19
|
+
#
|
20
|
+
# The domain will be extended to cover verified internet domains.
|
21
|
+
# They will also latch onto LDAP domains so when admins add, revoke
|
22
|
+
# or remove users, their openkey access is adjusted accordingly.
|
23
|
+
#
|
24
|
+
# @param domain [String] the DOMAIN eg lecturers@harvard for your family or work group.
|
25
|
+
# @param store_url [String] the STORE_URL for connecting to the backend storage service
|
26
|
+
#
|
27
|
+
def self.register_domain domain, store_url
|
28
|
+
|
29
|
+
# -> read config file map
|
30
|
+
# -> create new domain in map
|
31
|
+
# -> add type and store url to map
|
32
|
+
# -> backup configuration
|
33
|
+
# -> overwrite the ini config file
|
34
|
+
puts "hello i am registering this super domain #{domain} at #{store_url}"
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
# --
|
40
|
+
# -- Get a viable machine password taking into account the human
|
41
|
+
# -- password length and the specified mix_ratio.
|
42
|
+
# --
|
43
|
+
# -- machine password length = human password length * mix_ratio - 1
|
44
|
+
# --
|
45
|
+
def self.get_amalgam_password human_password, machine_password, mix_ratio
|
46
|
+
|
47
|
+
size_error_msg = "Human pass length times mix_ratio must equal machine pass length."
|
48
|
+
lengths_are_perfect = human_password.length * mix_ratio == machine_password.length
|
49
|
+
raise ArgumentError.new size_error_msg unless lengths_are_perfect
|
50
|
+
|
51
|
+
machine_passwd_chunk = 0
|
52
|
+
amalgam_passwd_index = 0
|
53
|
+
amalgamated_password = ""
|
54
|
+
|
55
|
+
human_password.each_char do |passwd_char|
|
56
|
+
|
57
|
+
amalgamated_password[amalgam_passwd_index] = passwd_char
|
36
58
|
amalgam_passwd_index += 1
|
59
|
+
|
60
|
+
for i in 0..(mix_ratio-1) do
|
61
|
+
machine_pass_index = machine_passwd_chunk * mix_ratio + i
|
62
|
+
amalgamated_password[amalgam_passwd_index] = machine_password[machine_pass_index]
|
63
|
+
amalgam_passwd_index += 1
|
64
|
+
end
|
65
|
+
|
66
|
+
machine_passwd_chunk += 1
|
67
|
+
|
37
68
|
end
|
38
69
|
|
39
|
-
|
70
|
+
return amalgamated_password
|
40
71
|
|
41
72
|
end
|
42
73
|
|
43
|
-
return amalgamated_password
|
44
74
|
|
45
|
-
|
75
|
+
# --
|
76
|
+
# -- Get a viable machine password taking into account the human
|
77
|
+
# -- password length and the specified mix_ratio.
|
78
|
+
# --
|
79
|
+
# -- machine password length = human password length * mix_ratio - 1
|
80
|
+
# --
|
81
|
+
def self.get_machine_password human_password_length, mix_ratio
|
46
82
|
|
47
|
-
|
48
|
-
|
49
|
-
# -- password length and the specified mix_ratio.
|
50
|
-
# --
|
51
|
-
# -- machine password length = human password length * mix_ratio - 1
|
52
|
-
# --
|
53
|
-
def self.get_machine_password human_password_length, mix_ratio
|
83
|
+
machine_raw_secret = engineer_password( human_password_length * ( mix_ratio + 1) )
|
84
|
+
return machine_raw_secret[ 0..( human_password_length * mix_ratio - 1 ) ]
|
54
85
|
|
55
|
-
|
56
|
-
return machine_raw_secret[ 0..( human_password_length * mix_ratio - 1 ) ]
|
86
|
+
end
|
57
87
|
|
58
|
-
end
|
59
88
|
|
89
|
+
# --
|
90
|
+
# -- Collect a password from the user with a minimum length
|
91
|
+
# -- specified in the parameter.
|
92
|
+
# --
|
93
|
+
# -- An exception is raised if the minimum length is not at
|
94
|
+
# -- least 8 characters.
|
95
|
+
# --
|
96
|
+
def self.collect_secret minimum_size, prompt_1, prompt_2
|
60
97
|
|
61
|
-
|
62
|
-
# -- Collect a password from the user with a minimum length
|
63
|
-
# -- specified in the parameter.
|
64
|
-
# --
|
65
|
-
# -- An exception is raised if the minimum length is not at
|
66
|
-
# -- least 8 characters.
|
67
|
-
# --
|
68
|
-
def self.collect_secret minimum_size, prompt_1, prompt_2
|
98
|
+
assert_min_size minimum_size
|
69
99
|
|
70
|
-
|
100
|
+
sleep(1)
|
101
|
+
puts "\n#{prompt_1} : "
|
102
|
+
first_secret = STDIN.noecho(&:gets).chomp
|
71
103
|
|
72
|
-
|
73
|
-
puts "\n#{prompt_1} : "
|
74
|
-
first_secret = STDIN.noecho(&:gets).chomp
|
104
|
+
assert_input_text_size first_secret.length, minimum_size
|
75
105
|
|
76
|
-
|
106
|
+
sleep(1)
|
107
|
+
puts "\n#{prompt_2} : "
|
108
|
+
check_secret = STDIN.noecho(&:gets).chomp
|
77
109
|
|
78
|
-
|
79
|
-
|
80
|
-
|
110
|
+
assert_same_size_text first_secret, check_secret
|
111
|
+
|
112
|
+
return first_secret
|
81
113
|
|
82
|
-
|
83
|
-
|
84
|
-
return first_secret
|
114
|
+
end
|
85
115
|
|
86
|
-
end
|
87
116
|
|
117
|
+
# --
|
118
|
+
# -- Engineer a raw password that is similar (approximate) in
|
119
|
+
# -- length to the integer parameter.
|
120
|
+
# --
|
121
|
+
def self.engineer_password approx_length
|
88
122
|
|
89
|
-
|
90
|
-
|
91
|
-
# -- length to the integer parameter.
|
92
|
-
# --
|
93
|
-
def self.engineer_password approx_length
|
123
|
+
non_alphanum = SecureRandom.urlsafe_base64(approx_length);
|
124
|
+
return non_alphanum.delete("-_")
|
94
125
|
|
95
|
-
|
96
|
-
return non_alphanum.delete("-_")
|
126
|
+
end
|
97
127
|
|
98
|
-
end
|
99
128
|
|
129
|
+
# --
|
130
|
+
# -- Raise an exception if asked to collect text that is less
|
131
|
+
# -- than 3 characters in length.
|
132
|
+
# --
|
133
|
+
def self.assert_min_size minimum_size
|
100
134
|
|
101
|
-
|
102
|
-
|
103
|
-
# -- than 3 characters in length.
|
104
|
-
# --
|
105
|
-
def self.assert_min_size minimum_size
|
135
|
+
min_length_msg = "\n\nCrypts with 2 (or less) characters open up exploitable holes.\n\n"
|
136
|
+
raise ArgumentError.new min_length_msg if minimum_size < 3
|
106
137
|
|
107
|
-
|
108
|
-
raise ArgumentError.new min_length_msg if minimum_size < 3
|
138
|
+
end
|
109
139
|
|
110
|
-
end
|
111
140
|
|
141
|
+
# --
|
142
|
+
# -- Output an error message and then exit if the entered input
|
143
|
+
# -- text size does not meet the minimum requirements.
|
144
|
+
# --
|
145
|
+
def self.assert_input_text_size input_size, minimum_size
|
112
146
|
|
113
|
-
|
114
|
-
# -- Output an error message and then exit if the entered input
|
115
|
-
# -- text size does not meet the minimum requirements.
|
116
|
-
# --
|
117
|
-
def self.assert_input_text_size input_size, minimum_size
|
147
|
+
if( input_size < minimum_size )
|
118
148
|
|
119
|
-
|
149
|
+
puts
|
150
|
+
puts "Input is too short. Please enter at least #{minimum_size} characters."
|
151
|
+
puts
|
120
152
|
|
121
|
-
|
122
|
-
puts "Input is too short. Please enter at least #{minimum_size} characters."
|
123
|
-
puts
|
153
|
+
exit
|
124
154
|
|
125
|
-
|
155
|
+
end
|
126
156
|
|
127
157
|
end
|
128
158
|
|
129
|
-
end
|
130
159
|
|
160
|
+
# --
|
161
|
+
# -- Assert that the text entered the second time is exactly (case sensitive)
|
162
|
+
# -- the same as the text entered the first time.
|
163
|
+
# --
|
164
|
+
def self.assert_same_size_text first_text, second_text
|
165
|
+
|
166
|
+
unless( first_text.eql? second_text )
|
131
167
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
# --
|
136
|
-
def self.assert_same_size_text first_text, second_text
|
137
|
-
|
138
|
-
unless( first_text.eql? second_text )
|
168
|
+
puts
|
169
|
+
puts "Those two bits of text are not the same (in my book)!"
|
170
|
+
puts
|
139
171
|
|
140
|
-
|
141
|
-
puts "Those two bits of text are not the same (in my book)!"
|
142
|
-
puts
|
172
|
+
exit
|
143
173
|
|
144
|
-
|
174
|
+
end
|
145
175
|
|
146
176
|
end
|
147
177
|
|
148
|
-
end
|
149
178
|
|
179
|
+
# --
|
180
|
+
# -- Print out the machine password that is to be kept as an environment variable
|
181
|
+
# -- on any workstation used for material decryption.
|
182
|
+
# --
|
183
|
+
# -- Remember that neither the human nor machine passwords are required for the
|
184
|
+
# -- encryption phase. That is the beauty of assymetric cryptography - you don't
|
185
|
+
# -- need a private key to encrypt - just the end user's public key.
|
186
|
+
# --
|
187
|
+
def self.print_secret_env_var env_var_name, env_var_value
|
150
188
|
|
151
|
-
|
152
|
-
# -- Print out the machine password that is to be kept as an environment variable
|
153
|
-
# -- on any workstation used for material decryption.
|
154
|
-
# --
|
155
|
-
# -- Remember that neither the human nor machine passwords are required for the
|
156
|
-
# -- encryption phase. That is the beauty of assymetric cryptography - you don't
|
157
|
-
# -- need a private key to encrypt - just the end user's public key.
|
158
|
-
# --
|
159
|
-
def self.print_secret_env_var env_var_name, env_var_value
|
189
|
+
machine_to_env_txt = "sudo echo \"#{env_var_name}=#{env_var_value}\" >> /etc/environment"
|
160
190
|
|
161
|
-
|
191
|
+
puts
|
192
|
+
puts "@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
|
193
|
+
puts "@@@ Add as environment variable @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
|
194
|
+
puts "@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
|
195
|
+
puts machine_to_env_txt
|
196
|
+
puts "@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
|
197
|
+
puts
|
162
198
|
|
163
|
-
|
164
|
-
puts "@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
|
165
|
-
puts "@@@ Add as environment variable @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
|
166
|
-
puts "@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
|
167
|
-
puts machine_to_env_txt
|
168
|
-
puts "@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
|
169
|
-
puts
|
199
|
+
end
|
170
200
|
|
171
201
|
end
|
172
202
|
|
173
|
-
|
174
203
|
end
|
data/lib/opensecret/version.rb
CHANGED
data/lib/opensecret.rb
CHANGED
@@ -1,13 +1,42 @@
|
|
1
1
|
require "opensecret/version"
|
2
2
|
require "thor"
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
# # How domains are joined?
|
5
|
+
#
|
6
|
+
# First the user **wishing to join* must be able to access the domain shared
|
7
|
+
# **backend storage** system. The planned list of supported storage systems (each of
|
8
|
+
# which is on-lined with a plugin (in plugins.io) is
|
9
|
+
#
|
10
|
+
# - Git (including GitHub, GitLab, BitBucket, OpenGit and private Git installations).
|
11
|
+
# - S3 Buckets from the Amazon Web Services (AWS) cloud.
|
12
|
+
# - SSH, SCP, SFTP connected file-systems
|
13
|
+
# - network storage including Samba, NFS, VMWare vSAN
|
14
|
+
# - GoogleDrive (only Windows has suitable synchronized support).
|
15
|
+
# - DropBox
|
16
|
+
#
|
17
|
+
# Access management is configured EXTERNAL to openkey. OpenKey simply piggybacks
|
18
|
+
# the network transport if authorization is granted.
|
9
19
|
#
|
10
|
-
#
|
20
|
+
# ## Use Case - Joining a Domain
|
21
|
+
#
|
22
|
+
# - ok will loop encrypting your public key's fingerprint with the public keys of present members
|
23
|
+
# - when they interact ok will ask if they trust the new id/email and key
|
24
|
+
# - if they say yes the fingerprint is imported and held with id/name
|
25
|
+
# - ongoing domainwide checks flag up public key / fingerprint mismatches
|
26
|
+
# - if keys are removed or updated similar questions are asked.
|
27
|
+
#
|
28
|
+
# # Begging for and Revealing Secrets
|
29
|
+
#
|
30
|
+
# - Why beg for a secret - why not just tell someone it?
|
31
|
+
# - It is much more secure to beg for a secret than just have someone reveal it.
|
32
|
+
# - When you beg for a secret - you are sending an encryption key to a single person
|
33
|
+
# - who must possess the private key and they send back the secret encrypted with both
|
34
|
+
# - your specific public key and the encryption key that originated from you.
|
35
|
+
# -
|
36
|
+
# - Any hijacker will need access to a great many things and be very precise with their
|
37
|
+
# - timing in order to serrupticiously subvert the system.
|
38
|
+
#
|
39
|
+
# ### This command line processor will
|
11
40
|
#
|
12
41
|
# - read the posted commands, options and switches
|
13
42
|
# - maps the incoming string data to objects
|
@@ -18,15 +47,38 @@ end
|
|
18
47
|
#
|
19
48
|
# @note the Thor ruby gem is used for the heavy lifting
|
20
49
|
#
|
50
|
+
# @example openkey initdomain create friends.joebloggs --secure
|
51
|
+
# @example openkey user create id=joe email=joebloggs@openkey.com
|
52
|
+
# @example openkey user create id=joe email=joebloggs@openkey.com
|
53
|
+
#
|
54
|
+
#
|
21
55
|
class CommandProcessor < Thor
|
22
56
|
|
23
|
-
|
57
|
+
desc "init DOMAIN", "DOMAIN eg lecturers@harvard names your friends, family or work group."
|
58
|
+
desc "init STORE_URL", "STORE_URL is backend Git/S3/SSH crypt store. Use https://www.eco-platform.co.uk/crypt.store.git"
|
59
|
+
|
60
|
+
# Initialize (configure) two fundamental crypt pointers
|
61
|
+
#
|
62
|
+
# - an openkey domain like » **lecturers@harvard**
|
63
|
+
# - the url to a backend store like Git, S3 or an SSH accessible drive.
|
64
|
+
#
|
65
|
+
# The domain will be extended to cover verified internet domains.
|
66
|
+
# They will also latch onto LDAP domains so when admins add, revoke
|
67
|
+
# or remove users, their openkey access is adjusted accordingly.
|
68
|
+
#
|
69
|
+
# @example openkey user create id=joe email=joebloggs@openkey.com
|
70
|
+
#
|
71
|
+
# @param domain [String] the DOMAIN eg lecturers@harvard for your family or work group.
|
72
|
+
# @param store_url [String] the STORE_URL for connecting to the backend storage service
|
73
|
+
#
|
74
|
+
def init domain, store_url
|
24
75
|
|
25
|
-
|
26
|
-
def init( domain )
|
76
|
+
OpenSecret::Crypto.register_domain domain, store_url
|
27
77
|
|
28
|
-
puts "
|
29
|
-
|
78
|
+
puts ""
|
79
|
+
puts "New domain configured => [ #{domain} ]"
|
80
|
+
puts "Crypt store configured => [ #{store_url} ]"
|
81
|
+
puts ""
|
30
82
|
|
31
83
|
end
|
32
84
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
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.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Apollo Akora
|
@@ -99,7 +99,7 @@ files:
|
|
99
99
|
- README.md
|
100
100
|
- Rakefile
|
101
101
|
- bin/opensecret
|
102
|
-
- lib/
|
102
|
+
- lib/config.openkey.ini
|
103
103
|
- lib/opensecret.rb
|
104
104
|
- lib/opensecret/additions/array.rb
|
105
105
|
- lib/opensecret/additions/dir.rb
|
data/lib/opensecret-domain.ini
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
opensecret configure mode="secure"
|
7
|
-
opensecret configure mode="secure"
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
[@[os|domain.id]]
|
13
|
-
|
14
|
-
secrecy = play # Options are play | secure | enterprise see website for details.
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
[people]
|
19
|
-
|
20
|
-
jack = jackhiggins@blueyonder.com
|
21
|
-
gaz = gareth.southgate@gmail.com
|
22
|
-
jiji = johnjames23@yahoo.co.uk
|
23
|
-
|