Net::SSH expect like interface

Hi All,
I have been looking for expect like interface for Net::SSH lib,
but apparently there is none.

Net::SSH is working fine for me except one place I need to check
the scp command prompt and send the password. (Invoking scp on
the machine to which I have ssh’ed).

Can somebody on list, provide some guidelines as to how can this
be achieved.

  • I tried sending the password blindly to the popen session once
    i get on_success or on_stderr callback. However this seems to be
    not working. The log says…

--------snippet of the log…
[DEBUG] Thu Apr 26 14:05:48 +0530 2007 – connection.driver:
CHANNEL_SUCCESS recieved (1)
[DEBUG] Thu Apr 26 14:05:48 +0530 2007 – transport.session: sending
message >>"^\000\000\000\000\000\000\000\tpassword\n"<<
[DEBUG] Thu Apr 26 14:05:48 +0530 2007 – transport.session: waiting for
packet from server…
[DEBUG] Thu Apr 26 14:05:48 +0530 2007 –
transport.incoming_packet_stream: reading 8 bytes from socket…
[DEBUG] Thu Apr 26 14:05:48 +0530 2007 –
transport.incoming_packet_stream: packet length(60) remaining(56)
[DEBUG] Thu Apr 26 14:05:48 +0530 2007 –
transport.incoming_packet_stream: received:
“_\000\000\000\001\000\000\000\001\000\000\000&Permission denied, please
try again.\r\n”
[DEBUG] Thu Apr 26 14:05:48 +0530 2007 – transport.session: got packet
of type 95
[DEBUG] Thu Apr 26 14:05:48 +0530 2007 – connection.driver:
CHANNEL_EXTENDED_DATA recieved (1:1:“Permission denied, please try
again.\r\n”)
[DEBUGrequesting result of password
–> Permission denied, please try again.

requesting result of password
–> Permission denied, please try again.

requesting result of password
–> Permission denied (publickey,gssapi-with-mic,password).

requesting result of password
process finished with exit status: 1
] Thu Apr 26 14:05:48 +0530 2007 – transport.session: sending message

“^\000\000\000\000\000\000\000\tpassword\n”<<
[DEBUG] Thu Apr 26 14:05:48 +0530 2007 – transport.session: waiting for
packet from server…


What I think is that there are these extra keysequence that are being
passed to the sever.
Do I need to emulate any kind of terminal for this to work.

What will be the best approach to implement expect like interface to
Net::SSH if at all
I can’t get this working with existing functinoality.

Any pointer will be greatly appreciated.
Thanks and Regards,
Manish

I would suggest looking into using keys instead of passwords, and
leveraging
agent forwarding. That should get you around the entire problem.

On Thu, Apr 26, 2007 at 05:56:34PM +0900, Manish S. wrote:

I have been looking for expect like interface for Net::SSH lib,
but apparently there is none.

This is something I’ve been wanting for a long time too, ideally to use
ssh
as a drop-in replacement for Net::Telnet.

I’ve made a first step by monkey-patching Net::SSH so that the
process.popen3 interface is also available for shell sessions, just by
passing in nil as the command name (see attached). Once you’ve done
this,
you can drive Net::SSH like this:


require ‘rubygems’
require ‘net/ssh’

class ShellSession
def initialize(*args)
@session = Net::SSH.start(*args)
@inp, @out, @err = @session.process.popen3 # nil means shell
end

def cmd(command, prompt = /[>#$?] ?\z/)
puts “(#{command})”
@inp.puts command
res = “”

while true
  @out.channel.connection.process  # block for incoming data
  res << @out.read if @out.data_available?
  res << @err.read if @err.data_available?
  break if res =~ prompt
end

res

end
end

s = ShellSession.new(“x.x.x.x”, “cisco”, “cisco”)
puts s.cmd(“term len 0”)
puts s.cmd(“show ver”)
puts s.cmd(“show run”)
puts s.cmd(“enable”, /assword:/)
puts s.cmd(“cisco”)
puts s.cmd(“show run”)

However this is only part of the story. Both IO#expect and Net::Telnet
expect a real IO object that you can use as an argument to
Kernel#select.

One solution may be to make a Socketpair:

s1, s2 = Socket.pair(Socket::AF_LOCAL, Socket::SOCK_STREAM, 0)

However, then the code which copies the other end of the pair to/from
the
ssh session needs to run as a thread. It’s probably also not portable to
Windows.

Alternatively, a modified version of Net::Telnet can be made. And in
that
case, it could use the ssh channel interface directly and so not rely on
a
patched Net::SSH.

Regards,

Brian.

On Mon, Sep 24, 2007 at 11:55:41AM +0100, Brian C. wrote:

Alternatively, a modified version of Net::Telnet can be made. And in that
case, it could use the ssh channel interface directly and so not rely on a
patched Net::SSH.

Here’s my attempt at this. It provides Net::SSH::Telnet which has an
almost
identical API to Net::Telnet, since it uses mostly the same code.

Anyone want to give this a try and see if it works for them?

Regards,

Brian.

P.S. Unlike Net::Telnet, it doesn’t delegate. I’m not sure if it would
be
useful to delegate to the underlying socket, the ssh session, or the
shell
channel.