diff --git a/acceptance/tests/ssl/autosign_command.rb b/acceptance/tests/ssl/autosign_command.rb index ac4cdc51c..b161c1be5 100644 --- a/acceptance/tests/ssl/autosign_command.rb +++ b/acceptance/tests/ssl/autosign_command.rb @@ -1,130 +1,128 @@ require 'puppet/acceptance/common_utils' extend Puppet::Acceptance::CAUtils test_name "autosign command and csr attributes behavior (#7243,#7244)" do - skip_test "This test is pending additional CA work" if @options[:is_jvm_puppet] - def assert_key_generated(name) assert_match(/Creating a new SSL key for #{name}/, stdout, "Expected agent to create a new SSL key for autosigning") end testdirs = {} step "generate tmp dirs on all hosts" do hosts.each { |host| testdirs[host] = host.tmpdir('autosign_command') } end teardown do step "Remove autosign configuration" testdirs.each do |host,testdir| on(host, host_command("rm -rf '#{testdir}'") ) end reset_agent_ssl end hostname = master.execute('facter hostname') fqdn = master.execute('facter fqdn') reset_agent_ssl(false) step "Step 1: ensure autosign command can approve CSRs" do master_opts = { 'master' => { 'autosign' => '/bin/true', 'dns_alt_names' => "puppet,#{hostname},#{fqdn}", } } with_puppet_running_on(master, master_opts) do agents.each do |agent| next if agent == master on(agent, puppet("agent --test --server #{master} --waitforcert 0 --certname #{agent}-autosign")) assert_key_generated(agent) assert_match(/Caching certificate for #{agent}/, stdout, "Expected certificate to be autosigned") end end end reset_agent_ssl(false) step "Step 2: ensure autosign command can reject CSRs" do master_opts = { 'master' => { 'autosign' => '/bin/false', 'dns_alt_names' => "puppet,#{hostname},#{fqdn}", } } with_puppet_running_on(master, master_opts) do agents.each do |agent| next if agent == master on(agent, puppet("agent --test --server #{master} --waitforcert 0 --certname #{agent}-reject"), :acceptable_exit_codes => [1]) assert_key_generated(agent) assert_match(/no certificate found/, stdout, "Expected certificate to not be autosigned") end end end autosign_inspect_csr_path = "#{testdirs[master]}/autosign_inspect_csr.rb" step "Step 3: setup an autosign command that inspects CSR attributes" do autosign_inspect_csr = <<-END #!/usr/bin/env ruby require 'openssl' def unwrap_attr(attr) set = attr.value str = set.value.first str.value end csr_text = STDIN.read csr = OpenSSL::X509::Request.new(csr_text) passphrase = csr.attributes.find { |a| a.oid == '1.3.6.1.4.1.34380.2.1' } # And here we jump hoops to unwrap ASN1's Attr Set Str if unwrap_attr(passphrase) == 'my passphrase' exit 0 end exit 1 END create_remote_file(master, autosign_inspect_csr_path, autosign_inspect_csr) on master, "chmod 777 #{testdirs[master]}" on master, "chmod 777 #{autosign_inspect_csr_path}" end agent_csr_attributes = {} step "Step 4: create attributes for inclusion on csr on agents" do csr_attributes = <<-END custom_attributes: 1.3.6.1.4.1.34380.2.0: hostname.domain.com 1.3.6.1.4.1.34380.2.1: my passphrase 1.3.6.1.4.1.34380.2.2: # system IPs in hex - 0xC0A80001 # 192.168.0.1 - 0xC0A80101 # 192.168.1.1 END agents.each do |agent| agent_csr_attributes[agent] = "#{testdirs[agent]}/csr_attributes.yaml" create_remote_file(agent, agent_csr_attributes[agent], csr_attributes) end end reset_agent_ssl(false) step "Step 5: successfully obtain a cert" do master_opts = { 'master' => { 'autosign' => autosign_inspect_csr_path, 'dns_alt_names' => "puppet,#{hostname},#{fqdn}", }, } with_puppet_running_on(master, master_opts) do agents.each do |agent| next if agent == master step "attempting to obtain cert for #{agent}" on(agent, puppet("agent --test --server #{master} --waitforcert 0 --csr_attributes '#{agent_csr_attributes[agent]}' --certname #{agent}-attrs"), :acceptable_exit_codes => [0]) assert_key_generated(agent) end end end end diff --git a/acceptance/tests/ssl/certificate_extensions.rb b/acceptance/tests/ssl/certificate_extensions.rb index 1a46d6837..1f7832aa2 100644 --- a/acceptance/tests/ssl/certificate_extensions.rb +++ b/acceptance/tests/ssl/certificate_extensions.rb @@ -1,77 +1,75 @@ require 'puppet/acceptance/common_utils' require 'puppet/acceptance/temp_file_utils' extend Puppet::Acceptance::CAUtils extend Puppet::Acceptance::TempFileUtils initialize_temp_dirs test_name "certificate extensions available as trusted data" do - skip_test "This test is pending additional CA work" if @options[:is_jvm_puppet] - teardown do reset_agent_ssl end hostname = master.execute('facter hostname') fqdn = master.execute('facter fqdn') site_pp = get_test_file_path(master, "site.pp") master_config = { 'master' => { 'autosign' => '/bin/true', 'dns_alt_names' => "puppet,#{hostname},#{fqdn}", 'manifest' => site_pp, 'trusted_node_data' => true, } } csr_attributes = YAML.dump({ 'extension_requests' => { # registered puppet extensions 'pp_uuid' => 'b5e63090-5167-11e3-8f96-0800200c9a66', 'pp_instance_id' => 'i-3fkva', # private (arbitrary) extensions '1.3.6.1.4.1.34380.1.2.1' => 'db-server', # node role '1.3.6.1.4.1.34380.1.2.2' => 'webops' # node group } }) create_test_file(master, "site.pp", <<-SITE) file { "$test_dir/trusted.yaml": ensure => file, content => inline_template("<%= YAML.dump(@trusted) %>") } SITE reset_agent_ssl(false) with_puppet_running_on(master, master_config) do agents.each do |agent| next if agent == master agent_csr_attributes = get_test_file_path(agent, "csr_attributes.yaml") create_remote_file(agent, agent_csr_attributes, csr_attributes) on(agent, puppet("agent", "--test", "--server", master, "--waitforcert", 0, "--csr_attributes", agent_csr_attributes, "--certname #{agent}-extensions", 'ENV' => { "FACTER_test_dir" => get_test_file_path(agent, "") }), :acceptable_exit_codes => [0, 2]) trusted_data = YAML.load(on(agent, "cat #{get_test_file_path(agent, 'trusted.yaml')}").stdout) assert_equal({ 'authenticated' => 'remote', 'certname' => "#{agent}-extensions", 'extensions' => { 'pp_uuid' => 'b5e63090-5167-11e3-8f96-0800200c9a66', 'pp_instance_id' => 'i-3fkva', '1.3.6.1.4.1.34380.1.2.1' => 'db-server', '1.3.6.1.4.1.34380.1.2.2' => 'webops' } }, trusted_data) end end end diff --git a/acceptance/tests/ssl/puppet_cert_generate_and_autosign.rb b/acceptance/tests/ssl/puppet_cert_generate_and_autosign.rb index 485d2c34b..618b9a000 100644 --- a/acceptance/tests/ssl/puppet_cert_generate_and_autosign.rb +++ b/acceptance/tests/ssl/puppet_cert_generate_and_autosign.rb @@ -1,193 +1,191 @@ require 'puppet/acceptance/common_utils' extend Puppet::Acceptance::CAUtils test_name "Puppet cert generate behavior (#6112)" do - skip_test "This test is pending additional CA work" if @options[:is_jvm_puppet] - # This acceptance test documents the behavior of `puppet cert generate` calls # for three cases: # # 1) On a host which has ssl/ca infrastructure. Typically this would be the # puppet master which is also the CA, and the expectation is that this is the # host that `puppet cert generate` commands should be issued on. # # This case should succeed as it is the documented use case for the command. # # 2) On a host which has no ssl/ca infrastructure but has a valid ca.pem from # the CA cached in ssl/cert. This would be a host (let's say CN=foo) with a # puppet agent that has checked in and received a signed ca.pem and foo.pem # certificate from the master CA. # # Talking with Nick Fagerlund, this behavior is unspecified, although it # should not result in a certificate. And it currently fails with "Error: # The certificate retrieved from the master does not match the agent's # private key." This error messaging is a little misleading, in that it is # strictly speaking true but does not point out that it is the CA cert and # local CA keys that are involved. # # What happens is `puppet cert generate` starts by creating a local # CertificateAuthority instance which looks for a locally cached # ssl/cert/ca.pem, generating ssl/ca/ keys in the process. It finds an # ssl/cert/ca.pem, because we have the master CA's pem, but this certificate # does not match the keys in ssl/ca that have just been generated (for the # local CA instance), and validation of the cert fails with the above error. # # 3) On a host which has no ssl infrastructure at all (fresh install, hasn't # tried to send a CSR to the puppet master yet). # # Tracing this case, what happens is that `puppet cert generate` starts by # creating a local CertificateAuthority instance which looks for a locally # cached ssl/cert/ca.pem. It does not find one and then procedes to # generate_ca_certificate, which populates a local ssl/ca with public/private # keys for a local ca cert, creates a CSR locally for this cert, which it # then signs and saves in ssl/ca/ca_crt.pem and caches in ssl/certs/ca.pem. # (This is the normal bootstrapping case for a CA; same thing happens during an # initial `puppet master` run). # # This case succeeds, but future calls such as `puppet agent -t` fail. # Haven't fully traced what happens here. test_cn = "cert.test" teardown do step "And try to leave with a good ssl configuration" reset_agent_ssl clean_cert(master, test_cn, false) end def generate_and_clean_cert(host, cn, autosign) on(host, puppet('cert', 'generate', cn, '--autosign', autosign)) assert_no_match(/Could not find certificate request for.*cert\.test/i, stderr, "Should not see an error message for a missing certificate request.") clean_cert(host, cn) end def fail_to_generate_cert_on_agent_that_is_not_ca(host, cn, autosign) return if master.is_pe? on(host, puppet('cert', 'generate', cn, '--autosign', autosign), :acceptable_exit_codes => [23]) assert_match(/Error: The certificate retrieved from the master does not match the agent's private key./, stderr, "Should not be able to generate a certificate on an agent that is not also the CA, with autosign #{autosign}.") end def generate_and_clean_cert_with_dns_alt_names(host, cn, autosign) on(host, puppet('cert', 'generate', cn, '--autosign', autosign, '--dns_alt_names', 'foo,bar')) on(master, puppet('cert', 'list', '--all')) assert_match(/cert.test.*DNS:foo/, stdout, "Should find a dns entry for 'foo' in the cert.test listing.") assert_match(/cert.test.*DNS:bar/, stdout, "Should find a dns entry for 'bar' in the cert.test listing.") clean_cert(host, cn) end # @return true if the passed host operates in a master role. def host_is_master?(host) host['roles'].include?('master') end ################ # Cases 1 and 2: step "Case 1 and 2: Tests behavior of `puppet cert generate` on a master node, and on an agent node that has already authenticated to the master. Tests with combinations of autosign and dns_alt_names." reset_agent_ssl # User story: # A root user on the puppet master has a configuration where autosigning is # explicitly false. They run 'puppet cert generate foo.bar' for a new # certificate and expect a certificate to be generated and signed because they # are the root CA, and autosigning should not effect this. step "puppet cert generate with autosign false" hosts.each do |host| if host_is_master?(host) generate_and_clean_cert(host, test_cn, false) else fail_to_generate_cert_on_agent_that_is_not_ca(host, test_cn, false) end end # User story: # A root user on the puppet master has a configuration where autosigning is # explicitly true. They run 'puppet cert generate foo.bar' for a new # certificate and expect a certificate to be generated and signed without # interference from the autosigning setting. (This succeedes in 3.2.2 and # earlier but produces an extraneous error message per #6112 because there are # two attempts to sign the CSR, only the first of which succedes due to the CSR # already haveing been signed and removed.) step "puppet cert generate with autosign true" hosts.each do |host| if host_is_master?(host) generate_and_clean_cert(host, test_cn, true) else fail_to_generate_cert_on_agent_that_is_not_ca(host, test_cn, true) end end # These steps are documenting the current behavior with regard to --dns_alt_names # flags submitted on the command line with a puppet cert generate. step "puppet cert generate with autosign false and dns_alt_names" hosts.each do |host| if host_is_master?(host) generate_and_clean_cert_with_dns_alt_names(host, test_cn, false) else fail_to_generate_cert_on_agent_that_is_not_ca(host, test_cn, false) end end step "puppet cert generate with autosign true and dns_alt_names" hosts.each do |host| if host_is_master?(host) on(host, puppet('cert', 'generate', test_cn, '--autosign', 'true', '--dns_alt_names', 'foo,bar'), :acceptable_exit_codes => [24]) assert_match(/Error: CSR '#{test_cn}' contains subject alternative names.*Use.*--allow-dns-alt-names/, stderr, "Should not be able to generate a certificate, with autosign true and dns_alt_names without specifying allow_dns_alt_names flag.") # And now sign with allow_dns_alt_names set on(host, puppet('cert', '--allow-dns-alt-names', 'sign', test_cn)) assert_match(/Signed certificate request for #{test_cn}/, stdout, "Signed certificate once --allow-dns-alt-names specified") clean_cert(host, test_cn) else fail_to_generate_cert_on_agent_that_is_not_ca(host, test_cn, true) end end ######### # Case 3: # Attempting to run this in a windows machine fails during the CA generation # attempting to set the ssl/ca/serial file. Fails inside # Puppet::Settings#readwritelock because we can't overwrite the lock file in # Windows. step "Case 3: A host with no ssl infrastructure makes a `puppet cert generate` call" do if !master.is_pe? confine_block :except, :platform => 'windows' do clear_agent_ssl step "puppet cert generate" hosts.each do |host| generate_and_clean_cert(host, test_cn, false) # Commenting this out until we can figure out whether this behavior is a bug or # not, and what the platform issues are. # # Need to figure out exactly why this fails, where it fails, and document or # fix. Can reproduce a failure locally in Ubuntu, and the attempt fails # 'as expected' in Jenkins acceptance jobs on Lucid and Fedora, but succeeds # on RHEL and Centos... # # Redmine (#21739) captures this. # # with_puppet_running_on(master, :master => { :certname => master, :autosign => true }) do # step "but now unable to authenticate normally as an agent" # # on(host, puppet('agent', '-t'), :acceptable_exit_codes => [1]) # # end end end end end ########## # PENDING: Test behavior of `puppet cert generate` with an external ca. end diff --git a/acceptance/tests/ticket_3360_allow_duplicate_csr_with_option_set.rb b/acceptance/tests/ticket_3360_allow_duplicate_csr_with_option_set.rb index b9a8fcc66..54d69177e 100644 --- a/acceptance/tests/ticket_3360_allow_duplicate_csr_with_option_set.rb +++ b/acceptance/tests/ticket_3360_allow_duplicate_csr_with_option_set.rb @@ -1,62 +1,60 @@ test_name "#3360: Allow duplicate CSR when allow_duplicate_certs is on" -skip_test "This test is pending additional CA work" if @options[:is_jvm_puppet] - agent_hostnames = agents.map {|a| a.to_s} with_puppet_running_on master, {'master' => {'allow_duplicate_certs' => true}} do agents.each do |agent| if agent['platform'].include?('windows') Log.warn("Pending: Windows does not support facter fqdn") next end step "Generate a certificate request for the agent" fqdn = on(agent, facter("fqdn")).stdout.strip on agent, "puppet certificate generate #{fqdn} --ca-location remote --server #{master}" end step "Collect the original certs" on master, puppet_cert("--sign --all") original_certs = on master, puppet_cert("--list --all") old_certs = {} original_certs.stdout.each_line do |line| if line =~ /^\+ (\S+) \((.+)\)$/ old_certs[$1] = $2 puts "old cert: #{$1} #{$2}" end end agents.each do |agent| if agent['platform'].include?('windows') Log.warn("Pending: Windows does not support facter fqdn") next end fqdn = on(agent, facter("fqdn")).stdout.strip step "Make another request with the same certname" on agent, "puppet certificate generate #{fqdn} --ca-location remote --server #{master}" end step "Collect the new certs" on master, puppet_cert("--sign --all") new_cert_list = on master, puppet_cert("--list --all") new_certs = {} new_cert_list.stdout.each_line do |line| if line =~ /^\+ (\S+) \((.+)\)$/ new_certs[$1] = $2 puts "new cert: #{$1} #{$2}" end end step "Verify the certs have changed" # using the agent name as the key may cause errors; # agent name from cfg file is likely to have short name # where certs might be signed with long names. old_certs.each_key { |key| next if key.include? master # skip the masters cert, only care about agents assert_not_equal(old_certs[key], new_certs[key], "Expected #{key} to have a changed key") } end diff --git a/acceptance/tests/ticket_7117_broke_env_criteria_authconf.rb b/acceptance/tests/ticket_7117_broke_env_criteria_authconf.rb index 089b90612..7ae06b19a 100644 --- a/acceptance/tests/ticket_7117_broke_env_criteria_authconf.rb +++ b/acceptance/tests/ticket_7117_broke_env_criteria_authconf.rb @@ -1,40 +1,38 @@ # Windows doesn't suppoert Facter fqdn properly confine :except, :platform => 'windows' test_name "#7117 Broke the environment criteria in auth.conf" -skip_test "This test is pending additional CA work -- support for dns_alt_names in PE-4372" if @options[:is_jvm_puppet] - -testdir = master.tmpdir('env_in_auth_conf') +testdir = create_tmpdir_for_user master, 'env_in_auth_conf' # add to auth.conf add_2_authconf = %q{ path / environment override auth any allow * } step "Create a temp auth.conf" create_remote_file master, "#{testdir}/auth.conf", add_2_authconf on master, "chmod 644 #{testdir}/auth.conf" on master, "chmod 777 #{testdir}" with_puppet_running_on master, {'master' => {'rest_authconfig' => "#{testdir}/auth.conf"}}, testdir do agents.each do |agent| # Run test on Agents step "Run agent to upload facts" on agent, puppet_agent("--test --server #{master}") certname = master.is_pe? ? agent.to_s : on(agent, facter('fqdn')).stdout.chomp step "Fetch agent facts from Puppet Master" on(agent, "curl -k -H \"Accept: yaml\" https://#{master}:8140/override/facts/#{certname}") do assert_match(/--- !ruby\/object:Puppet::Node::Facts/, stdout, "Agent Facts not returned for #{agent}") end end end