net-ssh 6.1.0 → 7.3.0

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.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.dockerignore +6 -0
  4. data/.github/FUNDING.yml +1 -0
  5. data/.github/config/rubocop_linter_action.yml +4 -0
  6. data/.github/workflows/ci-with-docker.yml +44 -0
  7. data/.github/workflows/ci.yml +94 -0
  8. data/.github/workflows/rubocop.yml +16 -0
  9. data/.gitignore +4 -0
  10. data/.rubocop.yml +12 -1
  11. data/.rubocop_todo.yml +475 -376
  12. data/CHANGES.txt +64 -3
  13. data/DEVELOPMENT.md +23 -0
  14. data/Dockerfile +29 -0
  15. data/Dockerfile.openssl3 +17 -0
  16. data/Gemfile +2 -0
  17. data/Gemfile.noed25519 +2 -0
  18. data/Gemfile.norbnacl +12 -0
  19. data/README.md +38 -22
  20. data/Rakefile +92 -0
  21. data/SECURITY.md +4 -0
  22. data/docker-compose.yml +25 -0
  23. data/lib/net/ssh/authentication/agent.rb +29 -13
  24. data/lib/net/ssh/authentication/certificate.rb +14 -11
  25. data/lib/net/ssh/authentication/constants.rb +0 -1
  26. data/lib/net/ssh/authentication/ed25519.rb +14 -11
  27. data/lib/net/ssh/authentication/ed25519_loader.rb +4 -7
  28. data/lib/net/ssh/authentication/key_manager.rb +65 -36
  29. data/lib/net/ssh/authentication/methods/abstract.rb +12 -3
  30. data/lib/net/ssh/authentication/methods/hostbased.rb +3 -5
  31. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +2 -2
  32. data/lib/net/ssh/authentication/methods/none.rb +6 -9
  33. data/lib/net/ssh/authentication/methods/password.rb +2 -3
  34. data/lib/net/ssh/authentication/methods/publickey.rb +57 -17
  35. data/lib/net/ssh/authentication/pageant.rb +97 -97
  36. data/lib/net/ssh/authentication/pub_key_fingerprint.rb +3 -3
  37. data/lib/net/ssh/authentication/session.rb +25 -17
  38. data/lib/net/ssh/buffer.rb +71 -51
  39. data/lib/net/ssh/buffered_io.rb +25 -26
  40. data/lib/net/ssh/config.rb +33 -20
  41. data/lib/net/ssh/connection/channel.rb +84 -82
  42. data/lib/net/ssh/connection/constants.rb +0 -4
  43. data/lib/net/ssh/connection/event_loop.rb +30 -24
  44. data/lib/net/ssh/connection/keepalive.rb +12 -12
  45. data/lib/net/ssh/connection/session.rb +109 -108
  46. data/lib/net/ssh/connection/term.rb +56 -58
  47. data/lib/net/ssh/errors.rb +12 -12
  48. data/lib/net/ssh/key_factory.rb +7 -8
  49. data/lib/net/ssh/known_hosts.rb +86 -18
  50. data/lib/net/ssh/loggable.rb +8 -9
  51. data/lib/net/ssh/packet.rb +1 -1
  52. data/lib/net/ssh/prompt.rb +9 -11
  53. data/lib/net/ssh/proxy/command.rb +1 -1
  54. data/lib/net/ssh/proxy/errors.rb +2 -4
  55. data/lib/net/ssh/proxy/http.rb +18 -20
  56. data/lib/net/ssh/proxy/https.rb +8 -10
  57. data/lib/net/ssh/proxy/jump.rb +8 -10
  58. data/lib/net/ssh/proxy/socks4.rb +2 -4
  59. data/lib/net/ssh/proxy/socks5.rb +3 -5
  60. data/lib/net/ssh/service/forward.rb +7 -7
  61. data/lib/net/ssh/test/channel.rb +24 -26
  62. data/lib/net/ssh/test/extensions.rb +35 -35
  63. data/lib/net/ssh/test/kex.rb +6 -8
  64. data/lib/net/ssh/test/local_packet.rb +0 -2
  65. data/lib/net/ssh/test/packet.rb +3 -3
  66. data/lib/net/ssh/test/remote_packet.rb +6 -8
  67. data/lib/net/ssh/test/script.rb +25 -27
  68. data/lib/net/ssh/test/socket.rb +12 -15
  69. data/lib/net/ssh/test.rb +4 -5
  70. data/lib/net/ssh/transport/aes128_gcm.rb +40 -0
  71. data/lib/net/ssh/transport/aes256_gcm.rb +40 -0
  72. data/lib/net/ssh/transport/algorithms.rb +51 -19
  73. data/lib/net/ssh/transport/chacha20_poly1305_cipher.rb +117 -0
  74. data/lib/net/ssh/transport/chacha20_poly1305_cipher_loader.rb +17 -0
  75. data/lib/net/ssh/transport/cipher_factory.rb +56 -29
  76. data/lib/net/ssh/transport/constants.rb +3 -3
  77. data/lib/net/ssh/transport/ctr.rb +7 -7
  78. data/lib/net/ssh/transport/gcm_cipher.rb +207 -0
  79. data/lib/net/ssh/transport/hmac/abstract.rb +20 -5
  80. data/lib/net/ssh/transport/hmac/md5.rb +0 -2
  81. data/lib/net/ssh/transport/hmac/md5_96.rb +0 -2
  82. data/lib/net/ssh/transport/hmac/none.rb +0 -2
  83. data/lib/net/ssh/transport/hmac/ripemd160.rb +0 -2
  84. data/lib/net/ssh/transport/hmac/sha1.rb +0 -2
  85. data/lib/net/ssh/transport/hmac/sha1_96.rb +0 -2
  86. data/lib/net/ssh/transport/hmac.rb +12 -12
  87. data/lib/net/ssh/transport/identity_cipher.rb +19 -13
  88. data/lib/net/ssh/transport/kex/abstract.rb +12 -5
  89. data/lib/net/ssh/transport/kex/abstract5656.rb +1 -1
  90. data/lib/net/ssh/transport/kex/curve25519_sha256.rb +2 -1
  91. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +4 -4
  92. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha256.rb +11 -0
  93. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +21 -21
  94. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +1 -2
  95. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +2 -2
  96. data/lib/net/ssh/transport/kex.rb +8 -6
  97. data/lib/net/ssh/transport/key_expander.rb +7 -8
  98. data/lib/net/ssh/transport/openssl.rb +51 -26
  99. data/lib/net/ssh/transport/openssl_cipher_extensions.rb +8 -0
  100. data/lib/net/ssh/transport/packet_stream.rb +46 -26
  101. data/lib/net/ssh/transport/server_version.rb +17 -16
  102. data/lib/net/ssh/transport/session.rb +9 -7
  103. data/lib/net/ssh/transport/state.rb +44 -44
  104. data/lib/net/ssh/verifiers/accept_new.rb +0 -2
  105. data/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +1 -2
  106. data/lib/net/ssh/verifiers/always.rb +6 -4
  107. data/lib/net/ssh/verifiers/never.rb +0 -2
  108. data/lib/net/ssh/version.rb +2 -2
  109. data/lib/net/ssh.rb +15 -8
  110. data/net-ssh-public_cert.pem +19 -18
  111. data/net-ssh.gemspec +7 -4
  112. data/support/ssh_tunnel_bug.rb +3 -3
  113. data.tar.gz.sig +0 -0
  114. metadata +76 -29
  115. metadata.gz.sig +0 -0
  116. data/.travis.yml +0 -52
