Skip to content

Commit

Permalink
Refs #6875 - separate the default CA and server CA
Browse files Browse the repository at this point in the history
Up until now, we used the default CA for both server and client certificates.
This made practically impossible to issue the server certificates outside of
the installer and pass it in as arguments.

By default, the server CA is the same as default CA, unless the $server_ca_cert
is specified.

In the bootstrap rpm, we ship both server CA (for verifying the server) as well
the default CA (for verifying the qpid by the gofer).
  • Loading branch information
iNecas committed Aug 15, 2014
1 parent 30b541c commit dff469d
Show file tree
Hide file tree
Showing 19 changed files with 348 additions and 139 deletions.
48 changes: 37 additions & 11 deletions lib/puppet/provider/ca/katello_ssl_tool.rb
Expand Up @@ -6,19 +6,45 @@
protected

def generate!
katello_ssl_tool('--gen-ca',
'-p', "file:#{resource[:password_file]}",
'--force',
'--ca-cert-dir', target_path('certs'),
'--set-common-name', resource[:common_name],
'--ca-cert', File.basename(pubkey),
'--ca-key', File.basename(privkey),
'--ca-cert-rpm', rpmfile_base_name,
*common_args)
if existing_pubkey
FileUtils.mkdir_p(build_path)
FileUtils.cp(existing_pubkey, build_path(File.basename(pubkey)))
katello_ssl_tool('--gen-ca',
'--ca-cert-dir', target_path('certs'),
'--ca-cert', File.basename(pubkey),
'--ca-cert-rpm', rpmfile_base_name,
'--rpm-only')
else
katello_ssl_tool('--gen-ca',
'-p', "file:#{resource[:password_file]}",
'--force',
'--ca-cert-dir', target_path('certs'),
'--set-common-name', resource[:common_name],
'--ca-cert', File.basename(pubkey),
'--ca-key', File.basename(privkey),
'--ca-cert-rpm', rpmfile_base_name,
*common_args)

end
super
end

def existing_pubkey
if resource[:ca]
ca_details[:pubkey]
elsif resource[:custom_pubkey]
resource[:custom_pubkey]
end
end

def files_to_generate
[rpmfile, privkey]
def deploy!
if File.exists?(rpmfile)
# the rpm is available locally on the file system
rpm('-Uvh', '--force', rpmfile)
else
# we search the rpm in yum repo
yum("install", "-y", rpmfile_base_name)
end
end

def files_to_deploy
Expand Down
50 changes: 27 additions & 23 deletions lib/puppet/provider/cert/katello_ssl_tool.rb
Expand Up @@ -4,34 +4,38 @@
Puppet::Type.type(:cert).provide(:katello_ssl_tool, :parent => Puppet::Provider::KatelloSslTool::Cert) do

def generate!
resource[:common_name] ||= resource[:hostname]
purpose = resource[:purpose]
katello_ssl_tool("--gen-#{purpose}",
'-p', "file:#{resource[:password_file]}",
'--set-hostname', resource[:hostname],
'--set-common-name', resource[:common_name],
'--ca-cert', ca_details[:pubkey],
'--ca-key', ca_details[:privkey],
'--server-cert', File.basename(pubkey),
'--server-cert-req', "#{File.basename(pubkey)}.req",
'--server-key', File.basename(privkey),
'--server-rpm', rpmfile_base_name,
*common_args)
args = [ "--gen-#{resource[:purpose]}",
'--set-hostname', resource[:hostname],
'--server-cert', File.basename(pubkey),
'--server-cert-req', File.basename(req_file),
'--server-key', File.basename(privkey),
'--server-rpm', rpmfile_base_name ]
if resource[:custom_pubkey]
FileUtils.mkdir_p(build_path)
FileUtils.cp(resource[:custom_pubkey], build_path(File.basename(pubkey)))
FileUtils.cp(resource[:custom_privkey], build_path(File.basename(privkey)))
FileUtils.cp(resource[:custom_req], build_path(File.basename(req_file)))
args << '--rpm-only'
else
resource[:common_name] ||= resource[:hostname]
args.concat(['-p', "file:#{resource[:password_file]}",
'--set-hostname', resource[:hostname],
'--set-common-name', resource[:common_name],
'--ca-cert', ca_details[:pubkey],
'--ca-key', ca_details[:privkey]])
args.concat(common_args)
end
katello_ssl_tool(*args)
super
end

