trocla 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
- ---
2
- SHA512:
3
- data.tar.gz: a56b787f5de6d03d6549ba0ff7a0bd99f33df521d77e3bbdbc22f2b8b55ae0bb8e1011c3a43eb6c7bd067066d8e6ad9837ab0aa87aad97e5e45b0fddc45a88a1
4
- metadata.gz: e33922bae12b243f51cce3508ae7765e75b43f1cad57bd913d01f90a1c6da8ccde41764b186743d62c10eafe8ddc20f01a872fecc0d7f178e16faae4268afc43
5
- SHA1:
6
- data.tar.gz: 52fad21a71a8885e4bd731df9e14200e3c97e08f
7
- metadata.gz: 31e837a767930953bf64f2e724aaa80b2dabfb5c
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5013d3c6ab75dc39bbbb5f7c8a77b19f7b5bed1c
4
+ data.tar.gz: bffc23e9979133c7303c7fde6b4b7a24fe367f8b
5
+ SHA512:
6
+ metadata.gz: 009e2b762c641a8f10be76d673a3860b98cd3dd91a27b77da5d0775c9312da26f454c1c54a039bc9011d25c6c77dd6813b87007e0a71dcab35839fb09d5a3457
7
+ data.tar.gz: e873f4ac50bebf1ab00eddb06b3c9cca0040783a46195391f7064cebba0b2c47648454cef391e20831c405ff6280d2354f249050eb5605452f8e1f3f5becbdc7
data/.travis.yml CHANGED
@@ -1,5 +1,9 @@
1
1
  language: ruby
2
+ sudo: false
2
3
  rvm:
4
+ - jruby-18mode
5
+ - jruby-19mode
6
+ - 2.2.0
3
7
  - 2.1.0
4
8
  - 2.0.0
5
9
  - 1.9.3
data/Gemfile CHANGED
@@ -11,12 +11,14 @@ else
11
11
  gem "highline", "~> 1.6.2"
12
12
  end
13
13
 
14
+ if defined?(RUBY_ENGINE) && (RUBY_ENGINE == 'jruby')
15
+ gem 'jruby-openssl'
16
+ end
14
17
  gem "bcrypt"
15
18
 
16
19
  # Add dependencies to develop your gem here.
17
20
  # Include everything needed to run rake, tests, features, etc.
18
21
  group :development do
19
- gem "mocha"
20
22
  if RUBY_VERSION.to_f > 1.8
21
23
  gem "rspec"
22
24
  gem "rdoc"
@@ -26,4 +28,5 @@ group :development do
26
28
  gem "rdoc", "~> 3.8"
27
29
  gem "jeweler", "~> 1.6"
28
30
  end
31
+ gem 'rspec-pending_for'
29
32
  end
data/README.md CHANGED
@@ -11,21 +11,26 @@ Furthermore it provides you a simple cli that helps you to modify the password
11
11
  storage from the cli.
12
12
 
13
13
  Trocla does not only create and/or store a plain password, it is also able to
14
- generate (and store) any kind hashed passwords based on the plain password.
14
+ generate (and store) any kind of hashed passwords based on the plain password.
15
15
  As long as the plain password is preset, trocla is able to generate any kind
16
16
  of hashed passwords through an easy extendible plugin system.
17
17
 
18
18
  It is not necessary to store the plain password on the server, you can also
19
19
  just feed trocla with the hashed password and use that in your other tools.
20
20
  A common example for that is that you let puppet retrieve (and hence create)
21
- a salted md5 password for a user. This will then store the salted md5 of
21
+ a salted sha512 password for a user. This will then store the salted sha512 of
22
22
  a random password AND the plain text password in trocla. Later you can
23
23
  retrieve (by deleting) the plain password and send it to the user. Puppet
24
24
  will still simply retrieve the hashed password that is stored in trocla,
25
25
  while the plain password is not anymore stored on the server.