@@ -1,7 +1,6 @@
1
- module Net
2
- module SSH
1
+ module Net
2
+ module SSH
3
3
  module Connection
4
-
5
4
  # These constants are used when requesting a pseudo-terminal (via
6
5
  # Net::SSH::Connection::Channel#request_pty). The descriptions for each are
7
6
  # taken directly from RFC 4254 ("The Secure Shell (SSH) Connection Protocol"),
@@ -10,173 +9,172 @@ module Net
10
9
  # Interrupt character; 255 if none. Similarly for the other characters.
11
10
  # Not all of these characters are supported on all systems.
12
11
  VINTR = 1
13
-
12
+
14
13
  # The quit character (sends SIGQUIT signal on POSIX systems).
15
14
  VQUIT = 2
16
-
15
+
17
16
  # Erase the character to left of the cursor.
18
17
  VERASE = 3
19
-
18
+
20
19
  # Kill the current input line.
21
20
  VKILL = 4
22
-
21
+
23
22
  # End-of-file character (sends EOF from the terminal).
24
23
  VEOF = 5
25
-
24
+
26
25
  # End-of-line character in addition to carriage return and/or linefeed.
27
26
  VEOL = 6
28
-
27
+
29
28
  # Additional end-of-line character.
30
29
  VEOL2 = 7
31
-
30
+
32
31
  # Continues paused output (normally control-Q).
33
32
  VSTART = 8
34
-
33
+
35
34
  # Pauses output (normally control-S).
36
35
  VSTOP = 9
37
-
36
+
38
37
  # Suspends the current program.
39
38
  VSUSP = 10
40
-
39
+
41
40
  # Another suspend character.
42
41
  VDSUSP = 11
43
-
42
+
44
43
  # Reprints the current input line.
45
44
  VREPRINT = 12
46
-
45
+
47
46
  # Erases a word left of cursor.
48
47
  VWERASE = 13
49
-
48
+
50
49
  # Enter the next character typed literally, even if it is a special
51
50
  # character.
52
51
  VLNEXT = 14
53
-
52
+
54
53
  # Character to flush output.
55
54
  VFLUSH = 15
56
-
55
+
57
56
  # Switch to a different shell layer.
58
57
  VSWITCH = 16
59
-
58
+
60
59
  # Prints system status line (load, command, pid, etc).
61
60
  VSTATUS = 17
62
-
61
+
63
62
  # Toggles the flushing of terminal output.
64
63
  VDISCARD = 18
65
-
64
+
66
65
  # The ignore parity flag. The parameter SHOULD be 0 if this flag is FALSE,
67
66
  # and 1 if it is TRUE.
68
67
  IGNPAR = 30
69
-
68
+
70
69
  # Mark parity and framing errors.
71
70
  PARMRK = 31
72
-
71
+
73
72
  # Enable checking of parity errors.
74
73
  INPCK = 32
75
-
74
+
76
75
  # Strip 8th bit off characters.
77
76
  ISTRIP = 33
78
-
77
+
79
78
  # Map NL into CR on input.
80
79
  INCLR = 34
81
-
80
+
82
81
  # Ignore CR on input.
83
82
  IGNCR = 35
84
-
83
+
85
84
  # Map CR to NL on input.
86
85
  ICRNL = 36
87
-
86
+
88
87
  # Translate uppercase characters to lowercase.
89
88
  IUCLC = 37
90
-
89
+
91
90
  # Enable output flow control.
92
91
  IXON = 38
93
-
92
+
94
93
  # Any char will restart after stop.
95
94
  IXANY = 39
96
-
95
+
97
96
  # Enable input flow control.
98
97
  IXOFF = 40
99
-
98
+
100
99
  # Ring bell on input queue full.
101
100
  IMAXBEL = 41
102
-
101
+
103
102
  # Enable signals INTR, QUIT, [D]SUSP.
104
103
  ISIG = 50
105
-
104
+
106
105
  # Canonicalize input lines.
107
106
  ICANON = 51
108
-
107
+
109
108
  # Enable input and output of uppercase characters by preceding their
110
109
  # lowercase equivalents with "\".
111
110
  XCASE = 52
112
-
111
+
113
112
  # Enable echoing.
114
113
  ECHO = 53
115
-
114
+
116
115
  # Visually erase chars.
117
116
  ECHOE = 54
118
-
117
+
119
118
  # Kill character discards current line.
120
119
  ECHOK = 55
121
-
120
+
122
121
  # Echo NL even if ECHO is off.
123
122
  ECHONL = 56
124
-
123
+
125
124
  # Don't flush after interrupt.
126
125
  NOFLSH = 57
127
-
126
+
128
127
  # Stop background jobs from output.
129
128
  TOSTOP = 58
130
-
129
+
131
130
  # Enable extensions.
132
131
  IEXTEN = 59
133
-
132
+
134
133
  # Echo control characters as ^(Char).
135
134
  ECHOCTL = 60
136
-
135
+
137
136
  # Visual erase for line kill.
138
137
  ECHOKE = 61
139
-
138
+
140
139
  # Retype pending input.
141
140
  PENDIN = 62
142
-
141
+
143
142
  # Enable output processing.
144
143
  OPOST = 70
145
-
144
+
146
145
  # Convert lowercase to uppercase.
147
146
  OLCUC = 71
148
-
147
+
149
148
  # Map NL to CR-NL.
150
149
  ONLCR = 72
151
-
150
+
152
151
  # Translate carriage return to newline (output).
153
152
  OCRNL = 73
154
-
153
+
155
154
  # Translate newline to carriage return-newline (output).
156
155
  ONOCR = 74
157
-
156
+
158
157
  # Newline performs a carriage return (output).
159
158
  ONLRET = 75
160
-
159
+
161
160
  # 7 bit mode.
162
161
  CS7 = 90
163
-
162
+
164
163
  # 8 bit mode.
165
164
  CS8 = 91
166
-
165
+
167
166
  # Parity enable.
168
167
  PARENB = 92
169
-
168
+
170
169
  # Odd parity, else even.
171
170
  PARODD = 93
172
-
171
+
173
172
  # Specifies the input baud rate in bits per second.
174
173
  TTY_OP_ISPEED = 128
175
-
174
+
176
175
  # Specifies the output baud rate in bits per second.
177
176
  TTY_OP_OSPEED = 129
178
177
  end
179
-
180
178
  end
181
179
  end
182
180
  end
@@ -1,4 +1,4 @@
1
- module Net
1
+ module Net
2
2
  module SSH
3
3
  # A general exception class, to act as the ancestor of all other Net::SSH
4
4
  # exception classes.
@@ -33,7 +33,7 @@ module Net
33
33
  # a "channel open failed" message.
34
34
  class ChannelOpenFailed < Net::SSH::Exception
35
35
  attr_reader :code, :reason
36
-
36
+
37
37
  def initialize(code, reason)
38
38
  @code, @reason = code, reason
39
39
  super "#{reason} (#{code})"
@@ -45,43 +45,43 @@ module Net
45
45
  # the remember_host! method on the exception, and then retry.
46
46
  class HostKeyError < Net::SSH::Exception
47
47
  # the callback to use when #remember_host! is called
48
- attr_writer :callback #:nodoc:
49
-
48
+ attr_writer :callback # :nodoc:
49
+
50
50
  # situation-specific data describing the host (see #host, #port, etc.)
51
- attr_writer :data #:nodoc:
52
-
51
+ attr_writer :data # :nodoc:
52
+
53
53
  # An accessor for getting at the data that was used to look up the host
54
54
  # (see also #fingerprint, #host, #port, #ip, and #key).
55
55
  def [](key)
56
56
  @data && @data[key]
57
57
  end
58
-
58
+
59
59
  # Returns the fingerprint of the key for the host, which either was not
60
60
  # found or did not match.
61
61
  def fingerprint
62
62
  @data && @data[:fingerprint]
63
63
  end
64
-
64
+
65
65
  # Returns the host name for the remote host, as reported by the socket.
66
66
  def host
67
67
  @data && @data[:peer] && @data[:peer][:host]
68
68
  end
69
-
69
+
70
70
  # Returns the port number for the remote host, as reported by the socket.
71
71
  def port
72
72
  @data && @data[:peer] && @data[:peer][:port]
