net-ssh 5.0.0.beta2 → 5.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|