Copy insecure private key to user owned directory [GH-580]

This commit is contained in:
Mitchell Hashimoto 2011-12-11 16:31:25 -08:00
parent 42a5e02db4
commit 05ae297fd2
7 changed files with 67 additions and 6 deletions

View File

@ -9,6 +9,8 @@
- Tweaks to SSH to hopefully be more reliable in coming up. - Tweaks to SSH to hopefully be more reliable in coming up.
- Helpful error message when SCP is unavailable in the guest. [GH-568] - Helpful error message when SCP is unavailable in the guest. [GH-568]
- Error message for improperly packaged box files. [GH-198] - Error message for improperly packaged box files. [GH-198]
- Copy insecure private key to user-owned directory so even
`sudo` installed Vagrant installations work. [GH-580]
## 0.8.10 (December 10, 2011) ## 0.8.10 (December 10, 2011)

View File

@ -10,7 +10,6 @@ Vagrant::Config.run do |config|
config.ssh.forwarded_port_destination = 22 config.ssh.forwarded_port_destination = 22
config.ssh.max_tries = 100 config.ssh.max_tries = 100
config.ssh.timeout = 7 config.ssh.timeout = 7
config.ssh.private_key_path = File.expand_path("keys/vagrant", Vagrant.source_root)
config.ssh.forward_agent = false config.ssh.forward_agent = false
config.ssh.forward_x11 = false config.ssh.forward_x11 = false

View File

@ -20,14 +20,17 @@ module Vagrant
@port = nil @port = nil
@forward_agent = false @forward_agent = false
@forward_x11 = false @forward_x11 = false
@private_key_path = nil
end end
def validate(env, errors) def validate(env, errors)
[:username, :host, :forwarded_port_key, :max_tries, :timeout, :private_key_path].each do |field| [:username, :host, :forwarded_port_key, :max_tries, :timeout].each do |field|
errors.add(I18n.t("vagrant.config.common.error_empty", :field => field)) if !instance_variable_get("@#{field}".to_sym) errors.add(I18n.t("vagrant.config.common.error_empty", :field => field)) if !instance_variable_get("@#{field}".to_sym)
end end
errors.add(I18n.t("vagrant.config.ssh.private_key_missing", :path => private_key_path)) if !File.file?(private_key_path) if private_key_path && !File.file?(private_key_path)
errors.add(I18n.t("vagrant.config.ssh.private_key_missing", :path => private_key_path))
end
end end
end end
end end

View File

@ -3,6 +3,8 @@ require 'fileutils'
require 'log4r' require 'log4r'
require 'vagrant/util/file_mode'
module Vagrant module Vagrant
# Represents a single Vagrant environment. A "Vagrant environment" is # Represents a single Vagrant environment. A "Vagrant environment" is
# defined as basically a folder with a "Vagrantfile." This class allows # defined as basically a folder with a "Vagrantfile." This class allows
@ -31,6 +33,9 @@ module Vagrant
# The directory where boxes are stored. # The directory where boxes are stored.
attr_reader :boxes_path attr_reader :boxes_path
# The path to the default private key
attr_reader :default_private_key_path
#--------------------------------------------------------------- #---------------------------------------------------------------
# Class Methods # Class Methods
#--------------------------------------------------------------- #---------------------------------------------------------------
@ -95,6 +100,10 @@ module Vagrant
setup_home_path setup_home_path
@tmp_path = @home_path.join("tmp") @tmp_path = @home_path.join("tmp")
@boxes_path = @home_path.join("boxes") @boxes_path = @home_path.join("boxes")
# Setup the default private key
@default_private_key_path = @home_path.join("insecure_private_key")
copy_insecure_private_key
end end
#--------------------------------------------------------------- #---------------------------------------------------------------
@ -461,5 +470,27 @@ module Vagrant
end end
end end
end end
protected
# This method copies the private key into the home directory if it
# doesn't already exist.
#
# This must be done because `ssh` requires that the key is chmod
# 0600, but if Vagrant is installed as a separate user, then the
# effective uid won't be able to read the key. So the key is copied
# to the home directory and chmod 0600.
def copy_insecure_private_key
if !@default_private_key_path.exist?
@logger.info("Copying private key to home directory")
FileUtils.cp(File.expand_path("keys/vagrant", Vagrant.source_root),
@default_private_key_path)
end
if Util::FileMode.from_octal(@default_private_key_path.stat.mode) != "600"
@logger.info("Changing permissions on private key to 0600")
@default_private_key_path.chmod(0600)
end
end
end end
end end

View File

@ -32,7 +32,8 @@ module Vagrant
options = {} options = {}
options[:port] = port(opts) options[:port] = port(opts)
[:host, :username, :private_key_path].each do |param| options[:private_key_path] = private_key_path
[:host, :username].each do |param|
options[param] = opts[param] || @vm.config.ssh.send(param) options[param] = opts[param] || @vm.config.ssh.send(param)
end end
@ -200,7 +201,8 @@ module Vagrant
end end
def private_key_path def private_key_path
File.expand_path(@vm.config.ssh.private_key_path, @vm.env.root_path) path = @vm.config.ssh.private_key_path || @vm.env.default_private_key_path
File.expand_path(path, @vm.env.root_path)
end end
end end
end end

View File

@ -0,0 +1,12 @@
module Vagrant
module Util
class FileMode
# This returns the file permissions as a string from
# an octal number.
def self.from_octal(octal)
perms = sprintf("%o", octal)
perms.reverse[0..2].reverse
end
end
end
end

View File

@ -1,7 +1,8 @@
require File.expand_path("../../base", __FILE__) require File.expand_path("../../base", __FILE__)
require "pathname" require "pathname"
require "vagrant/util/file_mode"
require "support/tempdir" require "support/tempdir"
describe Vagrant::Environment do describe Vagrant::Environment do
@ -44,6 +45,17 @@ describe Vagrant::Environment do
end end
end end
describe "copying the private SSH key" do
it "copies the SSH key into the home directory" do
env = isolated_environment
instance = described_class.new(:home_path => env.homedir)
pk = env.homedir.join("insecure_private_key")
pk.should be_exist
Vagrant::Util::FileMode.from_octal(pk.stat.mode).should == "600"
end
end
it "has a box collection pointed to the proper directory" do it "has a box collection pointed to the proper directory" do
collection = instance.boxes collection = instance.boxes
collection.should be_kind_of(Vagrant::BoxCollection) collection.should be_kind_of(Vagrant::BoxCollection)