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.

Files changed (154) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +2 -0
  4. data/.autotest +1 -1
  5. data/History.txt +82 -153
  6. data/Manifest.txt +35 -9
  7. data/Rakefile +35 -36
  8. data/lib/rubygems.rb +106 -18
  9. data/lib/rubygems/available_set.rb +68 -0
  10. data/lib/rubygems/basic_specification.rb +139 -0
  11. data/lib/rubygems/command_manager.rb +37 -40
  12. data/lib/rubygems/commands/cert_command.rb +78 -29
  13. data/lib/rubygems/commands/cleanup_command.rb +2 -2
  14. data/lib/rubygems/commands/contents_command.rb +101 -58
  15. data/lib/rubygems/commands/dependency_command.rb +94 -53
  16. data/lib/rubygems/commands/environment_command.rb +70 -53
  17. data/lib/rubygems/commands/fetch_command.rb +1 -2
  18. data/lib/rubygems/commands/help_command.rb +85 -55
  19. data/lib/rubygems/commands/install_command.rb +84 -42
  20. data/lib/rubygems/commands/outdated_command.rb +2 -12
  21. data/lib/rubygems/commands/owner_command.rb +6 -0
  22. data/lib/rubygems/commands/pristine_command.rb +26 -16
  23. data/lib/rubygems/commands/sources_command.rb +85 -70
  24. data/lib/rubygems/commands/uninstall_command.rb +32 -2
  25. data/lib/rubygems/commands/update_command.rb +111 -75
  26. data/lib/rubygems/config_file.rb +15 -3
  27. data/lib/rubygems/core_ext/kernel_require.rb +9 -31
  28. data/lib/rubygems/defaults.rb +8 -0
  29. data/lib/rubygems/dependency.rb +4 -2
  30. data/lib/rubygems/dependency_installer.rb +180 -170
  31. data/lib/rubygems/dependency_resolver.rb +191 -526
  32. data/lib/rubygems/dependency_resolver/activation_request.rb +109 -0
  33. data/lib/rubygems/dependency_resolver/api_set.rb +65 -0
  34. data/lib/rubygems/dependency_resolver/api_specification.rb +36 -0
  35. data/lib/rubygems/dependency_resolver/composed_set.rb +18 -0
  36. data/lib/rubygems/dependency_resolver/current_set.rb +16 -0
  37. data/lib/rubygems/dependency_resolver/dependency_conflict.rb +85 -0
  38. data/lib/rubygems/dependency_resolver/dependency_request.rb +51 -0
  39. data/lib/rubygems/dependency_resolver/index_set.rb +59 -0
  40. data/lib/rubygems/dependency_resolver/index_specification.rb +53 -0
  41. data/lib/rubygems/dependency_resolver/installed_specification.rb +38 -0
  42. data/lib/rubygems/dependency_resolver/installer_set.rb +130 -0
  43. data/lib/rubygems/exceptions.rb +88 -1
  44. data/lib/rubygems/ext/builder.rb +1 -1
  45. data/lib/rubygems/gem_runner.rb +17 -9
  46. data/lib/rubygems/gemcutter_utilities.rb +72 -42
  47. data/lib/rubygems/install_default_message.rb +12 -0
  48. data/lib/rubygems/install_update_options.rb +3 -0
  49. data/lib/rubygems/installer.rb +55 -30
  50. data/lib/rubygems/name_tuple.rb +18 -7
  51. data/lib/rubygems/package.rb +50 -25
  52. data/lib/rubygems/package/tar_test_case.rb +9 -9
  53. data/lib/rubygems/package/tar_writer.rb +35 -12
  54. data/lib/rubygems/package_task.rb +2 -5
  55. data/lib/rubygems/path_support.rb +10 -0
  56. data/lib/rubygems/platform.rb +9 -3
  57. data/lib/rubygems/psych_additions.rb +1 -1
  58. data/lib/rubygems/remote_fetcher.rb +9 -276
  59. data/lib/rubygems/request.rb +267 -0
  60. data/lib/rubygems/request_set.rb +123 -125
  61. data/lib/rubygems/request_set/gem_dependency_api.rb +39 -0
  62. data/lib/rubygems/security.rb +32 -23
  63. data/lib/rubygems/security/policy.rb +35 -9
  64. data/lib/rubygems/security/signer.rb +2 -2
  65. data/lib/rubygems/server.rb +8 -16
  66. data/lib/rubygems/source.rb +25 -14
  67. data/lib/rubygems/source/installed.rb +28 -0
  68. data/lib/rubygems/source/local.rb +122 -0
  69. data/lib/rubygems/source/specific_file.rb +28 -0
  70. data/lib/rubygems/source_local.rb +2 -89
  71. data/lib/rubygems/source_specific_file.rb +2 -26
  72. data/lib/rubygems/spec_fetcher.rb +11 -11
  73. data/lib/rubygems/specification.rb +186 -198
  74. data/lib/rubygems/ssl_certs/AddTrustExternalCARoot.pem +88 -30
  75. data/lib/rubygems/ssl_certs/Entrust_net-Secure-Server-Certification-Authority.pem +90 -0
  76. data/lib/rubygems/ssl_certs/{GeoTrustGlobalCA.pem → GeoTrust_Global_CA.pem} +20 -20
  77. data/lib/rubygems/ssl_certs/VerisignClass3PublicPrimaryCertificationAuthority-G2.pem +57 -0
  78. data/lib/rubygems/stub_specification.rb +119 -0
  79. data/lib/rubygems/test_case.rb +117 -49
  80. data/lib/rubygems/uninstaller.rb +14 -9
  81. data/lib/rubygems/uri_formatter.rb +39 -0
  82. data/lib/rubygems/util/list.rb +44 -0
  83. data/lib/rubygems/version.rb +15 -5
  84. data/lib/rubygems/version_option.rb +8 -2
  85. data/test/rubygems/ca_cert.pem +23 -0
  86. data/test/rubygems/client.pem +49 -0
  87. data/test/rubygems/encrypted_private_key.pem +30 -0
  88. data/test/rubygems/invalid_client.pem +49 -0
  89. data/test/rubygems/specifications/bar-0.0.2.gemspec +9 -0
  90. data/test/rubygems/specifications/foo-0.0.1.gemspec +0 -0
  91. data/test/rubygems/test_gem.rb +76 -454
  92. data/test/rubygems/test_gem_command_manager.rb +23 -21
  93. data/test/rubygems/test_gem_commands_cert_command.rb +154 -14
  94. data/test/rubygems/test_gem_commands_cleanup_command.rb +15 -0
  95. data/test/rubygems/test_gem_commands_contents_command.rb +32 -4
  96. data/test/rubygems/test_gem_commands_environment_command.rb +9 -1
  97. data/test/rubygems/test_gem_commands_fetch_command.rb +2 -28
  98. data/test/rubygems/test_gem_commands_help_command.rb +6 -3
  99. data/test/rubygems/test_gem_commands_install_command.rb +2 -65
  100. data/test/rubygems/test_gem_commands_owner_command.rb +49 -0
  101. data/test/rubygems/test_gem_commands_pristine_command.rb +30 -0
  102. data/test/rubygems/test_gem_commands_sources_command.rb +1 -1
  103. data/test/rubygems/test_gem_commands_uninstall_command.rb +33 -0
  104. data/test/rubygems/test_gem_commands_update_command.rb +2 -1
  105. data/test/rubygems/test_gem_config_file.rb +12 -0
  106. data/test/rubygems/test_gem_dependency_installer.rb +58 -65
  107. data/test/rubygems/test_gem_dependency_resolver.rb +6 -3
  108. data/test/rubygems/test_gem_dependency_resolver_dependency_conflict.rb +36 -0
  109. data/test/rubygems/test_gem_ext_builder.rb +2 -4
  110. data/test/rubygems/test_gem_ext_ext_conf_builder.rb +7 -2
  111. data/test/rubygems/test_gem_gem_runner.rb +17 -13
  112. data/test/rubygems/test_gem_gemcutter_utilities.rb +6 -19
  113. data/test/rubygems/test_gem_impossible_dependencies_error.rb +41 -0
  114. data/test/rubygems/test_gem_install_update_options.rb +4 -1
  115. data/test/rubygems/test_gem_installer.rb +31 -2
  116. data/test/rubygems/test_gem_name_tuple.rb +22 -0
  117. data/test/rubygems/test_gem_package.rb +122 -11
  118. data/test/rubygems/test_gem_package_old.rb +8 -0
  119. data/test/rubygems/test_gem_package_tar_reader.rb +9 -8
  120. data/test/rubygems/test_gem_package_tar_reader_entry.rb +1 -1
  121. data/test/rubygems/test_gem_package_tar_writer.rb +78 -56
  122. data/test/rubygems/test_gem_package_task.rb +2 -23
  123. data/test/rubygems/test_gem_path_support.rb +17 -0
  124. data/test/rubygems/test_gem_platform.rb +18 -0
  125. data/test/rubygems/test_gem_remote_fetcher.rb +106 -385
  126. data/test/rubygems/test_gem_request.rb +239 -0
  127. data/test/rubygems/test_gem_requirement.rb +9 -11
  128. data/test/rubygems/test_gem_security.rb +58 -2
  129. data/test/rubygems/test_gem_security_policy.rb +42 -1
  130. data/test/rubygems/test_gem_security_signer.rb +13 -1
  131. data/test/rubygems/test_gem_security_trust_dir.rb +5 -1
  132. data/test/rubygems/test_gem_server.rb +1 -105
  133. data/test/rubygems/test_gem_source.rb +4 -14
  134. data/test/rubygems/test_gem_source_local.rb +4 -4
  135. data/test/rubygems/test_gem_source_specific_file.rb +1 -1
  136. data/test/rubygems/test_gem_spec_fetcher.rb +0 -12
  137. data/test/rubygems/test_gem_specification.rb +452 -28
  138. data/test/rubygems/test_gem_stub_specification.rb +30 -0
  139. data/test/rubygems/test_gem_uninstaller.rb +14 -0
  140. data/test/rubygems/test_gem_uri_formatter.rb +20 -0
  141. data/test/rubygems/test_gem_version.rb +23 -13
  142. data/test/rubygems/test_gem_version_option.rb +63 -1
  143. data/test/rubygems/test_require.rb +0 -12
  144. data/util/create_encrypted_key.rb +16 -0
  145. metadata +161 -23
  146. metadata.gz.sig +0 -0
  147. data/CVE-2013-4287.txt +0 -36
  148. data/CVE-2013-4363.txt +0 -45
  149. data/lib/rubygems/ssl_certs/AddTrustExternalCARoot-2048.pem +0 -25
  150. data/lib/rubygems/ssl_certs/Class3PublicPrimaryCertificationAuthority.pem +0 -14
  151. data/lib/rubygems/ssl_certs/DigiCertHighAssuranceEVRootCA.pem +0 -23
  152. data/lib/rubygems/ssl_certs/EntrustnetSecureServerCertificationAuthority.pem +0 -28
  153. data/test/rubygems/test_bundled_ca.rb +0 -59
  154. data/util/update_bundled_ca_certificates.rb +0 -103