26
26
 
27
- You can use any kind of key/value based storage supported by moneta for
28
- trocla. By default it uses a simple yaml file.
27
+ Be default trocla uses moneta to store the passwords and can use any kind of
28
+ key/value based storage supported by moneta for trocla. By default it uses a
29
+ simple yaml file.
30
+ However, since version 0.2.0 trocla also supports a pluggable storage backend
31
+ which allows you to write your custom backend. See more about stores below.
32
+
33
+ Trocla can also be integrated into [Hiera](https://docs.puppetlabs.com/hiera/) by using ZeroPointEnergy's [hiera-backend](https://github.com/ZeroPointEnergy/hiera-backend-trocla).
29
34
 
30
35
  ## Usage
31
36
 
@@ -59,8 +64,11 @@ This will create a pgsql password hash using the username user1.
59
64
 
60
65
  Valid global options are:
61
66
 
62
- * length: int - Define any lenght that a newly created password should have. Default: 12 - or whatever you define in your global settings.
67
+ * length: int - Define any lenght that a newly created password should have. Default: 16 - or whatever you define in your global settings.
63
68
  * charset: (default|alphanumeric|shellsafe) - Which set of chars should be used for a random password? Default: default - or whatever you define in your global settings.
69
+ * profiles: a profile name or an array of profiles matching a profile_name in your configuration. Learn more about profiles below.
70
+ * random: boolean - Whether we allow creation of random passwords or we expect a password to be preset. Default: true - or whatever you define in your global settings.
71
+ * expires: An integer indicating the amount of seconds a value (e.g. password) is available. After expiration a value will not be available anymore and trying to `get` this key will return no value (nil). Meaning that calling create after expiration, would create a new password automatically. There is more about expiration in the storage backends section.
64
72
 
65
73
  Example:
66
74
 
@@ -88,15 +96,22 @@ far.
88
96
  trocla set user3 plain
89
97
 
90
98
  This will ask you for a password and set it under the appropriate key/format.
99
+ We expect a plain password to be entered and will format the password with
100
+ the selected format before storing it.
91
101
 
92
102
  trocla set --password mysupersecretpassword user4 plain
93
103
 
94
104
  This will take the password from the cli without asking you.
95
105
 
96
- trocla set user5 mysql -p *ABC....
106
+ trocla set user5 mysql -p mysuperdbpassword
97
107
 
98
108
  This will store a mysql sha1 hash for the key user5, without storing any kind
99
109
  of plain text password.
110
+ If you like trocla not to format a password, as you are passing in an already
111
+ formatted password (like the sha512 hash), then you must use `--no-format` to
112
+ skip formatting. Like:
113
+
114
+ trocla set user5 sha512crypt --no-format -p '$6$1234$xxxx....'
100
115
 
101
116
  You can also pipe in a password:
102
117
 
@@ -124,37 +139,140 @@ deleted as well, as the hashes wouldn't match anymore the plain text password.
124
139
 
125
140
  This will delete the plain password of the key user1 and return it.
126
141
 
142
+ ### formats
143
+
144
+ trocla formats
145
+
146
+ This will list all available and supported formats.
147
+
127
148
  ## Attention
128
149
 
129
150
  If you don't feed trocla initially with a hash and/or delete the generated
130
151
  plain text passwords trocla will likely create a lot of plain text passwords
131
152
  and store them on your machine/server. This is by intend and is all about which
132
153
  problems (mainly passwords in configuration management manifests) trocla tries
133
- to address.
154
+ to address. It is possible to store all passwords encrypted in the specific
155
+ backend.
156
+ See backend encryption for more information, however be aware that the key must
157
+ always also reside on the trocla node. So it mainly makes sense if you store
158
+ them on a remote backend like a central database server.
159
+
160
+ ## Formats
161
+
162
+ Most formats are straight forward to use. Some formats require some additional
163
+ options to work properly. These are documented here:
164
+
165
+ ### pgsql
166
+
167
+ Password hashes for PostgreSQL servers. Requires the option `username` to be set
168
+ to the username to which the password will be assigned.
169
+
170
+ ### x509
171
+
172
+ This format takes a set of additional options. Required are:
173
+
174
+ subject: A subject for the target certificate. E.g. /C=ZZ/O=Trocla Inc./CN=test/emailAddress=example@example.com
175
+ OR
176
+ CN: The CN of the the target certificate. E.g. 'This is my self-signed certificate which doubles as CA'
177
+
178
+ Additional options are:
179
+
180
+ ca The trocla key of CA (imported into or generated within trocla) that
181
+ will be used to sign that certificate.
182
+ become_ca Whether the certificate should become a CA or not. Default: false,
183
+ to enable set it to true.
184
+ hash Hash to be used. Default sha2
185
+ keysize Keysize for the new key. Default is: 4096
186
+ serial Serial to be used, default is selecting a random one.
187
+ days How many days should the certificate be valid. Default 365
188
+ C instead within the subject string
189
+ ST instead within the subject string
190
+ L instead within the subject string
191
+ O instead within the subject string
192
+ OU instead within the subject string
193
+ emailAddress instead within the subject string
194
+ altnames An array of subjectAltNames. By default for non CA certificates we
195
+ ensure that the CN ends up here as well. If you don't want that.
196
+ You need to pass an empty array.
197
+ name_constraints An array of domains that are added as permitted x509 NameConstraint.
198
+ By default, we do not add any contraint, meaning all domains are
199
+ signable by the CA, as soon as we have one item in the list, only
200
+ DNS entries matching this list are allowed. Be aware, that older
201
+ openssl versions have a bug with [leading dots](https://rt.openssl.org/Ticket/Display.html?id=3562) for name
202
+ constraints. So using them might not work everywhere as expected.
134
203
 
135
204
  ## Installation
136
205
 
137
- Simply build and install the gem.
206
+ Simply build and install the gem.
138
207
 
139
208
  ## Configuration
140
209
 
141
210
  Trocla can be configured in /etc/troclarc.yaml and in ~/.troclarc.yaml. A sample configuration file can be found in `lib/trocla/default_config.yaml`.
211
+ By default trocla configures moneta to store all data in /tmp/trocla.yaml
212
+
213
+ ### Profiles
214
+
215
+ It is possible to define profiles within the configuration file. The idea behind profiles are to make it easy to group together certain options for
216
+ automatic password generation.
217
+
218
+ Trocla ships with a default set of profiles, which are part of the `lib/trocla/default_config.yaml` configuration file. It is possible to override
219
+ the existing profiles within your own configuration file, as well as adding more. Note that the profiles part of the configuration file is merged
220
+ together and your configuration file has precedence.
221
+
222
+ The profiles part in the config is a hash where each entry consist of a name (key) and a hash of options (value).
223
+
224
+ Profiles make it especially easy to define a preset of options for SSL certificates as you will only need to set the certificate specific options,
225
+ while global options such as C, O or OU can be preset within the profile.
226
+
227
+ Profiles are used by setting the profiles option to a name of the pre-configured profiles, when passing options to the password option. On the cli
228
+ this looks like:
229
+
230
+ trocla create foo plain 'profiles: rootpw'
231
+
232
+ It is possible to pass mutliple profiles as an array, while the order will also reflect the precedence of the options.
233
+
234
+ Also it is possible to set a default profiles option in the options part of the configuration file.
142
235
 
143
236
  ### Storage backends
144
237
 
145
- Trocla can store your passwords in all backends supported by moneta. A simple YAML file configuration may look as follows:
238
+ Trocla has a pluggable storage backend, which allows you to choose the way that values are stored (persistently).
239
+ Such a store is a simple class that implements Trocla::Store and at the moment there are the following store implementations:
240
+
241
+ * Moneta - the default store using [moneta](https://rubygems.org/gems/moneta) to delegate storing the values
242
+ * Memory - simple inmemory backend. Mainly used for testing.
243
+
244
+ The backend is chosen based on the `store` configuration option. If it is a symbol, we expect it to be a store that we ship with trocla. Otherwise, we assume it to be a fully qualified ruby class name, that inherits from Trocla::Store. If trocla should load an additional library to be able to find your custom store class, you can set `store_require` to whatever should be passed to a ruby require statement.
245
+
246
+ Store backends can be configured through the `store_options` configuration.
247
+
248
+ #### Expiration
249
+
250
+ We expect storage backends to implement support for the `expires` option, so that keys expire after the passed amount of seconds. Furthermore a storage backend needs to implement the behaviour described by the rspec shared_example 'store_validation' section 'expiration'. Mainly:
251
+
252
+ * Expiration is always for all formats per key.
253
+ * Adding, deleting or updating a format will keep the existing expiration, but reset the planned expiration.
254
+ * While setting a new plain format will not only erase all other formats, but also erase/reset any expires.
255
+ * Setting a value with an expires option of 0 or false, will remove any existent expiration.
256
+
257
+ New backends should be tested using the provided shared example.
258
+
259
+ #### Moneta backends
260
+
261
+ Trocla uses moneta as its default storage backend and hence can store your passwords in any of moneta's supported backends. By default it uses the yaml backend, which is configured as followed:
146
262
 
147
263
  ```YAML
148
- adapter: :YAML
149
- adapter_options:
264
+ store_options:
265
+ adapter: :YAML
266
+ adapter_options:
150
267
  :file: '/tmp/trocla.yaml'
151
268
  ```
152
269
 
153
270
  In environments with multiple Puppet masters using an existing DB cluster might make sense. The configured user needs to be granted at least SELECT, INSERT, UPDATE, DELETE and CREATE permissions on your database:
154
271
 
155
272
  ```YAML
156
- adapter: :Sequel
157
- adapter_options:
273
+ store_options:
274
+ adapter: :Sequel
275
+ adapter_options:
158
276
  :db: 'mysql://db.server.name'
159
277
  :user: 'trocla'
160
278
  :password: '***'
@@ -162,21 +280,50 @@ adapter_options:
162
280
  :table: 'trocla'
163
281
  ```
164
282
 
165
- These examples are by no way complete, moneta has much more to offer.
283
+ These examples are by no way complete, moneta has much more to offer. Please have a look at [moneta's documentation](https://github.com/minad/moneta/blob/master/README.md) for further information.
166
284
 
167
- ### SSL encryption
285
+ ### Backend encryption
168
286
 
169
- You might want to let Trocla encrypt all your passwords
287
+ By default trocla does not encrypt anything it stores. You might want to let Trocla encrypt all your passwords, at the moment the only supported way is SSL.
288
+ Given that often trocla's store is on the same system at it's being used, there might be little sense to encrypt everything while the encryption keys are on the same system. However, if you are for example using an existing DB cluster using backend encryption you won't store any plaintext passwords within the database system.
289
+
290
+ ### Backend SSL encryption
291
+
292
+ To enable SSL encryption (e.g. by using your puppet masters SSL keys), you need to set the following configuration options:
170
293
 
171
294
  ```YAML
172
295
  encryption: :ssl
173
- ssl_options:
296
+ encryption_options:
174
297
  :private_key: '/var/lib/puppet/ssl/private_keys/trocla.pem'
175
298
  :public_key: '/var/lib/puppet/ssl/public_keys/trocla.pem'
176
299
  ```
177
300
 
178
301
  ## Update & Changes
179
302
 
303
+ ### to 0.2.0
304
+
305
+ 1. New feature profiles: Introduce profiles to make it easy to have a default set of properties. See the profiles section for more information.
306
+ 1. New feature expiration: Make it possible that keys can have an expiration. See the expiration section for more information.
307
+ 1. Increase default password length to 16.
308
+ 1. Add a console safe password charset. It should provide a subset of chars that are easier to type on a physical keyboard.
309
+ 1. Fix a bug with encryptions while deleting all formats.
310
+ 1. Introduce pluggable stores, so in the future we are able to talk to different backends and not only moneta. For testing and inspiration a simple in memory storage backend was added.
311
+ 1. CHANGE: moneta's configuration for `adapter` & `adapter_options` now live under store_options in the configuration file. Till 0.3.0 old configuration entries will still be accepted.
312
+ 1. CHANGE: ssl_options is now known as encryption_options. Till 0.3.0 old configuration entries will still be accepted.
313
+ 1. Improve randomness when creating a serial number.
314
+ 1. Add a new charset: hexadecimal
315
+ 1. Add support for name constraints within the x509 format
316
+ 1. Clarify documentation of the set action, as well as introduce `--no-format` for the set action.
317
+
318
+ ### to 0.1.3
319
+
320
+ 1. CHANGE: Self signed certificates are no longer CAs by default, actually they have never been due to a bug. If you want that a certificate is also a CA, you *must* pass `become_ca: true` to the options hash. But this makes it actually possible, that you can even have certificate chains. Thanks for initial hint to [Adrien Bréfort](https://github.com/abrefort)
321
+ 1. Default keysize is now 4096
322
+ 1. SECURITY: Do not increment serial, rather choose a random one.
323
+ 1. Fixing setting of altnames, was not possible due to bug, till now.
324
+ 1. Add extended tests for the x509 format, that describe all the internal specialities and should give an idea how it can be used.
325
+ 1. Add cli option to list all formats
326
+
180
327
  ### to 0.1.1
181
328
 
182
329
  1. fix storing data longer that public Keysize -11. Thanks [Timo Goebel](https://github.com/timogoebel)
data/bin/trocla CHANGED
@@ -9,12 +9,12 @@ require 'yaml'
9
9
  options = { :config_file => nil, :ask_password => true, :trace => false }
10
10
 
11
11
  OptionParser.new do |opts|
12
- opts.on("--version", "-V", "Version information") do
12
+ opts.on('--version', '-V', 'Version information') do
13
13
  puts Trocla::VERSION::STRING
14
14
  exit
15
15
  end
16
16
 
17
- opts.on("--config CONFIG", "-c", "Configuration file") do |v|
17
+ opts.on('--config CONFIG', '-c', 'Configuration file') do |v|
18
18
  if File.exist?(v)
19
19
  options[:config_file] = v
20
20
  else
@@ -23,19 +23,23 @@ OptionParser.new do |opts|
23
23
  end
24
24
  end
25
25
 
26
- opts.on("--trace", "Show stack trace on failure") do
26
+ opts.on('--trace', 'Show stack trace on failure') do
27
27
  options[:trace] = true
28
28
  end
29
29
 
30
- opts.on("--no-random") do
30
+ opts.on('--no-random', 'Do not generate a random password if there is no plain text password available') do
31
31
  options['random'] = false
32
32
  end
33
33
 
34
- opts.on("--length LENGTH") do |v|
34
+ opts.on('--no-format', 'Do not format a password when setting it using `set`') do
35
+ options['no_format'] = true
36
+ end
37
+
38
+ opts.on('--length LENGTH', 'Length for a randomly created password') do |v|
35
39
  options['length'] = v.to_i
36
40
  end
37
41
 
38
- opts.on("--password [PASSWORD]", "-p", "Provide password at command line") do |pass|
42
+ opts.on('--password [PASSWORD]', '-p', 'Provide password at command line or STDIN') do |pass|
39
43
  options[:ask_password] = false
40
44
  options[:password] = pass
41
45
  end
@@ -59,23 +63,29 @@ end
59
63
  def set(options)
60
64
  if options.delete(:ask_password)
61
65
  require 'highline/import'
62
- password = ask("Enter your password: ") { |q| q.echo = "x" }.to_s
63
- pwd2 = ask("Repeat password: ") { |q| q.echo = "x" }.to_s
66
+ password = ask('Enter your password: ') { |q| q.echo = 'x' }.to_s
67
+ pwd2 = ask('Repeat password: ') { |q| q.echo = 'x' }.to_s
64
68
  unless password == pwd2
65
- STDERR.puts "Passwords did not match, exiting!"
69
+ STDERR.puts 'Passwords did not match, exiting!'
66
70
  exit 1
67
71
  end
68
72
  else
69
73
  password = options.delete(:password) || STDIN.read.chomp
70
74
  end
71
75
  format = options.delete(:trocla_format)
76
+ no_format = options.delete('no_format')
72
77
  trocla = Trocla.new(options.delete(:config_file))
78
+ value = if no_format
79
+ password
80
+ else
81
+ trocla.formats(format).format(password, options.delete(:other_options).shift.to_s)
82
+ end
73
83
  trocla.set_password(
74
84
  options.delete(:trocla_key),
75
85
  format,
76
- trocla.formats(format).format(password, options.delete(:other_options).shift.to_s)
86
+ value
77
87
  )
78
- ""
88
+ ''
79
89
  end
80
90
 
81
91
  def reset(options)
@@ -93,9 +103,13 @@ def delete(options)
93
103
  )
94
104
  end
95
105
 
106
+ def formats(options)
107
+ "Available formats: #{Trocla::Formats.all.join(', ')}"
108
+ end
109
+
96
110
  def check_format(format_name)
97
111
  if format_name.nil?
98
- STDERR.puts "Missing format, exiting..."
112
+ STDERR.puts 'Missing format, exiting...'
99
113
  exit 1
100
114
  elsif !Trocla::Formats.available?(format_name)
101
115
  STDERR.puts "Error: The format #{format_name} is not available"
@@ -103,13 +117,13 @@ def check_format(format_name)
103
117
  end
104
118
  end
105
119
 
106
- actions=['create','get','set','reset','delete']
120
+ actions=['create','get','set','reset','delete', 'formats' ]
107
121
 
108
- if !(ARGV.length < 2) && (action=ARGV.shift) && actions.include?(action)
122
+ if (action=ARGV.shift) && actions.include?(action)
109
123
  options[:trocla_key] = ARGV.shift
110
124
  options[:trocla_format] = ARGV.shift
111
125
  options[:other_options] = ARGV
112
- check_format(options[:trocla_format]) unless action == 'delete'
126
+ check_format(options[:trocla_format]) unless ['delete','formats'].include?(action)
113
127
  begin
114
128
  if result = send(action,options)
115
129
  puts result.is_a?(String) ? result : result.inspect
@@ -117,13 +131,14 @@ if !(ARGV.length < 2) && (action=ARGV.shift) && actions.include?(action)
117
131
  rescue Exception => e
118
132
  unless e.message == 'exit'
119
133
  STDERR.puts "Action failed with the following message: #{e.message}"
120
- STDERR.puts "(See full trace by running task with --trace)"
134
+ STDERR.puts '(See full trace by running task with --trace)'
121
135
  end
122
136
  raise e if options[:trace]
123
137
  exit 1
124
138
  end
125
139
  else
126
140
  STDERR.puts "Please supply one of the following actions: #{actions.join(', ')}"
141
+ STDERR.puts "Use #{$0} --help to get a list of options for these actions"
127
142
  exit 1
128
143
  end
129
144
 
data/lib/VERSION CHANGED
@@ -1,4 +1,4 @@
1
1
  major:0
2
- minor:1
3
- patch:2
2
+ minor:2
3
+ patch:0
4
4
  build: