Using net::ssh shell to sudo to another user and execute commands

The following program does not get past the part where sudo asks for a
password. Any ideas ?
This is run from windows onto a linux box, so I can’t use a local ssh
command.

it outputs

connected
cd

Net::SSH.start(host, :port => 22, :username => usr, :password => pwd)
do |session|

shell = session.shell.sync

puts “connected”

shell.cd ‘/somedir’

puts “cd”

shell.send_command ‘sudo su otheruser’, pwd

puts ‘sudo’

shell.cp ‘file_6.js tt6.js’

puts “cp”

shell.exit

puts “exit”

end

On Feb 7, 8:22 am, “[email protected][email protected] wrote:

The following program does not get past the part where sudo asks for a
password. Any ideas ?
This is run from windows onto a linux box, so I can’t use a local ssh
command.

This is just a guess as I haven’t used Net::SSH, but you might need to
append a newline to the password that’s being sent to sudo.

Also, there are Win32 ports of the ssh client so you probably could
use a local ssh command.

On Feb 7, 10:00 am, yermej [email protected] wrote:

Also, there are Win32 ports of the ssh client so you probably could
use a local ssh command.

Thanks,

Adding a newline didn’t work. The remote host will prompt with
“Password:” . Is it possible I have to read that prompt out of the
stream ?

Is it possible that linux sudo reads the password from the terminal
and not stdin ?

In order to use win32 ssh, I have to install that from someplace so
that I can use it from a DOS shell I think you mean ? Otherwise if I
try to do ssh inside of a ruby process it won’t work.

On Feb 7, 2008, at 9:09 AM, [email protected] wrote:

This is just a guess as I haven’t used Net::SSH, but you might
stream ?

Is it possible that linux sudo reads the password from the terminal
and not stdin ?

In order to use win32 ssh, I have to install that from someplace so
that I can use it from a DOS shell I think you mean ? Otherwise if I
try to do ssh inside of a ruby process it won’t work.

it is read from stdin

On Feb 7, 12:40 pm, John J. [email protected]
wrote:

This is run from windows onto a linux box, so I can’t use a local
Thanks,
try to do ssh inside of a ruby process it won’t work.

it is read from stdin

I don’t know why my program is not working or what I can try to see
what is happening ?

It’s not possible that ruby writes to stdin before sudo is prepared
to read ? That is not how streams work from my understanding. So I am
confused

On Feb 7, 12:40 pm, John J. [email protected]
wrote:

This is run from windows onto a linux box, so I can’t use a local
Thanks,
try to do ssh inside of a ruby process it won’t work.

it is read from stdin

I think I also so a man page on sudo that said -S causes it to read
the password from stdin, that is why I wondered if it might be able to
do some other kind of input from the terminal, raw input or something
by default for security reasons ?

Just tested this mini-script on Windows, and it works.

require ‘net/ssh’

Net::SSH.start(‘yourhost.com’, :port => 22, :username => ‘youruser’,
:password => ‘yourpassword’) do |session|
shell = session.shell.sync
puts “connected”
puts “ls”
shell.send_command “echo ‘yourpassword’ | sudo -S ls”
puts ‘Exiting’
shell.exit
puts “Exited”
end

Hope this works for you, btw, I couldn’t make it work by sending the
text as parameter to send_command :(, at least you can make it work
some way.

Gabriel Medina.

On Thu, 7 Feb 2008 06:22:19 -0800 (PST), “[email protected]

unsubscribe

On Feb 7, 5:42 pm, Rha [email protected] wrote:

    puts 'Exiting'
    shell.exit
    puts "Exited"

end

Hope this works for you, btw, I couldn’t make it work by sending the
text as parameter to send_command :(, at least you can make it work
some way.

Gabriel Medina.

The admins somehow set me up so the only sudo command I can do is:
sudo su acctname
When I do that command, sudo reads raw characters or something because
you can not see anything on the screen at all.

What I ended up doing is creating a named pipe on the remote machine,
then I run this
perl script (while logged in using sudo) that just reads from the pipe
and executes any commands I send it. So I use net::ssh to copy the
files to my remote home dir, then I write: “cp file destfile” to the
pipe and the perl script moves them into the directory that the sudo
privillges are needed to acces.

#!/usr/local/bin/perl

while (1) {
open(PIP, ‘mypipe’);

while () {
chomp;
print "$\n";
system($
);
}

close(PIP);
}

I have got the shell to work, I would like to know if its possible to
run a series of commands and retrieve the output without exiting the
shell. Coz I hav an app and it needs to log into another server and run
a couple of commands but each commands output determines whether to run
the next command or not. Is it possible that I could do this without
having to exit the shell each time to analyse the output? Please help
guys…

All,

While I don’t have the specific reason your scripts are failing, I have
a snippet from something I’m writing that might be handy. Note that
'yall are using Net::SSH v1, and my solution is for v2.

def exec(cmd)

the built in ssh.exec wraps some stuff up for us, but to catch sudo

we

have to construct the whole thing ourselves, starting with the

channel.
channel = ssh.open_channel do |channel|
# now we request a “pty” (i.e. interactive) session so we can send
data
# back and forth if needed. it WILL NOT WORK without this, and it
has to
# be done before any call to exec.
channel.request_pty do |ch, success|
raise “Could not obtain pty (i.e. an interactive ssh session)” if
!success
end

channel.exec(cmd) do |ch, success|
  # 'success' isn't related to bash exit codes or anything, but more
  # about ssh internals (i think... not bash related anyways).
  # not sure why it would fail at such a basic level, but it seems 

smart
# to do something about it.
abort “could not execute command” unless success

  # on_data is a hook that fires when the loop that this block is 

fired
# in (see below) returns data. This is what we’ve been doing all
this
# for; now we can check to see if it’s a password prompt, and
# interactively return data if so (see request_pty above).
channel.on_data do |ch, data|
if data == “Password:”
puts “Password request”
channel.send_data “#{self.password}\n”
else
# ssh channels can be treated as a hash for the specific
purpose of
# getting values out of the block later
channel[:result] ||= “”
channel[:result] << data
end
end

  channel.on_extended_data do |ch, type, data|
    raise "SSH command returned on stderr: #{data}"
  end
end

end

Nothing has actually happened yet. Everything above will respond to

the

server after each execution of the ssh loop until it has nothing

left

to process. For example, if the above recieved a password challenge

from

the server, ssh’s exec loop would execute twice - once for the

password,

then again after clearing the password (or twice more and exit if

the

password was bad)

channel.wait

return channel[:result].strip # it returns with \r\n at the end
end