net-ssh-backports 6.3.0.backports
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/ci.yml +93 -0
- data/.gitignore +13 -0
- data/.rubocop.yml +21 -0
- data/.rubocop_todo.yml +1074 -0
- data/.travis.yml +51 -0
- data/CHANGES.txt +698 -0
- data/Gemfile +13 -0
- data/Gemfile.noed25519 +12 -0
- data/ISSUE_TEMPLATE.md +30 -0
- data/LICENSE.txt +19 -0
- data/Manifest +132 -0
- data/README.md +287 -0
- data/Rakefile +105 -0
- data/THANKS.txt +110 -0
- data/appveyor.yml +58 -0
- data/lib/net/ssh/authentication/agent.rb +284 -0
- data/lib/net/ssh/authentication/certificate.rb +183 -0
- data/lib/net/ssh/authentication/constants.rb +20 -0
- data/lib/net/ssh/authentication/ed25519.rb +185 -0
- data/lib/net/ssh/authentication/ed25519_loader.rb +31 -0
- data/lib/net/ssh/authentication/key_manager.rb +297 -0
- data/lib/net/ssh/authentication/methods/abstract.rb +69 -0
- data/lib/net/ssh/authentication/methods/hostbased.rb +72 -0
- data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +77 -0
- data/lib/net/ssh/authentication/methods/none.rb +34 -0
- data/lib/net/ssh/authentication/methods/password.rb +80 -0
- data/lib/net/ssh/authentication/methods/publickey.rb +95 -0
- data/lib/net/ssh/authentication/pageant.rb +497 -0
- data/lib/net/ssh/authentication/pub_key_fingerprint.rb +43 -0
- data/lib/net/ssh/authentication/session.rb +163 -0
- data/lib/net/ssh/buffer.rb +434 -0
- data/lib/net/ssh/buffered_io.rb +202 -0
- data/lib/net/ssh/config.rb +406 -0
- data/lib/net/ssh/connection/channel.rb +695 -0
- data/lib/net/ssh/connection/constants.rb +33 -0
- data/lib/net/ssh/connection/event_loop.rb +123 -0
- data/lib/net/ssh/connection/keepalive.rb +59 -0
- data/lib/net/ssh/connection/session.rb +712 -0
- data/lib/net/ssh/connection/term.rb +180 -0
- data/lib/net/ssh/errors.rb +106 -0
- data/lib/net/ssh/key_factory.rb +218 -0
- data/lib/net/ssh/known_hosts.rb +264 -0
- data/lib/net/ssh/loggable.rb +62 -0
- data/lib/net/ssh/packet.rb +106 -0
- data/lib/net/ssh/prompt.rb +62 -0
- data/lib/net/ssh/proxy/command.rb +123 -0
- data/lib/net/ssh/proxy/errors.rb +16 -0
- data/lib/net/ssh/proxy/http.rb +98 -0
- data/lib/net/ssh/proxy/https.rb +50 -0
- data/lib/net/ssh/proxy/jump.rb +54 -0
- data/lib/net/ssh/proxy/socks4.rb +67 -0
- data/lib/net/ssh/proxy/socks5.rb +140 -0
- data/lib/net/ssh/service/forward.rb +426 -0
- data/lib/net/ssh/test/channel.rb +147 -0
- data/lib/net/ssh/test/extensions.rb +173 -0
- data/lib/net/ssh/test/kex.rb +46 -0
- data/lib/net/ssh/test/local_packet.rb +53 -0
- data/lib/net/ssh/test/packet.rb +101 -0
- data/lib/net/ssh/test/remote_packet.rb +40 -0
- data/lib/net/ssh/test/script.rb +180 -0
- data/lib/net/ssh/test/socket.rb +65 -0
- data/lib/net/ssh/test.rb +94 -0
- data/lib/net/ssh/transport/algorithms.rb +502 -0
- data/lib/net/ssh/transport/cipher_factory.rb +103 -0
- data/lib/net/ssh/transport/constants.rb +40 -0
- data/lib/net/ssh/transport/ctr.rb +115 -0
- data/lib/net/ssh/transport/hmac/abstract.rb +97 -0
- data/lib/net/ssh/transport/hmac/md5.rb +10 -0
- data/lib/net/ssh/transport/hmac/md5_96.rb +9 -0
- data/lib/net/ssh/transport/hmac/none.rb +13 -0
- data/lib/net/ssh/transport/hmac/ripemd160.rb +11 -0
- data/lib/net/ssh/transport/hmac/sha1.rb +11 -0
- data/lib/net/ssh/transport/hmac/sha1_96.rb +9 -0
- data/lib/net/ssh/transport/hmac/sha2_256.rb +11 -0
- data/lib/net/ssh/transport/hmac/sha2_256_96.rb +9 -0
- data/lib/net/ssh/transport/hmac/sha2_256_etm.rb +12 -0
- data/lib/net/ssh/transport/hmac/sha2_512.rb +11 -0
- data/lib/net/ssh/transport/hmac/sha2_512_96.rb +9 -0
- data/lib/net/ssh/transport/hmac/sha2_512_etm.rb +12 -0
- data/lib/net/ssh/transport/hmac.rb +47 -0
- data/lib/net/ssh/transport/identity_cipher.rb +57 -0
- data/lib/net/ssh/transport/kex/abstract.rb +130 -0
- data/lib/net/ssh/transport/kex/abstract5656.rb +72 -0
- data/lib/net/ssh/transport/kex/curve25519_sha256.rb +39 -0
- data/lib/net/ssh/transport/kex/curve25519_sha256_loader.rb +30 -0
- data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +37 -0
- data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha256.rb +11 -0
- data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +122 -0
- data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +72 -0
- data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb +11 -0
- data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +39 -0
- data/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +21 -0
- data/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +21 -0
- data/lib/net/ssh/transport/kex.rb +31 -0
- data/lib/net/ssh/transport/key_expander.rb +30 -0
- data/lib/net/ssh/transport/openssl.rb +253 -0
- data/lib/net/ssh/transport/packet_stream.rb +280 -0
- data/lib/net/ssh/transport/server_version.rb +77 -0
- data/lib/net/ssh/transport/session.rb +354 -0
- data/lib/net/ssh/transport/state.rb +208 -0
- data/lib/net/ssh/verifiers/accept_new.rb +33 -0
- data/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +33 -0
- data/lib/net/ssh/verifiers/always.rb +58 -0
- data/lib/net/ssh/verifiers/never.rb +19 -0
- data/lib/net/ssh/version.rb +68 -0
- data/lib/net/ssh.rb +330 -0
- data/net-ssh-public_cert.pem +20 -0
- data/net-ssh.gemspec +44 -0
- data/support/ssh_tunnel_bug.rb +65 -0
- metadata +271 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
module Net
|
2
|
+
module SSH
|
3
|
+
module Verifiers
|
4
|
+
# This host key verifier simply allows every key it sees, without
|
5
|
+
# any verification. This is simple, but very insecure because it
|
6
|
+
# exposes you to MiTM attacks.
|
7
|
+
class Never
|
8
|
+
# Returns true.
|
9
|
+
def verify(arguments)
|
10
|
+
true
|
11
|
+
end
|
12
|
+
|
13
|
+
def verify_signature(&block)
|
14
|
+
true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Net
|
2
|
+
module SSH
|
3
|
+
# A class for describing the current version of a library. The version
|
4
|
+
# consists of three parts: the +major+ number, the +minor+ number, and the
|
5
|
+
# +tiny+ (or +patch+) number.
|
6
|
+
#
|
7
|
+
# Two Version instances may be compared, so that you can test that a version
|
8
|
+
# of a library is what you require:
|
9
|
+
#
|
10
|
+
# require 'net/ssh/version'
|
11
|
+
#
|
12
|
+
# if Net::SSH::Version::CURRENT < Net::SSH::Version[2,1,0]
|
13
|
+
# abort "your software is too old!"
|
14
|
+
# end
|
15
|
+
class Version
|
16
|
+
include Comparable
|
17
|
+
|
18
|
+
# A convenience method for instantiating a new Version instance with the
|
19
|
+
# given +major+, +minor+, and +tiny+ components.
|
20
|
+
def self.[](major, minor, tiny, pre = nil)
|
21
|
+
new(major, minor, tiny, pre)
|
22
|
+
end
|
23
|
+
|
24
|
+
attr_reader :major, :minor, :tiny
|
25
|
+
|
26
|
+
# Create a new Version object with the given components.
|
27
|
+
def initialize(major, minor, tiny, pre = nil)
|
28
|
+
@major, @minor, @tiny, @pre = major, minor, tiny, pre
|
29
|
+
end
|
30
|
+
|
31
|
+
# Compare this version to the given +version+ object.
|
32
|
+
def <=>(version)
|
33
|
+
to_i <=> version.to_i
|
34
|
+
end
|
35
|
+
|
36
|
+
# Converts this version object to a string, where each of the three
|
37
|
+
# version components are joined by the '.' character. E.g., 2.0.0.
|
38
|
+
def to_s
|
39
|
+
@to_s ||= [@major, @minor, @tiny, @pre].compact.join(".")
|
40
|
+
end
|
41
|
+
|
42
|
+
# Converts this version to a canonical integer that may be compared
|
43
|
+
# against other version objects.
|
44
|
+
def to_i
|
45
|
+
@to_i ||= @major * 1_000_000 + @minor * 1_000 + @tiny
|
46
|
+
end
|
47
|
+
|
48
|
+
# The major component of this version of the Net::SSH library
|
49
|
+
MAJOR = 6
|
50
|
+
|
51
|
+
# The minor component of this version of the Net::SSH library
|
52
|
+
MINOR = 3
|
53
|
+
|
54
|
+
# The tiny component of this version of the Net::SSH library
|
55
|
+
TINY = 0
|
56
|
+
|
57
|
+
# The prerelease component of this version of the Net::SSH library
|
58
|
+
# nil allowed
|
59
|
+
PRE = "backports"
|
60
|
+
|
61
|
+
# The current version of the Net::SSH library as a Version instance
|
62
|
+
CURRENT = new(*[MAJOR, MINOR, TINY, PRE].compact)
|
63
|
+
|
64
|
+
# The current version of the Net::SSH library as a String
|
65
|
+
STRING = CURRENT.to_s
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/net/ssh.rb
ADDED
@@ -0,0 +1,330 @@
|
|
1
|
+
# Make sure HOME is set, regardless of OS, so that File.expand_path works
|
2
|
+
# as expected with tilde characters.
|
3
|
+
ENV['HOME'] ||= ENV['HOMEPATH'] ? "#{ENV['HOMEDRIVE']}#{ENV['HOMEPATH']}" : Dir.pwd
|
4
|
+
|
5
|
+
require 'logger'
|
6
|
+
require 'etc'
|
7
|
+
require 'shellwords'
|
8
|
+
|
9
|
+
require 'net/ssh/config'
|
10
|
+
require 'net/ssh/errors'
|
11
|
+
require 'net/ssh/loggable'
|
12
|
+
require 'net/ssh/transport/session'
|
13
|
+
require 'net/ssh/authentication/session'
|
14
|
+
require 'net/ssh/connection/session'
|
15
|
+
require 'net/ssh/prompt'
|
16
|
+
|
17
|
+
module Net
|
18
|
+
# Net::SSH is a library for interacting, programmatically, with remote
|
19
|
+
# processes via the SSH2 protocol. Sessions are always initiated via
|
20
|
+
# Net::SSH.start. From there, a program interacts with the new SSH session
|
21
|
+
# via the convenience methods on Net::SSH::Connection::Session, by opening
|
22
|
+
# and interacting with new channels (Net::SSH::Connection:Session#open_channel
|
23
|
+
# and Net::SSH::Connection::Channel), or by forwarding local and/or
|
24
|
+
# remote ports through the connection (Net::SSH::Service::Forward).
|
25
|
+
#
|
26
|
+
# The SSH protocol is very event-oriented. Requests are sent from the client
|
27
|
+
# to the server, and are answered asynchronously. This gives great flexibility
|
28
|
+
# (since clients can have multiple requests pending at a time), but it also
|
29
|
+
# adds complexity. Net::SSH tries to manage this complexity by providing
|
30
|
+
# some simpler methods of synchronous communication (see Net::SSH::Connection::Session#exec!).
|
31
|
+
#
|
32
|
+
# In general, though, and if you want to do anything more complicated than
|
33
|
+
# simply executing commands and capturing their output, you'll need to use
|
34
|
+
# channels (Net::SSH::Connection::Channel) to build state machines that are
|
35
|
+
# executed while the event loop runs (Net::SSH::Connection::Session#loop).
|
36
|
+
#
|
37
|
+
# Net::SSH::Connection::Session and Net::SSH::Connection::Channel have more
|
38
|
+
# information about this technique.
|
39
|
+
#
|
40
|
+
# = "Um, all I want to do is X, just show me how!"
|
41
|
+
#
|
42
|
+
# == X == "execute a command and capture the output"
|
43
|
+
#
|
44
|
+
# Net::SSH.start("host", "user", password: "password") do |ssh|
|
45
|
+
# result = ssh.exec!("ls -l")
|
46
|
+
# puts result
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# == X == "forward connections on a local port to a remote host"
|
50
|
+
#
|
51
|
+
# Net::SSH.start("host", "user", password: "password") do |ssh|
|
52
|
+
# ssh.forward.local(1234, "www.google.com", 80)
|
53
|
+
# ssh.loop { true }
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
# == X == "forward connections on a remote port to the local host"
|
57
|
+
#
|
58
|
+
# Net::SSH.start("host", "user", password: "password") do |ssh|
|
59
|
+
# ssh.forward.remote(80, "www.google.com", 1234)
|
60
|
+
# ssh.loop { true }
|
61
|
+
# end
|
62
|
+
module SSH
|
63
|
+
# This is the set of options that Net::SSH.start recognizes. See
|
64
|
+
# Net::SSH.start for a description of each option.
|
65
|
+
VALID_OPTIONS = %i[
|
66
|
+
auth_methods bind_address compression compression_level config
|
67
|
+
encryption forward_agent hmac host_key remote_user
|
68
|
+
keepalive keepalive_interval keepalive_maxcount kex keys key_data
|
69
|
+
keycerts languages logger paranoid password port proxy
|
70
|
+
rekey_blocks_limit rekey_limit rekey_packet_limit timeout verbose
|
71
|
+
known_hosts global_known_hosts_file user_known_hosts_file host_key_alias
|
72
|
+
host_name user properties passphrase keys_only max_pkt_size
|
73
|
+
max_win_size send_env set_env use_agent number_of_password_prompts
|
74
|
+
append_all_supported_algorithms non_interactive password_prompt
|
75
|
+
agent_socket_factory minimum_dh_bits verify_host_key
|
76
|
+
fingerprint_hash check_host_ip
|
77
|
+
]
|
78
|
+
|
79
|
+
# The standard means of starting a new SSH connection. When used with a
|
80
|
+
# block, the connection will be closed when the block terminates, otherwise
|
81
|
+
# the connection will just be returned. The yielded (or returned) value
|
82
|
+
# will be an instance of Net::SSH::Connection::Session (q.v.). (See also
|
83
|
+
# Net::SSH::Connection::Channel and Net::SSH::Service::Forward.)
|
84
|
+
#
|
85
|
+
# Net::SSH.start("host", "user") do |ssh|
|
86
|
+
# ssh.exec! "cp /some/file /another/location"
|
87
|
+
# hostname = ssh.exec!("hostname")
|
88
|
+
#
|
89
|
+
# ssh.open_channel do |ch|
|
90
|
+
# ch.exec "sudo -p 'sudo password: ' ls" do |ch, success|
|
91
|
+
# abort "could not execute sudo ls" unless success
|
92
|
+
#
|
93
|
+
# ch.on_data do |ch, data|
|
94
|
+
# print data
|
95
|
+
# if data =~ /sudo password: /
|
96
|
+
# ch.send_data("password\n")
|
97
|
+
# end
|
98
|
+
# end
|
99
|
+
# end
|
100
|
+
# end
|
101
|
+
#
|
102
|
+
# ssh.loop
|
103
|
+
# end
|
104
|
+
#
|
105
|
+
# This method accepts the following options (all are optional):
|
106
|
+
#
|
107
|
+
# * :auth_methods => an array of authentication methods to try
|
108
|
+
# * :bind_address => the IP address on the connecting machine to use in
|
109
|
+
# establishing connection. (:bind_address is discarded if :proxy
|
110
|
+
# is set.)
|
111
|
+
# * :check_host_ip => Also ckeck IP address when connecting to remote host.
|
112
|
+
# Defaults to +true+.
|
113
|
+
# * :compression => the compression algorithm to use, or +true+ to use
|
114
|
+
# whatever is supported.
|
115
|
+
# * :compression_level => the compression level to use when sending data
|
116
|
+
# * :config => set to +true+ to load the default OpenSSH config files
|
117
|
+
# (~/.ssh/config, /etc/ssh_config), or to +false+ to not load them, or to
|
118
|
+
# a file-name (or array of file-names) to load those specific configuration
|
119
|
+
# files. Defaults to +true+.
|
120
|
+
# * :encryption => the encryption cipher (or ciphers) to use
|
121
|
+
# * :forward_agent => set to true if you want the SSH agent connection to
|
122
|
+
# be forwarded
|
123
|
+
# * :known_hosts => a custom object holding known hosts records.
|
124
|
+
# It must implement #search_for and `add` in a similiar manner as KnownHosts.
|
125
|
+
# * :global_known_hosts_file => the location of the global known hosts
|
126
|
+
# file. Set to an array if you want to specify multiple global known
|
127
|
+
# hosts files. Defaults to %w(/etc/ssh/ssh_known_hosts /etc/ssh/ssh_known_hosts2).
|
128
|
+
# * :hmac => the hmac algorithm (or algorithms) to use
|
129
|
+
# * :host_key => the host key algorithm (or algorithms) to use
|
130
|
+
# * :host_key_alias => the host name to use when looking up or adding a
|
131
|
+
# host to a known_hosts dictionary file
|
132
|
+
# * :host_name => the real host name or IP to log into. This is used
|
133
|
+
# instead of the +host+ parameter, and is primarily only useful when
|
134
|
+
# specified in an SSH configuration file. It lets you specify an
|
135
|
+
# "alias", similarly to adding an entry in /etc/hosts but without needing
|
136
|
+
# to modify /etc/hosts.
|
137
|
+
# * :keepalive => set to +true+ to send a keepalive packet to the SSH server
|
138
|
+
# when there's no traffic between the SSH server and Net::SSH client for
|
139
|
+
# the keepalive_interval seconds. Defaults to +false+.
|
140
|
+
# * :keepalive_interval => the interval seconds for keepalive.
|
141
|
+
# Defaults to +300+ seconds.
|
142
|
+
# * :keepalive_maxcount => the maximun number of keepalive packet miss allowed.
|
143
|
+
# Defaults to 3
|
144
|
+
# * :kex => the key exchange algorithm (or algorithms) to use
|
145
|
+
# * :keys => an array of file names of private keys to use for publickey
|
146
|
+
# and hostbased authentication
|
147
|
+
# * :keycerts => an array of file names of key certificates to use
|
148
|
+
# with publickey authentication
|
149
|
+
# * :key_data => an array of strings, with each element of the array being
|
150
|
+
# a raw private key in PEM format.
|
151
|
+
# * :keys_only => set to +true+ to use only private keys from +keys+ and
|
152
|
+
# +key_data+ parameters, even if ssh-agent offers more identities. This
|
153
|
+
# option is intended for situations where ssh-agent offers many different
|
154
|
+
# identites.
|
155
|
+
# * :logger => the logger instance to use when logging
|
156
|
+
# * :max_pkt_size => maximum size we tell the other side that is supported per
|
157
|
+
# packet. Default is 0x8000 (32768 bytes). Increase to 0x10000 (65536 bytes)
|
158
|
+
# for better performance if your SSH server supports it (most do).
|
159
|
+
# * :max_win_size => maximum size we tell the other side that is supported for
|
160
|
+
# the window.
|
161
|
+
# * :non_interactive => set to true if your app is non interactive and prefers
|
162
|
+
# authentication failure vs password prompt. Non-interactive applications
|
163
|
+
# should set it to true to prefer failing a password/etc auth methods vs.
|
164
|
+
# asking for password.
|
165
|
+
# * :paranoid => deprecated alias for :verify_host_key
|
166
|
+
# * :passphrase => the passphrase to use when loading a private key (default
|
167
|
+
# is +nil+, for no passphrase)
|
168
|
+
# * :password => the password to use to login
|
169
|
+
# * :port => the port to use when connecting to the remote host
|
170
|
+
# * :properties => a hash of key/value pairs to add to the new connection's
|
171
|
+
# properties (see Net::SSH::Connection::Session#properties)
|
172
|
+
# * :proxy => a proxy instance (see Proxy) to use when connecting
|
173
|
+
# * :rekey_blocks_limit => the max number of blocks to process before rekeying
|
174
|
+
# * :rekey_limit => the max number of bytes to process before rekeying
|
175
|
+
# * :rekey_packet_limit => the max number of packets to process before rekeying
|
176
|
+
# * :send_env => an array of local environment variable names to export to the
|
177
|
+
# remote environment. Names may be given as String or Regexp.
|
178
|
+
# * :set_env => a hash of environment variable names and values to set to the
|
179
|
+
# remote environment. Override the ones if specified in +send_env+.
|
180
|
+
# * :timeout => how long to wait for the initial connection to be made
|
181
|
+
# * :user => the user name to log in as; this overrides the +user+
|
182
|
+
# parameter, and is primarily only useful when provided via an SSH
|
183
|
+
# configuration file.
|
184
|
+
# * :remote_user => used for substitution into the '%r' part of a ProxyCommand
|
185
|
+
# * :user_known_hosts_file => the location of the user known hosts file.
|
186
|
+
# Set to an array to specify multiple user known hosts files.
|
187
|
+
# Defaults to %w(~/.ssh/known_hosts ~/.ssh/known_hosts2).
|
188
|
+
# * :use_agent => Set false to disable the use of ssh-agent. Defaults to
|
189
|
+
# true
|
190
|
+
# * :verbose => how verbose to be (Logger verbosity constants, Logger::DEBUG
|
191
|
+
# is very verbose, Logger::FATAL is all but silent). Logger::FATAL is the
|
192
|
+
# default. The symbols :debug, :info, :warn, :error, and :fatal are also
|
193
|
+
# supported and are translated to the corresponding Logger constant.
|
194
|
+
# * :append_all_supported_algorithms => set to +true+ to append all supported
|
195
|
+
# algorithms by net-ssh. Was the default behaviour until 2.10
|
196
|
+
# * :number_of_password_prompts => Number of prompts for the password
|
197
|
+
# authentication method defaults to 3 set to 0 to disable prompt for
|
198
|
+
# password auth method
|
199
|
+
# * :password_prompt => a custom prompt object with ask method. See Net::SSH::Prompt
|
200
|
+
#
|
201
|
+
# * :agent_socket_factory => enables the user to pass a lambda/block that will serve as the socket factory
|
202
|
+
# Net::SSH.start(host,user,agent_socket_factory: ->{ UNIXSocket.open('/foo/bar') })
|
203
|
+
# example: ->{ UNIXSocket.open('/foo/bar')}
|
204
|
+
# * :verify_host_key => specify how strict host-key verification should be.
|
205
|
+
# In order of increasing strictness:
|
206
|
+
# * :never (very insecure) ::Net::SSH::Verifiers::Never
|
207
|
+
# * :accept_new_or_local_tunnel (insecure) ::Net::SSH::Verifiers::AcceptNewOrLocalTunnel
|
208
|
+
# * :accept_new (insecure) ::Net::SSH::Verifiers::AcceptNew
|
209
|
+
# * :always (secure) ::Net::SSH::Verifiers::Always
|
210
|
+
# You can also provide an own Object which responds to +verify+. The argument
|
211
|
+
# given to +verify+ is a hash consisting of the +:key+, the +:key_blob+,
|
212
|
+
# the +:fingerprint+ and the +:session+. Returning true accepts the host key,
|
213
|
+
# returning false declines it and closes the connection.
|
214
|
+
# * :fingerprint_hash => 'MD5' or 'SHA256', defaults to 'SHA256'
|
215
|
+
# If +user+ parameter is nil it defaults to USER from ssh_config, or
|
216
|
+
# local username
|
217
|
+
def self.start(host, user=nil, options={}, &block)
|
218
|
+
invalid_options = options.keys - VALID_OPTIONS
|
219
|
+
if invalid_options.any?
|
220
|
+
raise ArgumentError, "invalid option(s): #{invalid_options.join(', ')}"
|
221
|
+
end
|
222
|
+
|
223
|
+
assign_defaults(options)
|
224
|
+
_sanitize_options(options)
|
225
|
+
|
226
|
+
options[:user] = user if user
|
227
|
+
options = configuration_for(host, options.fetch(:config, true)).merge(options)
|
228
|
+
host = options.fetch(:host_name, host)
|
229
|
+
|
230
|
+
options[:check_host_ip] = true unless options.key?(:check_host_ip)
|
231
|
+
|
232
|
+
if options[:non_interactive]
|
233
|
+
options[:number_of_password_prompts] = 0
|
234
|
+
end
|
235
|
+
|
236
|
+
_support_deprecated_option_paranoid(options)
|
237
|
+
|
238
|
+
if options[:verbose]
|
239
|
+
options[:logger].level = case options[:verbose]
|
240
|
+
when Integer then options[:verbose]
|
241
|
+
when :debug then Logger::DEBUG
|
242
|
+
when :info then Logger::INFO
|
243
|
+
when :warn then Logger::WARN
|
244
|
+
when :error then Logger::ERROR
|
245
|
+
when :fatal then Logger::FATAL
|
246
|
+
else raise ArgumentError, "can't convert #{options[:verbose].inspect} to any of the Logger level constants"
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
transport = Transport::Session.new(host, options)
|
251
|
+
auth = Authentication::Session.new(transport, options)
|
252
|
+
|
253
|
+
user = options.fetch(:user, user) || Etc.getpwuid.name
|
254
|
+
if auth.authenticate("ssh-connection", user, options[:password])
|
255
|
+
connection = Connection::Session.new(transport, options)
|
256
|
+
if block_given?
|
257
|
+
begin
|
258
|
+
yield connection
|
259
|
+
ensure
|
260
|
+
connection.close unless connection.closed?
|
261
|
+
end
|
262
|
+
else
|
263
|
+
return connection
|
264
|
+
end
|
265
|
+
else
|
266
|
+
transport.close
|
267
|
+
raise AuthenticationFailed, "Authentication failed for user #{user}@#{host}"
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
# Returns a hash of the configuration options for the given host, as read
|
272
|
+
# from the SSH configuration file(s). If +use_ssh_config+ is true (the
|
273
|
+
# default), this will load configuration from both ~/.ssh/config and
|
274
|
+
# /etc/ssh_config. If +use_ssh_config+ is nil or false, nothing will be
|
275
|
+
# loaded (and an empty hash returned). Otherwise, +use_ssh_config+ may
|
276
|
+
# be a file name (or array of file names) of SSH configuration file(s)
|
277
|
+
# to read.
|
278
|
+
#
|
279
|
+
# See Net::SSH::Config for the full description of all supported options.
|
280
|
+
def self.configuration_for(host, use_ssh_config)
|
281
|
+
files = case use_ssh_config
|
282
|
+
when true then Net::SSH::Config.expandable_default_files
|
283
|
+
when false, nil then return {}
|
284
|
+
else Array(use_ssh_config)
|
285
|
+
end
|
286
|
+
|
287
|
+
Net::SSH::Config.for(host, files)
|
288
|
+
end
|
289
|
+
|
290
|
+
def self.assign_defaults(options)
|
291
|
+
if !options[:logger]
|
292
|
+
options[:logger] = Logger.new(STDERR)
|
293
|
+
options[:logger].level = Logger::FATAL
|
294
|
+
end
|
295
|
+
|
296
|
+
options[:password_prompt] ||= Prompt.default(options)
|
297
|
+
|
298
|
+
%i[password passphrase].each do |key|
|
299
|
+
options.delete(key) if options.key?(key) && options[key].nil?
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
def self._sanitize_options(options)
|
304
|
+
invalid_option_values = [nil,[nil]]
|
305
|
+
unless (options.values & invalid_option_values).empty?
|
306
|
+
nil_options = options.select { |_k,v| invalid_option_values.include?(v) }.map(&:first)
|
307
|
+
Kernel.warn "#{caller_locations(2, 1)[0]}: Passing nil, or [nil] to Net::SSH.start is deprecated for keys: #{nil_options.join(', ')}"
|
308
|
+
end
|
309
|
+
end
|
310
|
+
private_class_method :_sanitize_options
|
311
|
+
|
312
|
+
def self._support_deprecated_option_paranoid(options)
|
313
|
+
if options.key?(:paranoid)
|
314
|
+
Kernel.warn(
|
315
|
+
":paranoid is deprecated, please use :verify_host_key. Supported " \
|
316
|
+
"values are exactly the same, only the name of the option has changed."
|
317
|
+
)
|
318
|
+
if options.key?(:verify_host_key)
|
319
|
+
Kernel.warn(
|
320
|
+
"Both :paranoid and :verify_host_key were specified. " \
|
321
|
+
":verify_host_key takes precedence, :paranoid will be ignored."
|
322
|
+
)
|
323
|
+
else
|
324
|
+
options[:verify_host_key] = options.delete(:paranoid)
|
325
|
+
end
|
326
|
+
end
|
327
|
+
end
|
328
|
+
private_class_method :_support_deprecated_option_paranoid
|
329
|
+
end
|
330
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIDQDCCAiigAwIBAgIBATANBgkqhkiG9w0BAQsFADAlMSMwIQYDVQQDDBpuZXRz
|
3
|
+
c2gvREM9c29sdXRpb3VzL0RDPWNvbTAeFw0yMTA4MTAwODMyMzBaFw0yMjA4MTAw
|
4
|
+
ODMyMzBaMCUxIzAhBgNVBAMMGm5ldHNzaC9EQz1zb2x1dGlvdXMvREM9Y29tMIIB
|
5
|
+
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxieE22fR/qmdPKUHyYTyUx2g
|
6
|
+
wskLwrCkxay+Tvc97ZZUOwf85LDDDPqhQaTWLvRwnIOMgQE2nBPzwalVclK6a+pW
|
7
|
+
x/18KDeZY15vm3Qn5p42b0wi9hUxOqPm3J2hdCLCcgtENgdX21nVzejn39WVqFJO
|
8
|
+
lntgSDNW5+kCS8QaRsmIbzj17GKKkrsw39kiQw7FhWfJFeTjddzoZiWwc59KA/Bx
|
9
|
+
fBbmDnsMLAtAtauMOxORrbx3EOY7sHku/kSrMg3FXFay7jc6BkbbUij+MjJ/k82l
|
10
|
+
4o8o0YO4BAnya90xgEmgOG0LCCxRhuXQFnMDuDjK2XnUe0h4/6NCn94C+z9GsQID
|
11
|
+
AQABo3sweTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUBfKiwO2e
|
12
|
+
M4NEiRrVG793qEPLYyMwHwYDVR0RBBgwFoEUbmV0c3NoQHNvbHV0aW91cy5jb20w
|
13
|
+
HwYDVR0SBBgwFoEUbmV0c3NoQHNvbHV0aW91cy5jb20wDQYJKoZIhvcNAQELBQAD
|
14
|
+
ggEBABRChgo0Jo+iXSnTpODNongzZoU0sWqwx3/FQVo8nyAyr1qFuiqpSPb4bDbU
|
15
|
+
DsVnUn3t0X/gGA8qJhutlmfTpEQCjUeyj2x9rWpD3lvttlGWV6btQ0qN4Dfc2gsw
|
16
|
+
rCp9Jpful0HGWhiwfjWfsarqAdtLzIG0UC47IN7LGeCMRJIijOsXQhiZ915eNBEw
|
17
|
+
g9+WSSGHkMFt/7vi2pFkvXSC0+RF8ovvRWf4Zw2aYXtJ1GElgi4ZS/s6ZU0gmv20
|
18
|
+
i4SfC5m5UXIVZvOBYiMuZ/1B2m6R9xU41027zfOVwRFNtlVDiNfQRq6sDmz44At/
|
19
|
+
dv8pkxXDgySe41vzlRXFsgIgz5A=
|
20
|
+
-----END CERTIFICATE-----
|
data/net-ssh.gemspec
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
require_relative 'lib/net/ssh/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = "net-ssh-backports"
|
5
|
+
spec.version = Net::SSH::Version::STRING
|
6
|
+
spec.authors = ["Jamis Buck", "Delano Mandelbaum", "Mikl\u{f3}s Fazekas"]
|
7
|
+
spec.email = ["net-ssh@solutious.com"]
|
8
|
+
|
9
|
+
if ENV['NET_SSH_BUILDGEM_SIGNED']
|
10
|
+
spec.cert_chain = ["net-ssh-public_cert.pem"]
|
11
|
+
spec.signing_key = "/mnt/gem/net-ssh-private_key.pem"
|
12
|
+
end
|
13
|
+
|
14
|
+
spec.summary = %q{Net::SSH: a pure-Ruby implementation of the SSH2 client protocol.}
|
15
|
+
spec.description = %q{Net::SSH: a pure-Ruby implementation of the SSH2 client protocol. It allows you to write programs that invoke and interact with processes on remote servers, via SSH2.}
|
16
|
+
spec.homepage = "https://github.com/net-ssh/net-ssh"
|
17
|
+
spec.license = "MIT"
|
18
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.4.5")
|
19
|
+
spec.metadata = {
|
20
|
+
"changelog_uri" => "https://github.com/net-ssh/net-ssh/blob/master/CHANGES.txt"
|
21
|
+
}
|
22
|
+
|
23
|
+
spec.extra_rdoc_files = [
|
24
|
+
"LICENSE.txt",
|
25
|
+
"README.md"
|
26
|
+
]
|
27
|
+
|
28
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
29
|
+
spec.bindir = "exe"
|
30
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
31
|
+
spec.require_paths = ["lib"]
|
32
|
+
|
33
|
+
unless ENV['NET_SSH_NO_ED25519']
|
34
|
+
spec.add_development_dependency("bcrypt_pbkdf", "~> 1.0") unless RUBY_PLATFORM == "java"
|
35
|
+
spec.add_development_dependency("ed25519", "~> 1.2")
|
36
|
+
spec.add_development_dependency('x25519') unless RUBY_PLATFORM == 'java'
|
37
|
+
end
|
38
|
+
|
39
|
+
spec.add_development_dependency "bundler", ">= 1.17"
|
40
|
+
spec.add_development_dependency "minitest", "~> 5.10"
|
41
|
+
spec.add_development_dependency "mocha", "~> 1.11.2"
|
42
|
+
spec.add_development_dependency "rake", "~> 12.0"
|
43
|
+
spec.add_development_dependency "rubocop", "~> 1.12.1"
|
44
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
# SSH TUNNEL CONNECTION BUG
|
4
|
+
# from: http://net-ssh.lighthouseapp.com/projects/36253/tickets/7-an-existing-connection-was-forcibly-closed-by-the-remote-host#ticket-7-3
|
5
|
+
#
|
6
|
+
# Steps to reproduce:
|
7
|
+
#
|
8
|
+
# * Start HTTP Proxy
|
9
|
+
# * If running debian in EC2:
|
10
|
+
# * apt-get install squid
|
11
|
+
# * Add the following to /etc/squid/squid.conf:
|
12
|
+
# acl localnet src 1.2.3.0/255.255.255.0
|
13
|
+
# http_access allow localnet
|
14
|
+
# icp_access allow localnet
|
15
|
+
# visible_hostname netsshtest
|
16
|
+
# * Start squid squid -N -d 1 -D
|
17
|
+
# * Run this script
|
18
|
+
# * Configure browser proxy to use localhost with LOCAL_PORT.
|
19
|
+
# * Load any page, wait for it to load fully. If the page loads
|
20
|
+
# correctly, move on. If not, something needs to be corrected.
|
21
|
+
# * Refresh the page several times. This should cause this
|
22
|
+
# script to failed with the error: "closed stream". You may
|
23
|
+
# need to try a few times.
|
24
|
+
#
|
25
|
+
|
26
|
+
require 'highline/import'
|
27
|
+
require 'net/ssh'
|
28
|
+
|
29
|
+
LOCAL_PORT = 8080
|
30
|
+
PROXY_PORT = 3128
|
31
|
+
|
32
|
+
host, user = *ARGV
|
33
|
+
abort "Usage: #{$0} host user" unless ARGV.size == 2
|
34
|
+
|
35
|
+
puts "Connecting to #{user}@#{host}..."
|
36
|
+
pass = ask("Password: ") { |q| q.echo = "*" }
|
37
|
+
puts "Configure your browser proxy to localhost:#{LOCAL_PORT}"
|
38
|
+
|
39
|
+
begin
|
40
|
+
session = Net::SSH.start(host, user, password: pass)
|
41
|
+
session.forward.local(LOCAL_PORT, host, PROXY_PORT)
|
42
|
+
session.loop {true}
|
43
|
+
rescue StandardError => e
|
44
|
+
puts e.message
|
45
|
+
puts e.backtrace
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
__END__
|
50
|
+
|
51
|
+
$ ruby support/ssh_tunnel.rb host user
|
52
|
+
Connecting to user@host...
|
53
|
+
Password: ******
|
54
|
+
Configure your browser proxy to localhost:8080
|
55
|
+
closed stream
|
56
|
+
/usr/local/lib/ruby/gems/1.9.1/gems/net-ssh-2.0.15/lib/net/ssh/buffered_io.rb:99:in `send'
|
57
|
+
/usr/local/lib/ruby/gems/1.9.1/gems/net-ssh-2.0.15/lib/net/ssh/buffered_io.rb:99:in `send_pending'
|
58
|
+
/usr/local/lib/ruby/gems/1.9.1/gems/net-ssh-2.0.15/lib/net/ssh/connection/session.rb:236:in `block in postprocess'
|
59
|
+
/usr/local/lib/ruby/gems/1.9.1/gems/net-ssh-2.0.15/lib/net/ssh/connection/session.rb:235:in `each'
|
60
|
+
/usr/local/lib/ruby/gems/1.9.1/gems/net-ssh-2.0.15/lib/net/ssh/connection/session.rb:235:in `postprocess'
|
61
|
+
/usr/local/lib/ruby/gems/1.9.1/gems/net-ssh-2.0.15/lib/net/ssh/connection/session.rb:203:in `process'
|
62
|
+
/usr/local/lib/ruby/gems/1.9.1/gems/net-ssh-2.0.15/lib/net/ssh/connection/session.rb:161:in `block in loop'
|
63
|
+
/usr/local/lib/ruby/gems/1.9.1/gems/net-ssh-2.0.15/lib/net/ssh/connection/session.rb:161:in `loop'
|
64
|
+
/usr/local/lib/ruby/gems/1.9.1/gems/net-ssh-2.0.15/lib/net/ssh/connection/session.rb:161:in `loop'
|
65
|
+
|