Class: Puppet::SSL::Host
- Extended by:
- Util::Cacher
- Defined in:
- lib/puppet/ssl/host.rb
Overview
The class that manages all aspects of our SSL certificates – private keys, public keys, requests, etc.
Constant Summary collapse
- Key =
Yay, ruby’s strange constant lookups.
Puppet::SSL::Key
- CA_NAME =
Puppet::SSL::CA_NAME
- Certificate =
Puppet::SSL::Certificate
- CertificateRequest =
Puppet::SSL::CertificateRequest
- CertificateRevocationList =
Puppet::SSL::CertificateRevocationList
- CA_MODES =
{ # Our ca is local, so we use it as the ultimate source of information # And we cache files locally. :local => [:ca, :file], # We're a remote CA client. :remote => [:rest, :file], # We are the CA, so we don't have read/write access to the normal certificates. :only => [:ca], # We have no CA, so we just look in the local file store. :none => [:file] }
Class Attribute Summary collapse
-
.ca_location ⇒ Object
Returns the value of attribute ca_location.
Instance Attribute Summary collapse
-
#ca ⇒ Object
Returns the value of attribute ca.
- #certificate ⇒ Object
- #certificate_request ⇒ Object
- #key ⇒ Object
-
#name ⇒ Object
readonly
Returns the value of attribute name.
Attributes included from Util::Cacher::Expirer
Class Method Summary collapse
-
.ca_name ⇒ Object
This is the constant that people will use to mark that a given host is a certificate authority.
-
.configure_indirection(terminus, cache = nil) ⇒ Object
Configure how our various classes interact with their various terminuses.
-
.destroy(name) ⇒ Object
Remove all traces of a given host.
-
.search(options = {}) ⇒ Object
Search for more than one host, optionally only specifying an interest in hosts with a given file type.
Instance Method Summary collapse
-
#ca? ⇒ Boolean
Is this a ca host, meaning that all of its files go in the CA location?.
- #certificate_matches_key? ⇒ Boolean
-
#generate ⇒ Object
Generate all necessary parts of our ssl host.
-
#generate_certificate_request ⇒ Object
Our certificate request requires the key but that’s all.
-
#generate_key ⇒ Object
This is the private key; we can create it from scratch with no inputs.
-
#initialize(name = nil) ⇒ Host
constructor
A new instance of Host.
-
#public_key ⇒ Object
Extract the public key from the private key.
-
#ssl_store(purpose = OpenSSL::X509::PURPOSE_ANY) ⇒ Object
Create/return a store that uses our SSL info to validate connections.
-
#wait_for_cert(time) ⇒ Object
Attempt to retrieve a cert, if we don’t already have one.
Methods included from Util::Cacher
Methods included from Util::Cacher::Expirer
#dependent_data_expired?, #expire
Constructor Details
Class Attribute Details
.ca_location ⇒ Object
Returns the value of attribute ca_location.
41 42 43 |
# File 'lib/puppet/ssl/host.rb', line 41 def ca_location @ca_location end |
Instance Attribute Details
#ca ⇒ Object
Returns the value of attribute ca.
19 20 21 |
# File 'lib/puppet/ssl/host.rb', line 19 def ca @ca end |
#certificate ⇒ Object
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/puppet/ssl/host.rb', line 156 def certificate unless @certificate generate_key unless key # get the CA cert first, since it's required for the normal cert # to be of any use. return nil unless Certificate.find("ca") unless ca? return nil unless @certificate = Certificate.find(name) unless certificate_matches_key? raise Puppet::Error, "Retrieved certificate does not match private key; please remove certificate from server and regenerate it with the current key" end end @certificate end |
#certificate_request ⇒ Object
137 138 139 |
# File 'lib/puppet/ssl/host.rb', line 137 def certificate_request @certificate_request ||= CertificateRequest.find(name) end |
#key ⇒ Object
119 120 121 |
# File 'lib/puppet/ssl/host.rb', line 119 def key @key ||= Key.find(name) end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
18 19 20 |
# File 'lib/puppet/ssl/host.rb', line 18 def name @name end |
Class Method Details
.ca_name ⇒ Object
This is the constant that people will use to mark that a given host is a certificate authority.
36 37 38 |
# File 'lib/puppet/ssl/host.rb', line 36 def self.ca_name CA_NAME end |
.configure_indirection(terminus, cache = nil) ⇒ Object
Configure how our various classes interact with their various terminuses.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/puppet/ssl/host.rb', line 45 def self.configure_indirection(terminus, cache = nil) Certificate.terminus_class = terminus CertificateRequest.terminus_class = terminus CertificateRevocationList.terminus_class = terminus if cache # This is weird; we don't actually cache our keys, we # use what would otherwise be the cache as our normal # terminus. Key.terminus_class = cache else Key.terminus_class = terminus end if cache Certificate.cache_class = cache CertificateRequest.cache_class = cache CertificateRevocationList.cache_class = cache else # Make sure we have no cache configured. puppet master # switches the configurations around a bit, so it's important # that we specify the configs for absolutely everything, every # time. Certificate.cache_class = nil CertificateRequest.cache_class = nil CertificateRevocationList.cache_class = nil end end |
.destroy(name) ⇒ Object
Remove all traces of a given host
96 97 98 |
# File 'lib/puppet/ssl/host.rb', line 96 def self.destroy(name) [Key, Certificate, CertificateRequest].collect { |part| part.destroy(name) }.any? { |x| x } end |
.search(options = {}) ⇒ Object
Search for more than one host, optionally only specifying an interest in hosts with a given file type. This just allows our non-indirected class to have one of indirection methods.
104 105 106 107 108 109 110 111 112 |
# File 'lib/puppet/ssl/host.rb', line 104 def self.search( = {}) classlist = [[:for] || [Key, CertificateRequest, Certificate]].flatten # Collect the results from each class, flatten them, collect all of the names, make the name list unique, # then create a Host instance for each one. classlist.collect { |klass| klass.search }.flatten.collect { |r| r.name }.uniq.collect do |name| new(name) end end |
Instance Method Details
#ca? ⇒ Boolean
Is this a ca host, meaning that all of its files go in the CA location?
115 116 117 |
# File 'lib/puppet/ssl/host.rb', line 115 def ca? ca end |
#certificate_matches_key? ⇒ Boolean
172 173 174 175 176 177 |
# File 'lib/puppet/ssl/host.rb', line 172 def certificate_matches_key? return false unless key return false unless certificate certificate.content.check_private_key(key.content) end |
#generate ⇒ Object
Generate all necessary parts of our ssl host.
180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/puppet/ssl/host.rb', line 180 def generate generate_key unless key generate_certificate_request unless certificate_request # If we can get a CA instance, then we're a valid CA, and we # should use it to sign our request; else, just try to read # the cert. if ! certificate and ca = Puppet::SSL::CertificateAuthority.instance ca.sign(self.name) end end |
#generate_certificate_request ⇒ Object
Our certificate request requires the key but that’s all.
142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/puppet/ssl/host.rb', line 142 def generate_certificate_request generate_key unless key @certificate_request = CertificateRequest.new(name) @certificate_request.generate(key.content) begin @certificate_request.save rescue @certificate_request = nil raise end true end |
#generate_key ⇒ Object
This is the private key; we can create it from scratch with no inputs.
125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/puppet/ssl/host.rb', line 125 def generate_key @key = Key.new(name) @key.generate begin @key.save rescue @key = nil raise end true end |
#public_key ⇒ Object
Extract the public key from the private key.
199 200 201 |
# File 'lib/puppet/ssl/host.rb', line 199 def public_key key.content.public_key end |
#ssl_store(purpose = OpenSSL::X509::PURPOSE_ANY) ⇒ Object
Create/return a store that uses our SSL info to validate connections.
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
# File 'lib/puppet/ssl/host.rb', line 205 def ssl_store(purpose = OpenSSL::X509::PURPOSE_ANY) unless @ssl_store @ssl_store = OpenSSL::X509::Store.new @ssl_store.purpose = purpose # Use the file path here, because we don't want to cause # a lookup in the middle of setting our ssl connection. @ssl_store.add_file(Puppet[:localcacert]) # If there's a CRL, add it to our store. if crl = Puppet::SSL::CertificateRevocationList.find(CA_NAME) @ssl_store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK if Puppet.settings[:certificate_revocation] @ssl_store.add_crl(crl.content) end return @ssl_store end @ssl_store end |
#wait_for_cert(time) ⇒ Object
Attempt to retrieve a cert, if we don’t already have one.
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
# File 'lib/puppet/ssl/host.rb', line 225 def wait_for_cert(time) begin return if certificate generate return if certificate rescue SystemExit,NoMemoryError raise rescue Exception => detail puts detail.backtrace if Puppet[:trace] Puppet.err "Could not request certificate: #{detail}" if time < 1 puts "Exiting; failed to retrieve certificate and waitforcert is disabled" exit(1) else sleep(time) end retry end if time < 1 puts "Exiting; no certificate found and waitforcert is disabled" exit(1) end while true sleep time begin break if certificate Puppet.notice "Did not receive certificate" rescue StandardError => detail puts detail.backtrace if Puppet[:trace] Puppet.err "Could not request certificate: #{detail}" end end end |