73
73
  end
74
-
74
+
75
75
  # Returns the IP address of the remote host, as reported by the socket.
76
76
  def ip
77
77
  @data && @data[:peer] && @data[:peer][:ip]
78
78
  end
79
-
79
+
80
80
  # Returns the key itself, as reported by the remote host.
81
81
  def key
82
82
  @data && @data[:key]
83
83
  end
84
-
84
+
85
85
  # Tell Net::SSH to record this host and key in the known hosts file, so
86
86
  # that subsequent connections will remember them.
87
87
  def remember_host!
@@ -5,7 +5,6 @@ require 'net/ssh/authentication/ed25519_loader'
5
5
 
6
6
  module Net
7
7
  module SSH
8
-
9
8
  # A factory class for returning new Key classes. It is used for obtaining
10
9
  # OpenSSL key instances via their SSH names, and for loading both public and
11
10
  # private keys. It used used primarily by Net::SSH itself, internally, and
@@ -18,14 +17,14 @@ module Net
18
17
  class KeyFactory
19
18
  # Specifies the mapping of SSH names to OpenSSL key classes.
20
19
  MAP = {
21
- 'dh' => OpenSSL::PKey::DH,
22
- 'rsa' => OpenSSL::PKey::RSA,
23
- 'dsa' => OpenSSL::PKey::DSA,
20
+ 'dh' => OpenSSL::PKey::DH,
21
+ 'rsa' => OpenSSL::PKey::RSA,
22
+ 'dsa' => OpenSSL::PKey::DSA,
24
23
  'ecdsa' => OpenSSL::PKey::EC
25
24
  }
26
25
  MAP["ed25519"] = Net::SSH::Authentication::ED25519::PrivKey if defined? Net::SSH::Authentication::ED25519
27
26
 
28
- class <<self
27
+ class << self
29
28
  # Fetch an OpenSSL key instance by its SSH name. It will be a new,
30
29
  # empty key of the given type.
31
30
  def get(name)
@@ -37,7 +36,7 @@ module Net
37
36
  # appropriately. The new key is returned. If the key itself is
38
37
  # encrypted (requiring a passphrase to use), the user will be
39
38
  # prompted to enter their password unless passphrase works.
40
- def load_private_key(filename, passphrase=nil, ask_passphrase=true, prompt=Prompt.default)
39
+ def load_private_key(filename, passphrase = nil, ask_passphrase = true, prompt = Prompt.default)
41
40
  data = File.read(File.expand_path(filename))
42
41
  load_data_private_key(data, passphrase, ask_passphrase, filename, prompt)
43
42
  end
@@ -47,7 +46,7 @@ module Net
47
46
  # appropriately. The new key is returned. If the key itself is
48
47
  # encrypted (requiring a passphrase to use), the user will be
49
48
  # prompted to enter their password unless passphrase works.
50
- def load_data_private_key(data, passphrase=nil, ask_passphrase=true, filename="", prompt=Prompt.default)
49
+ def load_data_private_key(data, passphrase = nil, ask_passphrase = true, filename = "", prompt = Prompt.default)
51
50
  key_type = classify_key(data, filename)
52
51
 
53
52
  encrypted_key = nil
@@ -87,7 +86,7 @@ module Net
87
86
  # Loads a public key. It will correctly determine whether
88
87
  # the file describes an RSA or DSA key, and will load it
89
88
  # appropriately. The new public key is returned.
90
- def load_data_public_key(data, filename="")
89
+ def load_data_public_key(data, filename = "")
91
90
  fields = data.split(/ /)
92
91
 
93
92
  blob = nil
@@ -1,11 +1,68 @@
1
1
  require 'strscan'
2
2
  require 'openssl'
3
- require 'base64'
3
+ require 'delegate'
4
4
  require 'net/ssh/buffer'
5
5
  require 'net/ssh/authentication/ed25519_loader'
6
6
 
7
7
  module Net
8
8
  module SSH
