aboutsummaryrefslogtreecommitdiffstats
path: root/lib/rubygems/package.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rubygems/package.rb')
-rw-r--r--lib/rubygems/package.rb73
1 files changed, 49 insertions, 24 deletions
diff --git a/lib/rubygems/package.rb b/lib/rubygems/package.rb
index 957446257d..76f45a99d8 100644
--- a/lib/rubygems/package.rb
+++ b/lib/rubygems/package.rb
@@ -280,11 +280,16 @@ EOM
algorithms = if @checksums then
@checksums.keys
else
- [Gem::Security::DIGEST_NAME]
+ [Gem::Security::DIGEST_NAME].compact
end
algorithms.each do |algorithm|
- digester = OpenSSL::Digest.new algorithm
+ digester =
+ if defined?(OpenSSL::Digest) then
+ OpenSSL::Digest.new algorithm
+ else
+ Digest.const_get(algorithm).new
+ end
digester << entry.read(16384) until entry.eof?
@@ -298,8 +303,11 @@ EOM
##
# Extracts the files in this package into +destination_dir+
+ #
+ # If +pattern+ is specified, only entries matching that glob will be
+ # extracted.
- def extract_files destination_dir
+ def extract_files destination_dir, pattern = "*"
verify unless @spec
FileUtils.mkdir_p destination_dir
@@ -310,7 +318,7 @@ EOM
reader.each do |entry|
next unless entry.full_name == 'data.tar.gz'
- extract_tar_gz entry, destination_dir
+ extract_tar_gz entry, destination_dir, pattern
return # ignore further entries
end
@@ -324,10 +332,15 @@ EOM
# If an entry in the archive contains a relative path above
# +destination_dir+ or an absolute path is encountered an exception is
# raised.
+ #
+ # If +pattern+ is specified, only entries matching that glob will be
+ # extracted.
- def extract_tar_gz io, destination_dir # :nodoc:
+ def extract_tar_gz io, destination_dir, pattern = "*" # :nodoc:
open_tar_gz io do |tar|
tar.each do |entry|
+ next unless File.fnmatch pattern, entry.full_name
+
destination = install_location entry.full_name, destination_dir
FileUtils.rm_rf destination
@@ -428,12 +441,13 @@ EOM
# certificate and key are not present only checksum generation is set up.
def setup_signer
+ passphrase = ENV['GEM_PRIVATE_KEY_PASSPHRASE']
if @spec.signing_key then
- @signer = Gem::Security::Signer.new @spec.signing_key, @spec.cert_chain
+ @signer = Gem::Security::Signer.new @spec.signing_key, @spec.cert_chain, passphrase
@spec.signing_key = nil
@spec.cert_chain = @signer.cert_chain.map { |cert| cert.to_s }
else
- @signer = Gem::Security::Signer.new nil, nil
+ @signer = Gem::Security::Signer.new nil, nil, passphrase
@spec.cert_chain = @signer.cert_chain.map { |cert| cert.to_pem } if
@signer.cert_chain
end
@@ -510,27 +524,38 @@ EOM
end
##
+ # Verifies +entry+ in a .gem file.
+
+ def verify_entry entry
+ file_name = entry.full_name
+ @files << file_name
+
+ case file_name
+ when /\.sig$/ then
+ @signatures[$`] = entry.read if @security_policy
+ return
+ else
+ digest entry
+ end
+
+ case file_name
+ when /^metadata(.gz)?$/ then
+ load_spec entry
+ when 'data.tar.gz' then
+ verify_gz entry
+ end
+ rescue => e
+ message = "package is corrupt, exception while verifying: " +
+ "#{e.message} (#{e.class})"
+ raise Gem::Package::FormatError.new message, @gem
+ end
+
+ ##
# Verifies the files of the +gem+
def verify_files gem
gem.each do |entry|
- file_name = entry.full_name
- @files << file_name
-
- case file_name
- when /\.sig$/ then
- @signatures[$`] = entry.read if @security_policy
- next
- else
- digest entry
- end
-
- case file_name
- when /^metadata(.gz)?$/ then
- load_spec entry
- when 'data.tar.gz' then
- verify_gz entry
- end
+ verify_entry entry
end
unless @spec then