Skip to content

Commit

Permalink
feat: gpg verification error messages are captured in the exception
Browse files Browse the repository at this point in the history
previously these error messages went to stderr
  • Loading branch information
flavorjones committed May 30, 2024
1 parent 9919cf1 commit 3d68f33
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 18 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

#### Added

- When setting the C compiler through the `MiniPortile` constructor, the preferred keyword argument is now `:cc_command`. The original `:gcc_command` is still supported.
- When setting the C compiler through the `MiniPortile` constructor, the preferred keyword argument is now `:cc_command`. The original `:gcc_command` is still supported. @flavorjones
- GPG file verification error messages are captured in the raised exception. Previously these errors went to `stderr`. @flavorjones


### 2.8.6 / 2024-04-14
Expand Down
32 changes: 19 additions & 13 deletions lib/mini_portile2/mini_portile.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
require 'cgi'
require 'rbconfig'
require 'shellwords'
require 'open3'

# Monkey patch for Net::HTTP by ruby open-uri fix:
# https://github.com/ruby/ruby/commit/58835a9
Expand Down Expand Up @@ -463,24 +464,29 @@ def verify_file(file)
gpg_exe = which('gpg2') || which('gpg') || raise("Neither GPG nor GPG2 is installed")

# import the key into our own keyring
gpg_status = IO.popen([gpg_exe, "--status-fd", "1", "--no-default-keyring", "--keyring", KEYRING_NAME, "--import"], "w+") do |io|
io.write gpg[:key]
io.close_write
io.read
gpg_error = nil
gpg_status = Open3.popen3(gpg_exe, "--status-fd", "1", "--no-default-keyring", "--keyring", KEYRING_NAME, "--import") do |gpg_in, gpg_out, gpg_err, _thread|
gpg_in.write gpg[:key]
gpg_in.close
gpg_error = gpg_err.read
gpg_out.read
end
key_ids = gpg_status.scan(/\[GNUPG:\] IMPORT_OK \d+ (?<key_id>[0-9a-f]+)/i).map(&:first)
raise "invalid gpg key provided" if key_ids.empty?
raise "invalid gpg key provided:\n#{gpg_error}" if key_ids.empty?

# verify the signature against our keyring
gpg_status = IO.popen([gpg_exe, "--status-fd", "1", "--no-default-keyring", "--keyring", KEYRING_NAME, "--verify", signature_file, file[:local_path]], &:read)

# remove the key from our keyring
key_ids.each do |key_id|
IO.popen([gpg_exe, "--batch", "--yes", "--no-default-keyring", "--keyring", KEYRING_NAME, "--delete-keys", key_id], &:read)
raise "unable to delete the imported key" unless $?.exitstatus==0
begin
# verify the signature against our keyring
gpg_status, gpg_error, _status = Open3.capture3(gpg_exe, "--status-fd", "1", "--no-default-keyring", "--keyring", KEYRING_NAME, "--verify", signature_file, file[:local_path])

raise "signature mismatch:\n#{gpg_error}" unless gpg_status.match(/^\[GNUPG:\] VALIDSIG/)
ensure
# remove the key from our keyring
key_ids.each do |key_id|
IO.popen([gpg_exe, "--batch", "--yes", "--no-default-keyring", "--keyring", KEYRING_NAME, "--delete-keys", key_id], &:read)
raise "unable to delete the imported key" unless $?.exitstatus==0
end
end

raise "signature mismatch" unless gpg_status.match(/^\[GNUPG:\] VALIDSIG/)

else
digest = case
Expand Down
7 changes: 3 additions & 4 deletions test/test_digest.rb
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def test_with_invalid_gpg_signature
exception = assert_raises(RuntimeError){
@recipe.download
}
assert_equal("signature mismatch", exception.message)
assert_includes(exception.message, "signature mismatch")
end

def test_with_invalid_key
Expand All @@ -145,7 +145,7 @@ def test_with_invalid_key
}
}
exception = assert_raises(RuntimeError){ @recipe.download }
assert_equal("invalid gpg key provided", exception.message)
assert_includes(exception.message, "invalid gpg key provided")
end

def test_with_different_key_than_one_used_to_sign
Expand Down Expand Up @@ -209,7 +209,6 @@ def test_with_different_key_than_one_used_to_sign
}
}
exception = assert_raises(RuntimeError){ @recipe.download }
assert_equal("signature mismatch", exception.message)
assert_includes(exception.message, "signature mismatch")
end
end

0 comments on commit 3d68f33

Please sign in to comment.