Skip to content

Commit

Permalink
Check SSH key permissions in machine.ssh_info
Browse files Browse the repository at this point in the history
With this change, any caller of machine.ssh_info is assured that best
efforts will be done to fix possible wrong permissions on the private
key files.

Fix #4652
  • Loading branch information
gildegoma committed Oct 20, 2014
1 parent 6986a8e commit 4e81be8
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 37 deletions.
5 changes: 0 additions & 5 deletions lib/vagrant/action/builtin/ssh_exec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,6 @@ def call(env)

info[:private_key_path] ||= []

# Check SSH key permissions
info[:private_key_path].each do |path|
SSH.check_key_permissions(Pathname.new(path))
end

if info[:private_key_path].empty? && info[:password]
env[:ui].warn(I18n.t("vagrant.ssh_exec_password"))
end
Expand Down
5 changes: 0 additions & 5 deletions lib/vagrant/action/builtin/ssh_run.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,6 @@ def call(env)

info[:private_key_path] ||= []

# Check SSH key permissions
info[:private_key_path].each do |path|
SSH.check_key_permissions(Pathname.new(path))
end

if info[:private_key_path].empty?
raise Errors::SSHRunRequiresKeys
end
Expand Down
10 changes: 10 additions & 0 deletions lib/vagrant/machine.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require_relative "util/ssh"

require "digest/md5"
require "thread"

Expand Down Expand Up @@ -434,6 +436,14 @@ def ssh_info
File.expand_path(path, @env.root_path)
end

# Check that the private key permissions are valid
info[:private_key_path].each do |path|
key_path = Pathname.new(path)
if key_path.exist?
Vagrant::Util::SSH.check_key_permissions(key_path)
end
end

# Return the final compiled SSH info data
info
end
Expand Down
6 changes: 0 additions & 6 deletions plugins/communicators/ssh/communicator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
require 'vagrant/util/file_mode'
require 'vagrant/util/platform'
require 'vagrant/util/retryable'
require 'vagrant/util/ssh'

module VagrantPlugins
module CommunicatorSSH
Expand Down Expand Up @@ -305,11 +304,6 @@ def connect(**opts)
verbose: :debug,
}

# Check that the private key permissions are valid
ssh_info[:private_key_path].each do |path|
Vagrant::Util::SSH.check_key_permissions(Pathname.new(path))
end

# Connect to SSH, giving it a few tries
connection = nil
begin
Expand Down
20 changes: 0 additions & 20 deletions test/unit/vagrant/action/builtin/ssh_exec_test.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
require File.expand_path("../../../../base", __FILE__)

require "vagrant/util/ssh"

describe Vagrant::Action::Builtin::SSHExec do
let(:app) { lambda { |env| } }
let(:env) { { machine: machine } }
Expand All @@ -16,7 +14,6 @@
before(:each) do
# Stub the methods so that even if we test incorrectly, no side
# effects actually happen.
allow(ssh_klass).to receive(:check_key_permissions)
allow(ssh_klass).to receive(:exec)
end

Expand All @@ -29,23 +26,6 @@
to raise_error(Vagrant::Errors::SSHNotReady)
end

it "should check key permissions then exec" do
key_path = "/foo"
machine_ssh_info[:private_key_path] = [key_path]

expect(ssh_klass).to receive(:check_key_permissions).
with(Pathname.new(key_path)).
once.
ordered

expect(ssh_klass).to receive(:exec).
with(machine_ssh_info, nil).
once.
ordered

described_class.new(app, env).call(env)
end

it "should exec with the SSH info in the env if given" do
ssh_info = { foo: :bar }

Expand Down
31 changes: 30 additions & 1 deletion test/unit/vagrant/machine_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,8 @@ def detect?(machine)
end
end

describe "ssh info" do
describe "#ssh_info" do

describe "with the provider returning nil" do
it "should return nil if the provider returns nil" do
expect(provider).to receive(:ssh_info).and_return(nil)
Expand All @@ -480,9 +481,13 @@ def detect?(machine)

describe "with the provider returning data" do
let(:provider_ssh_info) { {} }
let(:ssh_klass) { Vagrant::Util::SSH }

before(:each) do
allow(provider).to receive(:ssh_info).and_return(provider_ssh_info)
# Stub the check_key_permissions method so that even if we test incorrectly,
# no side effects actually happen.
allow(ssh_klass).to receive(:check_key_permissions)
end

[:host, :port, :username].each do |type|
Expand Down Expand Up @@ -554,6 +559,30 @@ def detect?(machine)
])
end

it "should check and try to fix the permissions of the default private key file" do
provider_ssh_info[:private_key_path] = nil
instance.config.ssh.private_key_path = nil

expect(ssh_klass).to receive(:check_key_permissions).once.with(Pathname.new(instance.env.default_private_key_path.to_s))
instance.ssh_info
end

it "should check and try to fix the permissions of given private key files" do
provider_ssh_info[:private_key_path] = nil
# Use __FILE__ to provide an existing file
instance.config.ssh.private_key_path = [File.expand_path(__FILE__), File.expand_path(__FILE__)]

expect(ssh_klass).to receive(:check_key_permissions).twice.with(Pathname.new(File.expand_path(__FILE__)))
instance.ssh_info
end

it "should not check the permissions of a private key file that does not exist" do
provider_ssh_info[:private_key_path] = "/foo"

expect(ssh_klass).to_not receive(:check_key_permissions)
instance.ssh_info
end

context "expanding path relative to the root path" do
it "should with the provider key path" do
provider_ssh_info[:private_key_path] = "~/foo"
Expand Down

0 comments on commit 4e81be8

Please sign in to comment.