net-ssh 4.0.0.beta3 → 4.0.0.beta4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -49,8 +49,7 @@ module Net; module SSH; module Proxy
49
49
  # Return a new socket connected to the given host and port via the
50
50
  # proxy that was requested when the socket factory was instantiated.
51
51
  def open(host, port, connection_options)
52
- socket = Socket.tcp(proxy_host, proxy_port, nil, nil,
53
- connect_timeout: connection_options[:timeout])
52
+ socket = establish_connection(connection_options[:timeout])
54
53
  socket.write "CONNECT #{host}:#{port} HTTP/1.0\r\n"
55
54
 
56
55
  if options[:user]
@@ -68,7 +67,12 @@ module Net; module SSH; module Proxy
68
67
  raise ConnectError, resp.inspect
69
68
  end
70
69
 
71
- private
70
+ protected
71
+
72
+ def establish_connection(connect_timeout)
73
+ Socket.tcp(proxy_host, proxy_port, nil, nil,
74
+ connect_timeout: connect_timeout)
75
+ end
72
76
 
73
77
  def parse_response(socket)
74
78
  version, code, reason = socket.gets.chomp.split(/ /, 3)
@@ -89,7 +93,6 @@ module Net; module SSH; module Proxy
89
93
  :headers => headers,
90
94
  :body => body }
91
95
  end
92
-
93
96
  end
94
97
 
95
98
  end; end; end
@@ -0,0 +1,49 @@
1
+ require 'socket'
2
+ require 'openssl'
3
+ require 'net/ssh/proxy/errors'
4
+ require 'net/ssh/proxy/http'
5
+
6
+ module Net; module SSH; module Proxy
7
+
8
+ # A specialization of the HTTP proxy which encrypts the whole connection
9
+ # using OpenSSL. This has the advantage that proxy authentication
10
+ # information is not sent in plaintext.
11
+ class HTTPS < HTTP
12
+
13
+ # Create a new socket factory that tunnels via the given host and
14
+ # port. The +options+ parameter is a hash of additional settings that
15
+ # can be used to tweak this proxy connection. In addition to the options
16
+ # taken by Net::SSH::Proxy::HTTP it supports:
17
+ #
18
+ # * :ssl_context => the SSL configuration to use for the connection
19
+ def initialize(proxy_host, proxy_port=80, options={})
20
+ @ssl_context = options.delete(:ssl_context) ||
21
+ OpenSSL::SSL::SSLContext.new
22
+ super(proxy_host, proxy_port, options)
23
+ end
24
+
25
+ protected
26
+
27
+ # Shim to make OpenSSL::SSL::SSLSocket behave like a regular TCPSocket
28
+ # for all intents and purposes of Net::SSH::BufferedIo
29
+ module SSLSocketCompatibility
30
+ def self.extended(object) #:nodoc:
31
+ object.define_singleton_method(:recv, object.method(:sysread))
32
+ object.sync_close = true
33
+ end
34
+
35
+ def send(data, _opts)
36
+ syswrite(data)
37
+ end
38
+ end
39
+
40
+ def establish_connection(connect_timeout)
41
+ plain_socket = super(connect_timeout)
42
+ OpenSSL::SSL::SSLSocket.new(plain_socket, @ssl_context).tap do |socket|
43
+ socket.extend(SSLSocketCompatibility)
44
+ socket.connect
45
+ end
46
+ end
47
+ end
48
+
49
+ end; end; end
data/lib/net/ssh/test.rb CHANGED
@@ -50,7 +50,7 @@ module Net; module SSH
50
50
  # If a block is given, yields the script for the test socket (#socket).
51
51
  # Otherwise, simply returns the socket's script. See Net::SSH::Test::Script.
52
52
  def story
53
- yield socket.script if block_given?
53
+ Net::SSH::Test::Extensions::IO.with_test_extension { yield socket.script if block_given? }
54
54
  return socket.script
55
55
  end
56
56
 
@@ -81,7 +81,7 @@ module Net; module SSH
81
81
  # the block passed to this assertion.
