autosign 0.0.7 → 0.0.8

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,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YWFiZDhhNDExMzllMTRiNTMxMjYzZjNjNjljYzQ1MjdjNjc3NGM2MQ==
4
+ YTQ1YWExMWZhOTA2OGYzN2NmODBjOGRhNjAxY2NkMTdhZDQ4ZTliNQ==
5
5
  data.tar.gz: !binary |-
6
- Mzk0ZmVhNWNlNDg1Y2FjYmE0N2RjY2EzOTIyOTUyOWYzODk3NTgwOQ==
6
+ ZDNlZmY2YjcxMDY0ODZjMDM0ZDFkNzNhNGI5Zjk0NDMxZDgxMTc3Yw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MmZmZTA5YmE2ZjM4NjY3ZTdlZTNkMjhiMTllNDczNWU4MTYzNWZmMDc4MjI0
10
- ODhlZjE1YjUyZWYxNTU4ZDA1YzQ4Y2EyNGY1OGRiNjVjNzlhOGExN2M1ODZj
11
- Mzk5YzhkZWY2NGNhMTc0M2QwNGU4ZTMwZWIyOGUwMjQyZWVmNWE=
9
+ NTlkZDVhZDY3OWE5Mzk4YmQyMjVjYzg0OTI1Y2U3ZDU3ZjJkYjYzOTIzZDQz
10
+ Mzg2NjI0MGVkNDA2ZTcwMTk3MjNhODIyZjU0NzMxNGU0MDIyY2VmMDkyOWI3
11
+ MDI4OTE2OTg5NWMwYTM2NjdkMTYyN2JlZGRmZDY1YjY4NjY3ZDk=
12
12
  data.tar.gz: !binary |-
13
- MTJhNzI0NzM5NDYwMjVmOWU5MGI0NzIwODI5NDgwMGMwODlkNTY1NzRkZTcz
14
- NWE3ODdiNjY5NzdlYzU4MzVmNDg1YzgyODc3MzA4NTBkMjVmMmYwZGRlOGRh
15
- ZDQzYjYxZTFjMjY1NzViMmM5YmQ4YTBhYzViZTExMzA2YWY3YWM=
13
+ YWI5ZTQzNzljNGU3NWUzMjJmMmU2ZTM1OTlkNWEwZjhjNzBjYTI5MWExZmIx
14
+ NWUxNjg0N2ZjMTE2ZTIxNTM5ZDBlNGQxOTkxYjZlMWVhYjQ2YjcyOGFlNjBj
15
+ MThhYmY2MmVjYWE0ZmNkMDJiMDM2ZTlkNzQxNTYyNzcxYmE3M2U=
data/.gitignore CHANGED
@@ -3,3 +3,5 @@ doc
3
3
  .vagrant
4
4
  .yardoc
5
5
  autosign.conf
6
+ results.html
7
+ coverage/
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- autosign (0.0.7)
4
+ autosign (0.0.8)
5
5
  deep_merge (~> 1)
6
6
  gli (~> 2)
7
7
  iniparse (~> 1)
@@ -9,6 +9,7 @@ PATH
9
9
  jwt (~> 1)
10
10
  logging (~> 2)
11
11
  require_all (~> 1)
12
+ safe_yaml (~> 1)
12
13
  yard (~> 0.8)
13
14
 
14
15
  GEM
@@ -91,6 +92,7 @@ GEM
91
92
  diff-lcs (>= 1.2.0, < 2.0)
92
93
  rspec-support (~> 3.3.0)
93
94
  rspec-support (3.3.0)
95
+ safe_yaml (1.0.4)
94
96
  simplecov (0.10.0)
95
97
  docile (~> 1.1.0)
96
98
  json (~> 1.8)
data/README.md CHANGED
@@ -6,3 +6,93 @@ Tooling to make puppet autosigning easy, secure, and extensible
6
6
  ### Introduction
7
7
 
8
8
  This tool provides a CLI for performing puppet policy-based autosigning using JWT tokens. Read more at https://danieldreier.github.io/autosign.