9
+ module HostKeyEntries
10
+ # regular public key entry
11
+ class PubKey < Delegator
12
+ def initialize(key, comment: nil) # rubocop:disable Lint/MissingSuper
13
+ @key = key
14
+ @comment = comment
15
+ end
16
+
17
+ def ssh_type
18
+ @key.ssh_type
19
+ end
20
+
21
+ def ssh_types
22
+ [ssh_type]
23
+ end
24
+
25
+ def to_blob
26
+ @key.to_blob
27
+ end
28
+
29
+ def __getobj__
30
+ Kernel.warn("Calling Net::SSH::Buffer methods on HostKeyEntries PubKey is deprecated")
31
+ @key
32
+ end
33
+
34
+ def matches_key?(server_key)
35
+ @key.ssh_type == server_key.ssh_type && @key.to_blob == server_key.to_blob
36
+ end
37
+ end
38
+
39
+ # @cert-authority entry
40
+ class CertAuthority
41
+ def ssh_types
42
+ %w[
43
+ ecdsa-sha2-nistp256-cert-v01@openssh.com
44
+ ecdsa-sha2-nistp384-cert-v01@openssh.com
45
+ ecdsa-sha2-nistp521-cert-v01@openssh.com
46
+ ssh-ed25519-cert-v01@openssh.com
47
+ ssh-rsa-cert-v01@openssh.com
48
+ ssh-rsa-cert-v00@openssh.com
49
+ ]
50
+ end
51
+
52
+ def initialize(key, comment: nil)
53
+ @key = key
54
+ @comment = comment
55
+ end
56
+
57
+ def matches_key?(server_key)
58
+ if ssh_types.include?(server_key.ssh_type)
59
+ server_key.signature_valid? && (server_key.signature_key.to_blob == @key.to_blob)
60
+ else
61
+ false
62
+ end
63
+ end
64
+ end
65
+ end
9
66
 
10
67
  # Represents the result of a search in known hosts
11
68
  # see search_for
@@ -48,10 +105,10 @@ module Net
48
105
 
49
106
  SUPPORTED_TYPE.push('ssh-ed25519') if Net::SSH::Authentication::ED25519Loader::LOADED
50
107
 
51
- class <<self
108
+ class << self
52
109
  # Searches all known host files (see KnownHosts.hostfiles) for all keys
53
110
  # of the given host. Returns an enumerable of keys found.
54
- def search_for(host, options={})
111
+ def search_for(host, options = {})
55
112
  HostKeys.new(search_in(hostfiles(options), host, options), host, self, options)
56
113
  end
57
114
 
@@ -70,7 +127,7 @@ module Net
70
127
  #
71
128
  # If you only want the user known host files, you can pass :user as
72
129
  # the second option.
73
- def hostfiles(options, which=:all)
130
+ def hostfiles(options, which = :all)
74
131
  files = []
75
132
 
76
133
  files += Array(options[:user_known_hosts_file] || %w[~/.ssh/known_hosts ~/.ssh/known_hosts2]) if which == :all || which == :user
@@ -85,14 +142,12 @@ module Net
85
142
  # Looks in all user known host files (see KnownHosts.hostfiles) and tries to
86
143
  # add an entry for the given host and key to the first file it is able
87
144
  # to.
88
- def add(host, key, options={})
145
+ def add(host, key, options = {})
89
146
  hostfiles(options, :user).each do |file|
90
- begin
91
- KnownHosts.new(file).add(host, key)
92
- return
93
- rescue SystemCallError
94
- # try the next hostfile
95
- end
147
+ KnownHosts.new(file).add(host, key)
148
+ return
149
+ rescue SystemCallError
150
+ # try the next hostfile
96
151
  end
97
152
  end
98
153
  end
@@ -130,7 +185,13 @@ module Net
130
185
 
131
186
  File.open(source) do |file|
132
187
  file.each_line do |line|
133
- hosts, type, key_content = line.split(' ')
188
+ if line.start_with?('@')
189
+ marker, hosts, type, key_content, comment = line.split(' ')
190
+ else
191
+ marker = nil
192
+ hosts, type, key_content, comment = line.split(' ')
193
+ end
194
+
134
195
  # Skip empty line or one that is commented
