1

This is what I got so far. This works great, the problem being I can't input a password for the ssh login, I need to have shared ssh keys in order for this to work:

  def ssh_conn(user, host, &block)
     begin
       ping_output = []
       timeout(20) do
         ping_output = IO.popen("ssh #{user}@#{host} 'echo \"success\"'", "w+")
       end
     ping = ping_output.readlines.join[/success/] ? true : false
     rescue Timeout::Error
       ping = false
     rescue
       ping = false
     end
   ping_output.close
   if block_given? && ping
     yield
   end
   return ping
 end

The question here is: How can I do something similar to this, but with password input through the arguments passed to the method? Preferably using ruby native Classes/Methods without installing any "external" gems.

skimisha
  • 143
  • 1
  • 10

2 Answers2

2

By searching a bit in StackOverflow I've found this thread and I was able to solve my problem doing this:

def ssh_try(user, host, pass)
  puts "SSHing #{host} ..."
  Net::SSH.start( host.to_s, user.to_s, :password => pass.to_s ) do |ssh|
    puts ssh.exec!('date')
    puts "Logging out..."
  end
end

Anyone who is facing a similar problem can try this method, works great to test/use ssh connection in ruby.

Community
  • 1
  • 1
skimisha
  • 143
  • 1
  • 10
1

I believe you cannot do that with ssh itself, but that's what sshpass it's for, as you can read in this serverfault answer. In Ubuntu:

$ sudo apt-get install sshpass

And then change your IO call like this:

ping_output = IO.popen("sshpass -p ssh #{user}@#{host} 'echo \"success\"'", "w+")

An alternative would be to rewrite your code to use Ruby SSH client, such as net-ssh, instead of using the system command. This is actually my recommendation, since it'll allow you to work at a higher abstraction level and not deal with system issues. Also, the result looks more beautiful! Check this (untested) code:

require 'net/ssh'
def ssh_conn(user, host, password, &block)
  authentication_successful = Net::SSH::Authentication::Session.authenticate(host, user, password)

  authentication_successful && (yield if block_given?)
  authentication_successful
end
Community
  • 1
  • 1
dgilperez
  • 10,716
  • 8
  • 68
  • 96
  • Yeah, I've already heard of sshpass, I've tried it and it works great. The problem with sshpass is that I'm not allowed to install anything, and avoid using ruby gems (company policy, don't ask -.-). Don't you know any other way to do this? Maybe implement an expect/send in ruby, something like `expect "Password:"; send ""` – skimisha Feb 11 '15 at 14:09