rubygems-update 1.3.7 → 1.4.0
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.
- data.tar.gz.sig +0 -0
- data/.autotest +4 -1
- data/ChangeLog +23 -0
- data/History.txt +30 -1
- data/Manifest.txt +1 -1
- data/{README → README.rdoc} +4 -4
- data/Rakefile +7 -56
- data/lib/rbconfig/datadir.rb +6 -13
- data/lib/rubygems.rb +144 -89
- data/lib/rubygems/builder.rb +15 -5
- data/lib/rubygems/command.rb +12 -4
- data/lib/rubygems/command_manager.rb +1 -1
- data/lib/rubygems/commands/build_command.rb +1 -1
- data/lib/rubygems/commands/cert_command.rb +4 -4
- data/lib/rubygems/commands/check_command.rb +1 -1
- data/lib/rubygems/commands/fetch_command.rb +1 -1
- data/lib/rubygems/commands/install_command.rb +4 -16
- data/lib/rubygems/commands/lock_command.rb +1 -1
- data/lib/rubygems/commands/mirror_command.rb +4 -4
- data/lib/rubygems/commands/pristine_command.rb +0 -1
- data/lib/rubygems/commands/push_command.rb +13 -2
- data/lib/rubygems/commands/query_command.rb +4 -4
- data/lib/rubygems/commands/server_command.rb +9 -1
- data/lib/rubygems/commands/setup_command.rb +3 -3
- data/lib/rubygems/commands/sources_command.rb +2 -1
- data/lib/rubygems/commands/specification_command.rb +2 -1
- data/lib/rubygems/commands/unpack_command.rb +2 -1
- data/lib/rubygems/commands/update_command.rb +2 -2
- data/lib/rubygems/commands/which_command.rb +1 -0
- data/lib/rubygems/custom_require.rb +0 -2
- data/lib/rubygems/dependency.rb +15 -20
- data/lib/rubygems/dependency_installer.rb +31 -24
- data/lib/rubygems/dependency_list.rb +2 -7
- data/lib/rubygems/doc_manager.rb +2 -2
- data/lib/rubygems/ext/rake_builder.rb +1 -1
- data/lib/rubygems/format.rb +0 -4
- data/lib/rubygems/gem_openssl.rb +1 -3
- data/lib/rubygems/gem_path_searcher.rb +17 -0
- data/lib/rubygems/gem_runner.rb +6 -0
- data/lib/rubygems/gemcutter_utilities.rb +3 -3
- data/lib/rubygems/indexer.rb +4 -4
- data/lib/rubygems/install_update_options.rb +6 -0
- data/lib/rubygems/installer.rb +13 -6
- data/lib/rubygems/local_remote_options.rb +18 -5
- data/lib/rubygems/old_format.rb +4 -4
- data/lib/rubygems/package.rb +1 -6
- data/lib/rubygems/package/tar_input.rb +3 -0
- data/lib/rubygems/package_task.rb +6 -6
- data/lib/rubygems/platform.rb +1 -1
- data/lib/rubygems/remote_fetcher.rb +39 -8
- data/lib/rubygems/requirement.rb +1 -1
- data/lib/rubygems/security.rb +145 -106
- data/lib/rubygems/server.rb +16 -2
- data/lib/rubygems/source_index.rb +14 -45
- data/lib/rubygems/source_info_cache.rb +1 -2
- data/lib/rubygems/spec_fetcher.rb +32 -3
- data/lib/rubygems/specification.rb +34 -16
- data/lib/rubygems/text.rb +35 -0
- data/lib/rubygems/uninstaller.rb +1 -1
- data/lib/rubygems/user_interaction.rb +70 -0
- data/lib/rubygems/validator.rb +5 -3
- data/lib/rubygems/version.rb +36 -25
- data/test/gem_package_tar_test_case.rb +3 -1
- data/test/gemutilities.rb +26 -4
- data/test/test_config.rb +6 -2
- data/test/test_gem.rb +87 -29
- data/test/test_gem_command_manager.rb +3 -6
- data/test/test_gem_commands_cert_command.rb +2 -2
- data/test/test_gem_commands_install_command.rb +55 -0
- data/test/test_gem_commands_outdated_command.rb +2 -2
- data/test/test_gem_commands_owner_command.rb +6 -6
- data/test/test_gem_commands_push_command.rb +27 -7
- data/test/test_gem_commands_query_command.rb +0 -6
- data/test/test_gem_commands_specification_command.rb +4 -4
- data/test/test_gem_config_file.rb +0 -2
- data/test/test_gem_dependency_installer.rb +21 -23
- data/test/test_gem_ext_ext_conf_builder.rb +0 -9
- data/test/test_gem_ext_rake_builder.rb +0 -15
- data/test/test_gem_gemcutter_utilities.rb +1 -1
- data/test/test_gem_installer.rb +0 -5
- data/test/test_gem_local_remote_options.rb +18 -1
- data/test/test_gem_package_task.rb +1 -1
- data/test/test_gem_platform.rb +0 -1
- data/test/test_gem_remote_fetcher.rb +5 -3
- data/test/test_gem_requirement.rb +2 -2
- data/test/test_gem_security.rb +90 -0
- data/test/test_gem_server.rb +6 -6
- data/test/test_gem_source_index.rb +7 -13
- data/test/test_gem_specification.rb +3 -18
- data/test/test_gem_stream_ui.rb +69 -5
- data/test/test_gem_text.rb +43 -0
- data/test/test_gem_version.rb +14 -7
- data/test/test_kernel.rb +1 -1
- data/util/gem_prelude.rb +8 -8
- metadata +15 -10
- metadata.gz.sig +0 -0
@@ -1,9 +1,6 @@
|
|
1
|
-
require 'net/http'
|
2
|
-
require 'stringio'
|
3
|
-
require 'time'
|
4
|
-
require 'uri'
|
5
|
-
|
6
1
|
require 'rubygems'
|
2
|
+
require 'rubygems/user_interaction'
|
3
|
+
require 'uri'
|
7
4
|
|
8
5
|
##
|
9
6
|
# RemoteFetcher handles the details of fetching gems and gem information from
|
@@ -56,6 +53,11 @@ class Gem::RemoteFetcher
|
|
56
53
|
# * <tt>:no_proxy</tt>: ignore environment variables and _don't_ use a proxy
|
57
54
|
|
58
55
|
def initialize(proxy = nil)
|
56
|
+
require 'net/http'
|
57
|
+
require 'stringio'
|
58
|
+
require 'time'
|
59
|
+
require 'uri'
|
60
|
+
|
59
61
|
Socket.do_not_reverse_lookup = true
|
60
62
|
|
61
63
|
@connections = {}
|
@@ -75,6 +77,8 @@ class Gem::RemoteFetcher
|
|
75
77
|
# always replaced.
|
76
78
|
|
77
79
|
def download(spec, source_uri, install_dir = Gem.dir)
|
80
|
+
Gem.ensure_gem_subdirectories(install_dir) rescue nil
|
81
|
+
|
78
82
|
if File.writable?(install_dir)
|
79
83
|
cache_dir = File.join install_dir, 'cache'
|
80
84
|
else
|
@@ -147,7 +151,7 @@ class Gem::RemoteFetcher
|
|
147
151
|
source_uri.path
|
148
152
|
end
|
149
153
|
|
150
|
-
source_path =
|
154
|
+
source_path = unescape source_path
|
151
155
|
|
152
156
|
begin
|
153
157
|
FileUtils.cp source_path, local_gem_path unless
|
@@ -241,7 +245,7 @@ class Gem::RemoteFetcher
|
|
241
245
|
]
|
242
246
|
end
|
243
247
|
|
244
|
-
connection_id = net_http_args.join ':'
|
248
|
+
connection_id = [Thread.current.object_id, *net_http_args].join ':'
|
245
249
|
@connections[connection_id] ||= Net::HTTP.new(*net_http_args)
|
246
250
|
connection = @connections[connection_id]
|
247
251
|
|
@@ -339,7 +343,34 @@ class Gem::RemoteFetcher
|
|
339
343
|
|
340
344
|
say "#{request.method} #{uri}" if
|
341
345
|
Gem.configuration.really_verbose
|
342
|
-
|
346
|
+
|
347
|
+
file_name = File.basename(uri.path)
|
348
|
+
# perform download progress reporter only for gems
|
349
|
+
if request.response_body_permitted? && file_name =~ /\.gem$/
|
350
|
+
reporter = ui.download_reporter
|
351
|
+
response = connection.request(request) do |incomplete_response|
|
352
|
+
if Net::HTTPOK === incomplete_response
|
353
|
+
reporter.fetch(file_name, incomplete_response.content_length)
|
354
|
+
downloaded = 0
|
355
|
+
data = ''
|
356
|
+
|
357
|
+
incomplete_response.read_body do |segment|
|
358
|
+
data << segment
|
359
|
+
downloaded += segment.length
|
360
|
+
reporter.update(downloaded)
|
361
|
+
end
|
362
|
+
reporter.done
|
363
|
+
if incomplete_response.respond_to? :body=
|
364
|
+
incomplete_response.body = data
|
365
|
+
else
|
366
|
+
incomplete_response.instance_variable_set(:@body, data)
|
367
|
+
end
|
368
|
+
end
|
369
|
+
end
|
370
|
+
else
|
371
|
+
response = connection.request request
|
372
|
+
end
|
373
|
+
|
343
374
|
say "#{response.code} #{response.message}" if
|
344
375
|
Gem.configuration.really_verbose
|
345
376
|
|
data/lib/rubygems/requirement.rb
CHANGED
@@ -14,7 +14,7 @@ class Gem::Requirement
|
|
14
14
|
"<" => lambda { |v, r| v < r },
|
15
15
|
">=" => lambda { |v, r| v >= r },
|
16
16
|
"<=" => lambda { |v, r| v <= r },
|
17
|
-
"~>" => lambda { |v, r| v
|
17
|
+
"~>" => lambda { |v, r| v >= r && v.release < r.bump }
|
18
18
|
}
|
19
19
|
|
20
20
|
quoted = OPS.keys.map { |k| Regexp.quote k }.join "|"
|
data/lib/rubygems/security.rb
CHANGED
@@ -4,9 +4,10 @@
|
|
4
4
|
# See LICENSE.txt for permissions.
|
5
5
|
#++
|
6
6
|
|
7
|
-
require 'rubygems'
|
7
|
+
require 'rubygems/exceptions'
|
8
8
|
require 'rubygems/gem_openssl'
|
9
9
|
|
10
|
+
#
|
10
11
|
# = Signed Gems README
|
11
12
|
#
|
12
13
|
# == Table of Contents
|
@@ -265,6 +266,34 @@ require 'rubygems/gem_openssl'
|
|
265
266
|
# A more detailed description of each options is available in the walkthrough
|
266
267
|
# above.
|
267
268
|
#
|
269
|
+
# == Manually verifying signatures
|
270
|
+
#
|
271
|
+
# In case you don't trust RubyGems you can verify gem signatures manually:
|
272
|
+
#
|
273
|
+
# 1. Fetch and unpack the gem
|
274
|
+
#
|
275
|
+
# gem fetch some_signed_gem
|
276
|
+
# tar -xf some_signed_gem-1.0.gem
|
277
|
+
#
|
278
|
+
# 2. Grab the public key from the gemspec
|
279
|
+
#
|
280
|
+
# gem spec some_signed_gem-1.0.gem cert_chain | \
|
281
|
+
# ruby -pe 'sub(/^ +/, "")' > public_key.crt
|
282
|
+
#
|
283
|
+
# 3. Generate a SHA1 hash of the data.tar.gz
|
284
|
+
#
|
285
|
+
# openssl dgst -sha1 < data.tar.gz > my.hash
|
286
|
+
#
|
287
|
+
# 4. Verify the signature
|
288
|
+
#
|
289
|
+
# openssl rsautl -verify -inkey public_key.crt -certin \
|
290
|
+
# -in data.tar.gz.sig > verified.hash
|
291
|
+
#
|
292
|
+
# 5. Compare your hash to the verified hash
|
293
|
+
#
|
294
|
+
# diff -s verified.hash my.hash
|
295
|
+
#
|
296
|
+
# 6. Repeat 5 and 6 with metadata.gz
|
268
297
|
#
|
269
298
|
# == OpenSSL Reference
|
270
299
|
#
|
@@ -319,11 +348,14 @@ require 'rubygems/gem_openssl'
|
|
319
348
|
|
320
349
|
module Gem::Security
|
321
350
|
|
351
|
+
##
|
352
|
+
# Gem::Security default exception type
|
353
|
+
|
322
354
|
class Exception < Gem::Exception; end
|
323
355
|
|
324
|
-
|
325
|
-
#
|
326
|
-
|
356
|
+
##
|
357
|
+
# Default options for most of the methods below
|
358
|
+
|
327
359
|
OPT = {
|
328
360
|
# private key options
|
329
361
|
:key_algo => Gem::SSL::PKEY_RSA,
|
@@ -338,38 +370,38 @@ module Gem::Security
|
|
338
370
|
'basicConstraints' => 'CA:FALSE',
|
339
371
|
'subjectKeyIdentifier' => 'hash',
|
340
372
|
'keyUsage' => 'keyEncipherment,dataEncipherment,digitalSignature',
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
373
|
+
},
|
374
|
+
|
375
|
+
# save the key and cert to a file in build_self_signed_cert()?
|
376
|
+
:save_key => true,
|
377
|
+
:save_cert => true,
|
378
|
+
|
379
|
+
# if you define either of these, then they'll be used instead of
|
380
|
+
# the output_fmt macro below
|
381
|
+
:save_key_path => nil,
|
382
|
+
:save_cert_path => nil,
|
383
|
+
|
384
|
+
# output name format for self-signed certs
|
385
|
+
:output_fmt => 'gem-%s.pem',
|
386
|
+
:munge_re => Regexp.new(/[^a-z0-9_.-]+/),
|
387
|
+
|
388
|
+
# output directory for trusted certificate checksums
|
389
|
+
:trust_dir => File::join(Gem.user_home, '.gem', 'trust'),
|
390
|
+
|
391
|
+
# default permissions for trust directory and certs
|
392
|
+
:perms => {
|
393
|
+
:trust_dir => 0700,
|
394
|
+
:trusted_cert => 0600,
|
395
|
+
:signing_cert => 0600,
|
396
|
+
:signing_key => 0600,
|
397
|
+
},
|
366
398
|
}
|
367
399
|
|
368
|
-
|
400
|
+
##
|
369
401
|
# A Gem::Security::Policy object encapsulates the settings for verifying
|
370
402
|
# signed gem files. This is the base class. You can either declare an
|
371
403
|
# instance of this or use one of the preset security policies below.
|
372
|
-
|
404
|
+
|
373
405
|
class Policy
|
374
406
|
attr_accessor :verify_data, :verify_signer, :verify_chain,
|
375
407
|
:verify_root, :only_trusted, :only_signed
|
@@ -509,9 +541,9 @@ module Gem::Security
|
|
509
541
|
end
|
510
542
|
end
|
511
543
|
|
512
|
-
|
544
|
+
##
|
513
545
|
# No security policy: all package signature checks are disabled.
|
514
|
-
|
546
|
+
|
515
547
|
NoSecurity = Policy.new(
|
516
548
|
:verify_data => false,
|
517
549
|
:verify_signer => false,
|
@@ -521,14 +553,14 @@ module Gem::Security
|
|
521
553
|
:only_signed => false
|
522
554
|
)
|
523
555
|
|
524
|
-
|
556
|
+
##
|
525
557
|
# AlmostNo security policy: only verify that the signing certificate is the
|
526
558
|
# one that actually signed the data. Make no attempt to verify the signing
|
527
559
|
# certificate chain.
|
528
560
|
#
|
529
561
|
# This policy is basically useless. better than nothing, but can still be
|
530
562
|
# easily spoofed, and is not recommended.
|
531
|
-
|
563
|
+
|
532
564
|
AlmostNoSecurity = Policy.new(
|
533
565
|
:verify_data => true,
|
534
566
|
:verify_signer => false,
|
@@ -538,13 +570,13 @@ module Gem::Security
|
|
538
570
|
:only_signed => false
|
539
571
|
)
|
540
572
|
|
541
|
-
|
573
|
+
##
|
542
574
|
# Low security policy: only verify that the signing certificate is actually
|
543
575
|
# the gem signer, and that the signing certificate is valid.
|
544
576
|
#
|
545
577
|
# This policy is better than nothing, but can still be easily spoofed, and
|
546
578
|
# is not recommended.
|
547
|
-
|
579
|
+
|
548
580
|
LowSecurity = Policy.new(
|
549
581
|
:verify_data => true,
|
550
582
|
:verify_signer => true,
|
@@ -554,7 +586,7 @@ module Gem::Security
|
|
554
586
|
:only_signed => false
|
555
587
|
)
|
556
588
|
|
557
|
-
|
589
|
+
##
|
558
590
|
# Medium security policy: verify the signing certificate, verify the signing
|
559
591
|
# certificate chain all the way to the root certificate, and only trust root
|
560
592
|
# certificates that we have explicitly allowed trust for.
|
@@ -562,7 +594,7 @@ module Gem::Security
|
|
562
594
|
# This security policy is reasonable, but it allows unsigned packages, so a
|
563
595
|
# malicious person could simply delete the package signature and pass the
|
564
596
|
# gem off as unsigned.
|
565
|
-
|
597
|
+
|
566
598
|
MediumSecurity = Policy.new(
|
567
599
|
:verify_data => true,
|
568
600
|
:verify_signer => true,
|
@@ -572,7 +604,7 @@ module Gem::Security
|
|
572
604
|
:only_signed => false
|
573
605
|
)
|
574
606
|
|
575
|
-
|
607
|
+
##
|
576
608
|
# High security policy: only allow signed gems to be installed, verify the
|
577
609
|
# signing certificate, verify the signing certificate chain all the way to
|
578
610
|
# the root certificate, and only trust root certificates that we have
|
@@ -580,7 +612,7 @@ module Gem::Security
|
|
580
612
|
#
|
581
613
|
# This security policy is significantly more difficult to bypass, and offers
|
582
614
|
# a reasonable guarantee that the contents of the gem have not been altered.
|
583
|
-
|
615
|
+
|
584
616
|
HighSecurity = Policy.new(
|
585
617
|
:verify_data => true,
|
586
618
|
:verify_signer => true,
|
@@ -590,9 +622,9 @@ module Gem::Security
|
|
590
622
|
:only_signed => true
|
591
623
|
)
|
592
624
|
|
593
|
-
|
625
|
+
##
|
594
626
|
# Hash of configured security policies
|
595
|
-
|
627
|
+
|
596
628
|
Policies = {
|
597
629
|
'NoSecurity' => NoSecurity,
|
598
630
|
'AlmostNoSecurity' => AlmostNoSecurity,
|
@@ -601,25 +633,24 @@ module Gem::Security
|
|
601
633
|
'HighSecurity' => HighSecurity,
|
602
634
|
}
|
603
635
|
|
604
|
-
|
636
|
+
##
|
605
637
|
# Sign the cert cert with @signing_key and @signing_cert, using the digest
|
606
638
|
# algorithm opt[:dgst_algo]. Returns the newly signed certificate.
|
607
|
-
|
639
|
+
|
608
640
|
def self.sign_cert(cert, signing_key, signing_cert, opt = {})
|
609
641
|
opt = OPT.merge(opt)
|
610
642
|
|
611
|
-
# set up issuer information
|
612
643
|
cert.issuer = signing_cert.subject
|
613
|
-
cert.sign
|
644
|
+
cert.sign signing_key, opt[:dgst_algo].new
|
614
645
|
|
615
646
|
cert
|
616
647
|
end
|
617
648
|
|
618
|
-
|
649
|
+
##
|
619
650
|
# Make sure the trust directory exists. If it does exist, make sure it's
|
620
651
|
# actually a directory. If not, then create it with the appropriate
|
621
652
|
# permissions.
|
622
|
-
|
653
|
+
|
623
654
|
def self.verify_trust_dir(path, perms)
|
624
655
|
# if the directory exists, then make sure it is in fact a directory. if
|
625
656
|
# it doesn't exist, then create it with the appropriate permissions
|
@@ -636,94 +667,99 @@ module Gem::Security
|
|
636
667
|
end
|
637
668
|
end
|
638
669
|
|
639
|
-
|
670
|
+
##
|
640
671
|
# Build a certificate from the given DN and private key.
|
641
|
-
|
672
|
+
|
642
673
|
def self.build_cert(name, key, opt = {})
|
643
674
|
Gem.ensure_ssl_available
|
644
|
-
opt = OPT.merge
|
675
|
+
opt = OPT.merge opt
|
676
|
+
|
677
|
+
cert = OpenSSL::X509::Certificate.new
|
645
678
|
|
646
|
-
|
647
|
-
|
679
|
+
cert.not_after = Time.now + opt[:cert_age]
|
680
|
+
cert.not_before = Time.now
|
681
|
+
cert.public_key = key.public_key
|
682
|
+
cert.serial = 0
|
683
|
+
cert.subject = name
|
684
|
+
cert.version = 2
|
648
685
|
|
649
|
-
|
650
|
-
ret.version = 2
|
651
|
-
ret.serial = 0
|
652
|
-
ret.public_key = key.public_key
|
653
|
-
ret.not_before = Time.now
|
654
|
-
ret.not_after = Time.now + opt[:cert_age]
|
655
|
-
ret.subject = name
|
686
|
+
ef = OpenSSL::X509::ExtensionFactory.new nil, cert
|
656
687
|
|
657
|
-
|
658
|
-
|
659
|
-
|
688
|
+
cert.extensions = opt[:cert_exts].map do |ext_name, value|
|
689
|
+
ef.create_extension ext_name, value
|
690
|
+
end
|
660
691
|
|
661
|
-
|
662
|
-
|
663
|
-
ret = sign_cert(ret, i_key, i_cert, opt)
|
692
|
+
i_key = opt[:issuer_key] || key
|
693
|
+
i_cert = opt[:issuer_cert] || cert
|
664
694
|
|
665
|
-
|
666
|
-
|
695
|
+
cert = sign_cert cert, i_key, i_cert, opt
|
696
|
+
|
697
|
+
cert
|
667
698
|
end
|
668
699
|
|
669
|
-
|
700
|
+
##
|
670
701
|
# Build a self-signed certificate for the given email address.
|
671
|
-
|
702
|
+
|
672
703
|
def self.build_self_signed_cert(email_addr, opt = {})
|
673
704
|
Gem.ensure_ssl_available
|
674
705
|
opt = OPT.merge(opt)
|
675
706
|
path = { :key => nil, :cert => nil }
|
676
707
|
|
677
|
-
|
678
|
-
cn, dcs = email_addr.split('@')
|
679
|
-
dcs = dcs.split('.')
|
680
|
-
|
681
|
-
# munge email CN and DCs
|
682
|
-
cn = cn.gsub(opt[:munge_re], '_')
|
683
|
-
dcs = dcs.map { |dc| dc.gsub(opt[:munge_re], '_') }
|
684
|
-
|
685
|
-
# create DN
|
686
|
-
name = "CN=#{cn}/" << dcs.map { |dc| "DC=#{dc}" }.join('/')
|
687
|
-
name = OpenSSL::X509::Name::parse(name)
|
708
|
+
name = email_to_name email_addr, opt[:munge_re]
|
688
709
|
|
689
|
-
|
690
|
-
key = opt[:key_algo].new(opt[:key_size])
|
710
|
+
key = opt[:key_algo].new opt[:key_size]
|
691
711
|
|
692
|
-
|
693
|
-
verify_trust_dir(opt[:trust_dir], opt[:perms][:trust_dir])
|
712
|
+
verify_trust_dir opt[:trust_dir], opt[:perms][:trust_dir]
|
694
713
|
|
695
|
-
|
696
|
-
if opt[:save_key]
|
714
|
+
if opt[:save_key] then
|
697
715
|
path[:key] = opt[:save_key_path] || (opt[:output_fmt] % 'private_key')
|
698
|
-
|
699
|
-
|
700
|
-
|
716
|
+
|
717
|
+
open path[:key], 'wb' do |io|
|
718
|
+
io.chmod opt[:perms][:signing_key]
|
719
|
+
io.write key.to_pem
|
701
720
|
end
|
702
721
|
end
|
703
722
|
|
704
|
-
|
705
|
-
cert = build_cert(name, key, opt)
|
723
|
+
cert = build_cert name, key, opt
|
706
724
|
|
707
|
-
|
708
|
-
if opt[:save_cert]
|
725
|
+
if opt[:save_cert] then
|
709
726
|
path[:cert] = opt[:save_cert_path] || (opt[:output_fmt] % 'public_cert')
|
710
|
-
|
711
|
-
|
712
|
-
file.
|
727
|
+
|
728
|
+
open path[:cert], 'wb' do |file|
|
729
|
+
file.chmod opt[:perms][:signing_cert]
|
730
|
+
file.write cert.to_pem
|
713
731
|
end
|
714
732
|
end
|
715
733
|
|
716
|
-
# return key, cert, and paths (if applicable)
|
717
734
|
{ :key => key, :cert => cert,
|
718
735
|
:key_path => path[:key], :cert_path => path[:cert] }
|
719
736
|
end
|
720
737
|
|
721
|
-
|
738
|
+
##
|
739
|
+
# Turns +email_address+ into an OpenSSL::X509::Name
|
740
|
+
|
741
|
+
def self.email_to_name email_address, munge_re
|
742
|
+
cn, dcs = email_address.split '@'
|
743
|
+
|
744
|
+
dcs = dcs.split '.'
|
745
|
+
|
746
|
+
cn = cn.gsub munge_re, '_'
|
747
|
+
|
748
|
+
dcs = dcs.map do |dc|
|
749
|
+
dc.gsub munge_re, '_'
|
750
|
+
end
|
751
|
+
|
752
|
+
name = "CN=#{cn}/" << dcs.map { |dc| "DC=#{dc}" }.join('/')
|
753
|
+
|
754
|
+
OpenSSL::X509::Name.parse name
|
755
|
+
end
|
756
|
+
|
757
|
+
##
|
722
758
|
# Add certificate to trusted cert list.
|
723
759
|
#
|
724
760
|
# Note: At the moment these are stored in OPT[:trust_dir], although that
|
725
761
|
# directory may change in the future.
|
726
|
-
|
762
|
+
|
727
763
|
def self.add_trusted_cert(cert, opt = {})
|
728
764
|
opt = OPT.merge(opt)
|
729
765
|
|
@@ -743,11 +779,13 @@ module Gem::Security
|
|
743
779
|
nil
|
744
780
|
end
|
745
781
|
|
746
|
-
|
782
|
+
##
|
747
783
|
# Basic OpenSSL-based package signing class.
|
748
|
-
|
784
|
+
|
749
785
|
class Signer
|
750
|
-
|
786
|
+
|
787
|
+
attr_accessor :cert_chain
|
788
|
+
attr_accessor :key
|
751
789
|
|
752
790
|
def initialize(key, cert_chain)
|
753
791
|
Gem.ensure_ssl_available
|
@@ -774,13 +812,14 @@ module Gem::Security
|
|
774
812
|
end
|
775
813
|
end
|
776
814
|
|
777
|
-
|
815
|
+
##
|
778
816
|
# Sign data with given digest algorithm
|
779
|
-
|
817
|
+
|
780
818
|
def sign(data)
|
781
819
|
@key.sign(@algo.new, data)
|
782
820
|
end
|
783
821
|
|
784
822
|
end
|
823
|
+
|
785
824
|
end
|
786
825
|
|