Skip to content

Instantly share code, notes, and snippets.

@ruseel
Created August 29, 2013 06:34
Show Gist options
  • Save ruseel/6374849 to your computer and use it in GitHub Desktop.
Save ruseel/6374849 to your computer and use it in GitHub Desktop.
there is a (dumb) sock5 proxy preventing ssh 'exec' channel creation. so work around with ssh 'session' channel.
require 'net/ssh'
require 'net/ssh/proxy/socks5'
def escape s
# use ruby escpae, then replace double quote to single
buf = s.inspect
buf[0]="'"
buf[-1]="'"
buf
end
module XSSH
class Connection
def initialize(options={})
proxy = options[:proxy] || {}
socks5=Net::SSH::Proxy::SOCKS5.new(
proxy[:host], proxy[:port],
:user => proxy[:user],
:password => proxy[:password])
@session = Net::SSH.start(options[:host],
options[:user],
:password=>options[:password],
:config=>false,
:verbose=>:fatal,
:proxy=>socks5)
@prompt = options[:prompt]
@buf = []
@commands = []
@session.open_channel do |channel|
channel.on_data do |ch, data|
print data
STDOUT.flush
@buf << data
@output = @buf.join
if Regexp.new(@prompt) =~ @output then
@buf = []
@state = :idle
end
end
channel.on_process do |ch|
if @state == :queue then
cmd = @commands.shift
channel.send_data "bash -c $#{escape cmd}\n"
@state = :sent
end
end
channel.request_pty
channel.send_channel_request "shell"
end
wait
end
def wait
@session.loop { @state != :idle }
end
def queue cmd
@commands << cmd
@state = :queue
end
def queue_and_wait cmd
queue cmd
wait
@output
end
attr_accessor :output
def exec(cmd)
queue_and_wait(cmd)
queue_and_wait "echo $?"
ret = @output.split("\r\n")[1].to_i
wait
ret
end
def close
begin
@session.close
rescue Net::SSH::Disconnect => e
# pass, not sure
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment