Hello community,

here is the log from the commit of package rubygem-net-ssh for openSUSE:Factory 
checked in at 2017-03-21 22:50:40
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rubygem-net-ssh (Old)
 and      /work/SRC/openSUSE:Factory/.rubygem-net-ssh.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "rubygem-net-ssh"

Tue Mar 21 22:50:40 2017 rev:24 rq:479684 version:4.1.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/rubygem-net-ssh/rubygem-net-ssh.changes  
2017-01-25 23:27:35.372293963 +0100
+++ /work/SRC/openSUSE:Factory/.rubygem-net-ssh.new/rubygem-net-ssh.changes     
2017-03-21 22:50:47.608227636 +0100
@@ -1,0 +2,17 @@
+Sun Feb 19 05:32:48 UTC 2017 - co...@suse.com
+
+- updated to version 4.1.0
+ see installed CHANGES.txt
+
+  === 4.1.0
+  === 4.1.0.rc1
+  
+   * ProxyJump support [Ryan McGeary, #500]
+   * Fix agent detection on Windows [Christian Koehler, #495]
+  
+  === 4.1.0.beta1
+  
+   * Fix nil error when libsodium is not there [chapmajs ,#488]
+   * SSH certificate support for client auth [David Bartley, #485]
+
+-------------------------------------------------------------------

Old:
----
  net-ssh-4.0.1.gem

New:
----
  net-ssh-4.1.0.gem

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ rubygem-net-ssh.spec ++++++
--- /var/tmp/diff_new_pack.zQXdqX/_old  2017-03-21 22:50:48.468106073 +0100
+++ /var/tmp/diff_new_pack.zQXdqX/_new  2017-03-21 22:50:48.476104943 +0100
@@ -24,7 +24,7 @@
 #
 
 Name:           rubygem-net-ssh
-Version:        4.0.1
+Version:        4.1.0
 Release:        0
 %define mod_name net-ssh
 %define mod_full_name %{mod_name}-%{version}

++++++ net-ssh-4.0.1.gem -> net-ssh-4.1.0.gem ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/.travis.yml new/.travis.yml
--- old/.travis.yml     2017-01-07 15:36:27.000000000 +0100
+++ new/.travis.yml     2017-02-18 18:23:34.000000000 +0100
@@ -2,6 +2,10 @@
 sudo: true
 dist: trusty
 
+addon:
+  hosts:
+    gateway.netssh
+
 rvm:
   - 2.0
   - 2.1
@@ -40,6 +44,7 @@
   - ansible-playbook ./test/integration/playbook.yml -i "localhost," --become 
-c local -e 'no_rvm=true' -e 'myuser=travis' -e 'mygroup=travis' -e 
'homedir=/home/travis'
 
 script:
+  - ssh -V
   - bundle _1.13.7_ exec rake test
   - BUNDLE_GEMFILE=./Gemfile.norbnacl bundle _1.13.7_ exec rake test
   - bundle _1.13.7_ exec rake test_test
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/CHANGES.txt new/CHANGES.txt
--- old/CHANGES.txt     2017-01-07 15:36:27.000000000 +0100
+++ new/CHANGES.txt     2017-02-18 18:23:34.000000000 +0100
@@ -1,3 +1,14 @@
+=== 4.1.0
+=== 4.1.0.rc1
+
+ * ProxyJump support [Ryan McGeary, #500]
+ * Fix agent detection on Windows [Christian Koehler, #495]
+
+=== 4.1.0.beta1
+
+ * Fix nil error when libsodium is not there [chapmajs ,#488]
+ * SSH certificate support for client auth [David Bartley, #485]
+
 === 4.0.1
 === 4.0.1.rc2
 
Binary files old/checksums.yaml.gz and new/checksums.yaml.gz differ
Binary files old/checksums.yaml.gz.sig and new/checksums.yaml.gz.sig differ
Binary 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.rb 
new/lib/net/ssh/authentication/agent.rb
--- old/lib/net/ssh/authentication/agent.rb     2017-01-07 15:36:27.000000000 
+0100
+++ new/lib/net/ssh/authentication/agent.rb     2017-02-18 18:23:34.000000000 
+0100
@@ -29,20 +29,28 @@
       attr_accessor :comment
     end
 
-    SSH2_AGENT_REQUEST_VERSION    = 1
-    SSH2_AGENT_REQUEST_IDENTITIES = 11
-    SSH2_AGENT_IDENTITIES_ANSWER  = 12
-    SSH2_AGENT_SIGN_REQUEST       = 13
-    SSH2_AGENT_SIGN_RESPONSE      = 14
-    SSH2_AGENT_FAILURE            = 30
-    SSH2_AGENT_VERSION_RESPONSE   = 103
+    SSH2_AGENT_REQUEST_VERSION       = 1
+    SSH2_AGENT_REQUEST_IDENTITIES    = 11
+    SSH2_AGENT_IDENTITIES_ANSWER     = 12
+    SSH2_AGENT_SIGN_REQUEST          = 13
+    SSH2_AGENT_SIGN_RESPONSE         = 14
+    SSH2_AGENT_ADD_IDENTITY          = 17
+    SSH2_AGENT_REMOVE_IDENTITY       = 18
+    SSH2_AGENT_REMOVE_ALL_IDENTITIES = 19
+    SSH2_AGENT_ADD_ID_CONSTRAINED    = 25
+    SSH2_AGENT_FAILURE               = 30
+    SSH2_AGENT_VERSION_RESPONSE      = 103
 
-    SSH_COM_AGENT2_FAILURE        = 102
+    SSH_COM_AGENT2_FAILURE = 102
 
     SSH_AGENT_REQUEST_RSA_IDENTITIES = 1
     SSH_AGENT_RSA_IDENTITIES_ANSWER1 = 2
     SSH_AGENT_RSA_IDENTITIES_ANSWER2 = 5
     SSH_AGENT_FAILURE                = 5
+    SSH_AGENT_SUCCESS                = 6
+
+    SSH_AGENT_CONSTRAIN_LIFETIME = 1
+    SSH_AGENT_CONSTRAIN_CONFIRM  = 2
 
     # The underlying socket being used to communicate with the SSH agent.
     attr_reader :socket
@@ -71,7 +79,7 @@
       @socket =
         if agent_socket_factory
           agent_socket_factory.call
-        elsif ENV['SSH_AUTH_SOCK'] && defined?(unix_socket_class)
+        elsif ENV['SSH_AUTH_SOCK'] && unix_socket_class
           unix_socket_class.open(ENV['SSH_AUTH_SOCK'])
         elsif Gem.win_platform? && RUBY_ENGINE != "jruby"
           Pageant::Socket.open
@@ -139,10 +147,41 @@
       return reply.read_string
     end
 
+    # Adds the private key with comment to the agent.
+    # If lifetime is given, the key will automatically be removed after 
lifetime
+    # seconds.
+    # If confirm is true, confirmation will be required for each agent signing
+    # operation.
+    def add_identity(priv_key, comment, lifetime: nil, confirm: false)
+      constraints = Buffer.new
+      if lifetime
+        constraints.write_byte(SSH_AGENT_CONSTRAIN_LIFETIME)
+        constraints.write_long(lifetime)
+      end
+      constraints.write_byte(SSH_AGENT_CONSTRAIN_CONFIRM) if confirm
+
+      req_type = constraints.empty? ? SSH2_AGENT_ADD_IDENTITY : 
SSH2_AGENT_ADD_ID_CONSTRAINED
+      type, = send_and_wait(req_type, :string, priv_key.ssh_type, :raw, 
blob_for_add(priv_key),
+                            :string, comment, :raw, constraints)
+      raise AgentError, "could not add identity to agent" if type != 
SSH_AGENT_SUCCESS
+    end
+
+    # Removes key from the agent.
+    def remove_identity(key)
+      type, = send_and_wait(SSH2_AGENT_REMOVE_IDENTITY, :string, key.to_blob)
+      raise AgentError, "could not remove identity from agent" if type != 
SSH_AGENT_SUCCESS
+    end
+
+    # Removes all identities from the agent.
+    def remove_all_identities
+      type, = send_and_wait(SSH2_AGENT_REMOVE_ALL_IDENTITIES)
+      raise AgentError, "could not remove all identity from agent" if type != 
SSH_AGENT_SUCCESS
+    end
+
     private
 
     def unix_socket_class
-      UNIXSocket
+      defined?(UNIXSocket) && UNIXSocket
     end
 
     # Send a new packet of the given type, with the associated data.
@@ -178,6 +217,40 @@
         type == SSH2_AGENT_FAILURE ||
         type == SSH_COM_AGENT2_FAILURE
     end
+
+    def blob_for_add(priv_key)
+      # Ideally we'd have something like `to_private_blob` on the various key 
types, but the
+      # nuances with encoding (e.g. `n` and `e` are reversed for RSA keys) 
make this impractical.
+      case priv_key.ssh_type
+      when /^ssh-dss$/
+        Net::SSH::Buffer.from(:bignum, priv_key.p, :bignum, priv_key.q, 
:bignum, priv_key.g,
+                              :bignum, priv_key.pub_key, :bignum, 
priv_key.priv_key).to_s
+      when /^ssh-dss-cert-v01@openssh\.com$/
+        Net::SSH::Buffer.from(:string, priv_key.to_blob, :bignum, 
priv_key.key.priv_key).to_s
+      when /^ecdsa\-sha2\-(\w*)$/
+        curve_name = 
OpenSSL::PKey::EC::CurveNameAliasInv[priv_key.group.curve_name]
+        Net::SSH::Buffer.from(:string, curve_name, :mstring, 
priv_key.public_key.to_bn.to_s(2),
+                              :bignum, priv_key.private_key).to_s
+      when /^ecdsa\-sha2\-(\w*)-cert-v01@openssh\.com$/
+        Net::SSH::Buffer.from(:string, priv_key.to_blob, :bignum, 
priv_key.key.private_key).to_s
+      when /^ssh-ed25519$/
+        Net::SSH::Buffer.from(:string, priv_key.public_key.verify_key.to_bytes,
+                              :string, priv_key.sign_key.keypair_bytes).to_s
+      when /^ssh-ed25519-cert-v01@openssh\.com$/
+        # Unlike the other certificate types, the public key is included after 
the certifiate.
+        Net::SSH::Buffer.from(:string, priv_key.to_blob,
+                              :string, 
priv_key.key.public_key.verify_key.to_bytes,
+                              :string, 
priv_key.key.sign_key.keypair_bytes).to_s
+      when /^ssh-rsa$/
+        # `n` and `e` are reversed compared to the ordering in 
`OpenSSL::PKey::RSA#to_blob`.
+        Net::SSH::Buffer.from(:bignum, priv_key.n, :bignum, priv_key.e, 
:bignum, priv_key.d,
+                              :bignum, priv_key.iqmp, :bignum, priv_key.p, 
:bignum, priv_key.q).to_s
+      when /^ssh-rsa-cert-v01@openssh\.com$/
+        Net::SSH::Buffer.from(:string, priv_key.to_blob, :bignum, 
priv_key.key.d,
+                              :bignum, priv_key.key.iqmp, :bignum, 
priv_key.key.p,
+                              :bignum, priv_key.key.q).to_s
+      end
+    end
   end
 
 end; end; end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/net/ssh/authentication/certificate.rb 
new/lib/net/ssh/authentication/certificate.rb
--- old/lib/net/ssh/authentication/certificate.rb       1970-01-01 
01:00:00.000000000 +0100
+++ new/lib/net/ssh/authentication/certificate.rb       2017-02-18 
18:23:34.000000000 +0100
@@ -0,0 +1,169 @@
+require 'securerandom'
+
+module Net; module SSH; module Authentication
+  # Class for representing an SSH certificate.
+  #
+  # 
http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/usr.bin/ssh/PROTOCOL.certkeys?rev=1.10&content-type=text/plain
+  class Certificate
+    attr_accessor :nonce
+    attr_accessor :key
+    attr_accessor :serial
+    attr_accessor :type
+    attr_accessor :key_id
+    attr_accessor :valid_principals
+    attr_accessor :valid_after
+    attr_accessor :valid_before
+    attr_accessor :critical_options
+    attr_accessor :extensions
+    attr_accessor :reserved
+    attr_accessor :signature_key
+    attr_accessor :signature
+
+    # Read a certificate blob associated with a key of the given type.
+    def self.read_certblob(buffer, type)
+      cert = Certificate.new
+      cert.nonce = buffer.read_string
+      cert.key = buffer.read_keyblob(type)
+      cert.serial = buffer.read_int64
+      cert.type = type_symbol(buffer.read_long)
+      cert.key_id = buffer.read_string
+      cert.valid_principals = buffer.read_buffer.read_all(&:read_string)
+      cert.valid_after = Time.at(buffer.read_int64)
+      cert.valid_before = Time.at(buffer.read_int64)
+      cert.critical_options = read_options(buffer)
+      cert.extensions = read_options(buffer)
+      cert.reserved = buffer.read_string
+      cert.signature_key = buffer.read_buffer.read_key
+      cert.signature = buffer.read_string
+      cert
+    end
+
+    def ssh_type
+      key.ssh_type + "-cert-...@openssh.com"
+    end
+
+    def ssh_signature_type
+      key.ssh_type
+    end
+
+    # Serializes the certificate (and key).
+    def to_blob
+      Buffer.from(
+        :raw, to_blob_without_signature,
+        :string, signature
+      ).to_s
+    end
+
+    def ssh_do_sign(data)
+      key.ssh_do_sign(data)
+    end
+
+    def ssh_do_verify(sig, data)
+      key.ssh_do_verify(sig, data)
+    end
+
+    def to_pem
+      key.to_pem
+    end
+
+    def fingerprint
+      key.fingerprint
+    end
+
+    # Signs the certificate with key.
+    def sign!(key, sign_nonce=nil)
+      # ssh-keygen uses 32 bytes of nonce.
+      self.nonce = sign_nonce || SecureRandom.random_bytes(32)
+      self.signature_key = key
+      self.signature = Net::SSH::Buffer.from(
+        :string, key.ssh_signature_type,
+        :mstring, key.ssh_do_sign(to_blob_without_signature)
+      ).to_s
+      self
+    end
+
+    def sign(key, sign_nonce=nil)
+      cert = clone
+      cert.sign!(key, sign_nonce)
+    end
+
+    # Checks whether the certificate's signature was signed by signature key.
+    def signature_valid?
+      buffer = Buffer.new(signature)
+      buffer.read_string # skip signature format
+      signature_key.ssh_do_verify(buffer.read_string, 
to_blob_without_signature)
+    end
+
+    def self.read_options(buffer)
+      names = []
+      options = buffer.read_buffer.read_all do |b|
+        name = b.read_string
+        names << name
+        data = b.read_string
+        data = Buffer.new(data).read_string unless data.empty?
+        [name, data]
+      end
+
+      if names.sort != names
+        raise ArgumentError, "option/extension names must be in sorted order"
+      end
+
+      Hash[options]
+    end
+    private_class_method :read_options
+
+    def self.type_symbol(type)
+      types = {1 => :user, 2 => :host}
+      raise ArgumentError("unsupported type: #{type}") unless 
types.include?(type)
+      types.fetch(type)
+    end
+    private_class_method :type_symbol
+
+    private
+
+    def type_value(type)
+      types = {user: 1, host: 2}
+      raise ArgumentError("unsupported type: #{type}") unless 
types.include?(type)
+      types.fetch(type)
+    end
+
+    def ssh_time(t)
+      # Times in certificates are represented as a uint64.
+      [[t.to_i, 0].max, 2<<64 - 1].min
+    end
+
+    def to_blob_without_signature
+      Buffer.from(
+        :string, ssh_type,
+        :string, nonce,
+        :raw, key_without_type,
+        :int64, serial,
+        :long, type_value(type),
+        :string, key_id,
+        :string, valid_principals.inject(Buffer.new) { |acc, elem| 
acc.write_string(elem) }.to_s,
+        :int64, ssh_time(valid_after),
+        :int64, ssh_time(valid_before),
+        :string, options_to_blob(critical_options),
+        :string, options_to_blob(extensions),
+        :string, reserved,
+        :string, signature_key.to_blob
+      ).to_s
+    end
+
+    def key_without_type
+      # key.to_blob gives us e.g. "ssh-rsa,<key>" but we just want "<key>".
+      tmp = Buffer.new(key.to_blob)
+      tmp.read_string # skip the underlying key type
+      tmp.read
+    end
+
+    def options_to_blob(options)
+      options.keys.sort.inject(Buffer.new) do |b, name|
+        b.write_string(name)
+        data = options.fetch(name)
+        data = Buffer.from(:string, data).to_s unless data.empty?
+        b.write_string(data)
+      end.to_s
+    end
+  end
+end; end; end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/net/ssh/authentication/ed25519.rb 
new/lib/net/ssh/authentication/ed25519.rb
--- old/lib/net/ssh/authentication/ed25519.rb   2017-01-07 15:36:27.000000000 
+0100
+++ new/lib/net/ssh/authentication/ed25519.rb   2017-02-18 18:23:34.000000000 
+0100
@@ -1,7 +1,11 @@
 gem 'rbnacl', '>= 3.2.0', '< 5.0'
 gem 'bcrypt_pbkdf', '~> 1.0' unless RUBY_PLATFORM == "java"
 
-require 'rbnacl/libsodium'
+begin
+  require 'rbnacl/libsodium'
+rescue LoadError # rubocop:disable Lint/HandleExceptions
+end
+
 require 'rbnacl'
 require 'rbnacl/signatures/ed25519/verify_key'
 require 'rbnacl/signatures/ed25519/signing_key'
@@ -23,6 +27,8 @@
   end
 
   class PubKey
+    attr_reader :verify_key
+
     def initialize(data)
       @verify_key = RbNaCl::Signatures::Ed25519::VerifyKey.new(data)
     end
@@ -39,6 +45,10 @@
       "ssh-ed25519"
     end
 
+    def ssh_signature_type
+      ssh_type
+    end
+
     def ssh_do_verify(sig,data)
       @verify_key.verify(sig,data)
     end
@@ -60,6 +70,8 @@
     MEND = "-----END OPENSSH PRIVATE KEY-----\n"
     MAGIC = "openssh-key-v1"
 
+    attr_reader :sign_key
+
     def initialize(datafull,password)
       raise ArgumentError.new("Expected #{MBEGIN} at start of private key") 
unless datafull.start_with?(MBEGIN)
       raise ArgumentError.new("Expected #{MEND} at end of private key") unless 
datafull.end_with?(MEND)
@@ -116,6 +128,18 @@
       @sign_key = SigningKeyFromFile.new(pk,sk)
     end
 
+    def to_blob
+      public_key.to_blob
+    end
+
+    def ssh_type
+      "ssh-ed25519"
+    end
+
+    def ssh_signature_type
+      ssh_type
+    end
+
     def public_key
       PubKey.new(@pk)
     end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/net/ssh/authentication/ed25519_loader.rb 
new/lib/net/ssh/authentication/ed25519_loader.rb
--- old/lib/net/ssh/authentication/ed25519_loader.rb    2017-01-07 
15:36:27.000000000 +0100
+++ new/lib/net/ssh/authentication/ed25519_loader.rb    2017-02-18 
18:23:34.000000000 +0100
@@ -14,7 +14,7 @@
 end
 
 def self.raiseUnlessLoaded(message)
-  description = dependenciesRequiredForED25519 if ERROR.is_a?(Gem::LoadError)
+  description = ERROR.is_a?(LoadError) ? dependenciesRequiredForED25519 : ''
   description << "#{ERROR.class} : \"#{ERROR.message}\"\n" if ERROR
   raise NotImplementedError, "#{message}\n#{description}" unless LOADED
 end
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       2017-01-07 
15:36:27.000000000 +0100
+++ new/lib/net/ssh/authentication/key_manager.rb       2017-02-18 
18:23:34.000000000 +0100
@@ -146,7 +146,7 @@
           end
 
           if info[:key]
-            return Net::SSH::Buffer.from(:string, identity.ssh_type,
+            return Net::SSH::Buffer.from(:string, identity.ssh_signature_type,
               :mstring, info[:key].ssh_do_sign(data.to_s)).to_s
           end
 
@@ -189,8 +189,12 @@
           key_files.map do |file|
             if readable_file?(file)
               identity = {}
+              cert_file = file + "-cert.pub"
               public_key_file = file + ".pub"
-              if readable_file?(public_key_file)
+              if readable_file?(cert_file)
+                identity[:load_from] = :pubkey_file
+                identity[:pubkey_file] = cert_file
+              elsif readable_file?(public_key_file)
                 identity[:load_from] = :pubkey_file
                 identity[:pubkey_file] = public_key_file
               else
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/net/ssh/buffer.rb new/lib/net/ssh/buffer.rb
--- old/lib/net/ssh/buffer.rb   2017-01-07 15:36:28.000000000 +0100
+++ new/lib/net/ssh/buffer.rb   2017-02-18 18:23:34.000000000 +0100
@@ -1,6 +1,7 @@
 require 'net/ssh/ruby_compat'
 require 'net/ssh/transport/openssl'
 
+require 'net/ssh/authentication/certificate'
 require 'net/ssh/authentication/ed25519_loader'
 
 module Net; module SSH
@@ -186,6 +187,11 @@
       data
     end
 
+    # Calls block(self) until the buffer is empty, and returns all results.
+    def read_all(&block)
+      Enumerator.new { |e| e << yield(self) until eof? }.to_a
+    end
+
     # Return the next 8 bytes as a 64-bit integer (in network byte order).
     # Returns nil if there are less than 8 bytes remaining to be read in the
     # buffer.
@@ -246,7 +252,9 @@
     # a key. Only RSA, DSA, and ECDSA keys are supported.
     def read_keyblob(type)
       case type
-        when /^ssh-dss(-cert-v01@openssh\.com)?$/
+        when /^(.*)-cert-v01@openssh\.com$/
+          key = Net::SSH::Authentication::Certificate.read_certblob(self, $1)
+        when /^ssh-dss$/
           key = OpenSSL::PKey::DSA.new
           if key.respond_to?(:set_pqg)
             key.set_pqg(read_bignum, read_bignum, read_bignum)
@@ -260,8 +268,7 @@
           else
             key.pub_key = read_bignum
           end
-
-        when /^ssh-rsa(-cert-v01@openssh\.com)?$/
+        when /^ssh-rsa$/
           key = OpenSSL::PKey::RSA.new
           if key.respond_to?(:set_key)
             e = read_bignum
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/net/ssh/config.rb new/lib/net/ssh/config.rb
--- old/lib/net/ssh/config.rb   2017-01-07 15:36:28.000000000 +0100
+++ new/lib/net/ssh/config.rb   2017-02-18 18:23:34.000000000 +0100
@@ -27,6 +27,7 @@
   # * Port => :port
   # * PreferredAuthentications => maps to the :auth_methods option
   # * ProxyCommand => maps to the :proxy option
+  # * ProxyJump => maps to the :proxy option
   # * PubKeyAuthentication => maps to the :auth_methods option
   # * RekeyLimit => :rekey_limit
   # * User => :user
@@ -156,93 +157,7 @@
         auth_methods = default_auth_methods.clone
         (auth_methods << 'challenge-response').uniq!
         ret = settings.inject({auth_methods: auth_methods}) do |hash, (key, 
value)|
-          case key
-          when 'bindaddress' then
-            hash[:bind_address] = value
-          when 'ciphers' then
-            hash[:encryption] = value.split(/,/)
-          when 'compression' then
-            hash[:compression] = value
-          when 'compressionlevel' then
-            hash[:compression_level] = value
-          when 'connecttimeout' then
-            hash[:timeout] = value
-          when 'forwardagent' then
-            hash[:forward_agent] = value
-          when 'identitiesonly' then
-            hash[:keys_only] = value
-          when 'globalknownhostsfile'
-            hash[:global_known_hosts_file] = value
-          when 'hostbasedauthentication' then
-            if value
-              (hash[:auth_methods] << "hostbased").uniq!
-            else
-              hash[:auth_methods].delete("hostbased")
-            end
-          when 'hostkeyalgorithms' then
-            hash[:host_key] = value.split(/,/)
-          when 'hostkeyalias' then
-            hash[:host_key_alias] = value
-          when 'hostname' then
-            hash[:host_name] = value.gsub(/%h/, settings['host'])
-          when 'identityfile' then
-            hash[:keys] = value
-          when 'macs' then
-            hash[:hmac] = value.split(/,/)
-          when 'serveralivecountmax'
-            hash[:keepalive_maxcount] = value.to_i if value
-          when 'serveraliveinterval'
-            if value && value.to_i > 0
-              hash[:keepalive] = true
-              hash[:keepalive_interval] = value.to_i
-            else
-              hash[:keepalive] = false
-            end
-          when 'passwordauthentication'
-            if value
-              (hash[:auth_methods] << 'password').uniq!
-            else
-              hash[:auth_methods].delete('password')
-            end
-          when 'challengeresponseauthentication'
-            if value
-              (hash[:auth_methods] << 'challenge-response').uniq!
-            else
-              hash[:auth_methods].delete('challenge-response')
-            end
-          when 'kbdinteractiveauthentication'
-            if value
-              (hash[:auth_methods] << 'keyboard-interactive').uniq!
-            else
-              hash[:auth_methods].delete('keyboard-interactive')
-            end
-          when 'port'
-            hash[:port] = value
-          when 'preferredauthentications'
-            hash[:auth_methods] = value.split(/,/) # TODO we should place to 
preferred_auth_methods rather than auth_methods
-          when 'proxycommand'
-            if value and !(value =~ /^none$/)
-              require 'net/ssh/proxy/command'
-              hash[:proxy] = Net::SSH::Proxy::Command.new(value)
-            end
-          when 'pubkeyauthentication'
-            if value
-              (hash[:auth_methods] << 'publickey').uniq!
-            else
-              hash[:auth_methods].delete('publickey')
-            end
-          when 'rekeylimit'
-            hash[:rekey_limit] = interpret_size(value)
-          when 'user'
-            hash[:user] = value
-          when 'userknownhostsfile'
-            hash[:user_known_hosts_file] = value
-          when 'sendenv'
-            multi_send_env = value.to_s.split(/\s+/)
-            hash[:send_env] = multi_send_env.map { |e| Regexp.new 
pattern2regex(e).source, false }
-          when 'numberofpasswordprompts'
-            hash[:number_of_password_prompts] = value.to_i
-          end
+          translate_config_key(hash, key.to_sym, value, settings)
           hash
         end
         merge_challenge_response_with_keyboard_interactive(ret)
@@ -262,6 +177,93 @@
 
       private
 
+        def translate_config_key(hash, key, value, settings)
+          rename = {
+            bindaddress: :bind_address,
+            compression: :compression,
+            compressionlevel: :compression_level,
+            connecttimeout: :timeout,
+            forwardagent: :forward_agent,
+            identitiesonly: :keys_only,
+            globalknownhostsfile: :global_known_hosts_file,
+            hostkeyalias: :host_key_alias,
+            identityfile: :keys,
+            port: :port,
+            user: :user,
+            userknownhostsfile: :user_known_hosts_file
+          }
+          case key
+            when :ciphers
+              hash[:encryption] = value.split(/,/)
+            when :hostbasedauthentication
+              if value
+                (hash[:auth_methods] << "hostbased").uniq!
+              else
+                hash[:auth_methods].delete("hostbased")
+              end
+            when :hostkeyalgorithms
+              hash[:host_key] = value.split(/,/)
+            when :hostname
+              hash[:host_name] = value.gsub(/%h/, settings['host'])
+            when :macs
+              hash[:hmac] = value.split(/,/)
+            when :serveralivecountmax
+              hash[:keepalive_maxcount] = value.to_i if value
+            when :serveraliveinterval
+              if value && value.to_i > 0
+                hash[:keepalive] = true
+                hash[:keepalive_interval] = value.to_i
+              else
+                hash[:keepalive] = false
+              end
+            when :passwordauthentication
+              if value
+                (hash[:auth_methods] << 'password').uniq!
+              else
+                hash[:auth_methods].delete('password')
+              end
+            when :challengeresponseauthentication
+              if value
+                (hash[:auth_methods] << 'challenge-response').uniq!
+              else
+                hash[:auth_methods].delete('challenge-response')
+              end
+            when :kbdinteractiveauthentication
+              if value
+                (hash[:auth_methods] << 'keyboard-interactive').uniq!
+              else
+                hash[:auth_methods].delete('keyboard-interactive')
+              end
+            when :preferredauthentications
+              hash[:auth_methods] = value.split(/,/) # TODO we should place to 
preferred_auth_methods rather than auth_methods
+            when :proxycommand
+              if value and !(value =~ /^none$/)
+                require 'net/ssh/proxy/command'
+                hash[:proxy] = Net::SSH::Proxy::Command.new(value)
+              end
+            when :proxyjump
+              if value
+                require 'net/ssh/proxy/jump'
+                hash[:proxy] = Net::SSH::Proxy::Jump.new(value)
+              end
+            when :pubkeyauthentication
+              if value
+                (hash[:auth_methods] << 'publickey').uniq!
+              else
+                hash[:auth_methods].delete('publickey')
+              end
+            when :rekeylimit
+              hash[:rekey_limit] = interpret_size(value)
+            when :sendenv
+              multi_send_env = value.to_s.split(/\s+/)
+              hash[:send_env] = multi_send_env.map { |e| Regexp.new 
pattern2regex(e).source, false }
+            when :numberofpasswordprompts
+              hash[:number_of_password_prompts] = value.to_i
+            when *rename.keys
+              hash[rename[key]] = value
+          end
+        end
+
         # Converts an ssh_config pattern into a regex for matching against
         # host names.
         def pattern2regex(pattern)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/net/ssh/connection/channel.rb 
new/lib/net/ssh/connection/channel.rb
--- old/lib/net/ssh/connection/channel.rb       2017-01-07 15:36:28.000000000 
+0100
+++ new/lib/net/ssh/connection/channel.rb       2017-02-18 18:23:34.000000000 
+0100
@@ -613,7 +613,7 @@
         if callback = pending_requests.shift
           callback.call(self, false)
         else
-          error { "channel failure recieved with no pending request to handle 
it (bug?)" }
+          error { "channel failure received with no pending request to handle 
it (bug?)" }
         end
       end
 
@@ -623,7 +623,7 @@
         if callback = pending_requests.shift
           callback.call(self, true)
         else
-          error { "channel success recieved with no pending request to handle 
it (bug?)" }
+          error { "channel success received with no pending request to handle 
it (bug?)" }
         end
       end
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/net/ssh/key_factory.rb 
new/lib/net/ssh/key_factory.rb
--- old/lib/net/ssh/key_factory.rb      2017-01-07 15:36:28.000000000 +0100
+++ new/lib/net/ssh/key_factory.rb      2017-02-18 18:23:34.000000000 +0100
@@ -93,7 +93,7 @@
         blob = nil
         begin
           blob = fields.shift
-        end while !blob.nil? && 
!/^(ssh-(rsa|dss|ed25519)|ecdsa-sha2-nistp\d+)$/.match(blob)
+        end while !blob.nil? && 
!/^(ssh-(rsa|dss|ed25519)|ecdsa-sha2-nistp\d+)(-cert-v01@openssh\.com)?$/.match(blob)
         blob = fields.shift
 
         raise Net::SSH::Exception, "public key at #{filename} is not valid" if 
blob.nil?
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/net/ssh/proxy/jump.rb 
new/lib/net/ssh/proxy/jump.rb
--- old/lib/net/ssh/proxy/jump.rb       1970-01-01 01:00:00.000000000 +0100
+++ new/lib/net/ssh/proxy/jump.rb       2017-02-18 18:23:34.000000000 +0100
@@ -0,0 +1,53 @@
+require 'uri'
+require 'net/ssh/proxy/command'
+
+module Net; module SSH; module Proxy
+
+  # An implementation of a jump proxy. To use it, instantiate it,
+  # then pass the instantiated object via the :proxy key to
+  # Net::SSH.start:
+  #
+  #   require 'net/ssh/proxy/jump'
+  #
+  #   proxy = Net::SSH::Proxy::Jump.new('user@proxy')
+  #   Net::SSH.start('host', 'user', :proxy => proxy) do |ssh|
+  #     ...
+  #   end
+  class Jump < Command
+
+    # The jump proxies
+    attr_reader :jump_proxies
+
+    # Create a new socket factory that tunnels via multiple jump proxes as
+    # [user@]host[:port].
+    def initialize(jump_proxies)
+      @jump_proxies = jump_proxies
+    end
+
+    # Return a new socket connected to the given host and port via the jump
+    # proxy that was requested when the socket factory was instantiated.
+    def open(host, port, connection_options = nil)
+      build_proxy_command_equivalent(connection_options)
+      super
+    end
+
+    # We cannot build the ProxyCommand template until we know if the :config
+    # option was specified during `Net::SSH.start`.
+    def build_proxy_command_equivalent(connection_options = nil)
+      first_jump, extra_jumps = jump_proxies.split(",", 2)
+      config = connection_options && connection_options[:config]
+      uri = URI.parse("ssh://#{first_jump}")
+
+      template = "ssh"
+      template << " -l #{uri.user}"    if uri.user
+      template << " -p #{uri.port}"    if uri.port
+      template << " -J #{extra_jumps}" if extra_jumps
+      template << " -F #{config}" if config != true && config
+      template << " -W %h:%p "
+      template << uri.host
+
+      @command_line_template = template
+    end
+  end
+
+end; end; 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     2017-01-07 15:36:28.000000000 
+0100
+++ new/lib/net/ssh/transport/algorithms.rb     2017-02-18 18:23:34.000000000 
+0100
@@ -121,7 +121,7 @@
 
     # Start the algorithm negotation
     def start
-      raise ArgumentError, "Cannot call start if it's negoitation started or 
done" if @pending || @initialized
+      raise ArgumentError, "Cannot call start if it's negotiation started or 
done" if @pending || @initialized
       send_kexinit
     end
 
@@ -135,7 +135,7 @@
       send_kexinit
     end
 
-    # Called by the transport layer when a KEXINIT packet is recieved, 
indicating
+    # Called by the transport layer when a KEXINIT packet is received, 
indicating
     # that the server wants to exchange keys. This can be spontaneous, or it
     # can be in response to a client-initiated rekey request (see #rekey!). 
Either
     # way, this will block until the key exchange completes.
@@ -263,7 +263,7 @@
           is_supported
         end
 
-        lwarn { "unsupported #{algorithm} algorithm: `#{unsupported}'" } 
unless unsupported.empty?
+        lwarn { %(unsupported algorithm: `#{unsupported}') } unless 
unsupported.empty?
 
         list
       end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/net/ssh/transport/openssl.rb 
new/lib/net/ssh/transport/openssl.rb
--- old/lib/net/ssh/transport/openssl.rb        2017-01-07 15:36:28.000000000 
+0100
+++ new/lib/net/ssh/transport/openssl.rb        2017-02-18 18:23:34.000000000 
+0100
@@ -60,6 +60,10 @@
         "ssh-rsa"
       end
 
+      def ssh_signature_type
+        ssh_type
+      end
+
       # Converts the key to a blob, according to the SSH2 protocol.
       def to_blob
         @blob ||= Net::SSH::Buffer.from(:string, ssh_type, :bignum, e, 
:bignum, n).to_s
@@ -87,6 +91,10 @@
         "ssh-dss"
       end
 
+      def ssh_signature_type
+        ssh_type
+      end
+
       # Converts the key to a blob, according to the SSH2 protocol.
       def to_blob
         @blob ||= Net::SSH::Buffer.from(:string, ssh_type,
@@ -165,6 +173,10 @@
           "ecdsa-sha2-#{CurveNameAliasInv[self.group.curve_name]}"
         end
 
+        def ssh_signature_type
+          ssh_type
+        end
+
         def digester
           if self.group.curve_name =~ /^[a-z]+(\d+)\w*\z/
             curve_size = $1.to_i
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        2017-01-07 15:36:28.000000000 
+0100
+++ new/lib/net/ssh/transport/session.rb        2017-02-18 18:23:34.000000000 
+0100
@@ -198,7 +198,7 @@
           raise Net::SSH::Disconnect, "disconnected: #{packet[:description]} 
(#{packet[:reason_code]})"
 
         when IGNORE
-          debug { "IGNORE packet recieved: #{packet[:data].inspect}" }
+          debug { "IGNORE packet received: #{packet[:data].inspect}" }
 
         when UNIMPLEMENTED
           lwarn { "UNIMPLEMENTED: #{packet[:number]}" }
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  2017-01-07 15:36:28.000000000 +0100
+++ new/lib/net/ssh/version.rb  2017-02-18 18:23:34.000000000 +0100
@@ -48,10 +48,10 @@
     MAJOR = 4
 
     # The minor component of this version of the Net::SSH library
-    MINOR = 0
+    MINOR = 1
 
     # 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/metadata new/metadata
--- old/metadata        2017-01-07 15:36:27.000000000 +0100
+++ new/metadata        2017-02-18 18:23:34.000000000 +0100
@@ -1,7 +1,7 @@
 --- !ruby/object:Gem::Specification
 name: net-ssh
 version: !ruby/object:Gem::Version
-  version: 4.0.1
+  version: 4.1.0
 platform: ruby
 authors:
 - Jamis Buck
@@ -32,7 +32,7 @@
   L4d54WIy4HkZCqQXoTSiK5HZMIdXkPk3F1bZdJ8Dy1sMRru0rUkkM5mW7TQ75mfW
   Zp0QrZyNZhtitrXFbZneGRrIA/8G2Krft5Ly/A==
   -----END CERTIFICATE-----
-date: 2017-01-07 00:00:00.000000000 Z
+date: 2017-02-18 00:00:00.000000000 Z
 dependencies:
 - !ruby/object:Gem::Dependency
   requirement: !ruby/object:Gem::Requirement
@@ -166,6 +166,7 @@
 - appveyor.yml
 - lib/net/ssh.rb
 - lib/net/ssh/authentication/agent.rb
+- lib/net/ssh/authentication/certificate.rb
 - lib/net/ssh/authentication/constants.rb
 - lib/net/ssh/authentication/ed25519.rb
 - lib/net/ssh/authentication/ed25519_loader.rb
@@ -197,6 +198,7 @@
 - lib/net/ssh/proxy/errors.rb
 - lib/net/ssh/proxy/http.rb
 - lib/net/ssh/proxy/https.rb
+- lib/net/ssh/proxy/jump.rb
 - lib/net/ssh/proxy/socks4.rb
 - lib/net/ssh/proxy/socks5.rb
 - lib/net/ssh/ruby_compat.rb
Binary files old/metadata.gz.sig and new/metadata.gz.sig differ


Reply via email to