Merge pull request #459 from tphoney/modules-1675_check_gpg_version
authorMorgan Haskel <morgan@puppetlabs.com>
Fri, 13 Mar 2015 21:40:43 +0000 (14:40 -0700)
committerMorgan Haskel <morgan@puppetlabs.com>
Fri, 13 Mar 2015 21:40:43 +0000 (14:40 -0700)
initial commit for apt_key checking

README.md
lib/puppet/provider/apt_key/apt_key.rb
lib/puppet/type/apt_key.rb
spec/acceptance/apt_key_provider_spec.rb

index 7e39c8d9eeb328ca8dff84da171c47428ce464f1..b325ba9d2bbbe0d7c861ff80618237e828506f10 100644 (file)
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@ The apt module provides a simple interface for managing Apt source, key, and def
 
 The apt module automates obtaining and installing software packages on \*nix systems.
 
-**Note**: While this module allows the use of short keys, **we urge you NOT to use short keys**, as they pose a serious security issue by opening you up to collision attacks.
+**Note**: While this module allows the use of short keys, **warnings are thrown if a full fingerprint is not used**, as they pose a serious security issue by opening you up to collision attacks.
 
 ## Setup
 
index 67a8aa0643db68edb8fca0341262c5325b38bc4e..687c99502efb8e0bdd5e630ceefa4113609d307f 100644 (file)
@@ -16,6 +16,7 @@ Puppet::Type.type(:apt_key).provide(:apt_key) do
   confine    :osfamily => :debian
   defaultfor :osfamily => :debian
   commands   :apt_key  => 'apt-key'
+  commands   :gpg      => '/usr/bin/gpg'
 
   def self.instances
     cli_args = ['adv','--list-keys', '--with-colons', '--fingerprint']
@@ -136,6 +137,18 @@ Puppet::Type.type(:apt_key).provide(:apt_key) do
     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? command(:gpg)
+        extracted_key = execute(["#{command(: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 #{resource[:name]} and the fingerprint from content/source do not match. Please check there is not an error in the id or check the content/source is legitimate.")
+        end
+      else
+        warning ('/usr/bin/gpg cannot be found for verification of the id.')
+      end 
+    end
     file.path
   end
 
index 70825ac218c5bb286dc04219145eecf442803094..7130496ea9e55dafaf4e3386a59c7645ffa601dd 100644 (file)
@@ -23,6 +23,9 @@ Puppet::Type.newtype(:apt_key) do
     if self[:content] and self[:source]
       fail('The properties content and source are mutually exclusive.')
     end
+    if self[:id].length < 40 
+      warning('The id should be a full fingerprint (40 characters), see README.')
+    end 
   end
 
   newparam(:id, :namevar => true) do
index 24277d237ad60fcf392332e7eedc4b3e7d6d6a95..1f703c9ce62f02c9059c40f62d667c8b81df81b0 100644 (file)
@@ -520,4 +520,38 @@ ugVIB2pi+8u84f+an4Hml4xlyijgYu05pqNvnLRyJDLd61hviLC8GYU=
       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