Created
August 29, 2013 06:34
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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