@@ -5,178 +5,176 @@ require 'rubygems/dependency_list'
5
5
  require 'rubygems/installer'
6
6
  require 'tsort'
7
7
 
8
- module Gem
9
- class RequestSet
8
+ class Gem::RequestSet
10
9
 
11
- include TSort
10
+ include TSort
12
11
 
13
- def initialize(*deps)
14
- @dependencies = deps
12
+ ##
13
+ # Array of gems to install even if already installed
15
14
 
16
- yield self if block_given?
17
- end
15
+ attr_reader :always_install
18
16
 
19
- attr_reader :dependencies
17
+ attr_reader :dependencies
20
18
 
21
- # Declare that a gem of name +name+ with +reqs+ requirements
22
- # is needed.
23
- #
24
- def gem(name, *reqs)
25
- @dependencies << Gem::Dependency.new(name, reqs)
26
- end
19
+ attr_accessor :development
27
20
 
28
- # Add +deps+ Gem::Depedency objects to the set.
29
- #
30
- def import(deps)
31
- @dependencies += deps
32
- end
21
+ ##
22
+ # Treat missing dependencies as silent errors
33
23
 
34
- # Resolve the requested dependencies and return an Array of
35
- # Specification objects to be activated.
36
- #
37
- def resolve(set=nil)
38
- r = Gem::DependencyResolver.new(@dependencies, set)
39
- @requests = r.resolve
40
- end
24
+ attr_accessor :soft_missing
41
25
 
