initial commit for gpg key checking
authortphoney <tp@puppetlabs.com>
Fri, 6 Mar 2015 16:14:40 +0000 (16:14 +0000)
committertphoney <tp@puppetlabs.com>
Thu, 12 Mar 2015 18:25:26 +0000 (18:25 +0000)
better attempt at gpg version checking

adding in key length warning

removing version check, adding key check

adding tests

clean up the code

small changes

use commands

documentation updates

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

index 1c06e1760c40fde7ce3443be31cf52daba6d6295..45e905248f90e52fc052b4dcd7d25dc11ff0d45f 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.
 
 
 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
 
 
 ## 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'
   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']
 
   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
     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
 
     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[: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
   end
 
   newparam(:id, :namevar => true) do
index 24277d237ad60fcf392332e7eedc4b3e7d6d6a95..1f703c9ce62f02c9059c40f62d667c8b81df81b0 100644 (file)
@@ -520,4 +520,38 @@ ugVIB2pi+8u84f+an4Hml4xlyijgYu05pqNvnLRyJDLd61hviLC8GYU=
       end
     end
   end
       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
 end