diff --git a/lib/puppet/provider/apt_key/apt_key.rb b/lib/puppet/provider/apt_key/apt_key.rb index 67a8aa0643..e92aa250f5 100644 --- a/lib/puppet/provider/apt_key/apt_key.rb +++ b/lib/puppet/provider/apt_key/apt_key.rb @@ -136,6 +136,18 @@ def tempfile(content) file = Tempfile.new('apt_key') file.write content file.close + #confirm that the fingerprint from the file, matches the long key that is in the manifest + if name.size == 40 + if File.executable? '/usr/bin/gpg' + extracted_key = execute(["/usr/bin/gpg --with-fingerprint --with-colons #{file.path} | awk -F: '/^fpr:/ { print $10 }'"], :failonfail => false) + extracted_key = extracted_key.chomp + if extracted_key != name + fail ('The id in your manifest and the fingerprint from content/source do not match. Please check the content/source is legitimate.') + end + else + warning ('/usr/bin/gpg is not executable, we cannot verify that the id and the fingerprint from the source/content match.') + end + end file.path end diff --git a/lib/puppet/type/apt_key.rb b/lib/puppet/type/apt_key.rb index 70825ac218..5d559087f1 100644 --- a/lib/puppet/type/apt_key.rb +++ b/lib/puppet/type/apt_key.rb @@ -23,6 +23,9 @@ if self[:content] and self[:source] fail('The properties content and source are mutually exclusive.') end + if self[:id].length < 40 + warning('The key should be at least a full fingerprint.') + end end newparam(:id, :namevar => true) do diff --git a/spec/acceptance/apt_key_provider_spec.rb b/spec/acceptance/apt_key_provider_spec.rb index 24277d237a..1f703c9ce6 100644 --- a/spec/acceptance/apt_key_provider_spec.rb +++ b/spec/acceptance/apt_key_provider_spec.rb @@ -520,4 +520,38 @@ end end end + + describe 'fingerprint validation against source/content' do + context 'fingerprint in id matches fingerprint from remote key' do + it 'works' do + pp = <<-EOS + apt_key { 'puppetlabs': + id => '#{PUPPETLABS_GPG_KEY_FINGERPRINT}', + ensure => 'present', + source => 'https://#{PUPPETLABS_APT_URL}/#{PUPPETLABS_GPG_KEY_FILE}', + } + EOS + + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_failures => true) + end + end + + context 'fingerprint in id does NOT match fingerprint from remote key' do + it 'works' do + pp = <<-EOS + apt_key { 'puppetlabs': + id => '47B320EB4C7C375AA9DAE1A01054B7A24BD6E666', + ensure => 'present', + source => 'https://#{PUPPETLABS_APT_URL}/#{PUPPETLABS_GPG_KEY_FILE}', + } + EOS + + apply_manifest(pp, :expect_failures => true) do |r| + expect(r.stderr).to match(/do not match/) + end + end + end + end + end