net-ssh 4.0.0.rc1 → 4.0.0.rc2

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.
@@ -7,25 +7,26 @@ rvm:
7
7
  - 2.1
8
8
  - 2.2
9
9
  - 2.3.0
10
- - jruby-9.1.2.0
11
- - rbx-3.25
10
+ - 2.4.0-rc1
11
+ - jruby-9.1.6.0
12
+ - rbx-3.69
12
13
  - ruby-head
13
14
  env:
14
15
  NET_SSH_RUN_INTEGRATION_TESTS=1
15
16
 
16
17
  matrix:
17
18
  exclude:
18
- - rvm: rbx-3.25
19
- - rvm: jruby-9.1.2.0
19
+ - rvm: rbx-3.69
20
+ - rvm: jruby-9.1.6.0
20
21
  include:
21
- - rvm: rbx-3.25
22
+ - rvm: rbx-3.69
22
23
  env: NET_SSH_RUN_INTEGRATION_TESTS=
23
- - rvm: jruby-9.1.2.0
24
+ - rvm: jruby-9.1.6.0
24
25
  env: JRUBY_OPTS='--client -J-XX:+TieredCompilation -J-XX:TieredStopAtLevel=1 -Xcext.enabled=false -J-Xss2m -Xcompile.invokedynamic=false' NET_SSH_RUN_INTEGRATION_TESTS=
25
26
  fast_finish: true
26
27
  allow_failures:
27
- - rvm: rbx-3.25
28
- - rvm: jruby-9.1.2.0
28
+ - rvm: rbx-3.69
29
+ - rvm: jruby-9.1.6.0
29
30
  - rvm: ruby-head
30
31
 
31
32
  install:
@@ -1,3 +1,9 @@
1
+ === 4.0.0.rc2
2
+
3
+ * Fixed OpenSSL 2.0/Ruby 2.4.0 warnings [Miklós Fazekas, #468]
4
+ * Added ssh-ed25519 to KnownHosts:SUPPORTED_TYPE [detatka-kuzlatka-otevrete, Miklós Fazekas, #459]
5
+ * Allow nil for :passhrase and passing in nil option is now a depreaction warning [Miklós Fazekas, #465]
6
+
1
7
  === 4.0.0.rc1
2
8
 
3
9
  * Allow :password to be nil for capistrano v2 compatibility [Will Bryant, #357]
data/Gemfile CHANGED
@@ -3,10 +3,11 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in mygem.gemspec
4
4
  gemspec
5
5
 
6
- unless Gem.win_platform? || RUBY_PLATFORM == "java"
6
+ if !Gem.win_platform? && RUBY_ENGINE == "mri"
7
7
  gem 'byebug', group: [:development, :test]
8
8
  end
9
9
 
10
- gem 'simplecov', require: false, group: :test
11
-
12
- gem 'codecov', require: false, group: :test if ENV["CI"]
10
+ if ENV["CI"]
11
+ gem 'codecov', require: false, group: :test
12
+ gem 'simplecov', require: false, group: :test
13
+ end
@@ -4,7 +4,7 @@ ENV['NET_SSH_NO_RBNACL'] = 'true'
4
4
  # Specify your gem's dependencies in mygem.gemspec
5
5
  gemspec
6
6
 
7
- unless Gem.win_platform?
7
+ if ENV["CI"] && !Gem.win_platform?
8
8
  gem 'simplecov', require: false, group: :test
9
- gem 'codecov', require: false, group: :test if ENV["CI"]
9
+ gem 'codecov', require: false, group: :test
10
10
  end
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- net-ssh (4.0.0.beta3)
4
+ net-ssh (4.0.0.rc1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -38,4 +38,4 @@ DEPENDENCIES
38
38
  rubocop (~> 0.39.0)
39
39
 
40
40
  BUNDLED WITH
41
- 1.13.5
41
+ 1.13.6
@@ -1,6 +1,7 @@
1
1
  {<img src="https://badge.fury.io/rb/net-ssh.svg" alt="Gem Version" />}[https://badge.fury.io/rb/net-ssh]
2
2
  {<img src="https://badges.gitter.im/net-ssh/net-ssh.svg" alt="Join the chat at https://gitter.im/net-ssh/net-ssh">}[https://gitter.im/net-ssh/net-ssh?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge]
3
3
  {<img src="https://travis-ci.org/net-ssh/net-ssh.svg?branch=master" alt="Build Status" />}[https://travis-ci.org/net-ssh/net-ssh]
4
+ {<img src="https://codecov.io/gh/net-ssh/net-ssh/branch/master/graph/badge.svg" alt="Coverage status" />}[https://codecov.io/gh/net-ssh/net-ssh]
4
5
 
5
6
  = Net::SSH 4.x
6
7
 
@@ -129,6 +130,19 @@ To run integration tests see test/integration/README.txt
129
130
 
130
131
  rake build
131
132
 
133
+ === GEM SIGNING (for maintainers)
134
+
135
+ If you have the net-ssh private signing key, you will be able to create signed release builds. Make sure the private key path matches the `signing_key` path set in `net-ssh.gemspec` and tell rake to sign the gem by setting the `NET_SSH_BUILDGEM_SIGNED` flag:
136
+
137
+ NET_SSH_BUILDGEM_SIGNED=true rake build
138
+
139
+ For time to time, the public certificate associated to the private key needs to be renewed. You can do this with the following command:
140
+
141
+ gem cert --build netssh@solutious.com --private-key path/2/net-ssh-private_key.pem
142
+ mv gem-public_cert.pem net-ssh-public_cert.pem
143
+ gem cert --add net-ssh-public_cert.pem
144
+
145
+
132
146
  == LICENSE:
133
147
 
134
148
  (The MIT License)
data/Rakefile CHANGED
@@ -22,14 +22,14 @@ Rake::Task[:release].enhance [:check_NET_SSH_BUILDGEM_SIGNED]
22
22
  Rake::Task[:release].prerequisites.unshift(:check_NET_SSH_BUILDGEM_SIGNED)
23
23
 
24
24
 
25
- task :default => ["build"]
25
+ task default: ["build"]
26
26
  CLEAN.include [ 'pkg', 'rdoc' ]
27
27
  name = "net-ssh"
28
28
 
29
29
  require_relative "lib/net/ssh/version"
30
30
  version = Net::SSH::Version::CURRENT
31
31
 
32
- extra_files = %w[LICENSE.txt THANKS.txt CHANGES.txt ]
32
+ extra_files = %w[LICENSE.txt THANKS.txt CHANGES.txt]
33
33
  RDoc::Task.new do |rdoc|
34
34
  rdoc.rdoc_dir = "rdoc"
35
35
  rdoc.title = "#{name} #{version}"
@@ -41,21 +41,21 @@ module Net
41
41
  #
42
42
  # == X == "execute a command and capture the output"
43
43
  #
44
- # Net::SSH.start("host", "user", :password => "password") do |ssh|
44
+ # Net::SSH.start("host", "user", password: "password") do |ssh|
45
45
  # result = ssh.exec!("ls -l")
46
46
  # puts result
47
47
  # end
48
48
  #
49
49
  # == X == "forward connections on a local port to a remote host"
50
50
  #
51
- # Net::SSH.start("host", "user", :password => "password") do |ssh|
51
+ # Net::SSH.start("host", "user", password: "password") do |ssh|
52
52
  # ssh.forward.local(1234, "www.google.com", 80)
53
53
  # ssh.loop { true }
54
54
  # end
55
55
  #
56
56
  # == X == "forward connections on a remote port to the local host"
57
57
  #
58
- # Net::SSH.start("host", "user", :password => "password") do |ssh|
58
+ # Net::SSH.start("host", "user", password: "password") do |ssh|
59
59
  # ssh.forward.remote(80, "www.google.com", 1234)
60
60
  # ssh.loop { true }
61
61
  # end
@@ -154,8 +154,8 @@ module Net
154
154
  # * :max_win_size => maximum size we tell the other side that is supported for
155
155
  # the window.
156
156
  # * :non_interactive => set to true if your app is non interactive and prefers
157
- # authentication failure vs password prompt. Non-interactive applications
158
- # should set it to true to prefer failing a password/etc auth methods vs.
157
+ # authentication failure vs password prompt. Non-interactive applications
158
+ # should set it to true to prefer failing a password/etc auth methods vs.
159
159
  # asking for password.
160
160
  # * :paranoid => either false, true, :very, or :secure specifying how
161
161
  # strict host-key verification should be (in increasing order here).
@@ -208,13 +208,7 @@ module Net
208
208
  end
209
209
 
210
210
  assign_defaults(options)
211
-
212
- options.delete(:password) if options.key?(:password) && options[:password].nil?
213
-
214
- if options.values.include? nil
215
- nil_options = options.keys.select { |k| options[k].nil? }
216
- raise ArgumentError, "Value(s) have been set to nil: #{nil_options.join(', ')}"
217
- end
211
+ _sanitize_options(options)
218
212
 
219
213
  options[:user] = user if user
220
214
  options = configuration_for(host, options.fetch(:config, true)).merge(options)
@@ -226,7 +220,7 @@ module Net
226
220
 
227
221
  if options[:verbose]
228
222
  options[:logger].level = case options[:verbose]
229
- when Fixnum then options[:verbose]
223
+ when Integer then options[:verbose]
230
224
  when :debug then Logger::DEBUG
231
225
  when :info then Logger::INFO
232
226
  when :warn then Logger::WARN
@@ -283,6 +277,19 @@ module Net
283
277
  end
284
278
 
285
279
  options[:password_prompt] ||= Prompt.default(options)
280
+
281
+ [:password, :passphrase].each do |key|
282
+ options.delete(key) if options.key?(key) && options[key].nil?
283
+ end
284
+ end
285
+
286
+ def self._sanitize_options(options)
287
+ invalid_option_values = [nil,[nil]]
288
+ unless (options.values & invalid_option_values).empty?
289
+ nil_options = options.select { |_k,v| invalid_option_values.include?(v) }.map(&:first)
290
+ Kernel.warn "#{caller_locations(2, 1)[0]}: Passing nil, or [nil] to Net::SSH.start is deprecated for keys: #{nil_options.join(', ')}"
291
+ end
286
292
  end
293
+ private_class_method :_sanitize_options
287
294
  end
288
295
  end
@@ -108,7 +108,7 @@ module Net
108
108
  user_identities.delete(corresponding_user_identity) if corresponding_user_identity
109
109
 
110
110
  if !options[:keys_only] || corresponding_user_identity
111
- known_identities[key] = { :from => :agent }
111
+ known_identities[key] = { from: :agent }
112
112
  yield key
113
113
  end
114
114
  end
@@ -140,7 +140,7 @@ module Net
140
140
  if info[:key].nil? && info[:from] == :file
141
141
  begin
142
142
  info[:key] = KeyFactory.load_private_key(info[:file], options[:passphrase], !options[:non_interactive])
143
- rescue Exception, OpenSSL::OpenSSLError => e
143
+ rescue OpenSSL::OpenSSLError, Exception => e
144
144
  raise KeyManagerError, "the given identity is known, but the private key could not be loaded: #{e.class} (#{e.message})"
145
145
  end
146
146
  end
@@ -208,7 +208,7 @@ module Net
208
208
  # Prepared identities from user key_data, preserving their order and sources.
209
209
  def prepare_identities_from_data
210
210
  key_data.map do |data|
211
- { :load_from => :data, :data => data }
211
+ { load_from: :data, data: data }
212
212
  end
213
213
  end
214
214
 
@@ -219,15 +219,15 @@ module Net
219
219
  case identity[:load_from]
220
220
  when :pubkey_file
221
221
  key = KeyFactory.load_public_key(identity[:pubkey_file])
222
- { :public_key => key, :from => :file, :file => identity[:privkey_file] }
222
+ { public_key: key, from: :file, file: identity[:privkey_file] }
223
223
  when :privkey_file
224
224
  private_key = KeyFactory.load_private_key(identity[:privkey_file], options[:passphrase], ask_passphrase, options[:password_prompt])
225
225
  key = private_key.send(:public_key)
226
- { :public_key => key, :from => :file, :file => identity[:privkey_file], :key => private_key }
226
+ { public_key: key, from: :file, file: identity[:privkey_file], key: private_key }
227
227
  when :data
228
228
  private_key = KeyFactory.load_data_private_key(identity[:data], options[:passphrase], ask_passphrase, "<key in memory>", options[:password_prompt])
229
229
  key = private_key.send(:public_key)
230
- { :public_key => key, :from => :key_data, :data => identity[:data], :key => private_key }
230
+ { public_key: key, from: :key_data, data: identity[:data], key: private_key }
231
231
  else
232
232
  identity
233
233
  end
@@ -250,12 +250,15 @@ module Net; module SSH; module Authentication
250
250
  psd_information = malloc_ptr(Win::SECURITY_DESCRIPTOR.size)
251
251
  raise_error_if_zero(
252
252
  Win.InitializeSecurityDescriptor(psd_information,
253
- Win::REVISION))
253
+ Win::REVISION)
254
+ )
254
255
  raise_error_if_zero(
255
256
  Win.SetSecurityDescriptorOwner(psd_information, get_sid_ptr(user),
256
- 0))
257
+ 0)
258
+ )
257
259
  raise_error_if_zero(
258
- Win.IsValidSecurityDescriptor(psd_information))
260
+ Win.IsValidSecurityDescriptor(psd_information)
261
+ )
259
262
 
260
263
  sa = Win::SECURITY_ATTRIBUTES.new(to_struct_ptr(malloc_ptr(Win::SECURITY_ATTRIBUTES.size)))
261
264
  sa.nLength = Win::SECURITY_ATTRIBUTES.size
@@ -337,7 +340,8 @@ module Net; module SSH; module Authentication
337
340
 
338
341
  raise_error_if_zero(
339
342
  Win.OpenProcessToken(process_handle, desired_access,
340
- ptoken_handle))
343
+ ptoken_handle)
344
+ )
341
345
  token_handle = ptr_to_handle(ptoken_handle)
342
346
  return token_handle
343
347
  end
@@ -362,7 +366,8 @@ module Net; module SSH; module Authentication
362
366
  token_information_class,
363
367
  ptoken_information,
364
368
  ptoken_information.size,
365
- preturn_length))
369
+ preturn_length)
370
+ )
366
371
 