82
82
  def assert_scripted
83
83
  raise "there is no script to be processed" if socket.script.events.empty?
84
- yield
84
+ Net::SSH::Test::Extensions::IO.with_test_extension { yield }
85
85
  assert socket.script.events.empty?, "there should not be any remaining scripted events, but there are still #{socket.script.events.length} pending"
86
86
  end
87
87
  end
@@ -113,6 +113,22 @@ module Net; module SSH; module Test
113
113
  base.extend(ClassMethods)
114
114
  end
115
115
 
116
+ @extension_enabled = false
117
+
118
+ def self.with_test_extension(&block)
119
+ orig_value = @extension_enabled
120
+ @extension_enabled = true
121
+ begin
122
+ yield
123
+ ensure
124
+ @extension_enabled = orig_value
125
+ end
126
+ end
127
+
128
+ def self.extension_enabled?
129
+ @extension_enabled
130
+ end
131
+
116
132
  module ClassMethods
117
133
  def self.extended(obj) #:nodoc:
118
134
  class <<obj
@@ -125,6 +141,7 @@ module Net; module SSH; module Test
125
141
  # writers, and errors arrays are either nil, or contain only objects
126
142
  # that mix in Net::SSH::Test::Extensions::BufferedIo.
127
143
  def select_for_test(readers=nil, writers=nil, errors=nil, wait=nil)
144
+ return select_for_real(readers, writers, errors, wait) unless Net::SSH::Test::Extensions::IO.extension_enabled?
128
145
  ready_readers = Array(readers).select { |r| r.select_for_read? }
129
146
  ready_writers = Array(writers).select { |r| r.select_for_write? }
130
147
  ready_errors = Array(errors).select { |r| r.select_for_error? }
@@ -12,12 +12,10 @@ module Net::SSH::Transport
12
12
  @counter_len = orig.block_size
13
13
  orig.encrypt
14
14
  orig.padding = 0
15
- }
16
-
17
- class <<orig
18
- alias :_update :update
19
- private :_update
20
- undef :update
15
+
16
+ singleton_class.send(:alias_method, :_update, :update)
17
+ singleton_class.send(:private, :_update)
18
+ singleton_class.send(:undef_method, :update)
21
19
 
22
20
  def iv
23
21
  @counter
@@ -73,13 +71,12 @@ module Net::SSH::Transport
73
71
  s
74
72
  end
75
73
 
76
- private
77
-
78
74
  def xor!(s1, s2)
79
75
  s = []
80
76
  s1.unpack('Q*').zip(s2.unpack('Q*')) {|a,b| s.push(a^b) }
81
77
  s.pack('Q*')
82
78
  end
79
+ singleton_class.send(:private, :xor!)
83
80
 
84
81
  def increment_counter!
85
82
  c = @counter_len
@@ -89,7 +86,8 @@ module Net::SSH::Transport
89
86
  end
90
87
  end
91
88
  end
92
- end
89
+ singleton_class.send(:private, :increment_counter!)
90
+ }
93
91
  end
94
92
  end
95
93
  end
@@ -53,9 +53,9 @@ module Net; module SSH
53
53
  # The tiny component of this version of the Net::SSH library
54
54
  TINY = 0
55
55
 
56
- # The prerelease component of this version of the Net::SSH library
56
+ # The prerelease component of this version of the Net::SSH library
57
57
  # nil allowed
58
- PRE = "beta3"
58
+ PRE = "beta4"
59
59
 
60
60
  # The current version of the Net::SSH library as a Version instance
61
61
  CURRENT = new(*[MAJOR, MINOR, TINY, PRE].compact)
data/net-ssh.gemspec CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
22
22
  "LICENSE.txt",
23
23
  "README.rdoc"
24
24
  ]
25
-
25
+
26
26
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
27
27
  spec.bindir = "exe"
28
28
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
31
31
  unless ENV['NET_SSH_NO_RBNACL']