protected

def build_path(file_name)
self.class.build_path(File.join(resource[:hostname], file_name))
def req_file
"#{self.pubkey}.req"
end

def ca_details
return @ca_details if defined? @ca_details
if ca_resource = @resource[:ca]
name = ca_resource.to_hash[:name]
@ca_details = Puppet::Provider::KatelloSslTool::Cert.details(name)
else
raise 'Wanted to generate cert without ca specified'
end
def build_path(file_name = '')
self.class.build_path(File.join(resource[:hostname], file_name))
end
end
47 changes: 47 additions & 0 deletions lib/puppet/provider/certs_bootstrap_rpm/katello_ssl_tool.rb
@@ -0,0 +1,47 @@
require File.expand_path('../../katello_ssl_tool', __FILE__)

Puppet::Type.type(:certs_bootstrap_rpm).provide(:katello_ssl_tool) do

commands :katello_certs_gen_rpm => 'katello-certs-gen-rpm'

def run
post_script_file = File.join(resource[:dir], 'rhsm-katello-reconfigure')
File.open(post_script_file, 'w') { |f| f << resource[:bootstrap_script] }

Dir.chdir(resource[:dir]) do
katello_certs_gen_rpm('--name', resource[:name],
'--version', '1.0',
'--release', next_release,
'--packager', 'None',
'--vendor', 'None',
'--group', 'Applications/System',
'--summary', resource[:summary],
'--description', resource[:description],
'--requires', 'subscription-manager',
'--post', post_script_file,
*resource[:files])
if resource[:alias]
File.delete(resource[:alias]) if File.exists?(resource[:alias])
File.symlink(last_rpm, resource[:alias])
end
system('/sbin/restorecon ./*.rpm')
end
ensure
File.delete(post_script_file) if File.exists?(post_script_file)
end

protected

def last_rpm
Dir.glob(File.join(resource[:dir], "#{resource[:name]}-*.noarch.rpm")).sort.last
end

def next_release
if last_rpm
last_rpm[/-(\d+).noarch.rpm$/, 1].to_i + 1
else
1
end
end

end
23 changes: 22 additions & 1 deletion lib/puppet/provider/katello_ssl_tool.rb
Expand Up @@ -41,9 +41,16 @@ def katello_ssl_tool(*args)
end
end

def generate!
if File.exists?(update_file)
File.delete(update_file)
end
end

def generate?
return false unless resource[:generate]
return true if resource[:regenerate]
return true if File.exists?(update_file)
return files_to_generate.any? { |file| ! File.exist?(file) }
end

Expand Down Expand Up @@ -105,6 +112,11 @@ def rpmfile
return rpmfile
end

# file that indicates that a new version of the rpm should be updated
def update_file
self.build_path("#{rpmfile_base_name}.update")
end

def rpmfile_base_name
resource[:name]
end
Expand All @@ -129,14 +141,23 @@ def self.target_path(file_name = '')
File.join("/etc/pki/katello-certs-tools", file_name)
end

def build_path(file_name)
def build_path(file_name = '')
self.class.build_path(file_name)
end

def self.build_path(file_name = '')
File.join("/root/ssl-build", file_name)
end

def ca_details
return @ca_details if defined? @ca_details
if ca_resource = @resource[:ca]
name = ca_resource.to_hash[:name]
@ca_details = Puppet::Provider::KatelloSslTool::Cert.details(name)
else
raise 'Wanted to generate cert without ca specified'
end
end
end

class CertFile < Puppet::Provider
Expand Down
15 changes: 0 additions & 15 deletions lib/puppet/type/cert.rb
Expand Up @@ -7,22 +7,7 @@

newparam(:hostname)

newparam(:ca) do
validate do |value|
unless value.is_a?(Puppet::Resource) && value.resource_type.name == :ca
raise ArgumentError, "Expected Ca resource"
end
end
end

