Skip to content
Browse files

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

  • Loading branch information...
1 parent 42a5e02 commit 05ae297fd2acd522c0338ab7f65308668268079d @mitchellh committed
View
2 CHANGELOG.md
@@ -9,6 +9,8 @@
- Tweaks to SSH to hopefully be more reliable in coming up.
- Helpful error message when SCP is unavailable in the guest. [GH-568]
- 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)
View
1 config/default.rb
@@ -10,7 +10,6 @@
config.ssh.forwarded_port_destination = 22
config.ssh.max_tries = 100
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_x11 = false
View
7 lib/vagrant/config/ssh.rb
@@ -20,14 +20,17 @@ def initialize
@port = nil
@forward_agent = false
@forward_x11 = false
+ @private_key_path = nil
end
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)
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
View
31 lib/vagrant/environment.rb
@@ -3,6 +3,8 @@
require 'log4r'
+require 'vagrant/util/file_mode'
+
module Vagrant
# Represents a single Vagrant environment. A "Vagrant environment" is
# defined as basically a folder with a "Vagrantfile." This class allows
@@ -31,6 +33,9 @@ class Environment
# The directory where boxes are stored.
attr_reader :boxes_path
+ # The path to the default private key
+ attr_reader :default_private_key_path
+
#---------------------------------------------------------------
# Class Methods
#---------------------------------------------------------------
@@ -95,6 +100,10 @@ def initialize(opts=nil)
setup_home_path
@tmp_path = @home_path.join("tmp")
@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
#---------------------------------------------------------------
@@ -461,5 +470,27 @@ def setup_home_path
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
View
6 lib/vagrant/ssh.rb
@@ -32,7 +32,8 @@ def connect(opts={})
options = {}
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)
end
@@ -200,7 +201,8 @@ def port(opts={})
end
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
View
12 lib/vagrant/util/file_mode.rb
@@ -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
14 test/unit/vagrant/environment_test.rb
@@ -1,7 +1,8 @@
require File.expand_path("../../base", __FILE__)
-
require "pathname"
+require "vagrant/util/file_mode"
+
require "support/tempdir"
describe Vagrant::Environment do
@@ -44,6 +45,17 @@
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
collection = instance.boxes
collection.should be_kind_of(Vagrant::BoxCollection)

0 comments on commit 05ae297

Please sign in to comment.
Something went wrong with that request. Please try again.