diff options
| author | Delano Mandelbaum <delano@delanotes.com> | 2014-01-15 16:51:59 -0800 |
|---|---|---|
| committer | Delano Mandelbaum <delano@delanotes.com> | 2014-01-15 16:51:59 -0800 |
| commit | bd61eeab4927e9a68a5217ad9d8c04a99156efb2 (patch) | |
| tree | eb74455e3477ad6db69a23f1911e6312d02d619c | |
| parent | 7692be37ddb35df0646f406270f3fcd46c66e8c1 (diff) | |
| parent | 6ccd0fd0961f52115739e4f61e2c1774ca24feab (diff) | |
| download | net-ssh-bd61eeab4927e9a68a5217ad9d8c04a99156efb2.tar.gz | |
Merge pull request #140 from jarredholman/pageant
Fixed pageant support.
| -rw-r--r-- | lib/net/ssh/authentication/agent/socket.rb | 2 | ||||
| -rw-r--r-- | lib/net/ssh/authentication/pageant.rb | 86 | ||||
| -rw-r--r-- | lib/net/ssh/service/forward.rb | 24 |
3 files changed, 59 insertions, 53 deletions
diff --git a/lib/net/ssh/authentication/agent/socket.rb b/lib/net/ssh/authentication/agent/socket.rb index 78b6382..8fa20a0 100644 --- a/lib/net/ssh/authentication/agent/socket.rb +++ b/lib/net/ssh/authentication/agent/socket.rb @@ -126,7 +126,7 @@ module Net; module SSH; module Authentication # Returns the agent socket factory to use. def agent_socket_factory if Net::SSH::Authentication::PLATFORM == :win32 - Pageant::socket_factory + Pageant::Socket else UNIXSocket end diff --git a/lib/net/ssh/authentication/pageant.rb b/lib/net/ssh/authentication/pageant.rb index bbeb6a3..e351cac 100644 --- a/lib/net/ssh/authentication/pageant.rb +++ b/lib/net/ssh/authentication/pageant.rb @@ -110,21 +110,49 @@ module Net; module SSH; module Authentication "pageant process not running" end - @res = nil - @pos = 0 + @input_buffer = Net::SSH::Buffer.new + @output_buffer = Net::SSH::Buffer.new end # Forwards the data to #send_query, ignoring any arguments after - # the first. Returns 0. + # the first. def send(data, *args) - @res = send_query(data) - @pos = 0 + @input_buffer.append(data) + + ret = data.length + + while true + return ret if @input_buffer.length < 4 + msg_length = @input_buffer.read_long + 4 + @input_buffer.reset! + + return ret if @input_buffer.length < msg_length + msg = @input_buffer.read!(msg_length) + @output_buffer.append(send_query(msg)) + end + end + + # Reads +n+ bytes from the cached result of the last query. If +n+ + # is +nil+, returns all remaining data from the last query. + def read(n = nil) + @output_buffer.read(n) end + def close + end + + def send_query(query) + if RUBY_VERSION < "1.9" + send_query_18(query) + else + send_query_19(query) + end + end + # Packages the given query string and sends it to the pageant # process via the Windows messaging subsystem. The result is # cached, to be returned piece-wise when #read is called. - def send_query(query) + def send_query_18(query) res = nil filemap = 0 ptr = nil @@ -165,43 +193,10 @@ module Net; module SSH; module Authentication Win.closeHandle(filemap) if filemap != 0 end - # Conceptually close the socket. This doesn't really do anthing - # significant, but merely complies with the Socket interface. - def close - @res = nil - @pos = 0 - end - - # Conceptually asks if the socket is closed. As with #close, - # this doesn't really do anything significant, but merely - # complies with the Socket interface. - def closed? - @res.nil? && @pos.zero? - end - - # Reads +n+ bytes from the cached result of the last query. If +n+ - # is +nil+, returns all remaining data from the last query. - def read(n = nil) - return nil unless @res - if n.nil? - start, @pos = @pos, @res.size - return @res[start..-1] - else - start, @pos = @pos, @pos + n - return @res[start, n] - end - end - - end - - # Socket changes for Ruby 1.9 - # Functionality is the same as Ruby 1.8 but it includes the new calls to - # the DL module as well as other pointer transformations - class Socket19 < Socket # Packages the given query string and sends it to the pageant # process via the Windows messaging subsystem. The result is # cached, to be returned piece-wise when #read is called. - def send_query(query) + def send_query_19(query) res = nil filemap = 0 ptr = nil @@ -244,17 +239,6 @@ module Net; module SSH; module Authentication Win.CloseHandle(filemap) if filemap != 0 end end - - # Selects which socket to use depending on the ruby version - # This is needed due changes in the DL module. - def self.socket_factory - if RUBY_VERSION < "1.9" - Socket - else - Socket19 - end - end - end end; end; end diff --git a/lib/net/ssh/service/forward.rb b/lib/net/ssh/service/forward.rb index 5e23e36..3b0face 100644 --- a/lib/net/ssh/service/forward.rb +++ b/lib/net/ssh/service/forward.rb @@ -257,6 +257,24 @@ module Net; module SSH; module Service end end + # not a real socket, so use a simpler behaviour + def prepare_simple_client(client, channel, type) + channel[:socket] = client + + channel.on_data do |ch, data| + ch.debug { "data:#{data.length} on #{type} forwarded channel" } + ch[:socket].send(data) + end + + channel.on_process do |ch| + data = ch[:socket].read(8192) + if data + ch.debug { "read #{data.length} bytes from client, sending over #{type} forwarded connection" } + ch.send_data(data) + end + end + end + # The callback used when a new "forwarded-tcpip" channel is requested # by the server. This will open a new socket to the host/port specified # when the forwarded connection was first requested. @@ -287,7 +305,11 @@ module Net; module SSH; module Service begin agent = Authentication::Agent.connect(logger) - prepare_client(agent.socket, channel, :agent) + if (agent.socket.is_a? ::IO) + prepare_client(agent.socket, channel, :agent) + else + prepare_simple_client(agent.socket, channel, :agent) + end rescue Exception => e error { "attempted to connect to agent but failed: #{e.class.name} (#{e.message})" } raise Net::SSH::ChannelOpenFailed.new(2, "could not connect to authentication agent") |
