summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authordrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-02-05 02:37:35 +0000
committerdrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-02-05 02:37:35 +0000
commit1633e543db2cc5c1f690840e5e7ea1f2a9af0b55 (patch)
tree2fce34d522a822171b91823dfcf9e0b8a2c9d283 /lib
parent6dfd56696fb49310149dc5ed7af52c8d7f43e536 (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.rb29
-rw-r--r--lib/rubygems/commands/push_command.rb29
-rw-r--r--lib/rubygems/config_file.rb36
-rw-r--r--lib/rubygems/ext/builder.rb18
-rw-r--r--lib/rubygems/gemcutter_utilities.rb16
-rw-r--r--lib/rubygems/package.rb4
-rw-r--r--lib/rubygems/specification.rb2
-rw-r--r--lib/rubygems/test_case.rb7
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