Class: Puppet::SSL::StateMachine Private

Inherits:
Object
  • Object
show all
Defined in:
lib/puppet/ssl/state_machine.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

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.

Defined Under Namespace

Classes: Done, Error, KeySSLState, LockFailure, NeedCACerts, NeedCRLs, NeedCert, NeedKey, NeedLock, NeedSubmitCSR, SSLState, Wait

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(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]) ⇒ StateMachine

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

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.

Parameters:

  • waitforcert (Integer) (defaults to: Puppet[:waitforcert])

    how many seconds to wait between attempts

  • maxwaitforcert (Integer) (defaults to: Puppet[:maxwaitforcert])

    maximum amount of seconds to wait for the server to sign the certificate request

  • waitforlock (Integer) (defaults to: Puppet[:waitforlock])

    how many seconds to wait between attempts for acquiring the ssl lock

  • maxwaitforlock (Integer) (defaults to: Puppet[:maxwaitforlock])

    maximum amount of seconds to wait for an already running process to release the ssl lock

  • onetime (Boolean) (defaults to: Puppet[:onetime])

    whether to run onetime

  • lockfile (Puppet::Util::Pidlock) (defaults to: Puppet::Util::Pidlock.new(Puppet[:ssl_lockfile]))

    lockfile to protect against concurrent modification by multiple processes

  • cert_provider (Puppet::X509::CertProvider) (defaults to: Puppet::X509::CertProvider.new)

    cert provider to use to load and save X509 objects.

  • ssl_provider (Puppet::SSL::SSLProvider) (defaults to: Puppet::SSL::SSLProvider.new)

    ssl provider to use to construct ssl contexts.

  • digest (String) (defaults to: 'SHA256')

    digest algorithm to use for certificate fingerprinting

  • ca_fingerprint (String) (defaults to: Puppet[:ca_fingerprint])

    optional fingerprint to verify the downloaded CA bundle


381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
# File 'lib/puppet/ssl/state_machine.rb', line 381

def initialize(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])
  @waitforcert = waitforcert
  @wait_deadline = Time.now.to_i + maxwaitforcert
  @waitforlock = waitforlock
  @waitlock_deadline = Time.now.to_i + maxwaitforlock
  @onetime = onetime
  @cert_provider = cert_provider
  @ssl_provider = ssl_provider
  @lockfile = lockfile
  @digest = digest
  @ca_fingerprint = ca_fingerprint
  @session = Puppet.runtime[:http].create_session
end

Instance Attribute Details

#ca_fingerprintObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


352
353
354
# File 'lib/puppet/ssl/state_machine.rb', line 352

def ca_fingerprint
  @ca_fingerprint
end

#cert_providerObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


352
353
354
# File 'lib/puppet/ssl/state_machine.rb', line 352

def cert_provider
  @cert_provider
end

#digestObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


352
353
354
# File 'lib/puppet/ssl/state_machine.rb', line 352

def digest
  @digest
end

#sessionObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


353
354
355
# File 'lib/puppet/ssl/state_machine.rb', line 353

def session
  @session
end

#ssl_providerObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


352
353
354
# File 'lib/puppet/ssl/state_machine.rb', line 352

def ssl_provider
  @ssl_provider
end

#wait_deadlineObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


352
353
354
# File 'lib/puppet/ssl/state_machine.rb', line 352

def wait_deadline
  @wait_deadline
end

#waitforcertObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


352
353
354
# File 'lib/puppet/ssl/state_machine.rb', line 352

def waitforcert
  @waitforcert
end

#waitforlockObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


352
353
354
# File 'lib/puppet/ssl/state_machine.rb', line 352

def waitforlock
  @waitforlock
end

#waitlock_deadlineObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


352
353
354
# File 'lib/puppet/ssl/state_machine.rb', line 352

def waitlock_deadline
  @waitlock_deadline
end

Instance Method Details

#ensure_ca_certificatesPuppet::SSL::SSLContext

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Run the state machine for CA certs and CRLs.

Returns:

Raises:


409
410
411
412
# File 'lib/puppet/ssl/state_machine.rb', line 409

def ensure_ca_certificates
  final_state = run_machine(NeedLock.new(self), NeedKey)
  final_state.ssl_context
end

#ensure_client_certificatePuppet::SSL::SSLContext

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Run the state machine for CA certs and CRLs.

Returns:

Raises:


419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
# File 'lib/puppet/ssl/state_machine.rb', line 419

def ensure_client_certificate
  final_state = run_machine(NeedLock.new(self), Done)
  ssl_context = final_state.ssl_context

  if Puppet::Util::Log.sendlevel?(:debug)
    chain = ssl_context.client_chain
    # print from root to client
    chain.reverse.each_with_index do |cert, i|
      digest = Puppet::SSL::Digest.new(@digest, cert.to_der)
      if i == chain.length - 1
        Puppet.debug(_("Verified client certificate '%{subject}' fingerprint %{digest}") % {subject: cert.subject.to_utf8, digest: digest})
      else
        Puppet.debug(_("Verified CA certificate '%{subject}' fingerprint %{digest}") % {subject: cert.subject.to_utf8, digest: digest})
      end
    end
  end

  ssl_context
end

#lockObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


439
440
441
# File 'lib/puppet/ssl/state_machine.rb', line 439

def lock
  @lockfile.lock
end

#unlockObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


443
444
445
# File 'lib/puppet/ssl/state_machine.rb', line 443

def unlock
  @lockfile.unlock
end