32
32
  spec.add_development_dependency("rbnacl-libsodium", "~> 1.0.10")
33
33
  spec.add_development_dependency("rbnacl", "~> 3.4.0")
34
- spec.add_development_dependency("bcrypt_pbkdf", "~> 1.0.0.alpha1") unless RUBY_PLATFORM == "java"
34
+ spec.add_development_dependency("bcrypt_pbkdf", "~> 1.0.0") unless RUBY_PLATFORM == "java"
35
35
  end
36
36
 
37
37
  spec.add_development_dependency "bundler", "~> 1.11"
@@ -39,7 +39,6 @@ Gem::Specification.new do |spec|
39
39
  spec.add_development_dependency "minitest", "~> 5.0"
40
40
  spec.add_development_dependency "rubocop", "~> 0.39.0"
41
41
  spec.add_development_dependency "mocha", ">= 1.1.0"
42
- spec.add_development_dependency("byebug") if RUBY_ENGINE == "ruby"
43
42
 
44
- spec.add_dependency('jruby-pageant', '>= 1.1.1') if RUBY_PLATFORM == 'jruby'
43
+ spec.add_dependency('jruby-pageant', '>= 1.1.1') if RUBY_ENGINE == 'jruby'
45
44
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: net-ssh
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0.beta3
4
+ version: 4.0.0.beta4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jamis Buck
@@ -31,7 +31,7 @@ cert_chain:
31
31
  s/ZUKye79ELwFYKJOhjW5g725OL3hy+llhEleytwKRwgXFQBPTC4f5UkdxZVVWGH
32
32
  e2C9M1m/2odPZo8h
33
33
  -----END CERTIFICATE-----
34
- date: 2016-08-14 00:00:00.000000000 Z
34
+ date: 2016-11-25 00:00:00.000000000 Z
35
35
  dependencies:
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rbnacl-libsodium
@@ -67,14 +67,14 @@ dependencies:
67
67
  requirements:
68
68
  - - "~>"
69
69
  - !ruby/object:Gem::Version
70
- version: 1.0.0.alpha1
70
+ version: 1.0.0
71
71
  type: :development
72
72
  prerelease: false
73
73
  version_requirements: !ruby/object:Gem::Requirement
74
74
  requirements:
75
75
  - - "~>"
76
76
  - !ruby/object:Gem::Version
77
- version: 1.0.0.alpha1
77
+ version: 1.0.0
78
78
  - !ruby/object:Gem::Dependency
79
79
  name: bundler
80
80
  requirement: !ruby/object:Gem::Requirement
@@ -145,20 +145,6 @@ dependencies:
145
145
  - - ">="
146
146
  - !ruby/object:Gem::Version
147
147
  version: 1.1.0
148
- - !ruby/object:Gem::Dependency
149
- name: byebug
150
- requirement: !ruby/object:Gem::Requirement
151
- requirements:
152
- - - ">="
153
- - !ruby/object:Gem::Version
154
- version: '0'
155
- type: :development
156
- prerelease: false
157
- version_requirements: !ruby/object:Gem::Requirement
158
- requirements:
159
- - - ">="
160
- - !ruby/object:Gem::Version
161
- version: '0'
162
148
  description: 'Net::SSH: a pure-Ruby implementation of the SSH2 client protocol. It
163
149
  allows you to write programs that invoke and interact with processes on remote servers,
164
150
  via SSH2.'
@@ -178,6 +164,7 @@ files:
178
164
  - Gemfile
179
165
  - Gemfile.norbnacl
180
166
  - Gemfile.norbnacl.lock
167
+ - ISSUE_TEMPLATE.md
181
168
  - LICENSE.txt
182
169
  - Manifest
183
170
  - README.rdoc
@@ -186,8 +173,6 @@ files:
186
173
  - appveyor.yml
187
174
  - lib/net/ssh.rb
188
175
  - lib/net/ssh/authentication/agent.rb
189
- - lib/net/ssh/authentication/agent/java_pageant.rb
190
- - lib/net/ssh/authentication/agent/socket.rb
191
176
  - lib/net/ssh/authentication/constants.rb
