class Chef::Knife::SslFetch

Public Class Methods

new(*args) click to toggle source
Calls superclass method
# File lib/chef/knife/ssl_fetch.rb, line 35
def initialize(*args)
  super
  @uri = nil
end

Public Instance Methods

cn_of(certificate) click to toggle source
# File lib/chef/knife/ssl_fetch.rb, line 89
def cn_of(certificate)
  subject = certificate.subject
  cn_field_tuple = subject.to_a.find {|field| field[0] == "CN" }
  cn_field_tuple[1]
end
configuration() click to toggle source
# File lib/chef/knife/ssl_fetch.rb, line 108
def configuration
  Chef::Config
end
given_uri() click to toggle source
# File lib/chef/knife/ssl_fetch.rb, line 47
def given_uri
  (name_args[0] or Chef::Config.chef_server_url)
end
host() click to toggle source
# File lib/chef/knife/ssl_fetch.rb, line 51
def host
  uri.host
end
invalid_uri!() click to toggle source
# File lib/chef/knife/ssl_fetch.rb, line 67
def invalid_uri!
  ui.error("Given URI: `#{given_uri}' is invalid")
  show_usage
  exit 1
end
normalize_cn(cn) click to toggle source

Convert the CN of a certificate into something that will work well as a filename. To do so, all `*` characters are converted to the string “wildcard” and then all characters other than alphanumeric and hypen characters are converted to underscores. NOTE: There is some confustion about what the CN will contain when using internationalized domain names. RFC 6125 mandates that the ascii representation be used, but it is not clear whether this is followed in practice. tools.ietf.org/html/rfc6125#section-6.4.2

# File lib/chef/knife/ssl_fetch.rb, line 104
def normalize_cn(cn)
  cn.gsub("*", "wildcard").gsub(/[^[:alnum:]\-]/, '_')
end
noverify_peer_ssl_context() click to toggle source
# File lib/chef/knife/ssl_fetch.rb, line 80
def noverify_peer_ssl_context
  @noverify_peer_ssl_context ||= begin
    noverify_peer_context = OpenSSL::SSL::SSLContext.new
    noverify_peer_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
    noverify_peer_context
  end
end
port() click to toggle source
# File lib/chef/knife/ssl_fetch.rb, line 55
def port
  uri.port
end
remote_cert_chain() click to toggle source
# File lib/chef/knife/ssl_fetch.rb, line 73
def remote_cert_chain
  tcp_connection = TCPSocket.new(host, port)
  shady_ssl_connection = OpenSSL::SSL::SSLSocket.new(tcp_connection, noverify_peer_ssl_context)
  shady_ssl_connection.connect
  shady_ssl_connection.peer_cert_chain
end
run() click to toggle source
# File lib/chef/knife/ssl_fetch.rb, line 126
      def run
        validate_uri
        ui.warn("Certificates from #{host} will be fetched and placed in your trusted_cert
directory (#{trusted_certs_dir}).

Knife has no means to verify these are the correct certificates. You should
verify the authenticity of these certificates after downloading.

")
        remote_cert_chain.each do |cert|
          write_cert(cert)
        end
      end
trusted_certs_dir() click to toggle source
# File lib/chef/knife/ssl_fetch.rb, line 112
def trusted_certs_dir
  configuration.trusted_certs_dir
end
uri() click to toggle source
# File lib/chef/knife/ssl_fetch.rb, line 40
def uri
  @uri ||= begin
    Chef::Log.debug("Checking SSL cert on #{given_uri}")
    URI.parse(given_uri)
  end
end
validate_uri() click to toggle source
# File lib/chef/knife/ssl_fetch.rb, line 59
def validate_uri
  unless host && port
    invalid_uri!
  end
rescue URI::Error
  invalid_uri!
end
write_cert(cert) click to toggle source
# File lib/chef/knife/ssl_fetch.rb, line 116
def write_cert(cert)
  FileUtils.mkdir_p(trusted_certs_dir)
  cn = cn_of(cert)
  filename = File.join(trusted_certs_dir, "#{normalize_cn(cn)}.crt")
  ui.msg("Adding certificate for #{cn} in #{filename}")
  File.open(filename, File::CREAT|File::TRUNC|File::RDWR, 0644) do |f|
    f.print(cert.to_s)
  end
end