opensecret 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e0d63e217092bc721ad94dfb5ae966875a9fd17d
4
- data.tar.gz: 87eff49362703bb87775686c8976398deeeb80f3
3
+ metadata.gz: 9bc4bfc60cbda290f4cac72f199f16c7edeee9f7
4
+ data.tar.gz: 5b901aaa8a3d2db04a48bb1244bf9e305e7ab2a6
5
5
  SHA512:
6
- metadata.gz: 66f8e8cc37da72a39d075b0e89e7786e4d6499212e165c60b8e66ad014418c8905277e478c743d4f138ee3d5396c30e52afa7f165cf3763c82e8540220efca66
7
- data.tar.gz: 467e06826f0d175f88f50510da1f6c5c9dca4e5025c3da0f354bb29da5cef6277a8ef58fa92bd47090ab0f25ae2b3a2b5d6de06f99ff4b16147234b5be5ec687
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
- # -- Create dynamic secrets of various flavours including
5
- # --
6
- # -- - ssh public/private key secrets
7
- # -- - secret keys for internal database services
8
- # -- - hashed SHA256 keys for Jenkins user auth
9
- # --
10
- class Crypto
11
-
12
- # --
13
- # -- Get a viable machine password taking into account the human
14
- # -- password length and the specified mix_ratio.
15
- # --
16
- # -- machine password length = human password length * mix_ratio - 1
17
- # --
18
- def self.get_amalgam_password human_password, machine_password, mix_ratio
19
-
20
- size_error_msg = "Human pass length times mix_ratio must equal machine pass length."
21
- lengths_are_perfect = human_password.length * mix_ratio == machine_password.length
22
- raise ArgumentError.new size_error_msg unless lengths_are_perfect
23
-
24
- machine_passwd_chunk = 0
25
- amalgam_passwd_index = 0
26
- amalgamated_password = ""
27
-
28
- human_password.each_char do |passwd_char|
29
-
30
- amalgamated_password[amalgam_passwd_index] = passwd_char
31
- amalgam_passwd_index += 1
32
-
33
- for i in 0..(mix_ratio-1) do
34
- machine_pass_index = machine_passwd_chunk * mix_ratio + i
35
- amalgamated_password[amalgam_passwd_index] = machine_password[machine_pass_index]
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
- machine_passwd_chunk += 1
70
+ return amalgamated_password
40
71
 
41
72
  end
42
73
 
43
- return amalgamated_password
44
74
 
45
- end
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
- # -- Get a viable machine password taking into account the human
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
- machine_raw_secret = engineer_password( human_password_length * ( mix_ratio + 1) )
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
- assert_min_size minimum_size
100
+ sleep(1)
101
+ puts "\n#{prompt_1} : "
102
+ first_secret = STDIN.noecho(&:gets).chomp
71
103
 
72
- sleep(1)
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
- assert_input_text_size first_secret.length, minimum_size
106
+ sleep(1)
107
+ puts "\n#{prompt_2} : "
108
+ check_secret = STDIN.noecho(&:gets).chomp
77
109
 
78
- sleep(1)
79
- puts "\n#{prompt_2} : "
80
- check_secret = STDIN.noecho(&:gets).chomp
110
+ assert_same_size_text first_secret, check_secret
111
+
112
+ return first_secret
81
113
 
82
- assert_same_size_text first_secret, check_secret
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
- # -- Engineer a raw password that is similar (approximate) in
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
- non_alphanum = SecureRandom.urlsafe_base64(approx_length);
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
- # -- Raise an exception if asked to collect text that is less
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
- min_length_msg = "\n\nCrypts with 2 (or less) characters open up exploitable holes.\n\n"
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
- if( input_size < minimum_size )
149
+ puts
150
+ puts "Input is too short. Please enter at least #{minimum_size} characters."
151
+ puts
120
152
 
121
- puts
122
- puts "Input is too short. Please enter at least #{minimum_size} characters."
123
- puts
153
+ exit
124
154
 
125
- exit
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
- # -- Assert that the text entered the second time is exactly (case sensitive)
134
- # -- the same as the text entered the first time.
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
- puts
141
- puts "Those two bits of text are not the same (in my book)!"
142
- puts
172
+ exit
143
173
 
144
- exit
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
- machine_to_env_txt = "sudo echo \"#{env_var_name}=#{env_var_value}\" >> /etc/environment"
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
- puts
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
@@ -1,3 +1,3 @@
1
1
  module OpenSecret
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
data/lib/opensecret.rb CHANGED
@@ -1,13 +1,42 @@
1
1
  require "opensecret/version"
2
2
  require "thor"
3
3
 
4
- module OpenSecret
5
-
6
-
7
- end
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
- # This command line processor will
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
- # opensecret init lecturers@cambridge.university
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 &raquo; **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
- desc "init DOMAIN", "DOMAIN identifies your team, friends, family or business."
26
- def init( domain )
76
+ OpenSecret::Crypto.register_domain domain, store_url
27
77
 
28
- puts "You want to create the #{domain} domain.\n"
29
- return "goodbye"
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
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/opensecret-domain.ini
102
+ - lib/config.openkey.ini
103
103
  - lib/opensecret.rb
104
104
  - lib/opensecret/additions/array.rb
105
105
  - lib/opensecret/additions/dir.rb
@@ -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
-