diff options
author | Tim Smith <tsmith84@gmail.com> | 2020-06-05 00:21:58 -0700 |
---|---|---|
committer | Tim Smith <tsmith84@gmail.com> | 2020-06-22 23:10:01 -0700 |
commit | 9fbaff93360091b351c1ae72601b56fccf9c515e (patch) | |
tree | 31699f8177294983e0bb18031284170787640dc6 | |
parent | ee4a6e34a7c827b296940569c2d18260e88a19c1 (diff) | |
download | chef-zypper_15.tar.gz |
Add specs and rename fingerprint -> short idzypper_15
These aren't actually fingerprints. They're short key ids
https://futureboy.us/pgp.html#ShortKeyID
Signed-off-by: Tim Smith <tsmith@chef.io>
-rw-r--r-- | lib/chef/provider/zypper_repository.rb | 21 | ||||
-rw-r--r-- | spec/unit/provider/zypper_repository_spec.rb | 98 |
2 files changed, 86 insertions, 33 deletions
diff --git a/lib/chef/provider/zypper_repository.rb b/lib/chef/provider/zypper_repository.rb index d5ad8577c8..4602d804b9 100644 --- a/lib/chef/provider/zypper_repository.rb +++ b/lib/chef/provider/zypper_repository.rb @@ -119,7 +119,7 @@ class Chef # # @return [Gem::Version] the version of GPG def gpg_version - so = shell_out("gpg --version") + so = shell_out!("gpg --version") # matches 2.0 and 2.2 versions from SLES 12 and 15: https://rubular.com/r/e6D0WfGK6SXvUp version = /gpg \(GnuPG\)\s*(.*)/.match(so.stdout)[1] logger.trace("GPG package version is #{version}") @@ -133,27 +133,30 @@ class Chef def key_installed?(key_path) so = shell_out("/bin/rpm -qa gpg-pubkey*") # expected output & match: http://rubular.com/r/RdF7EcXEtb - status = /gpg-pubkey-#{key_fingerprint(key_path)}/.match(so.stdout) + status = /gpg-pubkey-#{short_key_id(key_path)}/.match(so.stdout) logger.trace("GPG key at #{key_path} is known by rpm? #{status ? "true" : "false"}") status end - # extract the gpg key fingerprint from a local file + # extract the gpg key's short key id from a local file. Learning moment: This 8 hex value ID + # is sometimes incorrectly called the fingerprint. The fingerprint is the full length value + # and googling for that will just result in sad times. + # # @param [String] key_path the path to the key on the local filesystem # - # @return [String] the fingerprint of the key - def key_fingerprint(key_path) + # @return [String] the short key id of the key + def short_key_id(key_path) if gpg_version >= Gem::Version.new("2.2") # SLES 15+ so = shell_out!("gpg --import-options import-show --dry-run --import --with-colons #{key_path}") # expected output and match: https://rubular.com/r/uXWJo3yfkli1qA - fingerprint = /fpr:*\h*(\h{8}):/.match(so.stdout)[1].downcase + short_key_id = /fpr:*\h*(\h{8}):/.match(so.stdout)[1].downcase else # SLES 12 and earlier so = shell_out!("gpg --with-fingerprint #{key_path}") # expected output and match: http://rubular.com/r/BpfMjxySQM - fingerprint = %r{pub\s*\S*/(\S*)}.match(so.stdout)[1].downcase + short_key_id = %r{pub\s*\S*/(\S*)}.match(so.stdout)[1].downcase end - logger.trace("GPG fingerprint of key at #{key_path} is #{fingerprint}") - fingerprint + logger.trace("GPG short key ID of key at #{key_path} is #{short_key_id}") + short_key_id end # install the provided gpg key diff --git a/spec/unit/provider/zypper_repository_spec.rb b/spec/unit/provider/zypper_repository_spec.rb index e01eb4c4ac..1e42fad5a8 100644 --- a/spec/unit/provider/zypper_repository_spec.rb +++ b/spec/unit/provider/zypper_repository_spec.rb @@ -18,22 +18,50 @@ require "spec_helper" -# Output of the command: -# => rpm -qa gpg-pubkey* -RPM_KEYS = <<~EOF.freeze - gpg-pubkey-307e3d54-4be01a65 - gpg-pubkey-3dbdc284-53674dd4 -EOF - -# Output of the command: -# => gpg --with-fingerprint [FILE] -ZYPPER_GPG_FINGER = <<~EOF.freeze - pub 2048R/3DBDC284 2011-08-19 [expires: 2024-06-14] - Key fingerprint = 573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62 - uid nginx signing key <signing-key@nginx.com> -EOF - describe Chef::Provider::ZypperRepository do + # Output of the command: + # => rpm -qa gpg-pubkey* + ZYPPER_RPM_KEYS = <<~EOF.freeze + gpg-pubkey-307e3d54-4be01a65 + gpg-pubkey-3dbdc284-53674dd4 + EOF + + # Output of the command: + # => gpg --with-fingerprint [FILE] + ZYPPER_GPG_20 = <<~EOF.freeze + pub 2048R/3DBDC284 2011-08-19 [expires: 2024-06-14] + Key fingerprint = 573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62 + uid nginx signing key <signing-key@nginx.com> + EOF + + # Output of the command: + # => gpg --import-options import-show --dry-run --import --with-colons [FILE] + ZYPPER_GPG_22 = <<~EOF.freeze + pub:-:2048:1:ABF5BD827BD9BF62:1313747554:1718374819::-:::scSC::::::23::0: + fpr:::::::::573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62: + uid:-::::1466086904::F18C4DBBFCB45099ABB59088DB6B252FA7E9FB41::nginx signing key <signing-key@nginx.com>::::::::::0: + gpg: Total number processed: 1 + EOF + + # Output of the command: + # -> gpg --version + ZYPPER_GPG_VERSION = <<~EOF.freeze + gpg (GnuPG) 2.2.20 + libgcrypt 1.8.5 + Copyright (C) 2020 Free Software Foundation, Inc. + License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html> + This is free software: you are free to change and redistribute it. + There is NO WARRANTY, to the extent permitted by law. + + Home: /Users/tsmith/.gnupg + Supported algorithms: + Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA + Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH, + CAMELLIA128, CAMELLIA192, CAMELLIA256 + Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224 + Compression: Uncompressed, ZIP, ZLIB, BZIP2 + EOF + let(:new_resource) { Chef::Resource::ZypperRepository.new("Nginx Repository") } let(:logger) { double("Mixlib::Log::Child").as_null_object } let(:provider) do @@ -48,8 +76,16 @@ describe Chef::Provider::ZypperRepository do double("shell_out", stdout: RPM_KEYS, exitstatus: 0, error?: false) end - let(:gpg_finger) do - double("shell_out", stdout: ZYPPER_GPG_FINGER, exitstatus: 0, error?: false) + let(:gpg_20) do + double("shell_out", stdout: ZYPPER_GPG_20, exitstatus: 0, error?: false) + end + + let(:gpg_22) do + double("shell_out", stdout: ZYPPER_GPG_22, exitstatus: 0, error?: false) + end + + let(:gpg_ver) do + double("shell_out", stdout: ZYPPER_GPG_VERSION, exitstatus: 0, error?: false) end it "responds to load_current_resource" do @@ -96,24 +132,38 @@ describe Chef::Provider::ZypperRepository do describe "#key_installed?" do before do - expect(provider).to receive(:shell_out).with("rpm -qa gpg-pubkey*").and_return(rpm_key_finger) + expect(provider).to receive(:shell_out).with("/bin/rpm -qa gpg-pubkey*").and_return(rpm_key_finger) end it "returns true if the key is installed" do - expect(provider).to receive(:key_fingerprint).and_return("3dbdc284") + expect(provider).to receive(:short_key_id).and_return("3dbdc284") expect(provider.key_installed?("/foo/nginx.key")).to be_truthy end it "returns false if the key is not installed" do - expect(provider).to receive(:key_fingerprint).and_return("BOGUS") + expect(provider).to receive(:short_key_id).and_return("BOGUS") expect(provider.key_installed?("/foo/nginx.key")).to be_falsey end end - describe "#key_fingerprint" do - it "returns the key's fingerprint" do - expect(provider).to receive(:shell_out!).with("gpg --with-fingerprint /foo/nginx.key").and_return(gpg_finger) - expect(provider.key_fingerprint("/foo/nginx.key")).to eq("3dbdc284") + describe "#gpg_version" do + it "returns the gpg version by shelling out to gpg" do + expect(provider).to receive(:shell_out!).with("gpg --version").and_return(gpg_ver) + expect(provider.gpg_version).to eq(Gem::Version.new("2.2.20")) + end + end + + describe "#short_key_id" do + it "returns the short key ID via running a dry-run import on gpg 2.2+" do + expect(provider).to receive(:gpg_version).and_return(Gem::Version.new("2.2")) + expect(provider).to receive(:shell_out!).with("gpg --import-options import-show --dry-run --import --with-colons /foo/nginx.key").and_return(gpg_22) + expect(provider.short_key_id("/foo/nginx.key")).to eq("7bd9bf62") + end + + it "returns the short key ID via --with-fingerpint on gpg < 2.2" do + expect(provider).to receive(:gpg_version).and_return(Gem::Version.new("2.0")) + expect(provider).to receive(:shell_out!).with("gpg --with-fingerprint /foo/nginx.key").and_return(gpg_20) + expect(provider.short_key_id("/foo/nginx.key")).to eq("3dbdc284") end end |