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


W

wbsurfver

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
 
Ad

Advertisements

Y

yermej

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.
 
W

wbsurfver

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.

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.
 
J

John Joyce

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.
it is read from stdin
 
W

wbsurfver

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
 
W

wbsurfver

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 ?
 
Ad

Advertisements

W

wbsurfver

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.



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 (<PIP>) {
chomp;
print "$_\n";
system($_);
}

close(PIP);
}
 
J

James George

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...
 
Ad

Advertisements

W

Woody Peterson

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top