rubygems-update 2.0.17 → 2.1.0.rc.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rubygems-update might be problematic. Click here for more details.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +2 -0
- data/.autotest +1 -1
- data/History.txt +82 -153
- data/Manifest.txt +35 -9
- data/Rakefile +35 -36
- data/lib/rubygems.rb +106 -18
- data/lib/rubygems/available_set.rb +68 -0
- data/lib/rubygems/basic_specification.rb +139 -0
- data/lib/rubygems/command_manager.rb +37 -40
- data/lib/rubygems/commands/cert_command.rb +78 -29
- data/lib/rubygems/commands/cleanup_command.rb +2 -2
- data/lib/rubygems/commands/contents_command.rb +101 -58
- data/lib/rubygems/commands/dependency_command.rb +94 -53
- data/lib/rubygems/commands/environment_command.rb +70 -53
- data/lib/rubygems/commands/fetch_command.rb +1 -2
- data/lib/rubygems/commands/help_command.rb +85 -55
- data/lib/rubygems/commands/install_command.rb +84 -42
- data/lib/rubygems/commands/outdated_command.rb +2 -12
- data/lib/rubygems/commands/owner_command.rb +6 -0
- data/lib/rubygems/commands/pristine_command.rb +26 -16
- data/lib/rubygems/commands/sources_command.rb +85 -70
- data/lib/rubygems/commands/uninstall_command.rb +32 -2
- data/lib/rubygems/commands/update_command.rb +111 -75
- data/lib/rubygems/config_file.rb +15 -3
- data/lib/rubygems/core_ext/kernel_require.rb +9 -31
- data/lib/rubygems/defaults.rb +8 -0
- data/lib/rubygems/dependency.rb +4 -2
- data/lib/rubygems/dependency_installer.rb +180 -170
- data/lib/rubygems/dependency_resolver.rb +191 -526
- data/lib/rubygems/dependency_resolver/activation_request.rb +109 -0
- data/lib/rubygems/dependency_resolver/api_set.rb +65 -0
- data/lib/rubygems/dependency_resolver/api_specification.rb +36 -0
- data/lib/rubygems/dependency_resolver/composed_set.rb +18 -0
- data/lib/rubygems/dependency_resolver/current_set.rb +16 -0
- data/lib/rubygems/dependency_resolver/dependency_conflict.rb +85 -0
- data/lib/rubygems/dependency_resolver/dependency_request.rb +51 -0
- data/lib/rubygems/dependency_resolver/index_set.rb +59 -0
- data/lib/rubygems/dependency_resolver/index_specification.rb +53 -0
- data/lib/rubygems/dependency_resolver/installed_specification.rb +38 -0
- data/lib/rubygems/dependency_resolver/installer_set.rb +130 -0
- data/lib/rubygems/exceptions.rb +88 -1
- data/lib/rubygems/ext/builder.rb +1 -1
- data/lib/rubygems/gem_runner.rb +17 -9
- data/lib/rubygems/gemcutter_utilities.rb +72 -42
- data/lib/rubygems/install_default_message.rb +12 -0
- data/lib/rubygems/install_update_options.rb +3 -0
- data/lib/rubygems/installer.rb +55 -30
- data/lib/rubygems/name_tuple.rb +18 -7
- data/lib/rubygems/package.rb +50 -25
- data/lib/rubygems/package/tar_test_case.rb +9 -9
- data/lib/rubygems/package/tar_writer.rb +35 -12
- data/lib/rubygems/package_task.rb +2 -5
- data/lib/rubygems/path_support.rb +10 -0
- data/lib/rubygems/platform.rb +9 -3
- data/lib/rubygems/psych_additions.rb +1 -1
- data/lib/rubygems/remote_fetcher.rb +9 -276
- data/lib/rubygems/request.rb +267 -0
- data/lib/rubygems/request_set.rb +123 -125
- data/lib/rubygems/request_set/gem_dependency_api.rb +39 -0
- data/lib/rubygems/security.rb +32 -23
- data/lib/rubygems/security/policy.rb +35 -9
- data/lib/rubygems/security/signer.rb +2 -2
- data/lib/rubygems/server.rb +8 -16
- data/lib/rubygems/source.rb +25 -14
- data/lib/rubygems/source/installed.rb +28 -0
- data/lib/rubygems/source/local.rb +122 -0
- data/lib/rubygems/source/specific_file.rb +28 -0
- data/lib/rubygems/source_local.rb +2 -89
- data/lib/rubygems/source_specific_file.rb +2 -26
- data/lib/rubygems/spec_fetcher.rb +11 -11
- data/lib/rubygems/specification.rb +186 -198
- data/lib/rubygems/ssl_certs/AddTrustExternalCARoot.pem +88 -30
- data/lib/rubygems/ssl_certs/Entrust_net-Secure-Server-Certification-Authority.pem +90 -0
- data/lib/rubygems/ssl_certs/{GeoTrustGlobalCA.pem → GeoTrust_Global_CA.pem} +20 -20
- data/lib/rubygems/ssl_certs/VerisignClass3PublicPrimaryCertificationAuthority-G2.pem +57 -0
- data/lib/rubygems/stub_specification.rb +119 -0
- data/lib/rubygems/test_case.rb +117 -49
- data/lib/rubygems/uninstaller.rb +14 -9
- data/lib/rubygems/uri_formatter.rb +39 -0
- data/lib/rubygems/util/list.rb +44 -0
- data/lib/rubygems/version.rb +15 -5
- data/lib/rubygems/version_option.rb +8 -2
- data/test/rubygems/ca_cert.pem +23 -0
- data/test/rubygems/client.pem +49 -0
- data/test/rubygems/encrypted_private_key.pem +30 -0
- data/test/rubygems/invalid_client.pem +49 -0
- data/test/rubygems/specifications/bar-0.0.2.gemspec +9 -0
- data/test/rubygems/specifications/foo-0.0.1.gemspec +0 -0
- data/test/rubygems/test_gem.rb +76 -454
- data/test/rubygems/test_gem_command_manager.rb +23 -21
- data/test/rubygems/test_gem_commands_cert_command.rb +154 -14
- data/test/rubygems/test_gem_commands_cleanup_command.rb +15 -0
- data/test/rubygems/test_gem_commands_contents_command.rb +32 -4
- data/test/rubygems/test_gem_commands_environment_command.rb +9 -1
- data/test/rubygems/test_gem_commands_fetch_command.rb +2 -28
- data/test/rubygems/test_gem_commands_help_command.rb +6 -3
- data/test/rubygems/test_gem_commands_install_command.rb +2 -65
- data/test/rubygems/test_gem_commands_owner_command.rb +49 -0
- data/test/rubygems/test_gem_commands_pristine_command.rb +30 -0
- data/test/rubygems/test_gem_commands_sources_command.rb +1 -1
- data/test/rubygems/test_gem_commands_uninstall_command.rb +33 -0
- data/test/rubygems/test_gem_commands_update_command.rb +2 -1
- data/test/rubygems/test_gem_config_file.rb +12 -0
- data/test/rubygems/test_gem_dependency_installer.rb +58 -65
- data/test/rubygems/test_gem_dependency_resolver.rb +6 -3
- data/test/rubygems/test_gem_dependency_resolver_dependency_conflict.rb +36 -0
- data/test/rubygems/test_gem_ext_builder.rb +2 -4
- data/test/rubygems/test_gem_ext_ext_conf_builder.rb +7 -2
- data/test/rubygems/test_gem_gem_runner.rb +17 -13
- data/test/rubygems/test_gem_gemcutter_utilities.rb +6 -19
- data/test/rubygems/test_gem_impossible_dependencies_error.rb +41 -0
- data/test/rubygems/test_gem_install_update_options.rb +4 -1
- data/test/rubygems/test_gem_installer.rb +31 -2
- data/test/rubygems/test_gem_name_tuple.rb +22 -0
- data/test/rubygems/test_gem_package.rb +122 -11
- data/test/rubygems/test_gem_package_old.rb +8 -0
- data/test/rubygems/test_gem_package_tar_reader.rb +9 -8
- data/test/rubygems/test_gem_package_tar_reader_entry.rb +1 -1
- data/test/rubygems/test_gem_package_tar_writer.rb +78 -56
- data/test/rubygems/test_gem_package_task.rb +2 -23
- data/test/rubygems/test_gem_path_support.rb +17 -0
- data/test/rubygems/test_gem_platform.rb +18 -0
- data/test/rubygems/test_gem_remote_fetcher.rb +106 -385
- data/test/rubygems/test_gem_request.rb +239 -0
- data/test/rubygems/test_gem_requirement.rb +9 -11
- data/test/rubygems/test_gem_security.rb +58 -2
- data/test/rubygems/test_gem_security_policy.rb +42 -1
- data/test/rubygems/test_gem_security_signer.rb +13 -1
- data/test/rubygems/test_gem_security_trust_dir.rb +5 -1
- data/test/rubygems/test_gem_server.rb +1 -105
- data/test/rubygems/test_gem_source.rb +4 -14
- data/test/rubygems/test_gem_source_local.rb +4 -4
- data/test/rubygems/test_gem_source_specific_file.rb +1 -1
- data/test/rubygems/test_gem_spec_fetcher.rb +0 -12
- data/test/rubygems/test_gem_specification.rb +452 -28
- data/test/rubygems/test_gem_stub_specification.rb +30 -0
- data/test/rubygems/test_gem_uninstaller.rb +14 -0
- data/test/rubygems/test_gem_uri_formatter.rb +20 -0
- data/test/rubygems/test_gem_version.rb +23 -13
- data/test/rubygems/test_gem_version_option.rb +63 -1
- data/test/rubygems/test_require.rb +0 -12
- data/util/create_encrypted_key.rb +16 -0
- metadata +161 -23
- metadata.gz.sig +0 -0
- data/CVE-2013-4287.txt +0 -36
- data/CVE-2013-4363.txt +0 -45
- data/lib/rubygems/ssl_certs/AddTrustExternalCARoot-2048.pem +0 -25
- data/lib/rubygems/ssl_certs/Class3PublicPrimaryCertificationAuthority.pem +0 -14
- data/lib/rubygems/ssl_certs/DigiCertHighAssuranceEVRootCA.pem +0 -23
- data/lib/rubygems/ssl_certs/EntrustnetSecureServerCertificationAuthority.pem +0 -28
- data/test/rubygems/test_bundled_ca.rb +0 -59
- data/util/update_bundled_ca_certificates.rb +0 -103
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rubygems/user_interaction'
|
3
|
+
|
4
|
+
##
|
5
|
+
# A post-install hook that displays "Successfully installed
|
6
|
+
# some_gem-1.0 as a default gem"
|
7
|
+
|
8
|
+
Gem.post_install do |installer|
|
9
|
+
ui = Gem::DefaultUserInteraction.ui
|
10
|
+
ui.say "Successfully installed #{installer.spec.full_name} as a default gem"
|
11
|
+
end
|
12
|
+
|
@@ -26,6 +26,9 @@ module Gem::InstallUpdateOptions
|
|
26
26
|
OptionParser.accept Gem::Security::Policy do |value|
|
27
27
|
require 'rubygems/security'
|
28
28
|
|
29
|
+
raise OptionParser::InvalidArgument, 'OpenSSL not installed' unless
|
30
|
+
defined?(Gem::Security::HighSecurity)
|
31
|
+
|
29
32
|
value = Gem::Security::Policies[value]
|
30
33
|
valid = Gem::Security::Policies.keys.sort
|
31
34
|
message = "#{value} (#{valid.join ', '} are valid)"
|
data/lib/rubygems/installer.rb
CHANGED
@@ -9,7 +9,6 @@ require 'rubygems/package'
|
|
9
9
|
require 'rubygems/ext'
|
10
10
|
require 'rubygems/user_interaction'
|
11
11
|
require 'fileutils'
|
12
|
-
require 'thread'
|
13
12
|
|
14
13
|
##
|
15
14
|
# The installer installs the files contained in the .gem into the Gem.home.
|
@@ -32,14 +31,6 @@ class Gem::Installer
|
|
32
31
|
|
33
32
|
ENV_PATHS = %w[/usr/bin/env /bin/env]
|
34
33
|
|
35
|
-
##
|
36
|
-
# The builder shells-out to run various commands after changing the
|
37
|
-
# directory. This means multiple installations cannot be allowed to build
|
38
|
-
# extensions in parallel as they may change each other's directories leading
|
39
|
-
# to broken extensions or failed installations.
|
40
|
-
|
41
|
-
CHDIR_MUTEX = Mutex.new # :nodoc:
|
42
|
-
|
43
34
|
##
|
44
35
|
# Raised when there is an error while building extensions.
|
45
36
|
#
|
@@ -93,8 +84,8 @@ class Gem::Installer
|
|
93
84
|
# :env_shebang:: Use /usr/bin/env in bin wrappers.
|
94
85
|
# :force:: Overrides all version checks and security policy checks, except
|
95
86
|
# for a signed-gems-only policy.
|
96
|
-
# :format_executable:: Format the executable the same as the
|
97
|
-
# If your
|
87
|
+
# :format_executable:: Format the executable the same as the Ruby executable.
|
88
|
+
# If your Ruby is ruby18, foo_exec will be installed as
|
98
89
|
# foo_exec18.
|
99
90
|
# :ignore_dependencies:: Don't raise if a dependency is missing.
|
100
91
|
# :install_dir:: The directory to install the gem into.
|
@@ -153,7 +144,7 @@ class Gem::Installer
|
|
153
144
|
io.gets # blankline
|
154
145
|
|
155
146
|
# TODO detect a specially formatted comment instead of trying
|
156
|
-
# to run a regexp against
|
147
|
+
# to run a regexp against Ruby code.
|
157
148
|
next unless io.gets =~ /This file was generated by RubyGems/
|
158
149
|
|
159
150
|
ruby_executable = true
|
@@ -222,15 +213,20 @@ class Gem::Installer
|
|
222
213
|
|
223
214
|
FileUtils.mkdir_p gem_dir
|
224
215
|
|
225
|
-
|
216
|
+
if @options[:install_as_default]
|
217
|
+
extract_bin
|
218
|
+
write_default_spec
|
219
|
+
else
|
220
|
+
extract_files
|
226
221
|
|
227
|
-
|
228
|
-
|
229
|
-
|
222
|
+
build_extensions
|
223
|
+
write_build_info_file
|
224
|
+
run_post_build_hooks
|
230
225
|
|
231
|
-
|
232
|
-
|
233
|
-
|
226
|
+
generate_bin
|
227
|
+
write_spec
|
228
|
+
write_cache_file
|
229
|
+
end
|
234
230
|
|
235
231
|
say spec.post_install_message unless spec.post_install_message.nil?
|
236
232
|
|
@@ -335,6 +331,14 @@ class Gem::Installer
|
|
335
331
|
File.join gem_home, "specifications", "#{spec.full_name}.gemspec"
|
336
332
|
end
|
337
333
|
|
334
|
+
##
|
335
|
+
# The location of of the default spec file for default gems.
|
336
|
+
#
|
337
|
+
|
338
|
+
def default_spec_file
|
339
|
+
File.join gem_home, "specifications/default", "#{spec.full_name}.gemspec"
|
340
|
+
end
|
341
|
+
|
338
342
|
##
|
339
343
|
# Writes the .gemspec specification (in Ruby) to the gem home's
|
340
344
|
# specifications directory.
|
@@ -346,6 +350,16 @@ class Gem::Installer
|
|
346
350
|
end
|
347
351
|
end
|
348
352
|
|
353
|
+
##
|
354
|
+
# Writes the full .gemspec specification (in Ruby) to the gem home's
|
355
|
+
# specifications/default directory.
|
356
|
+
|
357
|
+
def write_default_spec
|
358
|
+
File.open(default_spec_file, "w") do |file|
|
359
|
+
file.puts spec.to_ruby
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
349
363
|
##
|
350
364
|
# Creates windows .bat files for easy running of commands
|
351
365
|
|
@@ -547,13 +561,13 @@ class Gem::Installer
|
|
547
561
|
:bin_dir => nil,
|
548
562
|
:env_shebang => false,
|
549
563
|
:force => false,
|
550
|
-
:install_dir => Gem.dir,
|
551
564
|
:only_install_dir => false
|
552
565
|
}.merge options
|
553
566
|
|
554
567
|
@env_shebang = options[:env_shebang]
|
555
568
|
@force = options[:force]
|
556
|
-
@
|
569
|
+
@install_dir = options[:install_dir]
|
570
|
+
@gem_home = options[:install_dir] || Gem.dir
|
557
571
|
@ignore_dependencies = options[:ignore_dependencies]
|
558
572
|
@format_executable = options[:format_executable]
|
559
573
|
@security_policy = options[:security_policy]
|
@@ -628,7 +642,7 @@ TEXT
|
|
628
642
|
end
|
629
643
|
|
630
644
|
##
|
631
|
-
# return the stub script text used to launch the true
|
645
|
+
# return the stub script text used to launch the true Ruby script
|
632
646
|
|
633
647
|
def windows_stub_script(bindir, bin_file_name)
|
634
648
|
ruby = File.basename(Gem.ruby).chomp('"')
|
@@ -684,13 +698,11 @@ TEXT
|
|
684
698
|
begin
|
685
699
|
FileUtils.mkdir_p dest_path
|
686
700
|
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
results, @build_args)
|
701
|
+
Dir.chdir extension_dir do
|
702
|
+
results = builder.build(extension, gem_dir, dest_path,
|
703
|
+
results, @build_args)
|
691
704
|
|
692
|
-
|
693
|
-
end
|
705
|
+
say results.join("\n") if Gem.configuration.really_verbose
|
694
706
|
end
|
695
707
|
rescue
|
696
708
|
extension_build_error(extension_dir, results.join("\n"), $@)
|
@@ -727,6 +739,15 @@ EOF
|
|
727
739
|
@package.extract_files gem_dir
|
728
740
|
end
|
729
741
|
|
742
|
+
##
|
743
|
+
# Extracts only the bin/ files from the gem into the gem directory.
|
744
|
+
# This is used by default gems to allow a gem-aware stub to function
|
745
|
+
# without the full gem installed.
|
746
|
+
|
747
|
+
def extract_bin
|
748
|
+
@package.extract_files gem_dir, "bin/*"
|
749
|
+
end
|
750
|
+
|
730
751
|
##
|
731
752
|
# Prefix and suffix the program filename the same as ruby.
|
732
753
|
|
@@ -750,7 +771,7 @@ EOF
|
|
750
771
|
|
751
772
|
##
|
752
773
|
# Performs various checks before installing the gem such as the install
|
753
|
-
# repository is writable and its directories exist, required
|
774
|
+
# repository is writable and its directories exist, required Ruby and
|
754
775
|
# rubygems versions are met and that dependencies are installed.
|
755
776
|
#
|
756
777
|
# Version and dependency checks are skipped if this install is forced.
|
@@ -767,7 +788,11 @@ EOF
|
|
767
788
|
|
768
789
|
ensure_loadable_spec
|
769
790
|
|
770
|
-
|
791
|
+
if options[:install_as_default]
|
792
|
+
Gem.ensure_default_gem_subdirectories gem_home
|
793
|
+
else
|
794
|
+
Gem.ensure_gem_subdirectories gem_home
|
795
|
+
end
|
771
796
|
|
772
797
|
return true if @force
|
773
798
|
|
data/lib/rubygems/name_tuple.rb
CHANGED
@@ -42,6 +42,20 @@ class Gem::NameTuple
|
|
42
42
|
new nil, Gem::Version.new(0), nil
|
43
43
|
end
|
44
44
|
|
45
|
+
##
|
46
|
+
# Returns the full name (name-version) of this Gem. Platform information is
|
47
|
+
# included if it is not the default Ruby platform. This mimics the behavior
|
48
|
+
# of Gem::Specification#full_name.
|
49
|
+
|
50
|
+
def full_name
|
51
|
+
case @platform
|
52
|
+
when nil, 'ruby', ''
|
53
|
+
"#{@name}-#{@version}"
|
54
|
+
else
|
55
|
+
"#{@name}-#{@version}-#{@platform}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
45
59
|
##
|
46
60
|
# Indicate if this NameTuple matches the current platform.
|
47
61
|
|
@@ -59,12 +73,7 @@ class Gem::NameTuple
|
|
59
73
|
# Return the name that the gemspec file would be
|
60
74
|
|
61
75
|
def spec_name
|
62
|
-
|
63
|
-
when nil, 'ruby', ''
|
64
|
-
"#{@name}-#{@version}.gemspec"
|
65
|
-
else
|
66
|
-
"#{@name}-#{@version}-#{@platform}.gemspec"
|
67
|
-
end
|
76
|
+
"#{full_name}.gemspec"
|
68
77
|
end
|
69
78
|
|
70
79
|
##
|
@@ -74,10 +83,12 @@ class Gem::NameTuple
|
|
74
83
|
[@name, @version, @platform]
|
75
84
|
end
|
76
85
|
|
77
|
-
def
|
86
|
+
def inspect # :nodoc:
|
78
87
|
"#<Gem::NameTuple #{@name}, #{@version}, #{@platform}>"
|
79
88
|
end
|
80
89
|
|
90
|
+
alias to_s inspect # :nodoc:
|
91
|
+
|
81
92
|
def <=> other
|
82
93
|
to_a <=> other.to_a
|
83
94
|
end
|
data/lib/rubygems/package.rb
CHANGED
@@ -37,7 +37,7 @@
|
|
37
37
|
# the_gem.spec # get the spec out of the gem
|
38
38
|
# the_gem.verify # check the gem is OK (contains valid gem specification, contains a not corrupt contents archive)
|
39
39
|
#
|
40
|
-
# #files are the files in the .gem tar file, not the
|
40
|
+
# #files are the files in the .gem tar file, not the Ruby files in the gem
|
41
41
|
# #extract_files and #contents automatically call #verify
|
42
42
|
|
43
43
|
require 'rubygems/security'
|
@@ -280,11 +280,16 @@ EOM
|
|
280
280
|
algorithms = if @checksums then
|
281
281
|
@checksums.keys
|
282
282
|
else
|
283
|
-
[Gem::Security::DIGEST_NAME]
|
283
|
+
[Gem::Security::DIGEST_NAME].compact
|
284
284
|
end
|
285
285
|
|
286
286
|
algorithms.each do |algorithm|
|
287
|
-
digester =
|
287
|
+
digester =
|
288
|
+
if defined?(OpenSSL::Digest) then
|
289
|
+
OpenSSL::Digest.new algorithm
|
290
|
+
else
|
291
|
+
Digest.const_get(algorithm).new
|
292
|
+
end
|
288
293
|
|
289
294
|
digester << entry.read(16384) until entry.eof?
|
290
295
|
|
@@ -298,8 +303,11 @@ EOM
|
|
298
303
|
|
299
304
|
##
|
300
305
|
# Extracts the files in this package into +destination_dir+
|
306
|
+
#
|
307
|
+
# If +pattern+ is specified, only entries matching that glob will be
|
308
|
+
# extracted.
|
301
309
|
|
302
|
-
def extract_files destination_dir
|
310
|
+
def extract_files destination_dir, pattern = "*"
|
303
311
|
verify unless @spec
|
304
312
|
|
305
313
|
FileUtils.mkdir_p destination_dir
|
@@ -310,7 +318,7 @@ EOM
|
|
310
318
|
reader.each do |entry|
|
311
319
|
next unless entry.full_name == 'data.tar.gz'
|
312
320
|
|
313
|
-
extract_tar_gz entry, destination_dir
|
321
|
+
extract_tar_gz entry, destination_dir, pattern
|
314
322
|
|
315
323
|
return # ignore further entries
|
316
324
|
end
|
@@ -324,10 +332,15 @@ EOM
|
|
324
332
|
# If an entry in the archive contains a relative path above
|
325
333
|
# +destination_dir+ or an absolute path is encountered an exception is
|
326
334
|
# raised.
|
335
|
+
#
|
336
|
+
# If +pattern+ is specified, only entries matching that glob will be
|
337
|
+
# extracted.
|
327
338
|
|
328
|
-
def extract_tar_gz io, destination_dir # :nodoc:
|
339
|
+
def extract_tar_gz io, destination_dir, pattern = "*" # :nodoc:
|
329
340
|
open_tar_gz io do |tar|
|
330
341
|
tar.each do |entry|
|
342
|
+
next unless File.fnmatch pattern, entry.full_name
|
343
|
+
|
331
344
|
destination = install_location entry.full_name, destination_dir
|
332
345
|
|
333
346
|
FileUtils.rm_rf destination
|
@@ -428,12 +441,13 @@ EOM
|
|
428
441
|
# certificate and key are not present only checksum generation is set up.
|
429
442
|
|
430
443
|
def setup_signer
|
444
|
+
passphrase = ENV['GEM_PRIVATE_KEY_PASSPHRASE']
|
431
445
|
if @spec.signing_key then
|
432
|
-
@signer = Gem::Security::Signer.new @spec.signing_key, @spec.cert_chain
|
446
|
+
@signer = Gem::Security::Signer.new @spec.signing_key, @spec.cert_chain, passphrase
|
433
447
|
@spec.signing_key = nil
|
434
448
|
@spec.cert_chain = @signer.cert_chain.map { |cert| cert.to_s }
|
435
449
|
else
|
436
|
-
@signer = Gem::Security::Signer.new nil, nil
|
450
|
+
@signer = Gem::Security::Signer.new nil, nil, passphrase
|
437
451
|
@spec.cert_chain = @signer.cert_chain.map { |cert| cert.to_pem } if
|
438
452
|
@signer.cert_chain
|
439
453
|
end
|
@@ -509,28 +523,39 @@ EOM
|
|
509
523
|
end
|
510
524
|
end
|
511
525
|
|
526
|
+
##
|
527
|
+
# Verifies +entry+ in a .gem file.
|
528
|
+
|
529
|
+
def verify_entry entry
|
530
|
+
file_name = entry.full_name
|
531
|
+
@files << file_name
|
532
|
+
|
533
|
+
case file_name
|
534
|
+
when /\.sig$/ then
|
535
|
+
@signatures[$`] = entry.read if @security_policy
|
536
|
+
return
|
537
|
+
else
|
538
|
+
digest entry
|
539
|
+
end
|
540
|
+
|
541
|
+
case file_name
|
542
|
+
when /^metadata(.gz)?$/ then
|
543
|
+
load_spec entry
|
544
|
+
when 'data.tar.gz' then
|
545
|
+
verify_gz entry
|
546
|
+
end
|
547
|
+
rescue => e
|
548
|
+
message = "package is corrupt, exception while verifying: " +
|
549
|
+
"#{e.message} (#{e.class})"
|
550
|
+
raise Gem::Package::FormatError.new message, @gem
|
551
|
+
end
|
552
|
+
|
512
553
|
##
|
513
554
|
# Verifies the files of the +gem+
|
514
555
|
|
515
556
|
def verify_files gem
|
516
557
|
gem.each do |entry|
|
517
|
-
|
518
|
-
@files << file_name
|
519
|
-
|
520
|
-
case file_name
|
521
|
-
when /\.sig$/ then
|
522
|
-
@signatures[$`] = entry.read if @security_policy
|
523
|
-
next
|
524
|
-
else
|
525
|
-
digest entry
|
526
|
-
end
|
527
|
-
|
528
|
-
case file_name
|
529
|
-
when /^metadata(.gz)?$/ then
|
530
|
-
load_spec entry
|
531
|
-
when 'data.tar.gz' then
|
532
|
-
verify_gz entry
|
533
|
-
end
|
558
|
+
verify_entry entry
|
534
559
|
end
|
535
560
|
|
536
561
|
unless @spec then
|
@@ -71,7 +71,7 @@ class Gem::Package::TarTestCase < Gem::TestCase
|
|
71
71
|
SP(Z(to_oct(sum, 6)))
|
72
72
|
end
|
73
73
|
|
74
|
-
def header(type, fname, dname, length, mode, checksum = nil)
|
74
|
+
def header(type, fname, dname, length, mode, mtime, checksum = nil)
|
75
75
|
checksum ||= " " * 8
|
76
76
|
|
77
77
|
arr = [ # struct tarfile_entry_posix
|
@@ -80,7 +80,7 @@ class Gem::Package::TarTestCase < Gem::TestCase
|
|
80
80
|
Z(to_oct(0, 7)), # char uid[8]; ditto
|
81
81
|
Z(to_oct(0, 7)), # char gid[8]; ditto
|
82
82
|
Z(to_oct(length, 11)), # char size[12]; 0 padded, octal, null
|
83
|
-
Z(to_oct(
|
83
|
+
Z(to_oct(mtime, 11)), # char mtime[12]; 0 padded, octal, null
|
84
84
|
checksum, # char checksum[8]; 0 padded, octal, null, space
|
85
85
|
type, # char typeflag[1]; file: "0" dir: "5"
|
86
86
|
"\0" * 100, # char linkname[100]; ASCII + (Z unless filled)
|
@@ -105,16 +105,16 @@ class Gem::Package::TarTestCase < Gem::TestCase
|
|
105
105
|
ret
|
106
106
|
end
|
107
107
|
|
108
|
-
def tar_dir_header(name, prefix, mode)
|
109
|
-
h = header("5", name, prefix, 0, mode)
|
108
|
+
def tar_dir_header(name, prefix, mode, mtime)
|
109
|
+
h = header("5", name, prefix, 0, mode, mtime)
|
110
110
|
checksum = calc_checksum(h)
|
111
|
-
header("5", name, prefix, 0, mode, checksum)
|
111
|
+
header("5", name, prefix, 0, mode, mtime, checksum)
|
112
112
|
end
|
113
113
|
|
114
|
-
def tar_file_header(fname, dname, mode, length)
|
115
|
-
h = header("0", fname, dname, length, mode)
|
114
|
+
def tar_file_header(fname, dname, mode, length, mtime)
|
115
|
+
h = header("0", fname, dname, length, mode, mtime)
|
116
116
|
checksum = calc_checksum(h)
|
117
|
-
header("0", fname, dname, length, mode, checksum)
|
117
|
+
header("0", fname, dname, length, mode, mtime, checksum)
|
118
118
|
end
|
119
119
|
|
120
120
|
def to_oct(n, pad_size)
|
@@ -130,7 +130,7 @@ class Gem::Package::TarTestCase < Gem::TestCase
|
|
130
130
|
end
|
131
131
|
|
132
132
|
def util_dir_entry
|
133
|
-
util_entry tar_dir_header("foo", "bar", 0)
|
133
|
+
util_entry tar_dir_header("foo", "bar", 0, Time.now)
|
134
134
|
end
|
135
135
|
|
136
136
|
end
|
@@ -4,6 +4,8 @@
|
|
4
4
|
# See LICENSE.txt for additional licensing information.
|
5
5
|
#++
|
6
6
|
|
7
|
+
require 'digest'
|
8
|
+
|
7
9
|
##
|
8
10
|
# Allows writing of tar files
|
9
11
|
|
@@ -121,7 +123,8 @@ class Gem::Package::TarWriter
|
|
121
123
|
@io.pos = init_pos
|
122
124
|
|
123
125
|
header = Gem::Package::TarHeader.new :name => name, :mode => mode,
|
124
|
-
:size => size, :prefix => prefix
|
126
|
+
:size => size, :prefix => prefix,
|
127
|
+
:mtime => Time.now
|
125
128
|
|
126
129
|
@io.write header
|
127
130
|
@io.pos = final_pos
|
@@ -140,7 +143,15 @@ class Gem::Package::TarWriter
|
|
140
143
|
def add_file_digest name, mode, digest_algorithms # :yields: io
|
141
144
|
digests = digest_algorithms.map do |digest_algorithm|
|
142
145
|
digest = digest_algorithm.new
|
143
|
-
|
146
|
+
digest_name =
|
147
|
+
if digest.respond_to? :name then
|
148
|
+
digest.name
|
149
|
+
else
|
150
|
+
/::([^:]+)$/ =~ digest_algorithm.name
|
151
|
+
$1
|
152
|
+
end
|
153
|
+
|
154
|
+
[digest_name, digest]
|
144
155
|
end
|
145
156
|
|
146
157
|
digests = Hash[*digests.flatten]
|
@@ -165,22 +176,32 @@ class Gem::Package::TarWriter
|
|
165
176
|
def add_file_signed name, mode, signer
|
166
177
|
digest_algorithms = [
|
167
178
|
signer.digest_algorithm,
|
168
|
-
|
169
|
-
].uniq
|
179
|
+
Digest::SHA512,
|
180
|
+
].compact.uniq
|
170
181
|
|
171
182
|
digests = add_file_digest name, mode, digest_algorithms do |io|
|
172
183
|
yield io
|
173
184
|
end
|
174
185
|
|
175
|
-
signature_digest = digests.values.find do |digest|
|
176
|
-
|
186
|
+
signature_digest = digests.values.compact.find do |digest|
|
187
|
+
digest_name =
|
188
|
+
if digest.respond_to? :name then
|
189
|
+
digest.name
|
190
|
+
else
|
191
|
+
/::([^:]+)$/ =~ digest.class.name
|
192
|
+
$1
|
193
|
+
end
|
194
|
+
|
195
|
+
digest_name == signer.digest_name
|
177
196
|
end
|
178
197
|
|
179
|
-
|
198
|
+
if signer.key then
|
199
|
+
signature = signer.sign signature_digest.digest
|
180
200
|
|
181
|
-
|
182
|
-
|
183
|
-
|
201
|
+
add_file_simple "#{name}.sig", 0444, signature.length do |io|
|
202
|
+
io.write signature
|
203
|
+
end
|
204
|
+
end
|
184
205
|
|
185
206
|
digests
|
186
207
|
end
|
@@ -195,7 +216,8 @@ class Gem::Package::TarWriter
|
|
195
216
|
name, prefix = split_name name
|
196
217
|
|
197
218
|
header = Gem::Package::TarHeader.new(:name => name, :mode => mode,
|
198
|
-
:size => size, :prefix => prefix
|
219
|
+
:size => size, :prefix => prefix,
|
220
|
+
:mtime => Time.now).to_s
|
199
221
|
|
200
222
|
@io.write header
|
201
223
|
os = BoundedStream.new @io, size
|
@@ -256,7 +278,8 @@ class Gem::Package::TarWriter
|
|
256
278
|
|
257
279
|
header = Gem::Package::TarHeader.new :name => name, :mode => mode,
|
258
280
|
:typeflag => "5", :size => 0,
|
259
|
-
:prefix => prefix
|
281
|
+
:prefix => prefix,
|
282
|
+
:mtime => Time.now
|
260
283
|
|
261
284
|
@io.write header
|
262
285
|
|