9
+
10
+ ### Quick Start: How to Generate Tokens
11
+
12
+ ##### 1. Install Gem on Puppet Master
13
+ ```shell
14
+ gem install autosign
15
+ ```
16
+
17
+ ##### 2. Generate default configuration
18
+
19
+ ```shell
20
+ autosign config setup
21
+ ```
22
+
23
+ ##### 3. Generate your first autosign token on the puppet master
24
+ ```shell
25
+ autosign generate foo.example.com
26
+ ```
27
+
28
+ The output will look something like
29
+ ```
30
+ Autosign token for: foo.example.com, valid until: 2015-07-16 16:25:50 -0700
31
+ To use the token, put the following in ${puppet_confdir}/csr_attributes.yaml prior to running puppet agent for the first time:
32
+
33
+ custom_attributes:
34
+ challengePassword: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJkYXRhIjoie1wiY2VydG5hbWVcIjpcImZvby5leGFtcGxlLmNvbVwiLFwicmVxdWVzdGVyXCI6XCJEYW5pZWxzLU1hY0Jvb2stUHJvLTIubG9jYWxcIixcInJldXNhYmxlXCI6ZmFsc2UsXCJ2YWxpZGZvclwiOjcyMDAsXCJ1dWlkXCI6XCJkM2YyNzI0OC1jZDFmLTRhZmItYjI0MC02ZjBjMDU4NWJiZDNcIn0iLCJleHAiOiIxNDM3MDg5MTUwIn0.lC-EzWaV2dL81aLL7P-9mGwNbiOQDJWcoYjuSHVOqmaLtc7Wis5OZvHFOLln2Fn9qv98oSTnZsIkjmFpbI5dvA"
35
+ ```
36
+
37
+ The resulting output can be copied to `/etc/puppet/csr_attributes.yaml` on an agent machine prior to running puppet for the first time to add the token to the CSR as the `challengePassword` OID. (just copy-paste from one terminal to another to copy the text)
38
+
39
+ ### Quick Start: Puppet Master Configuration
40
+
41
+ Run through the previous quick start steps to get the gem installed, then configure puppet to use the `autosign-validator` executable as the policy autosign command:
42
+
43
+ ##### 1. Prerequisities
44
+ Note that these settings will be slightly different if you're running Puppet Enterprise, because you'll need to use the `pe-puppet` user instead of `puppet`.
45
+
46
+ ```shell
47
+ mkdir /var/autosign
48
+ chown puppet:puppet /var/autosign
49
+ chmod 750 /var/autosign
50
+ touch /var/log/autosign.log
51
+ chown puppet:puppet /var/log/autosign.log
52
+ ```
53
+
54
+
55
+ ##### 2. Configure master
56
+ ```shell
57
+ puppet config set autosign $(which autosign-validator) --section master
58
+ ```
59
+
60
+ Your master is now configured to autosign using the autosign gem.
61
+
62
+
63
+ ##### 3. Using Legacy Autosign Scripts
64
+
65
+ If you already had an autosign script you want to continue using, add a setting to your `autosign.conf` like:
66
+
67
+ ```yaml
68
+ multiplexer:
69
+ external_policy_executable: "/path/to/autosign/executable"
70
+ ```
71
+
72
+ The master will validate the certificate if either the token validator or the external validator succeeds.
73
+
74
+ If the autosign script was just validating simple strings, you can use the `password_list` validator instead. For example, to configure the master to sign any CSR that includes the challenge passwords of "hunter2" or "CPE1704TKS" you would add:
75
+
76
+ ```ini
77
+ password_list:
78
+ password: "hunter2"
79
+ password: "CPE1704TKS"
80
+ ```
81
+
82
+ Note that this is a relatively insecure way to do certificate autosigning. Using one-time tokens via the `autosign generate` command is more secure. This functionality is provided to grandfather in existing use cases to ease the transition.
83
+
84
+
85
+ ### Troubleshooting
86
+ If you're having problems, try the following:
87
+
88
+ - Set `loglevel: "debug"` in `/etc/autosign.conf`
89
+ - Check the `journalfile`, in `/var/autosign/autosign.journal` by default, to see if the one-time token's UUID has already been recorded. It's just YAML, so you can either delete it or remove the offending entry if you actually want to re-use a token.
90
+ - you can manually trigger the autosigning script with something like `cat the_csr.csr | autosign-validator certname.example.com`
91
+ - If you run the puppet master foregrounded, you'll see quite a bit of autosign script output if autosign loglevel is set to debug.
92
+
93
+
94
+ ### Further Reading
95
+
96
+ - [https://danieldreier.github.io/autosign](https://danieldreier.github.io/autosign) has background on why this exists.
97
+ - Automatically generated code documentation in YARDOC format is [available on rubydoc.info](http://rubydoc.info/github/danieldreier/autosign).
98
+ - Look at the [puppet-autosign](https://travis-ci.org/danieldreier/puppet-autosign) puppet module to automate setup of this tool, and for a puppet function to generate tokens inside of Puppet, for example when provisioning systems in AWS.
data/autosign.gemspec CHANGED
@@ -31,4 +31,5 @@ spec = Gem::Specification.new do |s|
31
31
  s.add_runtime_dependency('deep_merge', '~> 1')
32
32
  s.add_runtime_dependency('require_all', '~> 1')
33
33
  s.add_runtime_dependency('yard', '~> 0.8')
34
+ s.add_runtime_dependency('safe_yaml', '~> 1')
34
35
  end
@@ -8,9 +8,10 @@ Feature: Generate autosign key
8
8
  And a hostname of "foo.example.com"
9
9
  And a file named "autosign.conf" with:
10
10
  """
11
- [jwt_token]
12
- validity = 7200
13
- secret = secret
11
+ ---
12
+ jwt_token:
13
+ validity: '7200'
14
+ secret: 'secret'
14
15
  """
15
16
  When I run `chmod 600 autosign.conf`
16
17
  And I run `autosign --config autosign.conf generate foo.example.com`
@@ -23,9 +24,10 @@ Feature: Generate autosign key
23
24
  And a hostname of "foo.example.com"
24
25
  And a file named "autosign.conf" with:
25
26
  """
26
- [jwt_token]
27
- secret = secret
28
- validity = 7200
27
+ ---
28
+ jwt_token:
29
+ validity: '7200'
30
+ secret: 'secret'
29
31
  """
30
32
  When I run `chmod 600 autosign.conf`
31
33
  When I run `autosign --config autosign.conf generate foo.example.com --reusable`
@@ -38,8 +40,9 @@ Feature: Generate autosign key
38
40
  And a hostname of "foo.example.com"
39
41
  And a file named "autosign.conf" with:
40
42
  """
41
- [jwt_token]
42
- secret = secret
43
+ ---
44
+ jwt_token:
45
+ secret: 'secret'
43
46
  """
44
47
  When I run `chmod 600 autosign.conf`
45
48
  When I run `autosign --config autosign.conf validate --certname "foo.example.com" "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJkYXRhIjoie1wiY2VydG5hbWVcIjpcImZvby5leGFtcGxlLmNvbVwiLFwicmVxdWVzdGVyXCI6XCJEYW5pZWxzLU1hY0Jvb2stUHJvLTIubG9jYWxcIixcInJldXNhYmxlXCI6ZmFsc2UsXCJ2YWxpZGZvclwiOjI5OTk5OTk5OSxcInV1aWRcIjpcIjlkYTA0Yzc4LWQ5NjUtNDk2OC04MWNjLWVhM2RjZDllZjVjMFwifSIsImV4cCI6IjE3MzY0NjYxMzAifQ.PJwY8rIunVyWi_lw0ypFclME0jx3Vd9xJIQSyhN3VUmul3V8u4Tp9XwDgoAu9DVV0-WEG2Tfxs6F8R6Fn71Ndg"`
@@ -51,8 +54,9 @@ Feature: Generate autosign key
51
54
  And a hostname of "foo.example.com"
52
55
  And a file named "autosign.conf" with:
53
56
  """
54
- [jwt_token]
55
- secret = secret
57
+ ---
58
+ jwt_token:
59
+ secret: 'secret'
56
60
  """
57
61
  When I run `chmod 600 autosign.conf`
58
62
  When I run `autosign --config autosign.conf validate --certname "foo.example.com" "invalid_token"`
@@ -63,8 +67,9 @@ Feature: Generate autosign key
63
67
  And a hostname of "foo.example.com"
64
68
  And a file named "autosign.conf" with:
65
69
  """
66
- [jwt_token]
67
- secret = secret
70
+ ---
71
+ jwt_token:
72
+ secret: 'secret'
68
73
  """
69
74
  When I run `chmod 600 autosign.conf`
70
75
  When I run `autosign --config autosign.conf validate --certname "foo.example.com" "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJkYXRhIjoie1wiY2VydG5hbWVcIjpcImZvby5leGFtcGxlLmNvbVwiLFwicmVxdWVzdGVyXCI6XCJEYW5pZWxzLU1hY0Jvb2stUHJvLTIubG9jYWxcIixcInJldXNhYmxlXCI6ZmFsc2UsXCJ2YWxpZGZvclwiOjEsXCJ1dWlkXCI6XCJlNjI1Y2I1Ny02NzY5LTQwMzQtODNiZS0zNzkxNmQ5YmMxMDRcIn0iLCJleHAiOiIxNDM2NDY2MzAyIn0.UXEDEbRqEWx5SdSpQjfowU56JubY5Yz2QN6cckby2es-g2P_n2lyAS6AwFeliBXyCDyVUelIT3g1QP4TdB9EEA"`
@@ -1,7 +1,8 @@
1
- require 'iniparse'
2
1
  require 'rbconfig'
3
2
  require 'securerandom'
4
3
  require 'deep_merge'
4
+ require 'yaml'
5
+ require 'safe_yaml'
5
6
 
6
7
  module Autosign
7
8
  # Exceptions namespace for Autosign class
@@ -38,7 +39,7 @@ module Autosign
38
39
  # set up logging
39
40
  @log = Logging.logger['Autosign::Config']
40
41
  @log.debug "initializing Autosign::Config"
41
-
42
+ SafeYAML::OPTIONS[:default_mode] = :safe
42
43
  # validate parameter
43
44
  raise 'settings is not a hash' unless settings_param.is_a?(Hash)
44
45
 
@@ -101,7 +102,8 @@ module Autosign
101
102
  if File.file?(file)
102
103
  @log.debug "Reading config file from: " + file
103
104
  config_file = File.read(file)
104
- parsed_config_file = IniParse.parse(config_file).to_hash
105
+ parsed_config_file = YAML.safe_load(config_file)
106
+ #parsed_config_file = IniParse.parse(config_file).to_hash
105
107
  @log.debug "configuration read from config file: " + parsed_config_file.to_s
106
108
  return parsed_config_file if parsed_config_file.is_a?(Hash)
107
109
  else
@@ -161,27 +163,39 @@ module Autosign
161
163
  end
162
164
  )
163
165
 
164
- config = IniParse.gen do |doc|
165
- doc.section("general") do |general|
166
- general.option("loglevel", "warn")
167
- general.option("logfile", os_defaults['logpath'])
168
- end
169
- doc.section("jwt_token") do |jwt_token|
170
- jwt_token.option("secret", SecureRandom.base64(15))
171
- jwt_token.option("validity", 7200)
172
- jwt_token.option("journalfile", os_defaults['journalfile'])
173
- end
174
- doc.section("multiplexer") do |jwt_token|
175
- jwt_token.option(";external_policy_executable", '/usr/local/bin/some_autosign_executable')
176
- jwt_token.option(";external_policy_executable", '/usr/local/bin/another_autosign_executable')
177
- end
178
- doc.section("password_list") do |jwt_token|
179
- jwt_token.option(";password", 'static_autosign_password_here')
180
- jwt_token.option(";password", 'another_static_autosign_password')
181
- end
182
- end.to_ini
166
+ config = {
167
+ 'general' => {
168
+ 'loglevel' => 'warn',
169
+ 'logfile' => os_defaults['logpath']
170
+ },
171
+ 'jwt_token' => {
172
+ 'secret' => SecureRandom.base64(20),
173
+ 'validity' => '7200',
174
+ 'journalfile' => os_defaults['journalfile']
175
+ }
176
+ }
177
+
178
+ # config = IniParse.gen do |doc|
179
+ # doc.section("general") do |general|
180
+ # general.option("loglevel", "warn")
181
+ # general.option("logfile", os_defaults['logpath'])
182
+ # end
183
+ # doc.section("jwt_token") do |jwt_token|
184
+ # jwt_token.option("secret", SecureRandom.base64(15))
185
+ # jwt_token.option("validity", 7200)
186
+ # jwt_token.option("journalfile", os_defaults['journalfile'])
187
+ # end
188
+ # doc.section("multiplexer") do |jwt_token|
189
+ # jwt_token.option(";external_policy_executable", '/usr/local/bin/some_autosign_executable')
190
+ # jwt_token.option(";external_policy_executable", '/usr/local/bin/another_autosign_executable')
191
+ # end
192
+ # doc.section("password_list") do |jwt_token|
193
+ # jwt_token.option(";password", 'static_autosign_password_here')
194
+ # jwt_token.option(";password", 'another_static_autosign_password')
195
+ # end
196
+ # end.to_ini
183
197
  raise Autosign::Exceptions::Error, "file #{os_defaults['confpath']} already exists, aborting" if File.file?(os_defaults['confpath'])
184
- return os_defaults['confpath'] if File.write(os_defaults['confpath'], config)
198
+ return os_defaults['confpath'] if File.write(os_defaults['confpath'], config.to_yaml)
185
199
  end
186
200
  end
187
201
  end
@@ -23,7 +23,7 @@ module Autosign
23
23
  end
24
24
 
25
25
  # extract challenge password
26
- challenge_password = csr.attributes.select { |a| a.oid == 'challengePassword' }.first.value.value.first.value
26
+ challenge_password = csr.attributes.select { |a| a.oid == 'challengePassword' }.first.value.value.first.value.to_s
27
27
 
28
28
  # extract common name
29
29
  common_name = /^\/CN=(\S*)$/.match(csr.subject.to_s)[1]
@@ -106,7 +106,7 @@ module Autosign
106
106
 
107
107
  # check if the token is reusable or a one-time use token
108
108
  # @return [True, False] return true if the token can be used multiple times, false if the token can only be used once
109
- def reusable
109
+ def reusable?
110
110
  !!@reusable
111
111
  end
112
112
 
@@ -116,7 +116,7 @@ module Autosign
116
116
  {
117
117
  "certname" => certname,
118
118
  "requester" => requester,
119
- "reusable" => reusable,
119
+ "reusable" => reusable?,
120
120
  "validfor" => validfor,
121
121
  "uuid" => uuid
122
122
  }
@@ -132,6 +132,10 @@ module Autosign
132
132
  true
133
133
  end
134
134
 
135
+ # Find other classes that inherit from this class.
136
+ # Used to discover autosign validators. There is probably no reason to use
137
+ # this directly.
138
+ # @return [Array] of classes inheriting from Autosign::Validator
135
139
  def self.descendants
136
140
  ObjectSpace.each_object(Class).select { |klass| klass < self }
137
141
  end
@@ -38,7 +38,7 @@ module Autosign
38
38
  end
39
39
 
40
40
  def is_reusable?(token)
41
- Autosign::Token.from_token(token, settings['secret']).reusable
41
+ Autosign::Token.from_token(token, settings['secret']).reusable?
42
42
  end
43
43
 
44
44
  # Attempt to add a token to the one-time token journal.
@@ -1,3 +1,3 @@
1
1
  module Autosign
2
- VERSION = '0.0.7'
2
+ VERSION = '0.0.8'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: autosign
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Your Name Here
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-16 00:00:00.000000000 Z
11
+ date: 2015-07-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -220,6 +220,20 @@ dependencies:
220
220
  - - ~>
221
221
  - !ruby/object:Gem::Version
222
222
  version: '0.8'
223
+ - !ruby/object:Gem::Dependency
224
+ name: safe_yaml
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - ~>
228
+ - !ruby/object:Gem::Version
229
+ version: '1'
230
+ type: :runtime
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ~>
235
+ - !ruby/object:Gem::Version
236
+ version: '1'
223
237
  description:
224
238
  email: your@email.address.com
225
239
  executables: