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
data/lib/rubygems/request_set.rb
CHANGED
@@ -5,178 +5,176 @@ require 'rubygems/dependency_list'
|
|
5
5
|
require 'rubygems/installer'
|
6
6
|
require 'tsort'
|
7
7
|
|
8
|
-
|
9
|
-
class RequestSet
|
8
|
+
class Gem::RequestSet
|
10
9
|
|
11
|
-
|
10
|
+
include TSort
|
12
11
|
|
13
|
-
|
14
|
-
|
12
|
+
##
|
13
|
+
# Array of gems to install even if already installed
|
15
14
|
|
16
|
-
|
17
|
-
end
|
15
|
+
attr_reader :always_install
|
18
16
|
|
19
|
-
|
17
|
+
attr_reader :dependencies
|
20
18
|
|
21
|
-
|
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
|
-
|
29
|
-
|
30
|
-
def import(deps)
|
31
|
-
@dependencies += deps
|
32
|
-
end
|
21
|
+
##
|
22
|
+
# Treat missing dependencies as silent errors
|
33
23
|
|
34
|
-
|
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
|
-
|
43
|
-
|
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
|
-
|
51
|
-
|
52
|
-
|
53
|
-
gf = GemDepedencyAPI.new(self, path)
|
54
|
-
gf.load
|
55
|
-
end
|
29
|
+
@always_install = []
|
30
|
+
@development = false
|
31
|
+
@soft_missing = false
|
56
32
|
|
57
|
-
|
58
|
-
|
59
|
-
end
|
33
|
+
yield self if block_given?
|
34
|
+
end
|
60
35
|
|
61
|
-
|
62
|
-
|
63
|
-
end
|
36
|
+
##
|
37
|
+
# Declare that a gem of name +name+ with +reqs+ requirements is needed.
|
64
38
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
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
|
-
|
82
|
-
|
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
|
-
|
86
|
-
|
87
|
-
|
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
|
-
|
92
|
-
existing = force ? [] : specs_in(dir)
|
66
|
+
path = req.download cache_dir
|
93
67
|
|
94
|
-
|
68
|
+
inst = Gem::Installer.new path, options
|
95
69
|
|
96
|
-
|
70
|
+
yield req, inst if block_given?
|
97
71
|
|
98
|
-
|
99
|
-
|
100
|
-
b.call req, nil if b
|
101
|
-
next
|
102
|
-
end
|
72
|
+
specs << inst.install
|
73
|
+
end
|
103
74
|
|
104
|
-
|
75
|
+
specs
|
76
|
+
end
|
105
77
|
|
106
|
-
|
107
|
-
|
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
|
-
|
82
|
+
dir = File.expand_path dir
|
110
83
|
|
111
|
-
|
84
|
+
installed = []
|
112
85
|
|
113
|
-
|
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
|
-
|
117
|
-
end
|
92
|
+
path = req.download(dir)
|
118
93
|
|
119
|
-
|
120
|
-
|
121
|
-
|
94
|
+
unless path then # already installed
|
95
|
+
yield req, nil if block_given?
|
96
|
+
next
|
122
97
|
end
|
123
98
|
|
124
|
-
|
99
|
+
options[:install_dir] = dir
|
100
|
+
options[:only_install_dir] = true
|
125
101
|
|
126
|
-
|
102
|
+
inst = Gem::Installer.new path, options
|
127
103
|
|
128
|
-
|
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
|
-
|
106
|
+
inst.install
|
135
107
|
|
136
|
-
|
108
|
+
installed << req
|
109
|
+
end
|
137
110
|
|
138
|
-
|
111
|
+
installed
|
112
|
+
end
|
139
113
|
|
140
|
-
|
141
|
-
|
114
|
+
##
|
115
|
+
# Load a dependency management file.
|
142
116
|
|
143
|
-
|
144
|
-
|
117
|
+
def load_gemdeps path
|
118
|
+
gf = Gem::RequestSet::GemDepedencyAPI.new self, path
|
119
|
+
gf.load
|
120
|
+
end
|
145
121
|
|
146
|
-
|
147
|
-
|
148
|
-
|
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
|
-
|
155
|
-
|
156
|
-
|
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
|
-
|
131
|
+
@requests = resolver.resolve
|
132
|
+
end
|
159
133
|
|
160
|
-
|
161
|
-
|
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
|
-
|
164
|
-
|
165
|
-
|
138
|
+
def resolve_current
|
139
|
+
resolve Gem::DependencyResolver::CurrentSet.new
|
140
|
+
end
|
166
141
|
|
167
|
-
|
168
|
-
|
142
|
+
def sorted_requests
|
143
|
+
@sorted ||= strongly_connected_components.flatten
|
144
|
+
end
|
169
145
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
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
|
-
|
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
|
-
|
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
|
+
|
data/lib/rubygems/security.rb
CHANGED
@@ -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 =
|
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 =
|
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 =
|
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
|
-
|
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
|
-
|
583
|
-
require 'rubygems/security/
|
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
|
-
#
|
188
|
-
# signatures +signatures+ created by the signer depending on the
|
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
|
-
|
195
|
-
|
196
|
-
|
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
|
-
|
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
|