367
372
  return to_token_user(ptoken_information)
368
373
  end
@@ -430,8 +435,7 @@ module Net; module SSH; module Authentication
430
435
  @output_buffer.read(n)
431
436
  end
432
437
 
433
- def close
434
- end
438
+ def close; end
435
439
 
436
440
  # Packages the given query string and sends it to the pageant
437
441
  # process via the Windows messaging subsystem. The result is
@@ -162,7 +162,7 @@ module Net; module SSH
162
162
  index = @content.index(pattern, @position) or return nil
163
163
  length = case pattern
164
164
  when String then pattern.length
165
- when Fixnum then 1
165
+ when Integer then 1
166
166
  when Regexp then $&.length
167
167
  end
168
168
  index && read(index+length)
@@ -248,16 +248,29 @@ module Net; module SSH
248
248
  case type
249
249
  when /^ssh-dss(-cert-v01@openssh\.com)?$/
250
250
  key = OpenSSL::PKey::DSA.new
251
- key.p = read_bignum
252
- key.q = read_bignum
253
- key.g = read_bignum
254
- key.pub_key = read_bignum
251
+ if key.respond_to?(:set_pqg)
252
+ key.set_pqg(read_bignum, read_bignum, read_bignum)
253
+ else
254
+ key.p = read_bignum
255
+ key.q = read_bignum
256
+ key.g = read_bignum
257
+ end
258
+ if key.respond_to?(:set_key)
259
+ key.set_key(read_bignum, nil)
260
+ else
261
+ key.pub_key = read_bignum
262
+ end
255
263
 
256
264
  when /^ssh-rsa(-cert-v01@openssh\.com)?$/
257
265
  key = OpenSSL::PKey::RSA.new
258
- key.e = read_bignum
259
- key.n = read_bignum
260
-
266
+ if key.respond_to?(:set_key)
267
+ e = read_bignum
268
+ n = read_bignum
269
+ key.set_key(n, e, nil)
270
+ else
271
+ key.e = read_bignum
272
+ key.n = read_bignum
273
+ end
261
274
  when /^ssh-ed25519$/
262
275
  Net::SSH::Authentication::ED25519Loader.raiseUnlessLoaded("unsupported key type `#{type}'")
263
276
  key = Net::SSH::Authentication::ED25519::PubKey.read_keyblob(self)
@@ -144,7 +144,7 @@ module Net; module SSH
144
144
  def translate(settings)
145
145
  auth_methods = default_auth_methods.clone
146
146
  (auth_methods << 'challenge-response').uniq!
147
- ret = settings.inject({:auth_methods=>auth_methods}) do |hash, (key, value)|
147
+ ret = settings.inject({auth_methods: auth_methods}) do |hash, (key, value)|
148
148
  case key
149
149
  when 'bindaddress' then
150
150
  hash[:bind_address] = value
@@ -280,7 +280,7 @@ module Net; module SSH
280
280
  else size.to_i
281
281
  end
282
282
  end
283
-
283
+
284
284
  def merge_challenge_response_with_keyboard_interactive(hash)
285
285
  if hash[:auth_methods].include?('challenge-response')
286
286
  hash[:auth_methods].delete('challenge-response')
@@ -189,12 +189,12 @@ module Net; module SSH; module Connection
189
189
  end
190
190
 
191
191
  # A hash of the valid PTY options (see #request_pty).
