Hello community, here is the log from the commit of package rubygem-net-ssh for openSUSE:Factory checked in at 2016-07-01 10:00:41 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/rubygem-net-ssh (Old) and /work/SRC/openSUSE:Factory/.rubygem-net-ssh.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rubygem-net-ssh" Changes: -------- --- /work/SRC/openSUSE:Factory/rubygem-net-ssh/rubygem-net-ssh.changes 2016-04-22 16:24:24.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.rubygem-net-ssh.new/rubygem-net-ssh.changes 2016-07-01 10:00:43.000000000 +0200 @@ -1,0 +2,12 @@ +Mon Jun 20 04:35:04 UTC 2016 - co...@suse.com + +- updated to version 3.2.0 + see installed CHANGES.txt + + === 3.2.0 + + * Added agent_socket_factory option [Alon Goldboim] + * Send KEXINIT asap don't wait for server [Miklos Fazekas] + * Close channels in case server closed connection [Miklos Fazekas] + +------------------------------------------------------------------- Old: ---- net-ssh-3.1.1.gem New: ---- net-ssh-3.2.0.gem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rubygem-net-ssh.spec ++++++ --- /var/tmp/diff_new_pack.JTVSzM/_old 2016-07-01 10:00:44.000000000 +0200 +++ /var/tmp/diff_new_pack.JTVSzM/_new 2016-07-01 10:00:44.000000000 +0200 @@ -24,7 +24,7 @@ # Name: rubygem-net-ssh -Version: 3.1.1 +Version: 3.2.0 Release: 0 %define mod_name net-ssh %define mod_full_name %{mod_name}-%{version} ++++++ net-ssh-3.1.1.gem -> net-ssh-3.2.0.gem ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/CHANGES.txt new/CHANGES.txt --- old/CHANGES.txt 2016-03-23 13:28:21.000000000 +0100 +++ new/CHANGES.txt 2016-06-19 07:58:58.000000000 +0200 @@ -1,3 +1,9 @@ +=== 3.2.0 + +* Added agent_socket_factory option [Alon Goldboim] +* Send KEXINIT asap don't wait for server [Miklos Fazekas] +* Close channels in case server closed connection [Miklos Fazekas] + === 3.1.1 * added missing etc require Files old/checksums.yaml.gz and new/checksums.yaml.gz differ Files old/checksums.yaml.gz.sig and new/checksums.yaml.gz.sig differ Files old/data.tar.gz.sig and new/data.tar.gz.sig differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/net/ssh/authentication/agent/java_pageant.rb new/lib/net/ssh/authentication/agent/java_pageant.rb --- old/lib/net/ssh/authentication/agent/java_pageant.rb 2016-03-23 13:28:21.000000000 +0100 +++ new/lib/net/ssh/authentication/agent/java_pageant.rb 2016-06-19 07:58:58.000000000 +0200 @@ -19,7 +19,7 @@ # Instantiates a new agent object, connects to a running SSH agent, # negotiates the agent protocol version, and returns the agent object. - def self.connect(logger=nil) + def self.connect(logger=nil, agent_socket_factory) agent = new(logger) agent.connect! agent diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/net/ssh/authentication/agent/socket.rb new/lib/net/ssh/authentication/agent/socket.rb --- old/lib/net/ssh/authentication/agent/socket.rb 2016-03-23 13:28:21.000000000 +0100 +++ new/lib/net/ssh/authentication/agent/socket.rb 2016-06-19 07:58:58.000000000 +0200 @@ -42,9 +42,9 @@ # Instantiates a new agent object, connects to a running SSH agent, # negotiates the agent protocol version, and returns the agent object. - def self.connect(logger=nil) + def self.connect(logger=nil, agent_socket_factory = nil) agent = new(logger) - agent.connect! + agent.connect!(agent_socket_factory) agent.negotiate! agent end @@ -59,10 +59,10 @@ # given by the attribute writers. If the agent on the other end of the # socket reports that it is an SSH2-compatible agent, this will fail # (it only supports the ssh-agent distributed by OpenSSH). - def connect! + def connect!(agent_socket_factory = nil) begin debug { "connecting to ssh-agent" } - @socket = agent_socket_factory.open(ENV['SSH_AUTH_SOCK']) + @socket = agent_socket_factory.nil? ? socket_class.open(ENV['SSH_AUTH_SOCK']) : agent_socket_factory.call rescue error { "could not connect to ssh-agent" } raise AgentNotAvailable, $!.message @@ -132,7 +132,7 @@ private # Returns the agent socket factory to use. - def agent_socket_factory + def socket_class if Net::SSH::Authentication::PLATFORM == :win32 Pageant::Socket else diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/net/ssh/authentication/key_manager.rb new/lib/net/ssh/authentication/key_manager.rb --- old/lib/net/ssh/authentication/key_manager.rb 2016-03-23 13:28:21.000000000 +0100 +++ new/lib/net/ssh/authentication/key_manager.rb 2016-06-19 07:58:58.000000000 +0200 @@ -176,7 +176,7 @@ # or if the agent is otherwise not available. def agent return unless use_agent? - @agent ||= Agent.connect(logger) + @agent ||= Agent.connect(logger, options[:agent_socket_factory]) rescue AgentNotAvailable @use_agent = false nil diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/net/ssh/connection/session.rb new/lib/net/ssh/connection/session.rb --- old/lib/net/ssh/connection/session.rb 2016-03-23 13:28:21.000000000 +0100 +++ new/lib/net/ssh/connection/session.rb 2016-06-19 07:58:58.000000000 +0200 @@ -210,6 +210,9 @@ readers, writers, = Net::SSH::Compat.io_select(r, w, nil, io_select_wait(wait)) postprocess(readers, writers) + rescue + force_channel_cleanup_on_close if closed? + raise end # This is called internally as part of #process. It dispatches any @@ -475,6 +478,9 @@ send(MAP[packet.type], packet) end + rescue + force_channel_cleanup_on_close if closed? + raise end # Returns the next available channel id to be assigned, and increments @@ -483,6 +489,16 @@ @channel_id_counter += 1 end + def force_channel_cleanup_on_close + channels.each do |id, channel| + channel.remote_closed! + channel.close + + cleanup_channel(channel) + channel.do_close + end + end + # Invoked when a global request is received. The registered global # request callback will be invoked, if one exists, and the necessary # reply returned. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/net/ssh/service/forward.rb new/lib/net/ssh/service/forward.rb --- old/lib/net/ssh/service/forward.rb 2016-03-23 13:28:21.000000000 +0100 +++ new/lib/net/ssh/service/forward.rb 2016-06-19 07:58:58.000000000 +0200 @@ -357,7 +357,7 @@ channel[:invisible] = true begin - agent = Authentication::Agent.connect(logger) + agent = Authentication::Agent.connect(logger, session.options[:agent_socket_factory]) if (agent.socket.is_a? ::IO) prepare_client(agent.socket, channel, :agent) else diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/net/ssh/test/socket.rb new/lib/net/ssh/test/socket.rb --- old/lib/net/ssh/test/socket.rb 2016-03-23 13:28:21.000000000 +0100 +++ new/lib/net/ssh/test/socket.rb 2016-06-19 07:58:58.000000000 +0200 @@ -25,8 +25,8 @@ @script = Script.new - script.gets(:kexinit, 1, 2, 3, 4, "test", "ssh-rsa", "none", "none", "none", "none", "none", "none", "", "", false) script.sends(:kexinit) + script.gets(:kexinit, 1, 2, 3, 4, "test", "ssh-rsa", "none", "none", "none", "none", "none", "none", "", "", false) script.sends(:newkeys) script.gets(:newkeys) end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/net/ssh/transport/algorithms.rb new/lib/net/ssh/transport/algorithms.rb --- old/lib/net/ssh/transport/algorithms.rb 2016-03-23 13:28:21.000000000 +0100 +++ new/lib/net/ssh/transport/algorithms.rb 2016-06-19 07:58:58.000000000 +0200 @@ -124,6 +124,12 @@ prepare_preferred_algorithms! end + # Start the algorithm negotation + def start + raise ArgumentError, "Cannot call start if it's negoitation started or done" if @pending || @initialized + send_kexinit + end + # Request a rekey operation. This will return immediately, and does not # actually perform the rekey operation. It does cause the session to change # state, however--until the key exchange finishes, no new packets will be diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/net/ssh/transport/session.rb new/lib/net/ssh/transport/session.rb --- old/lib/net/ssh/transport/session.rb 2016-03-23 13:28:21.000000000 +0100 +++ new/lib/net/ssh/transport/session.rb 2016-06-19 07:58:58.000000000 +0200 @@ -84,6 +84,7 @@ @server_version = ServerVersion.new(socket, logger, options[:timeout]) @algorithms = Algorithms.new(self, options) + @algorithms.start wait { algorithms.initialized? } rescue Errno::ETIMEDOUT raise Net::SSH::ConnectionTimeout diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/net/ssh/version.rb new/lib/net/ssh/version.rb --- old/lib/net/ssh/version.rb 2016-03-23 13:28:21.000000000 +0100 +++ new/lib/net/ssh/version.rb 2016-06-19 07:58:58.000000000 +0200 @@ -48,10 +48,10 @@ MAJOR = 3 # The minor component of this version of the Net::SSH library - MINOR = 1 + MINOR = 2 # The tiny component of this version of the Net::SSH library - TINY = 1 + TINY = 0 # The prerelease component of this version of the Net::SSH library # nil allowed diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/net/ssh.rb new/lib/net/ssh.rb --- old/lib/net/ssh.rb 2016-03-23 13:28:21.000000000 +0100 +++ new/lib/net/ssh.rb 2016-06-19 07:58:58.000000000 +0200 @@ -70,7 +70,7 @@ :known_hosts, :global_known_hosts_file, :user_known_hosts_file, :host_key_alias, :host_name, :user, :properties, :passphrase, :keys_only, :max_pkt_size, :max_win_size, :send_env, :use_agent, :number_of_password_prompts, - :append_supported_algorithms, :non_interactive + :append_supported_algorithms, :non_interactive, :agent_socket_factory ] # The standard means of starting a new SSH connection. When used with a @@ -192,6 +192,9 @@ # password auth method # * :non_interactive => non interactive applications should set it to true # to prefer failing a password/etc auth methods vs asking for password + # * :agent_socket_factory => enables the user to pass a lambda/block that will serve as the socket factory + # Net::SSH::start(user,host,agent_socket_factory: ->{ UNIXSocket.open('/foo/bar') }) + # example: ->{ UNIXSocket.open('/foo/bar')} # # If +user+ parameter is nil it defaults to USER from ssh_config, or # local username diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/metadata new/metadata --- old/metadata 2016-03-23 13:28:21.000000000 +0100 +++ new/metadata 2016-06-19 07:58:58.000000000 +0200 @@ -1,7 +1,7 @@ --- !ruby/object:Gem::Specification name: net-ssh version: !ruby/object:Gem::Version - version: 3.1.1 + version: 3.2.0 platform: ruby authors: - Jamis Buck @@ -31,7 +31,7 @@ s/ZUKye79ELwFYKJOhjW5g725OL3hy+llhEleytwKRwgXFQBPTC4f5UkdxZVVWGH e2C9M1m/2odPZo8h -----END CERTIFICATE----- -date: 2016-03-23 00:00:00.000000000 Z +date: 2016-06-19 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: test-unit Files old/metadata.gz.sig and new/metadata.gz.sig differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/net-ssh.gemspec new/net-ssh.gemspec --- old/net-ssh.gemspec 2016-03-23 13:28:21.000000000 +0100 +++ new/net-ssh.gemspec 2016-06-19 07:58:58.000000000 +0200 @@ -2,17 +2,17 @@ # DO NOT EDIT THIS FILE DIRECTLY # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec' # -*- encoding: utf-8 -*- -# stub: net-ssh 3.1.1 ruby lib +# stub: net-ssh 3.2.0 ruby lib Gem::Specification.new do |s| s.name = "net-ssh" - s.version = "3.1.1" + s.version = "3.2.0" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.require_paths = ["lib"] s.authors = ["Jamis Buck", "Delano Mandelbaum", "Mikl\u{f3}s Fazekas"] s.cert_chain = ["net-ssh-public_cert.pem"] - s.date = "2016-03-23" + s.date = "2016-06-19" s.description = "Net::SSH: a pure-Ruby implementation of the SSH2 client protocol. It allows you to write programs that invoke and interact with processes on remote servers, via SSH2." s.email = "net-...@solutious.com" s.extra_rdoc_files = [ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/test/authentication/test_agent.rb new/test/authentication/test_agent.rb --- old/test/authentication/test_agent.rb 2016-03-23 13:28:21.000000000 +0100 +++ new/test/authentication/test_agent.rb 2016-06-19 07:58:58.000000000 +0200 @@ -32,6 +32,11 @@ agent(false).connect! end + def test_connect_should_use_agent_socket_factory_instead_of_factory + assert_equal agent.connect!, socket + assert_equal agent.connect!(agent_socket_factory), "/foo/bar.sock" + end + def test_connect_should_raise_error_if_connection_could_not_be_established factory.expects(:open).raises(SocketError) assert_raises(Net::SSH::Authentication::AgentNotAvailable) { agent(false).connect! } @@ -213,12 +218,15 @@ def agent(auto=:connect) @agent ||= begin agent = Net::SSH::Authentication::Agent.new - agent.stubs(:agent_socket_factory).returns(factory) + agent.stubs(:socket_class).returns(factory) agent.connect! if auto == :connect agent end end + def agent_socket_factory + @agent_socket_factory ||= ->{"/foo/bar.sock"} + end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/test/common.rb new/test/common.rb --- old/test/common.rb 2016-03-23 13:28:21.000000000 +0100 +++ new/test/common.rb 2016-06-19 07:58:58.000000000 +0200 @@ -15,6 +15,18 @@ $original_config_default_files = Net::SSH::Config.default_files.dup Net::SSH::Config.default_files.clear +def with_restored_default_files(&block) + act_default_files = Net::SSH::Config.default_files.dup + begin + Net::SSH::Config.default_files.clear + Net::SSH::Config.default_files.concat($_original_config_default_files) # rubocop:disable Style/GlobalVars + yield + ensure + Net::SSH::Config.default_files.clear + Net::SSH::Config.default_files.concat(act_default_files) + end +end + def P(*args) Net::SSH::Packet.new(Net::SSH::Buffer.from(*args)) end @@ -71,6 +83,10 @@ end end + def closed? + false + end + def poll_message @queue.shift end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/test/connection/test_session.rb new/test/connection/test_session.rb --- old/test/connection/test_session.rb 2016-03-23 13:28:21.000000000 +0100 +++ new/test/connection/test_session.rb 2016-06-19 07:58:58.000000000 +0200 @@ -182,6 +182,7 @@ end def test_global_request_handler_returning_other_value_should_raise_error + transport.expects(:closed?).at_least_once.returns(false) session.on_global_request("testing") { "bug" } transport.return(GLOBAL_REQUEST, :string, "testing", :bool, true) assert_raises(RuntimeError) { process_times(2) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/test/integration/test_forward.rb new/test/integration/test_forward.rb --- old/test/integration/test_forward.rb 2016-03-23 13:28:21.000000000 +0100 +++ new/test/integration/test_forward.rb 2016-06-19 07:58:58.000000000 +0200 @@ -17,6 +17,7 @@ require_relative './common' require 'net/ssh/buffer' require 'net/ssh' +require 'net/ssh/proxy/command' require 'timeout' require 'tempfile' @@ -31,8 +32,8 @@ 'net_ssh_1' end - def ssh_start_params - [localhost ,user , {:keys => @key_id_rsa, :verbose => :debug}] + def ssh_start_params(options = {}) + [localhost ,user , {:keys => @key_id_rsa}.merge(options)] end def setup_ssh_env(&block) @@ -337,6 +338,110 @@ end end end + + class TCPProxy + def initialize() + @sockets = [] + end + attr_reader :sockets + + def open(host, port, connection_options = nil) + socket = TCPSocket.new(host,port) + @sockets << socket + socket + end + + def close_all + sockets.each do |socket| + socket.close + end + end + end + + def test_transport_close_should_closes_channels_with_tcps + setup_ssh_env do + server = start_server do |client| + client.puts "Hello" + sleep(100) + client.puts "Hallo" + end + proxy = TCPProxy.new() + session = Net::SSH.start(*ssh_start_params(proxy: proxy)) + remote_port = server.addr[1] + local_port = session.forward.local(0, localhost, remote_port) + + # read on forwarded port + client_done = Queue.new + Thread.start do + begin + client = TCPSocket.new(localhost, local_port) + client.read(6) + proxy.close_all + client.read(7) + client.close + client_done << true + rescue + client_done << $! + end + end + Timeout.timeout(5) do + begin + session.loop(0.1) { true } + rescue EOFError, IOError + #puts "Error: #{$!} #{$!.backtrace.join("\n")}" + end + end + begin + Timeout.timeout(5) do + assert_equal true, client_done.pop + end + rescue + puts "Server error: #{server_error.class} #{server_error} bt:#{server_error.backtrace.join("\n")}" + raise + end + end + end + + def todo_test_transport_close_should_closes_channels_with_proxy + setup_ssh_env do + server = start_server do |client| + client.puts "Hello" + sleep(100) + client.puts "Hallo" + end + proxy = Net::SSH::Proxy::Command.new("/bin/nc localhost 22") + session = Net::SSH.start(*ssh_start_params(proxy: proxy)) + remote_port = server.addr[1] + local_port = session.forward.local(0, localhost, remote_port) + + # read on forwarded port + client_done = Queue.new + Thread.start do + begin + client = TCPSocket.new(localhost, local_port) + client.read(6) + system("killall /bin/nc") + client.read(7) + client.close + client_done << true + rescue + client_done << $! + end + end + Timeout.timeout(5) do + begin + session.loop(0.1) { true } + rescue EOFError + begin + session.close + rescue + end + #puts "Error: #{$!} #{$!.backtrace.join("\n")}" + end + assert_equal true, client_done.pop + end + end + end def test_client_close_should_be_handled setup_ssh_env do diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/test/transport/test_session.rb new/test/transport/test_session.rb --- old/test/transport/test_session.rb 2016-03-23 13:28:21.000000000 +0100 +++ new/test/transport/test_session.rb 2016-06-19 07:58:58.000000000 +0200 @@ -309,7 +309,7 @@ end def algorithms - @algorithms ||= stub("algorithms", :initialized? => true, :allow? => true) + @algorithms ||= stub("algorithms", :initialized? => true, :allow? => true, :start => true) end def session(options={})