class Puppet::SSL::StateMachine

This class implements a state machine for bootstrapping a host's CA and CRL bundles, private key and signed client certificate. Each state has a frozen SSLContext that it uses to make network connections. If a state makes progress bootstrapping the host, then the state will generate a new frozen SSLContext and pass that to the next state. For example, the NeedCACerts state will load or download a CA bundle, and generate a new SSLContext containing those CA certs. This way we're sure about which SSLContext is being used during any phase of the bootstrapping process.

@api private

Attributes

ca_fingerprint[R]
cert_provider[R]
digest[R]
session[RW]
ssl_provider[R]
wait_deadline[R]
waitforcert[R]
waitforlock[R]
waitlock_deadline[R]

Public Class Methods

new(waitforcert: Puppet[:waitforcert], maxwaitforcert: Puppet[:maxwaitforcert], waitforlock: Puppet[:waitforlock], maxwaitforlock: Puppet[:maxwaitforlock], onetime: Puppet[:onetime], cert_provider: Puppet::X509::CertProvider.new, ssl_provider: Puppet::SSL::SSLProvider.new, lockfile: Puppet::Util::Pidlock.new(Puppet[:ssl_lockfile]), digest: 'SHA256', ca_fingerprint: Puppet[:ca_fingerprint]) click to toggle source

Construct a state machine to manage the SSL initialization process. By default, if the state machine encounters an exception, it will log the exception and wait for `waitforcert` seconds and retry, restarting from the beginning of the state machine.

However, if `onetime` is true, then the state machine will raise the first error it encounters, instead of waiting. Otherwise, if `waitforcert` is 0, then then state machine will exit instead of wait.

@param waitforcert [Integer] how many seconds to wait between attempts @param maxwaitforcert [Integer] maximum amount of seconds to wait for the

server to sign the certificate request

@param waitforlock [Integer] how many seconds to wait between attempts for

acquiring the ssl lock

@param maxwaitforlock [Integer] maximum amount of seconds to wait for an

already running process to release the ssl lock

@param onetime [Boolean] whether to run onetime @param lockfile [Puppet::Util::Pidlock] lockfile to protect against

concurrent modification by multiple processes

@param cert_provider [Puppet::X509::CertProvider] cert provider to use

to load and save X509 objects.

@param ssl_provider [Puppet::SSL::SSLProvider] ssl provider to use

to construct ssl contexts.

@param digest [String] digest algorithm to use for certificate fingerprinting @param ca_fingerprint [String] optional fingerprint to verify the

downloaded CA bundle
    # File lib/puppet/ssl/state_machine.rb
391 def initialize(waitforcert: Puppet[:waitforcert],
392                maxwaitforcert: Puppet[:maxwaitforcert],
393                waitforlock: Puppet[:waitforlock],
394                maxwaitforlock: Puppet[:maxwaitforlock],
395                onetime: Puppet[:onetime],
396                cert_provider: Puppet::X509::CertProvider.new,
397                ssl_provider: Puppet::SSL::SSLProvider.new,
398                lockfile: Puppet::Util::Pidlock.new(Puppet[:ssl_lockfile]),
399                digest: 'SHA256',
400                ca_fingerprint: Puppet[:ca_fingerprint])
401   @waitforcert = waitforcert
402   @wait_deadline = Time.now.to_i + maxwaitforcert
403   @waitforlock = waitforlock
404   @waitlock_deadline = Time.now.to_i + maxwaitforlock
405   @onetime = onetime
406   @cert_provider = cert_provider
407   @ssl_provider = ssl_provider
408   @lockfile = lockfile
409   @digest = digest
410   @ca_fingerprint = ca_fingerprint
411   @session = Puppet.runtime[:http].create_session
412 end

Public Instance Methods

ensure_ca_certificates() click to toggle source

Run the state machine for CA certs and CRLs.

@return [Puppet::SSL::SSLContext] initialized SSLContext @raise [Puppet::Error] If we fail to generate an SSLContext @api private

    # File lib/puppet/ssl/state_machine.rb
419 def ensure_ca_certificates
420   final_state = run_machine(NeedLock.new(self), NeedKey)
421   final_state.ssl_context
422 end
ensure_client_certificate() click to toggle source

Run the state machine for CA certs and CRLs.

@return [Puppet::SSL::SSLContext] initialized SSLContext @raise [Puppet::Error] If we fail to generate an SSLContext @api private

    # File lib/puppet/ssl/state_machine.rb
429 def ensure_client_certificate
430   final_state = run_machine(NeedLock.new(self), Done)
431   ssl_context = final_state.ssl_context
432   @ssl_provider.print(ssl_context, @digest)
433   ssl_context
434 end
lock() click to toggle source
    # File lib/puppet/ssl/state_machine.rb
436 def lock
437   @lockfile.lock
438 end
unlock() click to toggle source
    # File lib/puppet/ssl/state_machine.rb
440 def unlock
441   @lockfile.unlock
442 end

Private Instance Methods

run_machine(state, stop) click to toggle source
    # File lib/puppet/ssl/state_machine.rb
446 def run_machine(state, stop)
447   loop do
448     state = run_step(state)
449 
450     case state
451     when stop
452       break
453     when LockFailure
454       raise Puppet::Error, state.message
455     when Error
456       if @onetime
457         Puppet.log_exception(state.error)
458         raise state.error
459       end
460     else
461       # fall through
462     end
463   end
464 
465   state
466 ensure
467   @lockfile.unlock if @lockfile.locked?
468 end
run_step(state) click to toggle source
    # File lib/puppet/ssl/state_machine.rb
470 def run_step(state)
471   state.next_state
472 rescue => e
473   state.to_error(e.message, e)
474 end