42
- # Resolve the requested dependencies against the gems
43
- # available via Gem.path and return an Array of Specification
44
- # objects to be activated.
45
- #
46
- def resolve_current
47
- resolve DependencyResolver::CurrentSet.new
48
- end
26
+ def initialize *deps
27
+ @dependencies = deps
49
28
 
50
- # Load a dependency management file.
51
- #
52
- def load_gemdeps(path)
53
- gf = GemDepedencyAPI.new(self, path)
54
- gf.load
55
- end
29
+ @always_install = []
30
+ @development = false
31
+ @soft_missing = false
56
32
 
57
- def specs
58
- @specs ||= @requests.map { |r| r.full_spec }
59
- end
33
+ yield self if block_given?
34
+ end
60
35
 
61
- def tsort_each_node(&block)
62
- @requests.each(&block)
63
- end
36
+ ##
37
+ # Declare that a gem of name +name+ with +reqs+ requirements is needed.
64
38
 
65
- def tsort_each_child(node)
66
- node.spec.dependencies.each do |dep|
67
- next if dep.type == :development
68
-
69
- match = @requests.find { |r| dep.match? r.spec.name, r.spec.version }
70
- if match
71
- begin
72
- yield match
73
- rescue TSort::Cyclic
74
- end
75
- else
76
- raise Gem::DependencyError, "Unresolved depedency found during sorting - #{dep}"
77
- end
78
- end
79
- end
39
+ def gem name, *reqs
40
+ @dependencies << Gem::Dependency.new(name, reqs)
41
+ end
42
+
43
+ ##
44
+ # Add +deps+ Gem::Dependency objects to the set.
45
+
46
+ def import deps
47
+ @dependencies += deps
48
+ end
80
49
 
81
- def sorted_requests
82
- @sorted ||= strongly_connected_components.flatten
50
+ def install options, &block
51
+ if dir = options[:install_dir]
52
+ return install_into dir, false, options, &block
83
53
  end
84
54
 
85
- def specs_in(dir)
86
- Dir["#{dir}/specifications/*.gemspec"].map do |g|
87
- Gem::Specification.load g
55
+ cache_dir = options[:cache_dir] || Gem.dir
56
+
57
+ specs = []
58
+
59
+ sorted_requests.each do |req|
60
+ if req.installed? and
61
+ @always_install.none? { |spec| spec == req.spec.spec } then
62
+ yield req, nil if block_given?
63
+ next
88
64
  end
89
- end
90
65
 
91
- def install_into(dir, force=true, &b)
92
- existing = force ? [] : specs_in(dir)
66
+ path = req.download cache_dir
93
67
 
94
- dir = File.expand_path dir
68
+ inst = Gem::Installer.new path, options
95
69
 
96
- installed = []
70
+ yield req, inst if block_given?
97
71
 
98
- sorted_requests.each do |req|
99
- if existing.find { |s| s.full_name == req.spec.full_name }
100
- b.call req, nil if b
101
- next
102
- end
72
+ specs << inst.install
73
+ end
103
74
 
104
- path = req.download(dir)
75
+ specs
76
+ end
105
77
 
106
- inst = Gem::Installer.new path, :install_dir => dir,
107
- :only_install_dir => true
78
+ def install_into dir, force = true, options = {}
79
+ existing = force ? [] : specs_in(dir)
80
+ existing.delete_if { |s| @always_install.include? s }
108
81
 
109
- b.call req, inst if b
82
+ dir = File.expand_path dir
110
83
 
111
- inst.install
84
+ installed = []
112
85
 
113
- installed << req
86
+ sorted_requests.each do |req|
87
+ if existing.find { |s| s.full_name == req.spec.full_name }
88
+ yield req, nil if block_given?
89
+ next
114
90
  end
115
91
 
116
- installed
117
- end
92
+ path = req.download(dir)
118
93
 
119
- def install(options, &b)
120
- if dir = options[:install_dir]
121
- return install_into(dir, false, &b)
94
+ unless path then # already installed
95
+ yield req, nil if block_given?
96
+ next
122
97
  end
123
98
 
124
- cache_dir = options[:cache_dir] || Gem.dir
99
+ options[:install_dir] = dir
100
+ options[:only_install_dir] = true
125
101
 
126
- specs = []
102
+ inst = Gem::Installer.new path, options
127
103
 
128
- sorted_requests.each do |req|
129
- if req.installed?
130
- b.call req, nil if b
131
- next
132
- end
104
+ yield req, inst if block_given?
133
105
 
134
- path = req.download cache_dir
106
+ inst.install
135
107
 
136
- inst = Gem::Installer.new path, options
108
+ installed << req
109
+ end
137
110
 
138
- b.call req, inst if b
111
+ installed
112
+ end
139
113
 
140
- specs << inst.install
141
- end
114
+ ##
115
+ # Load a dependency management file.
142
116
 
143
- specs
144
- end
117
+ def load_gemdeps path
118
+ gf = Gem::RequestSet::GemDepedencyAPI.new self, path
119
+ gf.load
120
+ end
145
121
 
146
- # A semi-compatible DSL for Bundler's Gemfile format
147
- #
148
- class GemDepedencyAPI
149
- def initialize(set, path)
150
- @set = set
151
- @path = path
152
- end
122
+ ##
123
+ # Resolve the requested dependencies and return an Array of Specification
124
+ # objects to be activated.
153
125
 
154
- def load
155
- instance_eval File.read(@path).untaint, @path, 1
156
- end
126
+ def resolve set = nil
127
+ resolver = Gem::DependencyResolver.new @dependencies, set
128
+ resolver.development = @development
129
+ resolver.soft_missing = @soft_missing
157
130
 
158
- # DSL
131
+ @requests = resolver.resolve
132
+ end
159
133
 
160
- def source(url)
161
- end
134
+ ##
135
+ # Resolve the requested dependencies against the gems available via Gem.path
136
+ # and return an Array of Specification objects to be activated.
162
137
 
163
- def gem(name, *reqs)
164
- # Ignore the opts for now.
165
- reqs.pop if reqs.last.kind_of?(Hash)
138
+ def resolve_current
139
+ resolve Gem::DependencyResolver::CurrentSet.new
140
+ end
166
141
 
167
- @set.gem name, *reqs
168
- end
142
+ def sorted_requests
143
+ @sorted ||= strongly_connected_components.flatten
144
+ end
169
145
 
170
- def platform(what)
171
- if what == :ruby
172
- yield
173
- end
174
- end
146
+ def specs
147
+ @specs ||= @requests.map { |r| r.full_spec }
148
+ end
149
+
150
+ def specs_in dir
151
+ Dir["#{dir}/specifications/*.gemspec"].map do |g|
152
+ Gem::Specification.load g
153
+ end
154
+ end
155
+
156
+ def tsort_each_node &block # :nodoc:
157
+ @requests.each(&block)
158
+ end
175
159
 
176
- alias_method :platforms, :platform
160
+ def tsort_each_child node # :nodoc:
161
+ node.spec.dependencies.each do |dep|
162
+ next if dep.type == :development and not @development
177
163
 
178
- def group(*what)
164
+ match = @requests.find { |r| dep.match? r.spec.name, r.spec.version }
165
+ if match
166
+ begin
167
+ yield match
168
+ rescue TSort::Cyclic
169
+ end
170
+ else
171
+ unless @soft_missing
172
+ raise Gem::DependencyError, "Unresolved depedency found during sorting - #{dep}"
173
+ end
179
174
  end
