puppetserver-ca 2.3.1 → 2.3.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
  SHA256:
3
- metadata.gz: 9443656cd200fac958b84f3b7444a402146344105b25022eef46dbe1d24201a1
4
- data.tar.gz: aa4c2fbcae1976a25346c6cfe16d792099b6ccc722f24770535e58367bc4128d
3
+ metadata.gz: 37981ba97c1f259e077b807b2903ea73d4726c56c4fb28b1e7e506fa456c2002
4
+ data.tar.gz: 15fab6a94a112e748d6605cb7d1b9a511fb17f663e6c25b59a2552d254f5c155
5
5
  SHA512:
6
- metadata.gz: 34e5662cbb5d7f92bf9f1b3f91f69d37149986c4ba998e42655cf5440349a242116f04c3abfc50244140f4de681fdffed77fa9c56128286bfe3e96d49ebc2939
7
- data.tar.gz: 24740e26cceae352f4def897433bc4971b78c8d51c94e0692b19868a10a73dec29c266c1f9f09281b46299dfd9f795cba00c57b00726556529faf0ef820bd664
6
+ metadata.gz: 993aa454173c018b817f5028bd0726679fd71c9588cf96aa75e4534e3726919b0b851b83c7bd04628c2cf9e58146739678d9b856e0b64fea8ca0fea98b78f567
7
+ data.tar.gz: ea9b4e92cf2a607274bee95d882f8e69c34fa5ae4dcf338aee4fae7697ed82d39f0cb1ffa16ba8466a88d2040e75d3d96b01f6b2c528adaf8170779966b2e366
@@ -26,7 +26,7 @@ Usage:
26
26
  puppetserver ca generate [--help]
27
27
  puppetserver ca generate --certname NAME[,NAME] [--config PATH]
28
28
  [--subject-alt-names NAME[,NAME]]
29
- [--ca-client]
29
+ [--ca-client [--force]]
30
30
 
31
31
  Description:
32
32
  Generates a new certificate signed by the intermediate CA
@@ -75,6 +75,10 @@ BANNER
75
75
  'Causes the cert to be generated offline.') do |ca_client|
76
76
  parsed['ca-client'] = true
77
77
  end
78
+ opts.on('--force', 'Suppress errors when signing cert offline.',
79
+ "To be used with '--ca-client'") do |force|
80
+ parsed['force'] = true
81
+ end
78
82
  opts.on('--ttl TTL', 'The time-to-live for each cert generated and signed') do |ttl|
79
83
  parsed['ttl'] = ttl
80
84
  end
@@ -139,8 +143,21 @@ BANNER
139
143
 
140
144
  # Generate and save certs and associated keys
141
145
  if input['ca-client']
142
- # Refused to generate certs offfline if the CA service is running
143
- return 1 if HttpClient.check_server_online(puppet.settings, @logger)
146
+ # Refuse to generate certs offline if the CA service is running
147
+ begin
148
+ return 1 if HttpClient.check_server_online(puppet.settings, @logger)
149
+ rescue Puppetserver::Ca::ConnectionFailed => e
150
+ base_message = "Could not determine whether Puppet Server is online."
151
+ if input['force']
152
+ @logger.inform("#{base_message} Connection check failed with " \
153
+ "error: #{e.wrapped}\nContinuing with certificate signing.")
154
+ else
155
+ @logger.inform("#{base_message} If you are certain that the " \
156
+ "Puppetserver service is stopped, run this command again " \
157
+ "with the '--force' flag.")
158
+ raise e
159
+ end
160
+ end
144
161
  all_passed = generate_authorized_certs(certnames, alt_names, puppet.settings, signer.digest)
145
162
  else
146
163
  all_passed = generate_certs(certnames, alt_names, puppet.settings, signer.digest, input['ttl'])
@@ -62,6 +62,7 @@ Options:
62
62
  certnames = input['certname'] || []
63
63
  all = input['all']
64
64
  output_format = input['format'] || "text"
65
+ missing = []
65
66
 
66
67
  unless VALID_FORMAT.include?(output_format)
67
68
  Errors.handle_with_usage(@logger, ["Unknown format flag '#{output_format}'. Valid formats are '#{VALID_FORMAT.join("', '")}'."])
@@ -87,14 +88,14 @@ Options:
87
88
  filter_names = lambda { |x| true }
88
89
  end
89
90
 
90
- all_certs = get_all_certs(puppet.settings).select { |cert| filter_names.call(cert) }
91
- requested, signed, revoked = separate_certs(all_certs)
92
- missing = certnames - all_certs.map { |cert| cert['name'] }
93
-
94
91
  if (all || certnames.any?)
92
+ all_certs = get_certs_or_csrs(puppet.settings).select { |cert| filter_names.call(cert) }
93
+ requested, signed, revoked = separate_certs(all_certs)
94
+ missing = certnames - all_certs.map { |cert| cert['name'] }
95
95
  output_certs_by_state(all, output_format, requested, signed, revoked, missing)
96
96
  else
97
- output_certs_by_state(all, output_format, requested)
97
+ all_csrs = get_certs_or_csrs(puppet.settings, "requested")
98
+ output_certs_by_state(all, output_format, all_csrs)
98
99
  end
99
100
 
100
101
  return missing.any? ? 1 : 0
@@ -209,8 +210,9 @@ Options:
209
210
  return requested, signed, revoked
210
211
  end
211
212
 
212
- def get_all_certs(settings)
213
- result = Puppetserver::Ca::CertificateAuthority.new(@logger, settings).get_certificate_statuses
213
+ def get_certs_or_csrs(settings, queried_state = nil)
214
+ query = queried_state ? { :state => queried_state } : {}
215
+ result = Puppetserver::Ca::CertificateAuthority.new(@logger, settings).get_certificate_statuses(query)
214
216
 
215
217
  if result
216
218
  return JSON.parse(result.body)
@@ -1,5 +1,6 @@
1
1
  require 'optparse'
2
2
  require 'openssl'
3
+ require 'set'
3
4
  require 'puppetserver/ca/errors'
4
5
  require 'puppetserver/ca/utils/cli_parsing'
5
6
  require 'puppetserver/ca/utils/file_system'
@@ -31,6 +32,7 @@ BANNER
31
32
 
32
33
  def run(inputs)
33
34
  config_path = inputs['config']
35
+ exit_code = 0
34
36
 
35
37
  # Validate the config path.
36
38
  if config_path
@@ -49,55 +51,59 @@ BANNER
49
51
  # Getting the CRL(s)
50
52
  loader = X509Loader.new(puppet.settings[:cacert], puppet.settings[:cakey], puppet.settings[:cacrl])
51
53
 
52
- puppet_crl = loader.crls.select { |crl| crl.verify(loader.key) }
53
- number_of_removed_duplicates = prune_CRLs(puppet_crl)
54
+ verified_crls = loader.crls.select { |crl| crl.verify(loader.key) }
54
55
 
55
- if number_of_removed_duplicates > 0
56
- update_pruned_CRL(puppet_crl, loader.key)
57
- FileSystem.write_file(puppet.settings[:cacrl], loader.crls, 0644)
58
- @logger.inform("Removed #{number_of_removed_duplicates} duplicated certs from Puppet's CRL.")
56
+ if verified_crls.length == 1
57
+ puppet_crl = verified_crls.first
58
+ @logger.inform("Total number of certificates found in Puppet's CRL is: #{puppet_crl.revoked.length}.")
59
+ number_of_removed_duplicates = prune_CRL(puppet_crl)
60
+
61
+ if number_of_removed_duplicates > 0
62
+ update_pruned_CRL(puppet_crl, loader.key)
63
+ FileSystem.write_file(puppet.settings[:cacrl], loader.crls, 0644)
64
+ @logger.inform("Removed #{number_of_removed_duplicates} duplicated certs from Puppet's CRL.")
65
+ else
66
+ @logger.inform("No duplicate revocations found in the CRL.")
67
+ end
59
68
  else
60
- @logger.inform("No duplicate revocations found in the CRL.")
69
+ @logger.err("Could not identify Puppet's CRL. Aborting prune action.")
70
+ exit_code = 1
61
71
  end
62
72
 
63
- return 0
73
+ return exit_code
64
74
  end
65
75
 
66
- def prune_CRLs(crl_list)
76
+ def prune_CRL(crl)
67
77
  number_of_removed_duplicates = 0
68
78
 
69
- crl_list.each do |crl|
70
- existed_serial_number = Set.new()
71
- revoked_list = crl.revoked
72
- @logger.debug("Pruning duplicate entries in CRL for issuer " \
73
- "#{crl.issuer.to_s(OpenSSL::X509::Name::RFC2253)}") if @logger.debug?
74
-
75
- revoked_list.delete_if do |revoked|
76
- if existed_serial_number.add?(revoked.serial)
77
- false
78
- else
79
- number_of_removed_duplicates += 1
80
- @logger.debug("Removing duplicate of #{revoked.serial}, " \
81
- "revoked on #{revoked.time}\n") if @logger.debug?
82
- true
83
- end
79
+ existed_serial_number = Set.new()
80
+ revoked_list = crl.revoked
81
+ @logger.debug("Pruning duplicate entries in CRL for issuer " \
82
+ "#{crl.issuer.to_s(OpenSSL::X509::Name::RFC2253)}") if @logger.debug?
83
+
84
+ revoked_list.delete_if do |revoked|
85
+ if existed_serial_number.add?(revoked.serial)
86
+ false
87
+ else
88
+ number_of_removed_duplicates += 1
89
+ @logger.debug("Removing duplicate of #{revoked.serial}, " \
90
+ "revoked on #{revoked.time}\n") if @logger.debug?
91
+ true
84
92
  end
85
- crl.revoked=(revoked_list)
86
93
  end
94
+ crl.revoked=(revoked_list)
87
95
 
88
96
  return number_of_removed_duplicates
89
97
  end
90
98
 
