Class: Vagrant::SSH

Inherits:
Object
  • Object
show all
Includes:
Util::SafeExec
Defined in:
lib/vagrant/ssh.rb

Overview

Manages SSH connection information as well as allows opening an SSH connection.

Instance Method Summary collapse

Constructor Details

#initialize(vm) ⇒ SSH

Returns a new instance of SSH.



14
15
16
17
# File 'lib/vagrant/ssh.rb', line 14

def initialize(vm)
  @vm     = vm
  @logger = Log4r::Logger.new("vagrant::ssh")
end

Instance Method Details

#check_key_permissions(key_path) ⇒ Object

Checks the file permissions for a private key, resetting them if needed.



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/vagrant/ssh.rb', line 110

def check_key_permissions(key_path)
  # Windows systems don't have this issue
  return if Util::Platform.windows?

  @logger.debug("Checking key permissions: #{key_path}")
  stat = File.stat(key_path)

  if stat.owned? && Util::FileMode.from_octal(stat.mode) != "600"
    @logger.info("Attempting to correct key permissions to 0600")
    File.chmod(0600, key_path)

    stat = File.stat(key_path)
    if Util::FileMode.from_octal(stat.mode) != "600"
      raise Errors::SSHKeyBadPermissions, :key_path => key_path
    end
  end
rescue Errno::EPERM
  # This shouldn't happen since we verified we own the file, but
  # it is possible in theory, so we raise an error.
  raise Errors::SSHKeyBadPermissions, :key_path => key_path
end

#exec(opts = {}) ⇒ Object

Connects to the environment’s virtual machine, replacing the ruby process with an SSH process.

Parameters:

  • opts (Hash) (defaults to: {})

    Options hash



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/vagrant/ssh.rb', line 55

def exec(opts={})
  # Get the SSH information and cache it here
  ssh_info = info

  # Ensure the platform supports ssh. On Windows there are several programs which
  # include ssh, notably git, mingw and cygwin, but make sure ssh is in the path!
  if !Util::FileUtil.which("ssh")
    if Util::Platform.windows?
      raise Errors::SSHUnavailableWindows, :host => ssh_info[:host],
                                           :port => ssh_info[:port],
                                           :username => ssh_info[:username],
                                           :key_path => ssh_info[:private_key_path]
    end
    raise Errors::SSHUnavailable 
  end

  # If plain mode is enabled then we don't do any authentication (we don't
  # set a user or an identity file)
  plain_mode = opts[:plain_mode]

  options = {}
  options[:host] = ssh_info[:host]
  options[:port] = ssh_info[:port]
  options[:username] = ssh_info[:username]
  options[:private_key_path] = ssh_info[:private_key_path]

  # Command line options
  command_options = ["-p", options[:port].to_s, "-o", "UserKnownHostsFile=/dev/null",
                     "-o", "StrictHostKeyChecking=no", "-o", "LogLevel=QUIET"]

  # Solaris/OpenSolaris/Illumos uses SunSSH which doesn't support the IdentitiesOnly option
  # (Also don't use it in plain mode, it'll skip user agents.)
  command_options += ["-o", "IdentitiesOnly=yes"] if !(Util::Platform.solaris? || plain_mode)

  command_options += ["-i", options[:private_key_path]] if !plain_mode
  command_options += ["-o", "ForwardAgent=yes"] if ssh_info[:forward_agent]

  # If there are extra options, then we append those
  command_options.concat(opts[:extra_args]) if opts[:extra_args]

  if ssh_info[:forward_x11]
    # Both are required so that no warnings are shown regarding X11
    command_options += ["-o", "ForwardX11=yes"]
    command_options += ["-o", "ForwardX11Trusted=yes"]
  end

  host_string = options[:host]
  host_string = "#{options[:username]}@#{host_string}" if !plain_mode
  command_options << host_string
  @logger.info("Invoking SSH: #{command_options.inspect}")
  safe_exec("ssh", *command_options)
end

#infoHash

Returns a hash of information necessary for accessing this virtual machine via SSH.

Returns:

  • (Hash)

Raises:



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/vagrant/ssh.rb', line 23

def info
  results = {
    :host          => @vm.config.ssh.host,
    :port          => @vm.config.ssh.port || @vm.driver.ssh_port(@vm.config.ssh.guest_port),
    :username      => @vm.config.ssh.username,
    :forward_agent => @vm.config.ssh.forward_agent,
    :forward_x11   => @vm.config.ssh.forward_x11
  }

  # This can happen if no port is set and for some reason Vagrant
  # can't detect an SSH port.
  raise Errors::SSHPortNotDetected if !results[:port]

  # Determine the private key path, which is either set by the
  # configuration or uses just the built-in insecure key.
  pk_path = @vm.config.ssh.private_key_path || @vm.env.default_private_key_path
  results[:private_key_path] = File.expand_path(pk_path, @vm.env.root_path)

  # We need to check and fix the private key permissions
  # to make sure that SSH gets a key with 0600 perms.
  check_key_permissions(results[:private_key_path])

  # Return the results
  return results
end