net-ssh 5.0.0.beta2 → 5.0.0.rc1
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.rubocop_todo.yml +6 -6
- data/CHANGES.txt +4 -1
- data/Manifest +4 -4
- data/lib/net/ssh.rb +6 -2
- data/lib/net/ssh/config.rb +26 -15
- data/lib/net/ssh/connection/channel.rb +10 -7
- data/lib/net/ssh/proxy/http.rb +2 -1
- data/lib/net/ssh/transport/session.rb +94 -73
- data/lib/net/ssh/verifiers/{strict.rb → accept_new.rb} +4 -4
- data/lib/net/ssh/verifiers/{lenient.rb → accept_new_or_local_tunnel.rb} +9 -9
- data/lib/net/ssh/verifiers/{secure.rb → always.rb} +9 -9
- data/lib/net/ssh/verifiers/never.rb +17 -0
- data/lib/net/ssh/version.rb +1 -1
- metadata +6 -6
- metadata.gz.sig +0 -0
- data/lib/net/ssh/verifiers/null.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bb3a015ee41b0d474fe7c702a00f8825674084df411eee8f617e6b6fa21cf81e
|
4
|
+
data.tar.gz: f75d9ca1f7b20f09f24c9622d6c72e206a6f20636c81a19c95c3a16a88b2742c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32546cfff9b3fa6e6b92b9fe7cd49a86dfe79c75936026681b12a5befcf3658ccd779d6e15496333185143c2236e2fb9dd3aa9435101fee0bc4048d16fd2057c
|
7
|
+
data.tar.gz: 98998932593dfded2649ca4bb0e4426d38b2ab38a7b4f2043c2a57850e42136f15d31c529f76055ecb62b5b63878801d2897219220e5acd4e0e19026036845e7
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/.rubocop_todo.yml
CHANGED
@@ -333,7 +333,7 @@ Style/BlockDelimiters:
|
|
333
333
|
- 'lib/net/ssh/proxy/command.rb'
|
334
334
|
- 'lib/net/ssh/transport/ctr.rb'
|
335
335
|
- 'test/test_buffer.rb'
|
336
|
-
- 'test/verifiers/
|
336
|
+
- 'test/verifiers/test_always.rb'
|
337
337
|
|
338
338
|
# Offense count: 8
|
339
339
|
# Cop supports --auto-correct.
|
@@ -554,7 +554,7 @@ Style/LineEndConcatenation:
|
|
554
554
|
- 'lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb'
|
555
555
|
- 'lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb'
|
556
556
|
- 'lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb'
|
557
|
-
- 'lib/net/ssh/verifiers/
|
557
|
+
- 'lib/net/ssh/verifiers/always.rb'
|
558
558
|
|
559
559
|
# Offense count: 12
|
560
560
|
# Cop supports --auto-correct.
|
@@ -611,7 +611,7 @@ Layout/MultilineOperationIndentation:
|
|
611
611
|
- 'lib/net/ssh/transport/algorithms.rb'
|
612
612
|
- 'lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb'
|
613
613
|
- 'lib/net/ssh/transport/state.rb'
|
614
|
-
- 'lib/net/ssh/verifiers/
|
614
|
+
- 'lib/net/ssh/verifiers/always.rb'
|
615
615
|
- 'test/authentication/methods/test_hostbased.rb'
|
616
616
|
- 'test/authentication/methods/test_publickey.rb'
|
617
617
|
|
@@ -736,7 +736,7 @@ Style/Proc:
|
|
736
736
|
- 'lib/net/ssh/connection/session.rb'
|
737
737
|
- 'lib/net/ssh/test/channel.rb'
|
738
738
|
- 'lib/net/ssh/transport/algorithms.rb'
|
739
|
-
- 'lib/net/ssh/verifiers/
|
739
|
+
- 'lib/net/ssh/verifiers/always.rb'
|
740
740
|
- 'test/authentication/methods/test_hostbased.rb'
|
741
741
|
- 'test/authentication/methods/test_publickey.rb'
|
742
742
|
- 'test/connection/test_channel.rb'
|
@@ -755,7 +755,7 @@ Style/RaiseArgs:
|
|
755
755
|
Style/RedundantBegin:
|
756
756
|
Exclude:
|
757
757
|
- 'lib/net/ssh/buffered_io.rb'
|
758
|
-
- 'lib/net/ssh/verifiers/
|
758
|
+
- 'lib/net/ssh/verifiers/accept_new.rb'
|
759
759
|
- 'test/manual/test_pageant.rb'
|
760
760
|
|
761
761
|
# Offense count: 1
|
@@ -825,7 +825,7 @@ Layout/SpaceAfterColon:
|
|
825
825
|
Exclude:
|
826
826
|
- 'lib/net/ssh/authentication/ed25519.rb'
|
827
827
|
- 'test/integration/test_ed25519_pkeys.rb'
|
828
|
-
- 'test/verifiers/
|
828
|
+
- 'test/verifiers/test_always.rb'
|
829
829
|
|
830
830
|
# Offense count: 254
|
831
831
|
# Cop supports --auto-correct.
|
data/CHANGES.txt
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
-
=== 5.0.0
|
1
|
+
=== 5.0.0.rc1
|
2
2
|
* Breaking change: ed25519 now requires ed25519 gem instead of RbNaCl gem [#563]
|
3
|
+
* Fix larger than 4GB file transfers [#599]
|
4
|
+
* Update HTTP proxy to version 1.1 [Connor Dunn, #597]
|
5
|
+
* Verify_host_key options rename (true, false, :very, :secure depreacted new equivalents are :never, :accept_new_or_local_tunnel :accept_new :always) [Jared Beck, #595]
|
3
6
|
|
4
7
|
=== 5.0.0.beta2
|
5
8
|
* Support for sha256 pubkey fingerprint [Tom Maher, #585]
|
data/Manifest
CHANGED
@@ -75,10 +75,10 @@ lib/net/ssh/transport/packet_stream.rb
|
|
75
75
|
lib/net/ssh/transport/server_version.rb
|
76
76
|
lib/net/ssh/transport/session.rb
|
77
77
|
lib/net/ssh/transport/state.rb
|
78
|
-
lib/net/ssh/verifiers/
|
79
|
-
lib/net/ssh/verifiers/
|
80
|
-
lib/net/ssh/verifiers/
|
81
|
-
lib/net/ssh/verifiers/
|
78
|
+
lib/net/ssh/verifiers/accept_new.rb
|
79
|
+
lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb
|
80
|
+
lib/net/ssh/verifiers/always.rb
|
81
|
+
lib/net/ssh/verifiers/never.rb
|
82
82
|
lib/net/ssh/version.rb
|
83
83
|
net-ssh.gemspec
|
84
84
|
setup.rb
|
data/lib/net/ssh.rb
CHANGED
@@ -195,8 +195,12 @@ module Net
|
|
195
195
|
# * :agent_socket_factory => enables the user to pass a lambda/block that will serve as the socket factory
|
196
196
|
# Net::SSH.start(host,user,agent_socket_factory: ->{ UNIXSocket.open('/foo/bar') })
|
197
197
|
# example: ->{ UNIXSocket.open('/foo/bar')}
|
198
|
-
# * :verify_host_key =>
|
199
|
-
#
|
198
|
+
# * :verify_host_key => specify how strict host-key verification should be.
|
199
|
+
# In order of increasing strictness:
|
200
|
+
# * :never (very insecure) ::Net::SSH::Verifiers::Never
|
201
|
+
# * :accept_new_or_local_tunnel (insecure) ::Net::SSH::Verifiers::AcceptNewOrLocalTunnel
|
202
|
+
# * :accept_new (insecure) ::Net::SSH::Verifiers::AcceptNew
|
203
|
+
# * :always (secure) ::Net::SSH::Verifiers::Always
|
200
204
|
# You can also provide an own Object which responds to +verify+. The argument
|
201
205
|
# given to +verify+ is a hash consisting of the +:key+, the +:key_blob+,
|
202
206
|
# the +:fingerprint+ and the +:session+. Returning true accepts the host key,
|
data/lib/net/ssh/config.rb
CHANGED
@@ -122,7 +122,7 @@ module Net
|
|
122
122
|
block_seen = true
|
123
123
|
settings[key] = host
|
124
124
|
elsif key == 'match'
|
125
|
-
block_matched =
|
125
|
+
block_matched = eval_match_conditions(value, host, settings)
|
126
126
|
block_seen = true
|
127
127
|
elsif !block_seen
|
128
128
|
case key
|
@@ -325,22 +325,33 @@ module Net
|
|
325
325
|
str.scan(/([^"\s]+)?(?:"([^"]+)")?\s*/).map(&:join)
|
326
326
|
end
|
327
327
|
|
328
|
-
def
|
329
|
-
|
330
|
-
|
331
|
-
condition = condition[1..-1]
|
332
|
-
else
|
333
|
-
negated = false
|
334
|
-
end
|
328
|
+
def eval_match_conditions(condition, host, settings)
|
329
|
+
conditions = condition.split(/\s+/)
|
330
|
+
return true if conditions == ["all"]
|
335
331
|
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
332
|
+
conditions = conditions.each_slice(2)
|
333
|
+
matching = true
|
334
|
+
conditions.each do |(kind,exprs)|
|
335
|
+
case kind.downcase
|
336
|
+
when "all"
|
337
|
+
raise "all cannot be mixed with other conditions"
|
338
|
+
when "host"
|
339
|
+
if exprs.start_with?('!')
|
340
|
+
negated = true
|
341
|
+
exprs = exprs[1..-1]
|
342
|
+
else
|
343
|
+
negated = false
|
344
|
+
end
|
345
|
+
condition_met = false
|
346
|
+
exprs.split(",").each do |expr|
|
347
|
+
condition_met = condition_met || host =~ pattern2regex(expr)
|
348
|
+
end
|
349
|
+
matching = matching && negated ^ condition_met
|
350
|
+
# else
|
351
|
+
# warn "net-ssh: Unsupported expr in Match block: #{kind}"
|
340
352
|
end
|
341
|
-
|
342
|
-
|
343
|
-
condition_met.nil? ? false : (negated ^ condition_met)
|
353
|
+
end
|
354
|
+
matching
|
344
355
|
end
|
345
356
|
end
|
346
357
|
end
|
@@ -629,15 +629,18 @@ module Net
|
|
629
629
|
error { "channel success received with no pending request to handle it (bug?)" }
|
630
630
|
end
|
631
631
|
end
|
632
|
-
|
632
|
+
|
633
633
|
private
|
634
|
-
|
634
|
+
|
635
635
|
# Runs the SSH event loop until the remote confirmed channel open
|
636
636
|
# experimental api
|
637
637
|
def wait_until_open_confirmed
|
638
638
|
connection.loop { !remote_id }
|
639
639
|
end
|
640
|
-
|
640
|
+
|
641
|
+
LOCAL_WINDOW_SIZE_INCREMENT = 0x20000
|
642
|
+
GOOD_LOCAL_MAXIUMUM_WINDOW_SIZE = 10 * LOCAL_WINDOW_SIZE_INCREMENT
|
643
|
+
|
641
644
|
# Updates the local window size by the given amount. If the window
|
642
645
|
# size drops to less than half of the local maximum (an arbitrary
|
643
646
|
# threshold), a CHANNEL_WINDOW_ADJUST message will be sent to the
|
@@ -646,12 +649,12 @@ module Net
|
|
646
649
|
@local_window_size -= size
|
647
650
|
if local_window_size < local_maximum_window_size / 2
|
648
651
|
connection.send_message(Buffer.from(:byte, CHANNEL_WINDOW_ADJUST,
|
649
|
-
:long, remote_id, :long,
|
650
|
-
@local_window_size +=
|
651
|
-
@local_maximum_window_size +=
|
652
|
+
:long, remote_id, :long, LOCAL_WINDOW_SIZE_INCREMENT))
|
653
|
+
@local_window_size += LOCAL_WINDOW_SIZE_INCREMENT
|
654
|
+
@local_maximum_window_size += LOCAL_WINDOW_SIZE_INCREMENT if @local_maximum_window_size < @local_window_size || @local_maximum_window_size < GOOD_LOCAL_MAXIUMUM_WINDOW_SIZE
|
652
655
|
end
|
653
656
|
end
|
654
|
-
|
657
|
+
|
655
658
|
# Gets an +Array+ of local environment variables in the remote process'
|
656
659
|
# environment.
|
657
660
|
# A variable name can either be described by a +Regexp+ or +String+.
|
data/lib/net/ssh/proxy/http.rb
CHANGED
@@ -51,7 +51,8 @@ module Net
|
|
51
51
|
# proxy that was requested when the socket factory was instantiated.
|
52
52
|
def open(host, port, connection_options)
|
53
53
|
socket = establish_connection(connection_options[:timeout])
|
54
|
-
socket.write "CONNECT #{host}:#{port} HTTP/1.
|
54
|
+
socket.write "CONNECT #{host}:#{port} HTTP/1.1\r\n"
|
55
|
+
socket.write "Host: #{host}:#{port}\r\n"
|
55
56
|
|
56
57
|
if options[:user]
|
57
58
|
credentials = ["#{options[:user]}:#{options[:password]}"].pack("m*").gsub(/\s/, "")
|
@@ -7,13 +7,13 @@ require 'net/ssh/transport/algorithms'
|
|
7
7
|
require 'net/ssh/transport/constants'
|
8
8
|
require 'net/ssh/transport/packet_stream'
|
9
9
|
require 'net/ssh/transport/server_version'
|
10
|
-
require 'net/ssh/verifiers/
|
11
|
-
require 'net/ssh/verifiers/
|
12
|
-
require 'net/ssh/verifiers/
|
13
|
-
require 'net/ssh/verifiers/
|
10
|
+
require 'net/ssh/verifiers/accept_new_or_local_tunnel'
|
11
|
+
require 'net/ssh/verifiers/accept_new'
|
12
|
+
require 'net/ssh/verifiers/always'
|
13
|
+
require 'net/ssh/verifiers/never'
|
14
14
|
|
15
|
-
module Net
|
16
|
-
module SSH
|
15
|
+
module Net
|
16
|
+
module SSH
|
17
17
|
module Transport
|
18
18
|
|
19
19
|
# The transport layer represents the lowest level of the SSH protocol, and
|
@@ -24,46 +24,46 @@ module Net
|
|
24
24
|
class Session
|
25
25
|
include Loggable
|
26
26
|
include Constants
|
27
|
-
|
27
|
+
|
28
28
|
# The standard port for the SSH protocol.
|
29
29
|
DEFAULT_PORT = 22
|
30
|
-
|
30
|
+
|
31
31
|
# The host to connect to, as given to the constructor.
|
32
32
|
attr_reader :host
|
33
|
-
|
33
|
+
|
34
34
|
# The port number to connect to, as given in the options to the constructor.
|
35
35
|
# If no port number was given, this will default to DEFAULT_PORT.
|
36
36
|
attr_reader :port
|
37
|
-
|
37
|
+
|
38
38
|
# The underlying socket object being used to communicate with the remote
|
39
39
|
# host.
|
40
40
|
attr_reader :socket
|
41
|
-
|
41
|
+
|
42
42
|
# The ServerVersion instance that encapsulates the negotiated protocol
|
43
43
|
# version.
|
44
44
|
attr_reader :server_version
|
45
|
-
|
45
|
+
|
46
46
|
# The Algorithms instance used to perform key exchanges.
|
47
47
|
attr_reader :algorithms
|
48
|
-
|
48
|
+
|
49
49
|
# The host-key verifier object used to verify host keys, to ensure that
|
50
50
|
# the connection is not being spoofed.
|
51
51
|
attr_reader :host_key_verifier
|
52
|
-
|
52
|
+
|
53
53
|
# The hash of options that were given to the object at initialization.
|
54
54
|
attr_reader :options
|
55
|
-
|
55
|
+
|
56
56
|
# Instantiates a new transport layer abstraction. This will block until
|
57
57
|
# the initial key exchange completes, leaving you with a ready-to-use
|
58
58
|
# transport session.
|
59
59
|
def initialize(host, options={})
|
60
60
|
self.logger = options[:logger]
|
61
|
-
|
61
|
+
|
62
62
|
@host = host
|
63
63
|
@port = options[:port] || DEFAULT_PORT
|
64
64
|
@bind_address = options[:bind_address] || nil
|
65
65
|
@options = options
|
66
|
-
|
66
|
+
|
67
67
|
@socket =
|
68
68
|
if (factory = options[:proxy])
|
69
69
|
debug { "establishing connection to #{@host}:#{@port} through proxy" }
|
@@ -73,63 +73,63 @@ module Net
|
|
73
73
|
Socket.tcp(@host, @port, @bind_address, nil,
|
74
74
|
connect_timeout: options[:timeout])
|
75
75
|
end
|
76
|
-
|
76
|
+
|
77
77
|
@socket.extend(PacketStream)
|
78
78
|
@socket.logger = @logger
|
79
|
-
|
79
|
+
|
80
80
|
debug { "connection established" }
|
81
|
-
|
81
|
+
|
82
82
|
@queue = []
|
83
|
-
|
83
|
+
|
84
84
|
@host_key_verifier = select_host_key_verifier(options[:verify_host_key])
|
85
|
-
|
85
|
+
|
86
86
|
@server_version = ServerVersion.new(socket, logger, options[:timeout])
|
87
|
-
|
87
|
+
|
88
88
|
@algorithms = Algorithms.new(self, options)
|
89
89
|
@algorithms.start
|
90
90
|
wait { algorithms.initialized? }
|
91
91
|
rescue Errno::ETIMEDOUT
|
92
92
|
raise Net::SSH::ConnectionTimeout
|
93
93
|
end
|
94
|
-
|
94
|
+
|
95
95
|
def host_keys
|
96
96
|
@host_keys ||= begin
|
97
97
|
known_hosts = options.fetch(:known_hosts, KnownHosts)
|
98
98
|
known_hosts.search_for(options[:host_key_alias] || host_as_string, options)
|
99
99
|
end
|
100
100
|
end
|
101
|
-
|
101
|
+
|
102
102
|
# Returns the host (and possibly IP address) in a format compatible with
|
103
103
|
# SSH known-host files.
|
104
104
|
def host_as_string
|
105
105
|
@host_as_string ||= begin
|
106
106
|
string = "#{host}"
|
107
107
|
string = "[#{string}]:#{port}" if port != DEFAULT_PORT
|
108
|
-
|
108
|
+
|
109
109
|
peer_ip = socket.peer_ip
|
110
|
-
|
110
|
+
|
111
111
|
if peer_ip != Net::SSH::Transport::PacketStream::PROXY_COMMAND_HOST_IP &&
|
112
112
|
peer_ip != host
|
113
113
|
string2 = peer_ip
|
114
114
|
string2 = "[#{string2}]:#{port}" if port != DEFAULT_PORT
|
115
115
|
string << "," << string2
|
116
116
|
end
|
117
|
-
|
117
|
+
|
118
118
|
string
|
119
119
|
end
|
120
120
|
end
|
121
|
-
|
121
|
+
|
122
122
|
# Returns true if the underlying socket has been closed.
|
123
123
|
def closed?
|
124
124
|
socket.closed?
|
125
125
|
end
|
126
|
-
|
126
|
+
|
127
127
|
# Cleans up (see PacketStream#cleanup) and closes the underlying socket.
|
128
128
|
def close
|
129
129
|
socket.cleanup
|
130
130
|
socket.close
|
131
131
|
end
|
132
|
-
|
132
|
+
|
133
133
|
# Performs a "hard" shutdown of the connection. In general, this should
|
134
134
|
# never be done, but it might be necessary (in a rescue clause, for instance,
|
135
135
|
# when the connection needs to close but you don't know the status of the
|
@@ -138,13 +138,13 @@ module Net
|
|
138
138
|
error { "forcing connection closed" }
|
139
139
|
socket.close
|
140
140
|
end
|
141
|
-
|
141
|
+
|
142
142
|
# Returns a new service_request packet for the given service name, ready
|
143
143
|
# for sending to the server.
|
144
144
|
def service_request(service)
|
145
145
|
Net::SSH::Buffer.from(:byte, SERVICE_REQUEST, :string, service)
|
146
146
|
end
|
147
|
-
|
147
|
+
|
148
148
|
# Requests a rekey operation, and blocks until the operation completes.
|
149
149
|
# If a rekey is already pending, this returns immediately, having no
|
150
150
|
# effect.
|
@@ -154,7 +154,7 @@ module Net
|
|
154
154
|
wait { algorithms.initialized? }
|
155
155
|
end
|
156
156
|
end
|
157
|
-
|
157
|
+
|
158
158
|
# Returns immediately if a rekey is already in process. Otherwise, if a
|
159
159
|
# rekey is needed (as indicated by the socket, see PacketStream#if_needs_rekey?)
|
160
160
|
# one is performed, causing this method to block until it completes.
|
@@ -162,19 +162,19 @@ module Net
|
|
162
162
|
return if algorithms.pending?
|
163
163
|
socket.if_needs_rekey? { rekey! }
|
164
164
|
end
|
165
|
-
|
165
|
+
|
166
166
|
# Returns a hash of information about the peer (remote) side of the socket,
|
167
167
|
# including :ip, :port, :host, and :canonized (see #host_as_string).
|
168
168
|
def peer
|
169
169
|
@peer ||= { ip: socket.peer_ip, port: @port.to_i, host: @host, canonized: host_as_string }
|
170
170
|
end
|
171
|
-
|
171
|
+
|
172
172
|
# Blocks until a new packet is available to be read, and returns that
|
173
173
|
# packet. See #poll_message.
|
174
174
|
def next_message
|
175
175
|
poll_message(:block)
|
176
176
|
end
|
177
|
-
|
177
|
+
|
178
178
|
# Tries to read the next packet from the socket. If mode is :nonblock (the
|
179
179
|
# default), this will not block and will return nil if there are no packets
|
180
180
|
# waiting to be read. Otherwise, this will block until a packet is
|
@@ -189,33 +189,33 @@ module Net
|
|
189
189
|
def poll_message(mode=:nonblock, consume_queue=true)
|
190
190
|
loop do
|
191
191
|
return @queue.shift if consume_queue && @queue.any? && algorithms.allow?(@queue.first)
|
192
|
-
|
192
|
+
|
193
193
|
packet = socket.next_packet(mode)
|
194
194
|
return nil if packet.nil?
|
195
|
-
|
195
|
+
|
196
196
|
case packet.type
|
197
197
|
when DISCONNECT
|
198
198
|
raise Net::SSH::Disconnect, "disconnected: #{packet[:description]} (#{packet[:reason_code]})"
|
199
|
-
|
199
|
+
|
200
200
|
when IGNORE
|
201
201
|
debug { "IGNORE packet received: #{packet[:data].inspect}" }
|
202
|
-
|
202
|
+
|
203
203
|
when UNIMPLEMENTED
|
204
204
|
lwarn { "UNIMPLEMENTED: #{packet[:number]}" }
|
205
|
-
|
205
|
+
|
206
206
|
when DEBUG
|
207
207
|
send(packet[:always_display] ? :fatal : :debug) { packet[:message] }
|
208
|
-
|
208
|
+
|
209
209
|
when KEXINIT
|
210
210
|
algorithms.accept_kexinit(packet)
|
211
|
-
|
211
|
+
|
212
212
|
else
|
213
213
|
return packet if algorithms.allow?(packet)
|
214
214
|
push(packet)
|
215
215
|
end
|
216
216
|
end
|
217
217
|
end
|
218
|
-
|
218
|
+
|
219
219
|
# Waits (blocks) until the given block returns true. If no block is given,
|
220
220
|
# this just waits long enough to see if there are any pending packets. Any
|
221
221
|
# packets read are enqueued (see #push).
|
@@ -227,78 +227,99 @@ module Net
|
|
227
227
|
break if !block_given?
|
228
228
|
end
|
229
229
|
end
|
230
|
-
|
230
|
+
|
231
231
|
# Adds the given packet to the packet queue. If the queue is non-empty,
|
232
232
|
# #poll_message will return packets from the queue in the order they
|
233
233
|
# were received.
|
234
234
|
def push(packet)
|
235
235
|
@queue.push(packet)
|
236
236
|
end
|
237
|
-
|
237
|
+
|
238
238
|
# Sends the given message via the packet stream, blocking until the
|
239
239
|
# entire message has been sent.
|
240
240
|
def send_message(message)
|
241
241
|
socket.send_packet(message)
|
242
242
|
end
|
243
|
-
|
243
|
+
|
244
244
|
# Enqueues the given message, such that it will be sent at the earliest
|
245
245
|
# opportunity. This does not block, but returns immediately.
|
246
246
|
def enqueue_message(message)
|
247
247
|
socket.enqueue_packet(message)
|
248
248
|
end
|
249
|
-
|
249
|
+
|
250
250
|
# Configure's the packet stream's client state with the given set of
|
251
251
|
# options. This is typically used to define the cipher, compression, and
|
252
252
|
# hmac algorithms to use when sending packets to the server.
|
253
253
|
def configure_client(options={})
|
254
254
|
socket.client.set(options)
|
255
255
|
end
|
256
|
-
|
256
|
+
|
257
257
|
# Configure's the packet stream's server state with the given set of
|
258
258
|
# options. This is typically used to define the cipher, compression, and
|
259
259
|
# hmac algorithms to use when reading packets from the server.
|
260
260
|
def configure_server(options={})
|
261
261
|
socket.server.set(options)
|
262
262
|
end
|
263
|
-
|
263
|
+
|
264
264
|
# Sets a new hint for the packet stream, which the packet stream may use
|
265
265
|
# to change its behavior. (See PacketStream#hints).
|
266
266
|
def hint(which, value=true)
|
267
267
|
socket.hints[which] = value
|
268
268
|
end
|
269
|
-
|
269
|
+
|
270
270
|
public
|
271
|
-
|
271
|
+
|
272
272
|
# this method is primarily for use in tests
|
273
273
|
attr_reader :queue #:nodoc:
|
274
|
-
|
274
|
+
|
275
275
|
private
|
276
|
-
|
276
|
+
|
277
277
|
# Instantiates a new host-key verification class, based on the value of
|
278
|
-
# the parameter.
|
279
|
-
#
|
280
|
-
#
|
281
|
-
#
|
282
|
-
#
|
283
|
-
#
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
278
|
+
# the parameter.
|
279
|
+
#
|
280
|
+
# Usually, the argument is a symbol like `:never` which corresponds to
|
281
|
+
# a verifier, like `::Net::SSH::Verifiers::Never`.
|
282
|
+
#
|
283
|
+
# - :never (very insecure)
|
284
|
+
# - :accept_new_or_local_tunnel (insecure)
|
285
|
+
# - :accept_new (insecure)
|
286
|
+
# - :always (secure)
|
287
|
+
#
|
288
|
+
# If the argument happens to respond to :verify, it is returned
|
289
|
+
# directly. Otherwise, an exception is raised.
|
290
|
+
#
|
291
|
+
# Values false, true, and :very were deprecated in
|
292
|
+
# [#595](https://github.com/net-ssh/net-ssh/pull/595)
|
293
|
+
def select_host_key_verifier(verifier)
|
294
|
+
case verifier
|
295
|
+
when false
|
296
|
+
Kernel.warn('verify_host_key: false is deprecated, use :never')
|
297
|
+
Net::SSH::Verifiers::Never.new
|
298
|
+
when :never then
|
299
|
+
Net::SSH::Verifiers::Never.new
|
300
|
+
when true
|
301
|
+
Kernel.warn('verify_host_key: true is deprecated, use :accept_new_or_local_tunnel')
|
302
|
+
Net::SSH::Verifiers::AcceptNewOrLocalTunnel.new
|
303
|
+
when :accept_new_or_local_tunnel, nil then
|
304
|
+
Net::SSH::Verifiers::AcceptNewOrLocalTunnel.new
|
305
|
+
when :very
|
306
|
+
Kernel.warn('verify_host_key: :very is deprecated, use :accept_new')
|
307
|
+
Net::SSH::Verifiers::AcceptNew.new
|
308
|
+
when :accept_new then
|
309
|
+
Net::SSH::Verifiers::AcceptNew.new
|
292
310
|
when :secure then
|
293
|
-
|
311
|
+
Kernel.warn('verify_host_key: :secure is deprecated, use :always')
|
312
|
+
Net::SSH::Verifiers::Always.new
|
313
|
+
when :always then
|
314
|
+
Net::SSH::Verifiers::Always.new
|
294
315
|
else
|
295
|
-
if
|
296
|
-
|
316
|
+
if verifier.respond_to?(:verify)
|
317
|
+
verifier
|
297
318
|
else
|
298
319
|
raise(
|
299
320
|
ArgumentError,
|
300
321
|
"Invalid argument to :verify_host_key (or deprecated " \
|
301
|
-
":paranoid): #{
|
322
|
+
":paranoid): #{verifier.inspect}"
|
302
323
|
)
|
303
324
|
end
|
304
325
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'net/ssh/errors'
|
2
2
|
require 'net/ssh/known_hosts'
|
3
|
-
require 'net/ssh/verifiers/
|
3
|
+
require 'net/ssh/verifiers/always'
|
4
4
|
|
5
|
-
module Net
|
6
|
-
module SSH
|
5
|
+
module Net
|
6
|
+
module SSH
|
7
7
|
module Verifiers
|
8
8
|
|
9
9
|
# Does a strict host verification, looking the server up in the known
|
@@ -12,7 +12,7 @@ module Net
|
|
12
12
|
# server. If the server does appear at least once, but the key given does
|
13
13
|
# not match any known for the server, an exception will be raised (HostKeyMismatch).
|
14
14
|
# Otherwise, this returns true.
|
15
|
-
class
|
15
|
+
class AcceptNew < Always
|
16
16
|
def verify(arguments)
|
17
17
|
begin
|
18
18
|
super
|
@@ -1,29 +1,29 @@
|
|
1
|
-
require 'net/ssh/verifiers/
|
1
|
+
require 'net/ssh/verifiers/accept_new'
|
2
2
|
|
3
|
-
module Net
|
4
|
-
module SSH
|
3
|
+
module Net
|
4
|
+
module SSH
|
5
5
|
module Verifiers
|
6
6
|
|
7
|
-
# Basically the same as the
|
7
|
+
# Basically the same as the AcceptNew verifier, but does not try to actually
|
8
8
|
# verify a connection if the server is the localhost and the port is a
|
9
9
|
# nonstandard port number. Those two conditions will typically mean the
|
10
10
|
# connection is being tunnelled through a forwarded port, so the known-hosts
|
11
11
|
# file will not be helpful (in general).
|
12
|
-
class
|
12
|
+
class AcceptNewOrLocalTunnel < AcceptNew
|
13
13
|
# Tries to determine if the connection is being tunnelled, and if so,
|
14
14
|
# returns true. Otherwise, performs the standard strict verification.
|
15
15
|
def verify(arguments)
|
16
16
|
return true if tunnelled?(arguments)
|
17
17
|
super
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
private
|
21
|
-
|
21
|
+
|
22
22
|
# A connection is potentially being tunnelled if the port is not 22,
|
23
23
|
# and the ip refers to the localhost.
|
24
24
|
def tunnelled?(args)
|
25
25
|
return false if args[:session].port == Net::SSH::Transport::Session::DEFAULT_PORT
|
26
|
-
|
26
|
+
|
27
27
|
ip = args[:session].peer[:ip]
|
28
28
|
return ip == "127.0.0.1" || ip == "::1"
|
29
29
|
end
|
@@ -31,4 +31,4 @@ module Net
|
|
31
31
|
|
32
32
|
end
|
33
33
|
end
|
34
|
-
end
|
34
|
+
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'net/ssh/errors'
|
2
2
|
require 'net/ssh/known_hosts'
|
3
3
|
|
4
|
-
module Net
|
5
|
-
module SSH
|
4
|
+
module Net
|
5
|
+
module SSH
|
6
6
|
module Verifiers
|
7
7
|
|
8
8
|
# Does a strict host verification, looking the server up in the known
|
@@ -13,29 +13,29 @@ module Net
|
|
13
13
|
# least once, but the key given does not match any known for the server, an
|
14
14
|
# exception will be raised (HostKeyMismatch).
|
15
15
|
# Otherwise, this returns true.
|
16
|
-
class
|
16
|
+
class Always
|
17
17
|
def verify(arguments)
|
18
18
|
host_keys = arguments[:session].host_keys
|
19
|
-
|
19
|
+
|
20
20
|
# We've never seen this host before, so raise an exception.
|
21
21
|
process_cache_miss(host_keys, arguments, HostKeyUnknown, "is unknown") if host_keys.empty?
|
22
|
-
|
22
|
+
|
23
23
|
# If we found any matches, check to see that the key type and
|
24
24
|
# blob also match.
|
25
25
|
found = host_keys.any? do |key|
|
26
26
|
key.ssh_type == arguments[:key].ssh_type &&
|
27
27
|
key.to_blob == arguments[:key].to_blob
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
# If a match was found, return true. Otherwise, raise an exception
|
31
31
|
# indicating that the key was not recognized.
|
32
32
|
process_cache_miss(host_keys, arguments, HostKeyMismatch, "does not match") unless found
|
33
|
-
|
33
|
+
|
34
34
|
found
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
private
|
38
|
-
|
38
|
+
|
39
39
|
def process_cache_miss(host_keys, args, exc_class, message)
|
40
40
|
exception = exc_class.new("fingerprint #{args[:fingerprint]} " +
|
41
41
|
"#{message} for #{host_keys.host.inspect}")
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Net
|
2
|
+
module SSH
|
3
|
+
module Verifiers
|
4
|
+
|
5
|
+
# This host key verifier simply allows every key it sees, without
|
6
|
+
# any verification. This is simple, but very insecure because it
|
7
|
+
# exposes you to MiTM attacks.
|
8
|
+
class Never
|
9
|
+
# Returns true.
|
10
|
+
def verify(arguments)
|
11
|
+
true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/net/ssh/version.rb
CHANGED
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: 5.0.0.
|
4
|
+
version: 5.0.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jamis Buck
|
@@ -32,7 +32,7 @@ cert_chain:
|
|
32
32
|
ZFwoIuXKeDmTTpryd/vI7sdLXDuV6MbWOLGh6gXn9RDDXG1EqEXW0bjovATBMpdH
|
33
33
|
9OGohJvAFzcvhDTWPwT6w3PG5B80pqb9j1hEAg==
|
34
34
|
-----END CERTIFICATE-----
|
35
|
-
date: 2018-
|
35
|
+
date: 2018-05-24 00:00:00.000000000 Z
|
36
36
|
dependencies:
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: bcrypt_pbkdf
|
@@ -238,10 +238,10 @@ files:
|
|
238
238
|
- lib/net/ssh/transport/server_version.rb
|
239
239
|
- lib/net/ssh/transport/session.rb
|
240
240
|
- lib/net/ssh/transport/state.rb
|
241
|
-
- lib/net/ssh/verifiers/
|
242
|
-
- lib/net/ssh/verifiers/
|
243
|
-
- lib/net/ssh/verifiers/
|
244
|
-
- lib/net/ssh/verifiers/
|
241
|
+
- lib/net/ssh/verifiers/accept_new.rb
|
242
|
+
- lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb
|
243
|
+
- lib/net/ssh/verifiers/always.rb
|
244
|
+
- lib/net/ssh/verifiers/never.rb
|
245
245
|
- lib/net/ssh/version.rb
|
246
246
|
- net-ssh-public_cert.pem
|
247
247
|
- net-ssh.gemspec
|
metadata.gz.sig
CHANGED
Binary file
|
@@ -1,16 +0,0 @@
|
|
1
|
-
module Net
|
2
|
-
module SSH
|
3
|
-
module Verifiers
|
4
|
-
|
5
|
-
# The Null host key verifier simply allows every key it sees, without
|
6
|
-
# bothering to verify. This is simple, but is not particularly secure.
|
7
|
-
class Null
|
8
|
-
# Returns true.
|
9
|
-
def verify(arguments)
|
10
|
-
true
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|