135
196
  next if hosts.nil? || hosts.start_with?('#')
136
197
 
@@ -145,7 +206,14 @@ module Net
145
206
  next unless found
146
207
 
147
208
  blob = key_content.unpack("m*").first
148
- keys << Net::SSH::Buffer.new(blob).read_key
209
+ raw_key = Net::SSH::Buffer.new(blob).read_key
210
+
211
+ keys <<
212
+ if marker == "@cert-authority"
213
+ HostKeyEntries::CertAuthority.new(raw_key, comment: comment)
214
+ else
215
+ HostKeyEntries::PubKey.new(raw_key, comment: comment)
216
+ end
149
217
  end
150
218
  end
151
219
 
@@ -155,11 +223,11 @@ module Net
155
223
  def match(host, pattern)
156
224
  if pattern.include?('*') || pattern.include?('?')
157
225
  # see man 8 sshd for pattern details
158
- pattern_regexp = pattern.split('*').map do |x|
159
- x.split('?').map do |y|
226
+ pattern_regexp = pattern.split('*', -1).map do |x|
227
+ x.split('?', -1).map do |y|
160
228
  Regexp.escape(y)
161
229
  end.join('.')
162
- end.join('[^.]*')
230
+ end.join('.*')
163
231
 
164
232
  host =~ Regexp.new("\\A#{pattern_regexp}\\z")
165
233
  else
@@ -172,11 +240,11 @@ module Net
172
240
  def known_host_hash?(hostlist, entries)
173
241
  if hostlist.size == 1 && hostlist.first =~ /\A\|1(\|.+){2}\z/
174
242
  chunks = hostlist.first.split(/\|/)
175
- salt = Base64.decode64(chunks[2])
243
+ salt = chunks[2].unpack1("m")
176
244
  digest = OpenSSL::Digest.new('sha1')
177
245
  entries.each do |entry|
178
246
  hmac = OpenSSL::HMAC.digest(digest, salt, entry)
179
- return true if Base64.encode64(hmac).chomp == chunks[3]
247
+ return true if [hmac].pack("m").chomp == chunks[3]
180
248
  end
181
249
  end
182
250
  false
@@ -1,6 +1,5 @@
1
- module Net
1
+ module Net
2
2
  module SSH
3
-
4
3
  # A simple module to make logging easier to deal with. It assumes that the
5
4
  # logger instance (if not nil) quacks like a Logger object (in Ruby's
6
5
  # standard library). Although used primarily internally by Net::SSH, it
@@ -19,39 +18,39 @@ module Net
19
18
  # The logger instance that will be used to log messages. If nil, nothing
20
19
  # will be logged.
21
20
  attr_accessor :logger
22
-
21
+
23
22
  # Displays the result of yielding if the log level is Logger::DEBUG or
24
23
  # greater.
25
24
  def debug
26
25
  logger.add(Logger::DEBUG, nil, facility) { yield } if logger && logger.debug?
27
26
  end
28
-
27
+
29
28
  # Displays the result of yielding if the log level is Logger::INFO or
30
29
  # greater.
31
30
  def info
32
31
  logger.add(Logger::INFO, nil, facility) { yield } if logger && logger.info?
33
32
  end
34
-
33
+
35
34
  # Displays the result of yielding if the log level is Logger::WARN or
36
35
  # greater. (Called lwarn to avoid shadowing with Kernel#warn.)
37
36
  def lwarn
38
37
  logger.add(Logger::WARN, nil, facility) { yield } if logger && logger.warn?
39
38
  end
40
-
39
+
41
40
  # Displays the result of yielding if the log level is Logger:ERROR or
42
41
  # greater.
43
42
  def error
44
43
  logger.add(Logger::ERROR, nil, facility) { yield } if logger && logger.error?
45
44
  end
46
-
45
+
47
46
  # Displays the result of yielding if the log level is Logger::FATAL or