192
177
  - lib/net/ssh/authentication/ed25519.rb
193
178
  - lib/net/ssh/authentication/ed25519_loader.rb
@@ -218,6 +203,7 @@ files:
218
203
  - lib/net/ssh/proxy/command.rb
219
204
  - lib/net/ssh/proxy/errors.rb
220
205
  - lib/net/ssh/proxy/http.rb
206
+ - lib/net/ssh/proxy/https.rb
221
207
  - lib/net/ssh/proxy/socks4.rb
222
208
  - lib/net/ssh/proxy/socks5.rb
223
209
  - lib/net/ssh/ruby_compat.rb
@@ -291,8 +277,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
291
277
  version: 1.3.1
292
278
  requirements: []
293
279
  rubyforge_project:
294
- rubygems_version: 2.4.6
280
+ rubygems_version: 2.5.1
295
281
  signing_key:
296
282
  specification_version: 4
297
283
  summary: 'Net::SSH: a pure-Ruby implementation of the SSH2 client protocol.'
298
284
  test_files: []
285
+ has_rdoc:
metadata.gz.sig CHANGED
Binary file
@@ -1,85 +0,0 @@
1
- require 'jruby_pageant'
2
-
3
- module Net; module SSH; module Authentication
4
-
5
- # This class implements an agent for JRuby + Pageant.
6
- #
7
- # Written by Artūras Šlajus <arturas.slajus@gmail.com>
8
- class Agent
9
- include Loggable
10
- include JRubyPageant
11
-
12
- # A simple module for extending keys, to allow blobs and comments to be
13
- # specified for them.
14
- module Key
15
- # :blob is used by OpenSSL::PKey::RSA#to_blob
16
- attr_accessor :java_blob
17
- attr_accessor :comment
18
- end
19
-
20
- # Instantiates a new agent object, connects to a running SSH agent,
21
- # negotiates the agent protocol version, and returns the agent object.
22
- def self.connect(logger=nil, agent_socket_factory)
23
- agent = new(logger)
24
- agent.connect!
25
- agent
26
- end
27
-
28
- # Creates a new Agent object, using the optional logger instance to
29
- # report status.
30
- def initialize(logger=nil)
31
- self.logger = logger
32
- end
33
-
34
- # Connect to the agent process using the socket factory and socket name
35
- # given by the attribute writers. If the agent on the other end of the
36
- # socket reports that it is an SSH2-compatible agent, this will fail
37
- # (it only supports the ssh-agent distributed by OpenSSH).
38
- def connect!
39
- debug { "connecting to Pageant ssh-agent (via java connector)" }
40
- @agent_proxy = JRubyPageant.create
41
- unless @agent_proxy.is_running
42
- raise AgentNotAvailable, "Pageant is not running!"
43
- end
44
- debug { "connection to Pageant ssh-agent (via java connector) succeeded" }
45
- rescue AgentProxyException => e
46
- error { "could not connect to Pageant ssh-agent (via java connector)" }
47
- raise AgentNotAvailable, e.message, e.backtrace
48
- end
49
-
50
- # Return an array of all identities (public keys) known to the agent.
51
- # Each key returned is augmented with a +comment+ property which is set
52
- # to the comment returned by the agent for that key.
53
- def identities
54
- debug { "getting identities from Pageant" }
55
- @agent_proxy.get_identities.map do |identity|
56
- blob = identity.get_blob
57
- key = Buffer.new(String.from_java_bytes(blob)).read_key
58
- key.extend(Key)
59
- key.java_blob = blob
60
- key.comment = String.from_java_bytes(identity.get_comment)
61
- key
62
- end
63
- rescue AgentProxyException => e
64
- raise AgentError, "Cannot get identities: #{e.message}", e.backtrace
65
- end
66
-
67
- # Simulate agent close. This agent reference is no longer able to
68
- # query the agent.
69
- def close
70
- @agent_proxy = nil
71
- end
72
-
73
- # Using the agent and the given public key, sign the given data. The
74
- # signature is returned in SSH2 format.
75
- def sign(key, data)
76
- signed = @agent_proxy.sign(key.java_blob, data.to_java_bytes)
77
- String.from_java_bytes(signed)
78
- rescue AgentProxyException => e
79
- raise AgentError,
80
- "agent could not sign data with requested identity: #{e.message}",
81
- e.backtrace
82
- end
83
- end
84
-
85
- end; end; end
@@ -1,178 +0,0 @@
1
- require 'net/ssh/transport/server_version'
2
-
3
- # Only load pageant on Windows
4
- if Net::SSH::Authentication::PLATFORM == :win32
5
- require 'net/ssh/authentication/pageant'
6
- end
7
-
8
- module Net; module SSH; module Authentication
9
-
10
- # This class implements a simple client for the ssh-agent protocol. It
11
- # does not implement any specific protocol, but instead copies the
12
- # behavior of the ssh-agent functions in the OpenSSH library (3.8).
13
- #
14
- # This means that although it behaves like a SSH1 client, it also has
15
- # some SSH2 functionality (like signing data).
16
- class Agent
17
- include Loggable
18
-
19
- # A simple module for extending keys, to allow comments to be specified
20
- # for them.
21
- module Comment
22
- attr_accessor :comment
23
- end
24
-
25
- SSH2_AGENT_REQUEST_VERSION = 1
26
- SSH2_AGENT_REQUEST_IDENTITIES = 11
27
- SSH2_AGENT_IDENTITIES_ANSWER = 12
28
- SSH2_AGENT_SIGN_REQUEST = 13
29
- SSH2_AGENT_SIGN_RESPONSE = 14
30
- SSH2_AGENT_FAILURE = 30
31
- SSH2_AGENT_VERSION_RESPONSE = 103
32
-
33
- SSH_COM_AGENT2_FAILURE = 102
34
-
35
- SSH_AGENT_REQUEST_RSA_IDENTITIES = 1
36
- SSH_AGENT_RSA_IDENTITIES_ANSWER1 = 2
37
- SSH_AGENT_RSA_IDENTITIES_ANSWER2 = 5
38
- SSH_AGENT_FAILURE = 5
39
-
40
- # The underlying socket being used to communicate with the SSH agent.
41
- attr_reader :socket
42
-
43
- # Instantiates a new agent object, connects to a running SSH agent,
44
- # negotiates the agent protocol version, and returns the agent object.
45
- def self.connect(logger=nil, agent_socket_factory = nil)
46
- agent = new(logger)
47
- agent.connect!(agent_socket_factory)
48
- agent.negotiate!
49
- agent
50
- end
51
-
52
- # Creates a new Agent object, using the optional logger instance to
53
- # report status.
54
- def initialize(logger=nil)
55
- self.logger = logger
56
- end
57
-
58
- # Connect to the agent process using the socket factory and socket name
59
- # given by the attribute writers. If the agent on the other end of the
60
- # socket reports that it is an SSH2-compatible agent, this will fail
61
- # (it only supports the ssh-agent distributed by OpenSSH).
62
- def connect!(agent_socket_factory = nil)
63
- begin
64
- debug { "connecting to ssh-agent" }
65
- @socket = agent_socket_factory.nil? ? socket_class.open(ENV['SSH_AUTH_SOCK']) : agent_socket_factory.call
66
- rescue
67
- error { "could not connect to ssh-agent" }
68
- raise AgentNotAvailable, $!.message
69
- end
70
- end
71
-
72
- # Attempts to negotiate the SSH agent protocol version. Raises an error
73
- # if the version could not be negotiated successfully.
74
- def negotiate!
75
- # determine what type of agent we're communicating with
76
- type, body = send_and_wait(SSH2_AGENT_REQUEST_VERSION, :string, Transport::ServerVersion::PROTO_VERSION)
77
-
78
- if type == SSH2_AGENT_VERSION_RESPONSE
79
- raise AgentNotAvailable, "SSH2 agents are not yet supported"
80
- elsif type == SSH2_AGENT_FAILURE
81
- debug { "Unexpected response type==#{type}, this will be ignored" }
82
- elsif type != SSH_AGENT_RSA_IDENTITIES_ANSWER1 && type != SSH_AGENT_RSA_IDENTITIES_ANSWER2
83
- raise AgentNotAvailable, "unknown response from agent: #{type}, #{body.to_s.inspect}"
84
- end
85
- end
86
-
87
- # Return an array of all identities (public keys) known to the agent.
88
- # Each key returned is augmented with a +comment+ property which is set
89
- # to the comment returned by the agent for that key.
90
- def identities
91
- type, body = send_and_wait(SSH2_AGENT_REQUEST_IDENTITIES)
92
- raise AgentError, "could not get identity count" if agent_failed(type)
93
- raise AgentError, "bad authentication reply: #{type}" if type != SSH2_AGENT_IDENTITIES_ANSWER
94
-
95
- identities = []
96
- body.read_long.times do
97
- key_str = body.read_string
98
- comment_str = body.read_string
99
- begin
100
- key = Buffer.new(key_str).read_key
101
- key.extend(Comment)
102
- key.comment = comment_str
103
- identities.push key
104
- rescue NotImplementedError => e
105
- error { "ignoring unimplemented key:#{e.message} #{comment_str}" }
106
- end
107
- end
108
-
109
- return identities
110
- end
111
-
112
- # Closes this socket. This agent reference is no longer able to
113
- # query the agent.
114
- def close
115
- @socket.close
116
- end
117
-
118
- # Using the agent and the given public key, sign the given data. The
119
- # signature is returned in SSH2 format.
120
- def sign(key, data)
121
- type, reply = send_and_wait(SSH2_AGENT_SIGN_REQUEST, :string, Buffer.from(:key, key), :string, data, :long, 0)
122
-
123
- if agent_failed(type)
124
- raise AgentError, "agent could not sign data with requested identity"
125
- elsif type != SSH2_AGENT_SIGN_RESPONSE
126
- raise AgentError, "bad authentication response #{type}"
127
- end
128
-
129
- return reply.read_string
130
- end
131
-
132
- private
133
-
134
- # Returns the agent socket factory to use.
135
- def socket_class
136
- if Net::SSH::Authentication::PLATFORM == :win32
137
- Pageant::Socket
138
- else
139
- UNIXSocket
140
- end
141
- end
142
-
143
- # Send a new packet of the given type, with the associated data.
144
- def send_packet(type, *args)
145
- buffer = Buffer.from(*args)
146
- data = [buffer.length + 1, type.to_i, buffer.to_s].pack("NCA*")
147
- debug { "sending agent request #{type} len #{buffer.length}" }
148
- @socket.send data, 0
149
- end
150
-
151
- # Read the next packet from the agent. This will return a two-part
152
- # tuple consisting of the packet type, and the packet's body (which
153
- # is returned as a Net::SSH::Buffer).
154
- def read_packet
155
- buffer = Net::SSH::Buffer.new(@socket.read(4))
156
- buffer.append(@socket.read(buffer.read_long))
157
- type = buffer.read_byte
158
- debug { "received agent packet #{type} len #{buffer.length-4}" }
159
- return type, buffer
160
- end
161
-
162
- # Send the given packet and return the subsequent reply from the agent.
163
- # (See #send_packet and #read_packet).
164
- def send_and_wait(type, *args)
165
- send_packet(type, *args)
166
- read_packet
167
- end
168
-
169
- # Returns +true+ if the parameter indicates a "failure" response from
170
- # the agent, and +false+ otherwise.
171
- def agent_failed(type)
172
- type == SSH_AGENT_FAILURE ||
173
- type == SSH2_AGENT_FAILURE ||
174
- type == SSH_COM_AGENT2_FAILURE
175
- end
176
- end
177
-
178
- end; end; end