summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Fazekas <mfazekas@szemafor.com>2015-01-15 17:07:57 +0100
committerMiklos Fazekas <mfazekas@szemafor.com>2015-01-15 17:07:57 +0100
commitbe3773be239a44244a1bfedcbe84d032d76f4afa (patch)
tree73ee692d9547e5f17efab24b9de4ca56bfd467b9
parentc93b0a5ed3d07ac447ea0741ce402ecf513338d7 (diff)
downloadnet-ssh-be3773be239a44244a1bfedcbe84d032d76f4afa.tar.gz
Added first integration unittests
-rw-r--r--CHANGES.txt5
-rw-r--r--lib/net/ssh/connection/channel.rb10
-rw-r--r--lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb2
-rw-r--r--lib/net/ssh/transport/server_session.rb69
-rw-r--r--test_server.rb24
5 files changed, 90 insertions, 20 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 4c21761..d59fcd8 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,3 +1,8 @@
+Server changes
+
+TODO: on_request now receives options with [:want_reply]
+
+
=== 2.9.2-rc3
* Remove advertised algorithms that were not working (curve25519-sha256@libssh.org) [mfazekas]
diff --git a/lib/net/ssh/connection/channel.rb b/lib/net/ssh/connection/channel.rb
index f8b4ea3..3341be8 100644
--- a/lib/net/ssh/connection/channel.rb
+++ b/lib/net/ssh/connection/channel.rb
@@ -317,6 +317,12 @@ module Net; module SSH; module Connection
end
end
+ # sends data if possible
+ def _flush
+ process
+ connection.process
+ end
+
# Registers a callback to be invoked when data packets are received by the
# channel. The callback is called with the channel as the first argument,
# and the data as the second.
@@ -548,7 +554,9 @@ module Net; module SSH; module Connection
begin
callback = @on_request[request] or raise ChannelRequestFailed
- callback.call(self, data)
+ opts = {want_reply:want_reply}
+ callback.call(self, data, opts)
+ want_reply = false if want_reply && !opts[:want_reply]
rescue ChannelRequestFailed
debug { "no request handler registered for #{request}" }
result = false
diff --git a/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb b/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb
index e061de0..10e608f 100644
--- a/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb
+++ b/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb
@@ -173,7 +173,6 @@ module Net; module SSH; module Transport; module Kex
buffer = connection.next_message
raise Net::SSH::Exception, "expected REPLY got #{buffer.type}" unless buffer.type == init
client_dh_pubkey = buffer.read_bignum
- puts " => client_dh_pubkey :#{client_dh_pubkey.to_s(16)}"
key_type = algorithms.host_key
if ! server_key = data[:server_keys][key_type]
@@ -187,7 +186,6 @@ module Net; module SSH; module Transport; module Kex
signature_buffer = build_signature_buffer({key_blob: server_key_blob,server_dh_pubkey: server_dh_pubkey,shared_secret: shared_secret,client_pubkey:client_dh_pubkey})
#puts "Signature buffer:#{signature_buffer}"
hash = @digester.digest(signature_buffer.to_s)
- puts "Hash on server:#{hash}"
signature = server_key.ssh_do_sign(hash)
buffer = Net::SSH::Buffer.from(:byte, reply, :string, server_key_blob, :bignum, server_dh_pubkey,
diff --git a/lib/net/ssh/transport/server_session.rb b/lib/net/ssh/transport/server_session.rb
index 6af7067..b3c5e6c 100644
--- a/lib/net/ssh/transport/server_session.rb
+++ b/lib/net/ssh/transport/server_session.rb
@@ -39,6 +39,11 @@ class ServerSession
# the initial key exchange completes, leaving you with a ready-to-use
# transport session.
def initialize(socket, options={})
+ options = options.merge(:server_side => true)
+
+ raise ArgumentError, "expected :server_keys options" unless options[:server_keys]
+ options[:host_key] ||= options[:server_keys].keys
+
self.logger = options[:logger]
@host = Socket.gethostname
@@ -92,24 +97,42 @@ class ServerSession
def run_loop(&block)
loop do
if @connection
- @connection.process
+ begin
+ @connection.process
+ rescue Net::SSH::Disconnect => e
+ debug { "connection was closed => shallowing exception:#{e}" }
+ break
+ rescue IOError => e
+ if e.message =~ /closed/ then
+ debug { "connection was reset => shallowing exception:#{e}" }
+ false
+ else
+ raise
+ end
+ end
else
packet = poll_message(:block)
- case packet.type
- when SERVICE_REQUEST
- packet_str = packet.read_string
- case packet_str
- when "ssh-userauth"
- send_message(Buffer.from(:byte, SERVICE_ACCEPT))
+ if packet
+ case packet.type
+ when SERVICE_REQUEST
+ packet_str = packet.read_string
+ case packet_str
+ when "ssh-userauth"
+ send_message(Buffer.from(:byte, SERVICE_ACCEPT))
+ end
+ true
+ when USERAUTH_REQUEST
+ username = packet.read_string
+ next_service = packet.read_string
+ auth_method = packet.read_string
+ send_message(Buffer.from(:byte,USERAUTH_SUCCESS))
+ @connection = Connection::Session.new(self, options)
+ result = yield @connection
+ @connection.process
+ result
end
- when USERAUTH_REQUEST
- username = packet.read_string
- next_service = packet.read_string
- auth_method = packet.read_string
- send_message(Buffer.from(:byte,USERAUTH_SUCCESS))
- @connection = Connection::Session.new(self, options)
- yield @connection
- @connection.process
+ else
+ true
end
end
end
@@ -221,6 +244,22 @@ class ServerSession
end
end
+ alias :loop_forever :loop
+
+ def loop(wait=nil, &block)
+ loop_forever { break unless yield }
+ end
+
+ def process(wait=nil, &block)
+ return false unless preprocess(&block)
+
+ r = listeners.keys
+ w = r.select { |w2| w2.respond_to?(:pending_write?) && w2.pending_write? }
+ readers, writers, = Net::SSH::Compat.io_select(r, w, nil, io_select_wait(wait))
+
+ postprocess(readers, writers)
+ end
+
# Adds the given packet to the packet queue. If the queue is non-empty,
# #poll_message will return packets from the queue in the order they
# were received.
diff --git a/test_server.rb b/test_server.rb
index 012960a..7f2926d 100644
--- a/test_server.rb
+++ b/test_server.rb
@@ -18,6 +18,12 @@ puts "Setting up server keys..."
server_keys = Net::SSH::Server::Keys.new(logger: logger, server_keys_directory: '.')
server_keys.load_or_generate
+def send_reply(channel,result)
+ msg_type = result ? Net::SSH::Connection::Constants::CHANNEL_SUCCESS : Net::SSH::Connection::Constants::CHANNEL_FAILURE
+ msg = Net::SSH::Buffer.from(:byte, msg_type, :long, channel.remote_id)
+ channel.connection.send_message(msg)
+end
+
puts "Listening on port #{PORT}..."
Thread.start do
server = TCPServer.new PORT
@@ -39,10 +45,24 @@ Thread.start do
puts "received command:#{command}"
channel.send_data "reply to :#{command}"
end
- channel.on_request 'exec' do |channel,data|
+ channel.on_request 'exec' do |channel,data,opt|
+ #channel.process
command = data.read_string
+ if opt[:want_reply]
+ send_reply(channel,true)
+ opt[:want_reply] = false
+ end
+ sleep 2
puts "received command:#{command}"
- channel.send_data "reply to :#{command}"
+ channel.send_data "command :#{command} reply: 42\n"
+ channel.eof!
+ channel._flush
+ channel.send_channel_request('exit-status',:long,42)
+ #channel.send_channel_request('eow@openssh.com')
+ channel.close
+ channel.on_eof { puts "on eof" ; channel.close }
+ #channel.close
+ #channel.send_channel_request('command-from-client', :string, "data-from-client")
end
end
end