48
47
  # greater.
49
48
  def fatal
50
49
  logger.add(Logger::FATAL, nil, facility) { yield } if logger && logger.fatal?
51
50
  end
52
-
51
+
53
52
  private
54
-
53
+
55
54
  # Sets the "facility" value, used for reporting where a log message
56
55
  # originates. It defaults to the name of class with the object_id
57
56
  # appended.
@@ -5,7 +5,6 @@ require 'net/ssh/connection/constants'
5
5
 
6
6
  module Net
7
7
  module SSH
8
-
9
8
  # A specialization of Buffer that knows the format of certain common
10
9
  # packet types. It auto-parses those packet types, and allows them to
11
10
  # be accessed via the #[] accessor.
@@ -85,6 +84,7 @@ module Net
85
84
  def [](name)
86
85
  name = name.to_sym
87
86
  raise ArgumentError, "no such element #{name}" unless @named_elements.key?(name)
87
+
88
88
  @named_elements[name]
89
89
  end
90
90
 
@@ -1,8 +1,7 @@
1
1
  require 'io/console'
2
2
 
3
- module Net
3
+ module Net
4
4
  module SSH
5
-
6
5
  # Default prompt implementation, called for asking password from user.
7
6
  # It will never be instantiated directly, but will instead be created for
8
7
  # you automatically.
@@ -13,8 +12,8 @@ module Net
13
12
  #
14
13
  # prompter = options[:password_prompt].start({type:'password'})
15
14
  # while !ok && max_retries < 3
16
- # user = prompter.ask("user: ", {}, true)
17
- # password = prompter.ask("password: ", {}, false)
15
+ # user = prompter.ask("user: ", true)
16
+ # password = prompter.ask("password: ", false)
18
17
  # ok = send(user, password)
19
18
  # prompter.sucess if ok
20
19
  # end
@@ -24,9 +23,9 @@ module Net
24
23
  def self.default(options = {})
25
24
  @default ||= new(options)
26
25
  end
27
-
26
+
28
27
  def initialize(options = {}); end
29
-
28
+
30
29
  # default prompt object implementation. More sophisticated implemenetations
31
30
  # might implement caching.
32
31
  class Prompter
@@ -36,22 +35,22 @@ module Net
36
35
  $stdout.puts(info[:instruction]) unless info[:instruction].empty?
37
36
  end
38
37
  end
39
-
38
+
40
39
  # ask input from user, a prompter might ask for multiple inputs
41
40
  # (like user and password) in a single session.
42
- def ask(prompt, echo=true)
41
+ def ask(prompt, echo = true)
43
42
  $stdout.print(prompt)
44
43
  $stdout.flush
45
44
  ret = $stdin.noecho(&:gets).chomp
46
45
  $stdout.print("\n")
47
46
  ret
48
47
  end
49
-
48
+
50
49
  # success method will be called when the password was accepted
51
50
  # It's a good time to save password asked to a cache.
52
51
  def success; end
53
52
  end
54
-
53
+
55
54
  # start password session. Multiple questions might be asked multiple times
56
55
  # on the returned object. Info hash tries to uniquely identify the password
57
56
  # session, so caching implementations can save passwords properly.
@@ -59,6 +58,5 @@ module Net
59
58
  Prompter.new(info)
60
59
  end
61
60
  end
62
-
63
61
  end
64
62
  end
@@ -5,7 +5,6 @@ require 'net/ssh/proxy/errors'
5
5
  module Net
6
6
  module SSH
7
7
  module Proxy
8
-
9
8
  # An implementation of a command proxy. To use it, instantiate it,
10
9
  # then pass the instantiated object via the :proxy key to
11
10
  # Net::SSH.start:
@@ -105,6 +104,7 @@ module Net
105
104
  if IO.select([self], nil, [self], timeout_in_seconds) == nil
106
105
  raise "Unexpected spurious read wakeup"
107
106
  end
107
+
108
108
  retry
109
109
  end
110
110
  result