diff options
author | drbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-02-05 02:37:35 +0000 |
---|---|---|
committer | drbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-02-05 02:37:35 +0000 |
commit | 1633e543db2cc5c1f690840e5e7ea1f2a9af0b55 (patch) | |
tree | 2fce34d522a822171b91823dfcf9e0b8a2c9d283 /lib | |
parent | 6dfd56696fb49310149dc5ed7af52c8d7f43e536 (diff) |
* lib/rubygems/commands/push_command.rb: Fixed credential download for
`gem push --host`
* lib/rubygems/gemcutter_utilities.rb: ditto.
* test/rubygems/test_gem_commands_push_command.rb: Test for the above.
* test/rubygems/test_gem_gemcutter_utilities.rb: ditto.
* lib/rubygems/config_file.rb: Abort if the `gem push` credentials
file has insecure permissions.
* test/rubygems/test_gem_config_file.rb: Test for the above.
* lib/rubygems/ext/builder.rb: Do not look for Gemfile, Isolate, etc.
while building gem extensions.
* lib/rubygems/package.rb: Unset spec and files list if a gem's
signatures cannot be verified.
* test/rubygems/test_gem_package.rb: Test for the above.
* lib/rubygems/specification.rb: Reduce use of eval.
* lib/rubygems/test_case.rb: ditto.
* test/rubygems/test_gem_specification.rb: Test setting
specification_version for legacy gems. Dup Gem.ruby before
untainting in case it's frozen.
* lib/rubygems.rb: Reduce use of eval. Only read files when looking
for Gemfile, Isolate, etc.
* test/rubygems/test_gem.rb: Test for the above.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@39055 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib')
-rw-r--r-- | lib/rubygems.rb | 29 | ||||
-rw-r--r-- | lib/rubygems/commands/push_command.rb | 29 | ||||
-rw-r--r-- | lib/rubygems/config_file.rb | 36 | ||||
-rw-r--r-- | lib/rubygems/ext/builder.rb | 18 | ||||
-rw-r--r-- | lib/rubygems/gemcutter_utilities.rb | 16 | ||||
-rw-r--r-- | lib/rubygems/package.rb | 4 | ||||
-rw-r--r-- | lib/rubygems/specification.rb | 2 | ||||
-rw-r--r-- | lib/rubygems/test_case.rb | 7 |
8 files changed, 90 insertions, 51 deletions
diff --git a/lib/rubygems.rb b/lib/rubygems.rb index dcfe74039c..0fb718aedc 100644 --- a/lib/rubygems.rb +++ b/lib/rubygems.rb @@ -207,7 +207,7 @@ module Gem begin while true - path = GEM_DEP_FILES.find { |f| File.exists?(f) } + path = GEM_DEP_FILES.find { |f| File.file?(f) } if path path = File.join here, path @@ -226,7 +226,9 @@ module Gem end end - return unless File.exists? path + path.untaint + + return unless File.file? path rs = Gem::RequestSet.new rs.load_gemdeps path @@ -370,29 +372,6 @@ module Gem end ## - # Expand each partial gem path with each of the required paths specified - # in the Gem spec. Each expanded path is yielded. - - def self.each_load_path(partials) - partials.each do |gp| - base = File.basename gp - specfn = File.join(dir, "specifications", "#{base}.gemspec") - if File.exists? specfn - spec = eval(File.read(specfn)) - spec.require_paths.each do |rp| - yield File.join(gp,rp) - end - else - filename = File.join(gp, 'lib') - yield(filename) if File.exists? filename - end - end - end - - private_class_method :each_load_path - - - ## # Quietly ensure the named Gem directory contains all the proper # subdirectories. If we can't create a directory due to a permission # problem, then we will silently continue. diff --git a/lib/rubygems/commands/push_command.rb b/lib/rubygems/commands/push_command.rb index ce70836823..2df00b0457 100644 --- a/lib/rubygems/commands/push_command.rb +++ b/lib/rubygems/commands/push_command.rb @@ -24,16 +24,19 @@ class Gem::Commands::PushCommand < Gem::Command add_proxy_option add_key_option - add_option( - '--host HOST', - 'Push to another gemcutter-compatible host' - ) do |value, options| + add_option('--host HOST', + 'Push to another gemcutter-compatible host') do |value, options| options[:host] = value end + + @host = nil end def execute - sign_in + @host = options[:host] + + sign_in @host + send_gem get_one_gem_name end @@ -44,26 +47,30 @@ class Gem::Commands::PushCommand < Gem::Command if latest_rubygems_version < Gem.rubygems_version and Gem.rubygems_version.prerelease? and - Gem::Version.new('2.0.0.preview3') != Gem.rubygems_version then + Gem::Version.new('2.0.0.rc.2') != Gem.rubygems_version then alert_error <<-ERROR You are using a beta release of RubyGems (#{Gem::VERSION}) which is not allowed to push gems. Please downgrade or upgrade to a release version. The latest released RubyGems version is #{latest_rubygems_version} + +You can upgrade or downgrade to the latest release version with: + + gem update --system=#{latest_rubygems_version} + ERROR terminate_interaction 1 end - host = options[:host] - unless host + unless @host then if gem_data = Gem::Package.new(name) then - host = gem_data.spec.metadata['default_gem_server'] + @host = gem_data.spec.metadata['default_gem_server'] end end - args << host if host + args << @host if @host - say "Pushing gem to #{host || Gem.host}..." + say "Pushing gem to #{@host || Gem.host}..." response = rubygems_api_request(*args) do |request| request.body = Gem.read_binary name diff --git a/lib/rubygems/config_file.rb b/lib/rubygems/config_file.rb index 81ee32a1d6..7e1432b349 100644 --- a/lib/rubygems/config_file.rb +++ b/lib/rubygems/config_file.rb @@ -33,6 +33,8 @@ class Gem::ConfigFile + include Gem::UserInteraction + DEFAULT_BACKTRACE = false DEFAULT_BULK_THRESHOLD = 1000 DEFAULT_VERBOSITY = true @@ -224,6 +226,34 @@ class Gem::ConfigFile end ## + # Checks the permissions of the credentials file. If they are not 0600 an + # error message is displayed and RubyGems aborts. + + def check_credentials_permissions + return unless File.exist? credentials_path + + existing_permissions = File.stat(credentials_path).mode & 0777 + + return if existing_permissions == 0600 + + alert_error <<-ERROR +Your gem push credentials file located at: + +\t#{credentials_path} + +has file permissions of 0#{existing_permissions.to_s 8} but 0600 is required. + +You should reset your credentials at: + +\thttps://rubygems.org/profile/edit + +if you believe they were disclosed to a third party. + ERROR + + terminate_interaction 1 + end + + ## # Location of RubyGems.org credentials def credentials_path @@ -231,6 +261,8 @@ class Gem::ConfigFile end def load_api_keys + check_credentials_permissions + @api_keys = if File.exist? credentials_path then load_file(credentials_path) else @@ -243,7 +275,9 @@ class Gem::ConfigFile end end - def rubygems_api_key=(api_key) + def rubygems_api_key= api_key + check_credentials_permissions + config = load_file(credentials_path).merge(:rubygems_api_key => api_key) dirname = File.dirname credentials_path diff --git a/lib/rubygems/ext/builder.rb b/lib/rubygems/ext/builder.rb index 81b96e84a9..d7d953fec3 100644 --- a/lib/rubygems/ext/builder.rb +++ b/lib/rubygems/ext/builder.rb @@ -43,12 +43,18 @@ class Gem::Ext::Builder def self.run(command, results, command_name = nil) verbose = Gem.configuration.really_verbose - if verbose - puts(command) - system(command) - else - results << command - results << `#{command} #{redirector}` + begin + # TODO use Process.spawn when ruby 1.8 support is dropped. + rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], nil + if verbose + puts(command) + system(command) + else + results << command + results << `#{command} #{redirector}` + end + ensure + ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps end unless $?.success? then diff --git a/lib/rubygems/gemcutter_utilities.rb b/lib/rubygems/gemcutter_utilities.rb index 3042092125..474d07f775 100644 --- a/lib/rubygems/gemcutter_utilities.rb +++ b/lib/rubygems/gemcutter_utilities.rb @@ -27,17 +27,25 @@ module Gem::GemcutterUtilities end end - def sign_in + def sign_in sign_in_host = self.host return if Gem.configuration.rubygems_api_key - say "Enter your RubyGems.org credentials." - say "Don't have an account yet? Create one at http://rubygems.org/sign_up" + pretty_host = if Gem::DEFAULT_HOST == sign_in_host then + 'RubyGems.org' + else + sign_in_host + end + + say "Enter your #{pretty_host} credentials." + say "Don't have an account yet? " + + "Create one at https://#{sign_in_host}/sign_up" email = ask " Email: " password = ask_for_password "Password: " say "\n" - response = rubygems_api_request :get, "api/v1/api_key" do |request| + response = rubygems_api_request(:get, "api/v1/api_key", + sign_in_host) do |request| request.basic_auth email, password end diff --git a/lib/rubygems/package.rb b/lib/rubygems/package.rb index e33dea06e9..c662da2a55 100644 --- a/lib/rubygems/package.rb +++ b/lib/rubygems/package.rb @@ -473,6 +473,10 @@ EOM @security_policy true + rescue Gem::Security::Exception + @spec = nil + @files = [] + raise rescue Errno::ENOENT => e raise Gem::Package::FormatError.new e.message rescue Gem::Package::TarInvalidError => e diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb index 841bfbf842..cabdf8df7f 100644 --- a/lib/rubygems/specification.rb +++ b/lib/rubygems/specification.rb @@ -904,7 +904,7 @@ class Gem::Specification raise Gem::Exception, "YAML data doesn't evaluate to gem specification" end - spec.instance_eval { @specification_version ||= NONEXISTENT_SPECIFICATION_VERSION } + spec.specification_version ||= NONEXISTENT_SPECIFICATION_VERSION spec.reset_nil_attributes_to_default spec diff --git a/lib/rubygems/test_case.rb b/lib/rubygems/test_case.rb index 47fb9d4962..3da3173285 100644 --- a/lib/rubygems/test_case.rb +++ b/lib/rubygems/test_case.rb @@ -143,8 +143,9 @@ class Gem::TestCase < MiniTest::Unit::TestCase @gemhome = File.join @tempdir, 'gemhome' @userhome = File.join @tempdir, 'userhome' - @orig_ruby = if ruby = ENV['RUBY'] then - Gem.class_eval { ruby, @ruby = @ruby, ruby.dup } + @orig_ruby = if ENV['RUBY'] then + ruby = Gem.instance_variable_get :@ruby + Gem.instance_variable_set :@ruby, ENV['RUBY'] ruby end @@ -264,7 +265,7 @@ class Gem::TestCase < MiniTest::Unit::TestCase ENV['GEM_PATH'] = @orig_gem_path _ = @orig_ruby - Gem.class_eval { @ruby = _ } if _ + Gem.instance_variable_set :@ruby, @orig_ruby if @orig_ruby if @orig_ENV_HOME then ENV['HOME'] = @orig_ENV_HOME |