diff options
| author | Miklos Fazekas <mfazekas@szemafor.com> | 2015-01-15 17:07:57 +0100 |
|---|---|---|
| committer | Miklos Fazekas <mfazekas@szemafor.com> | 2015-01-15 17:07:57 +0100 |
| commit | be3773be239a44244a1bfedcbe84d032d76f4afa (patch) | |
| tree | 73ee692d9547e5f17efab24b9de4ca56bfd467b9 | |
| parent | c93b0a5ed3d07ac447ea0741ce402ecf513338d7 (diff) | |
| download | net-ssh-be3773be239a44244a1bfedcbe84d032d76f4afa.tar.gz | |
Added first integration unittests
| -rw-r--r-- | CHANGES.txt | 5 | ||||
| -rw-r--r-- | lib/net/ssh/connection/channel.rb | 10 | ||||
| -rw-r--r-- | lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb | 2 | ||||
| -rw-r--r-- | lib/net/ssh/transport/server_session.rb | 69 | ||||
| -rw-r--r-- | test_server.rb | 24 |
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 |