180
175
  end
181
176
  end
177
+
182
178
  end
179
+
180
+ require 'rubygems/request_set/gem_dependency_api'
@@ -0,0 +1,39 @@
1
+ ##
2
+ # A semi-compatible DSL for Bundler's Gemfile format
3
+
4
+ class Gem::RequestSet::GemDepedencyAPI
5
+
6
+ def initialize set, path
7
+ @set = set
8
+ @path = path
9
+ end
10
+
11
+ def load
12
+ instance_eval File.read(@path).untaint, @path, 1
13
+ end
14
+
15
+ # :category: Bundler Gemfile DSL
16
+
17
+ def gem name, *reqs
18
+ # Ignore the opts for now.
19
+ reqs.pop if reqs.last.kind_of?(Hash)
20
+
21
+ @set.gem name, *reqs
22
+ end
23
+
24
+ def group *what
25
+ end
26
+
27
+ def platform what
28
+ if what == :ruby
29
+ yield
30
+ end
31
+ end
32
+
33
+ alias :platforms :platform
34
+
35
+ def source url
36
+ end
37
+
38
+ end
39
+
@@ -12,20 +12,6 @@ begin
12
12
  rescue LoadError => e
13
13
  raise unless (e.respond_to?(:path) && e.path == 'openssl') ||
14
14
  e.message =~ / -- openssl$/
15
-
16
- module OpenSSL # :nodoc:
17
- class Digest # :nodoc:
18
- class SHA1 # :nodoc:
19
- def name
20
- 'SHA1'
21
- end
22
- end
23
- end
24
- module PKey # :nodoc:
25
- class RSA # :nodoc:
26
- end
27
- end
28
- end
29
15
  end
30
16
 
31
17
  ##
@@ -352,23 +338,38 @@ module Gem::Security
352
338
  ##
353
339
  # Digest algorithm used to sign gems
354
340
 
355
- DIGEST_ALGORITHM = OpenSSL::Digest::SHA1
341
+ DIGEST_ALGORITHM =
342
+ if defined?(OpenSSL::Digest) then
343
+ OpenSSL::Digest::SHA1
344
+ end
356
345
 
357
346
  ##
358
347
  # Used internally to select the signing digest from all computed digests
359
348
 
360
- DIGEST_NAME = DIGEST_ALGORITHM.new.name # :nodoc:
349
+ DIGEST_NAME = # :nodoc:
350
+ if DIGEST_ALGORITHM then
351
+ DIGEST_ALGORITHM.new.name
352
+ end
361
353
 
362
354
  ##
363
355
  # Algorithm for creating the key pair used to sign gems
364
356
 
365
- KEY_ALGORITHM = OpenSSL::PKey::RSA
357
+ KEY_ALGORITHM =
358
+ if defined?(OpenSSL::PKey) then
359
+ OpenSSL::PKey::RSA
360
+ end
366
361
 
367
362
  ##
368
363
  # Length of keys created by KEY_ALGORITHM
369
364
 
370
365
  KEY_LENGTH = 2048
371
366
 
367
+ ##
368
+ # Cipher used to encrypt the key pair used to sign gems.
369
+ # Must be in the list returned by OpenSSL::Cipher.ciphers
370
+
371
+ KEY_CIPHER = OpenSSL::Cipher.new('AES-256-CBC') if defined?(OpenSSL::Cipher)
372
+
372
373
  ##
373
374
  # One year in seconds
374
375
 
@@ -563,13 +564,18 @@ module Gem::Security
563
564
 
564
565
  ##
565
566
  # Writes +pemmable+, which must respond to +to_pem+ to +path+ with the given
566
- # +permissions+.
567
+ # +permissions+. If passed +cipher+ and +passphrase+ those arguments will be
568
+ # passed to +to_pem+.
567
569
 
568
- def self.write pemmable, path, permissions = 0600
570
+ def self.write pemmable, path, permissions = 0600, passphrase = nil, cipher = KEY_CIPHER
569
571
  path = File.expand_path path
570
572
 
571
573
  open path, 'wb', permissions do |io|