newparam(:purpose) do
defaultto 'server'
end

autorequire(:ca) do
if @parameters.has_key?(:ca)
@parameters[:ca].value.to_hash[:name]
end
end

end
33 changes: 33 additions & 0 deletions lib/puppet/type/certs_bootstrap_rpm.rb
@@ -0,0 +1,33 @@
Puppet::Type.newtype(:certs_bootstrap_rpm) do

@doc = "Geneate certificates bootstrap rpm for the clietns
This resource generates an rpm that can be distributed to the clients to set
the subscription-manager to communicate with the server.
It should be subcribed to the resource that represent the server CA,
so that every time the resoruce is generated, a new bootstrap rpm version.
When alias is specified, it symlinks the latest rpm version to this alias
for easier redistribution.
"

desc 'Generates the rpm with certificates for boostraping the clients'
newparam(:name, :namevar => true)

newparam(:dir)

newparam(:summary)

newparam(:description)

newparam(:bootstrap_script)

newparam(:files)

newparam(:alias)

def refresh
provider.run
end
end
20 changes: 20 additions & 0 deletions lib/puppet/type/certs_common.rb
Expand Up @@ -8,6 +8,12 @@ module Certs

newparam(:name, :namevar => true)

newparam(:custom_pubkey)

newparam(:custom_privkey)

newparam(:custom_req)

newparam(:common_name)

newparam(:email)
Expand All @@ -31,6 +37,20 @@ module Certs
newparam(:deploy)

newparam(:password_file)

newparam(:ca) do
validate do |value|
if value && !value.is_a?(Puppet::Resource) || value.resource_type.name != :ca
raise ArgumentError, "Expected Ca resource"
end
end
end

autorequire(:ca) do
if @parameters.has_key?(:ca)
@parameters[:ca].value.to_hash[:name]
end
end
end

FILE_COMMON_PARAMS = Proc.new do
Expand Down
49 changes: 31 additions & 18 deletions manifests/apache.pp
Expand Up @@ -5,28 +5,39 @@
$generate = $::certs::generate,
$regenerate = $::certs::regenerate,
$deploy = $::certs::deploy,

$ca = $::certs::default_ca,
) inherits certs::params {

$apache_cert_name = "${hostname}-apache"
$apache_cert = "${certs::pki_dir}/certs/katello-apache.crt"
$apache_key = "${certs::pki_dir}/private/katello-apache.key"

cert { $apache_cert_name:
ensure => present,
hostname => $hostname,
country => $::certs::country,
state => $::certs::state,
city => $::certs::sity,
org => $::certs::org,
org_unit => $::certs::org_unit,
expiration => $::certs::expiration,
ca => $ca,
generate => $generate,
regenerate => $regenerate,
deploy => $deploy,
password_file => $certs::ca_key_password_file,
if $::certs::server_cert {
cert { $apache_cert_name:
ensure => present,
hostname => $hostname,
generate => $generate,
deploy => $deploy,
regenerate => $regenerate,
custom_pubkey => $::certs::server_cert,
custom_privkey => $::certs::server_key,
custom_req => $::certs::server_cert_req,
}
} else {
cert { $apache_cert_name:
ensure => present,
hostname => $hostname,
country => $::certs::country,
state => $::certs::state,
city => $::certs::sity,
org => $::certs::org,
org_unit => $::certs::org_unit,
expiration => $::certs::expiration,
ca => $::certs::default_ca,
generate => $generate,
regenerate => $regenerate,
deploy => $deploy,
password_file => $certs::ca_key_password_file,
}
}

if $deploy {
Expand All @@ -36,11 +47,13 @@
Cert[$apache_cert_name] ~>
pubkey { $apache_cert:
ensure => present,
key_pair => Cert[$apache_cert_name]
key_pair => Cert[$apache_cert_name],
notify => Service['httpd']
} ~>
privkey { $apache_key:
ensure => present,
key_pair => Cert[$apache_cert_name]
key_pair => Cert[$apache_cert_name],
notify => Service['httpd']
} ->
file { $apache_key:
owner => $::apache::user,
Expand Down

0 comments on commit dff469d

Please sign in to comment.