91
- def update_pruned_CRL(crl_list, pkey)
92
- crl_list.each do |crl|
93
- number_ext, other_ext = crl.extensions.partition{ |ext| ext.oid == "crlNumber" }
94
- number_ext.each do |crl_number|
95
- updated_crl_number = OpenSSL::BN.new(crl_number.value) + OpenSSL::BN.new(1)
96
- crl_number.value=(OpenSSL::ASN1::Integer(updated_crl_number))
97
- end
98
- crl.extensions=(number_ext + other_ext)
99
- crl.sign(pkey, OpenSSL::Digest::SHA256.new)
99
+ def update_pruned_CRL(crl, pkey)
100
+ number_ext, other_ext = crl.extensions.partition{ |ext| ext.oid == "crlNumber" }
101
+ number_ext.each do |crl_number|
102
+ updated_crl_number = OpenSSL::BN.new(crl_number.value) + OpenSSL::BN.new(1)
103
+ crl_number.value=(OpenSSL::ASN1::Integer(updated_crl_number))
100
104
  end
105
+ crl.extensions=(number_ext + other_ext)
106
+ crl.sign(pkey, OpenSSL::Digest::SHA256.new)
101
107
  end
102
108
 
103
109
  def self.parser(parsed = {})
@@ -41,8 +41,8 @@ module Puppetserver
41
41
  end
42
42
 
43
43
  # Returns a URI-like wrapper around CA specific urls
44
- def make_ca_url(resource_type = nil, certname = nil)
45
- HttpClient::URL.new('https', @ca_server, @ca_port, 'puppet-ca', 'v1', resource_type, certname)
44
+ def make_ca_url(resource_type = nil, certname = nil, query = {})
45
+ HttpClient::URL.new('https', @ca_server, @ca_port, 'puppet-ca', 'v1', resource_type, certname, query)
46
46
  end
47
47
 
48
48
  def process_ttl_input(ttl)
@@ -141,7 +141,7 @@ module Puppetserver
141
141
  when :revoke
142
142
  case result.code
143
143
  when '200', '204'
144
- @logger.inform "Revoked certificate for #{certname}"
144
+ @logger.inform "Certificate for #{certname} has been revoked"
145
145
  return :success
146
146
  when '404'
147
147
  @logger.err 'Error:'
@@ -215,7 +215,7 @@ module Puppetserver
215
215
  def check_revocation(certname, result)
216
216
  case result.code
217
217
  when '200', '204'
218
- @logger.inform "Revoked certificate for #{certname}"
218
+ @logger.inform "Certificate for #{certname} has been revoked"
219
219
  return :success
220
220
  when '409'
221
221
  return :invalid
@@ -250,8 +250,8 @@ module Puppetserver
250
250
  end
251
251
 
252
252
  # Returns nil for errors, else the result of the GET request
253
- def get_certificate_statuses
254
- result = get('certificate_statuses', 'any_key')
253
+ def get_certificate_statuses(query = {})
254
+ result = get('certificate_statuses', 'any_key', query)
255
255
 
256
256
  unless result.code == '200'
257
257
  @logger.err 'Error:'
@@ -287,8 +287,8 @@ module Puppetserver
287
287
  # @param resource_type [String] the resource type of url
288
288
  # @param resource_name [String] the resource name of url
289
289
  # @return [Struct] an instance of the Result struct with :code, :body
290
- def get(resource_type, resource_name)
291
- url = make_ca_url(resource_type, resource_name)
290
+ def get(resource_type, resource_name, query = {})
291
+ url = make_ca_url(resource_type, resource_name, query)
292
292
  @client.with_connection(url) do |connection|
293
293
  connection.get(url)
294
294
  end
@@ -1,5 +1,6 @@
1
1
  require 'net/https'
2
2
  require 'openssl'
3
+ require 'uri'
3
4
 
4
5
  require 'puppetserver/ca/errors'
5
6
 
@@ -114,7 +115,6 @@ module Puppetserver
114
115
  request.body = body
115
116
  result = @conn.request(request)
116
117
 
117
-
118
118
  Result.new(result.code, result.body)
119
119
  end
120
120
 
@@ -136,10 +136,13 @@ module Puppetserver
136
136
  # Like URI, but not... maybe of suspicious value
137
137
  URL = Struct.new(:protocol, :host, :port,
138
138
  :endpoint, :version,
139
- :resource_type, :resource_name) do
139
+ :resource_type, :resource_name, :query) do
140
140
  def full_url
141
- protocol + '://' + host + ':' + port + '/' +
142
- [endpoint, version, resource_type, resource_name].join('/')
141
+ url = protocol + '://' + host + ':' + port + '/' +
142
+ [endpoint, version, resource_type, resource_name].join('/')
143
+
144
+ url = url + "?" + URI.encode_www_form(query) unless query.nil? || query.empty?
145
+ return url
143
146
  end
144
147
 
145
148
  def to_uri
@@ -1,5 +1,5 @@
1
1
  module Puppetserver
2
2
  module Ca
3
- VERSION = "2.3.1"
3
+ VERSION = "2.3.5"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puppetserver-ca
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.1
4
+ version: 2.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet, Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-07-28 00:00:00.000000000 Z
11
+ date: 2021-09-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: facter