Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

initial commit for apt_key checking #459

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
13 changes: 13 additions & 0 deletions lib/puppet/provider/apt_key/apt_key.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
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']
Expand Down Expand Up @@ -136,6 +137,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? 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

Expand Down
3 changes: 3 additions & 0 deletions lib/puppet/type/apt_key.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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 id should be a full fingerprint (40 characters), see README.')
end
end

newparam(:id, :namevar => true) do
Expand Down
34 changes: 34 additions & 0 deletions spec/acceptance/apt_key_provider_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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