192
- VALID_PTY_OPTIONS = { :term => "xterm",
193
- :chars_wide => 80,
194
- :chars_high => 24,
195
- :pixels_wide => 640,
196
- :pixels_high => 480,
197
- :modes => {} }
192
+ VALID_PTY_OPTIONS = { term: "xterm",
193
+ chars_wide: 80,
194
+ chars_high: 24,
195
+ pixels_wide: 640,
196
+ pixels_high: 480,
197
+ modes: {} }
198
198
 
199
199
  # Requests that a pseudo-tty (or "pty") be made available for this channel.
200
200
  # This is useful when you want to invoke and interact with some kind of
@@ -68,14 +68,18 @@ module Net; module SSH; module Connection
68
68
 
69
69
  fired_sessions = {}
70
70
 
71
- readers.each do |reader|
72
- session = owners[reader]
73
- (fired_sessions[session] ||= {r: [],w: []})[:r] << reader
74
- end if readers
75
- writers.each do |writer|
76
- session = owners[writer]
77
- (fired_sessions[session] ||= {r: [],w: []})[:w] << writer
78
- end if writers
71
+ if readers
72
+ readers.each do |reader|
73
+ session = owners[reader]
74
+ (fired_sessions[session] ||= {r: [],w: []})[:r] << reader
75
+ end
76
+ end
77
+ if writers
78
+ writers.each do |writer|
79
+ session = owners[writer]
80
+ (fired_sessions[session] ||= {r: [],w: []})[:w] << writer
81
+ end
82
+ end
79
83
 
80
84
  fired_sessions.each do |s,rw|
81
85
  s.ev_do_handle_events(rw[:r],rw[:w])
@@ -78,8 +78,8 @@ module Net; module SSH; module Connection
78
78
  @on_global_request = {}
79
79
  @properties = (options[:properties] || {}).dup
80
80
 
81
- @max_pkt_size = (options.has_key?(:max_pkt_size) ? options[:max_pkt_size] : 0x8000)
82
- @max_win_size = (options.has_key?(:max_win_size) ? options[:max_win_size] : 0x20000)
81
+ @max_pkt_size = (options.key?(:max_pkt_size) ? options[:max_pkt_size] : 0x8000)
82
+ @max_win_size = (options.key?(:max_win_size) ? options[:max_win_size] : 0x20000)
83
83
 
84
84
  @keepalive = Keepalive.new(self)
85
85
 
@@ -5,14 +5,14 @@ module Net; module SSH
5
5
 
6
6
  # This exception is raised when authentication fails (whether it be
7
7
  # public key authentication, password authentication, or whatever).
8
- class AuthenticationFailed < Exception; end
8
+ class AuthenticationFailed < Net::SSH::Exception; end
9
9
 
10
10
  # This exception is raised when a connection attempt times out.
11
- class ConnectionTimeout < Exception; end
11
+ class ConnectionTimeout < Net::SSH::Exception; end
12
12
 
13
13
  # This exception is raised when the remote host has disconnected
14
14
  # unexpectedly.
15
- class Disconnect < Exception; end
15
+ class Disconnect < Net::SSH::Exception; end
16
16
 
17
17
  # This exception is raised when the remote host has disconnected/
18
18
  # timeouted unexpectedly.
@@ -23,14 +23,14 @@ module Net; module SSH
23
23
  # want to fail in such a way that the server knows it failed, you can
24
24
  # raise this exception in the handler and Net::SSH will translate that into
25
25
  # a "channel failure" message.
26
- class ChannelRequestFailed < Exception; end
26
+ class ChannelRequestFailed < Net::SSH::Exception; end
27
27
 
28
28
  # This is exception is primarily used internally, but if you have a channel
29
29
  # open handler (see Net::SSH::Connection::Session#on_open_channel) and you
30
30
  # want to fail in such a way that the server knows it failed, you can
31
31
  # raise this exception in the handler and Net::SSH will translate that into
32
32
  # a "channel open failed" message.
33
- class ChannelOpenFailed < Exception
33
+ class ChannelOpenFailed < Net::SSH::Exception
34
34
  attr_reader :code, :reason
35
35
 
36
36
  def initialize(code, reason)
@@ -42,7 +42,7 @@ module Net; module SSH
42
42
  # Base class for host key exceptions. When rescuing this exception, you can
43
43
  # inspect the key fingerprint and, if you want to proceed anyway, simply call
44
44
  # the remember_host! method on the exception, and then retry.
45
- class HostKeyError < Exception
45
+ class HostKeyError < Net::SSH::Exception
46
46
  # the callback to use when #remember_host! is called
47
47
  attr_writer :callback #:nodoc:
48
48