572
- io.write pemmable.to_pem
574
+ if passphrase and cipher
575
+ io.write pemmable.to_pem cipher, passphrase
576
+ else
577
+ io.write pemmable.to_pem
578
+ end
573
579
  end
574
580
 
575
581
  path
@@ -579,8 +585,11 @@ module Gem::Security
579
585
 
580
586
  end
581
587
 
582
- require 'rubygems/security/policy'
583
- require 'rubygems/security/policies'
588
+ if defined?(OpenSSL::SSL) then
589
+ require 'rubygems/security/policy'
590
+ require 'rubygems/security/policies'
591
+ require 'rubygems/security/trust_dir'
592
+ end
593
+
584
594
  require 'rubygems/security/signer'
585
- require 'rubygems/security/trust_dir'
586
595
 
@@ -1,3 +1,5 @@
1
+ require 'rubygems/user_interaction'
2
+
1
3
  ##
2
4
  # A Gem::Security::Policy object encapsulates the settings for verifying
3
5
  # signed gem files. This is the base class. You can either declare an
@@ -6,6 +8,8 @@
6
8
 
7
9
  class Gem::Security::Policy
8
10
 
11
+ include Gem::UserInteraction
12
+
9
13
  attr_reader :name
10
14
 
11
15
  attr_accessor :only_signed
@@ -175,6 +179,19 @@ class Gem::Security::Policy
175
179
  true
176
180
  end
177
181
 
182
+ ##
183
+ # Extracts the email or subject from +certificate+
184
+
185
+ def subject certificate # :nodoc:
186
+ certificate.extensions.each do |extension|
187
+ next unless extension.oid == 'subjectAltName'
188
+
189
+ return extension.value
190
+ end
191
+
192
+ certificate.subject.to_s
193
+ end
194
+
178
195
  def inspect # :nodoc:
179
196
  ("[Policy: %s - data: %p signer: %p chain: %p root: %p " +
180
197
  "signed-only: %p trusted-only: %p]") % [
@@ -184,16 +201,21 @@ class Gem::Security::Policy
184
201
  end
185
202
 
186
203
  ##
187
- # Verifies the certificate +chain+ is valid, the +digests+ match the
188
- # signatures +signatures+ created by the signer depending on the +policy+
189
- # settings.
204
+ # For +full_name+, verifies the certificate +chain+ is valid, the +digests+
205
+ # match the signatures +signatures+ created by the signer depending on the
206
+ # +policy+ settings.
190
207
  #
191
208
  # If +key+ is given it is used to validate the signing certificate.
192
209
 
193
- def verify chain, key = nil, digests = {}, signatures = {}
194
- if @only_signed and signatures.empty? then
195
- raise Gem::Security::Exception,
196
- "unsigned gems are not allowed by the #{name} policy"
210
+ def verify chain, key = nil, digests = {}, signatures = {},
211
+ full_name = '(unknown)'
212
+ if signatures.empty? then
213
+ if @only_signed then
214
+ raise Gem::Security::Exception,
215
+ "unsigned gems are not allowed by the #{name} policy"
216
+ else
217
+ alert_warning "#{full_name} is not signed"
218
+ end
197
219
  end
198
220
 
199
221
  opt = @opt
@@ -222,7 +244,11 @@ class Gem::Security::Policy
222
244
 
223
245
  check_root chain, time if @verify_root
224
246
 
225
- check_trust chain, digester, trust_dir if @only_trusted
247
+ if @only_trusted then
248
+ check_trust chain, digester, trust_dir
249
+ else
250
+ alert_warning "#{subject signer} is not trusted for #{full_name}"
251
+ end
226
252
 
227
253
  signatures.each do |file, _|
228
254
  digest = signer_digests[file]
@@ -252,7 +278,7 @@ class Gem::Security::Policy
252
278
  OpenSSL::X509::Certificate.new cert_pem
253
279
  end
254
280
 
255
- verify chain, nil, digests, signatures
281
+ verify chain, nil, digests, signatures, spec.full_name
256
282
 
257
283
  true
258
284
  end