hrr_rb_ssh 0.1.8 → 0.1.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +44 -8
- data/demo/server.rb +18 -4
- data/lib/hrr_rb_ssh/codable.rb +19 -20
- data/lib/hrr_rb_ssh/connection/channel.rb +9 -2
- data/lib/hrr_rb_ssh/connection/request_handler/reference_exec_request_handler.rb +115 -5
- data/lib/hrr_rb_ssh/connection/request_handler/reference_pty_req_request_handler.rb +38 -12
- data/lib/hrr_rb_ssh/connection/request_handler/reference_shell_request_handler.rb +46 -22
- data/lib/hrr_rb_ssh/connection/request_handler/reference_window_change_request_handler.rb +1 -1
- data/lib/hrr_rb_ssh/openssl_secure_random.rb +12 -0
- data/lib/hrr_rb_ssh/transport.rb +14 -8
- data/lib/hrr_rb_ssh/transport/compression_algorithm/functionable.rb +5 -0
- data/lib/hrr_rb_ssh/transport/compression_algorithm/unfunctionable.rb +4 -0
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp256.rb +4 -9
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp384.rb +4 -10
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp521.rb +4 -11
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_dss.rb +4 -16
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_rsa.rb +4 -31
- data/lib/hrr_rb_ssh/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 895f28010a8eb2c1e18c12369fd4c10922ba5a69ef0527ce165c97529eae0739
|
4
|
+
data.tar.gz: c6a0669ea1e9561e007ae22259d111ce011589e383cc0ac73b7678d5668b14cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3e41e26012c69eab8dbc2324fd71cd1212ebb56d87b76a30b4c7e59a4eba8627301bcfc18a26d42b7742784034f8ffbcf9ed06ca770a4717e05b7aac47e7780c
|
7
|
+
data.tar.gz: efd75bcd9eb57930c867880010eb6ffc9cb307080f4478df3ffa6363cf46845be9f0aa13a273d1abc161cfab60250562ae8d87ab9db068f7afe6c76382244ed9
|
data/README.md
CHANGED
@@ -7,6 +7,32 @@
|
|
7
7
|
|
8
8
|
hrr_rb_ssh is a pure Ruby SSH 2.0 server implementation.
|
9
9
|
|
10
|
+
## Table of Contents
|
11
|
+
|
12
|
+
- [Installation](#installation)
|
13
|
+
- [Usage](#usage)
|
14
|
+
- [Writing standard SSH server](#writing-standard-ssh-server)
|
15
|
+
- [Requiring hrr\_rb\_ssh library](#requiring-hrr_rb_ssh-library)
|
16
|
+
- [Starting server application](#starting-server-application)
|
17
|
+
- [Logging](#logging)
|
18
|
+
- [Registering pre\-generated secret keys for server host key](#registering-pre-generated-secret-keys-for-server-host-key)
|
19
|
+
- [Defining authentications](#defining-authentications)
|
20
|
+
- [Password authentication](#password-authentication)
|
21
|
+
- [Publickey authentication](#publickey-authentication)
|
22
|
+
- [None authentication (NOT recomended)](#none-authentication-not-recomended)
|
23
|
+
- [Handling session channel requests](#handling-session-channel-requests)
|
24
|
+
- [Reference request handlers](#reference-request-handlers)
|
25
|
+
- [Custom request handlers](#custom-request-handlers)
|
26
|
+
- [Defining preferred algorithms (optional)](#defining-preferred-algorithms-optional)
|
27
|
+
- [Demo](#demo)
|
28
|
+
- [Supported Features](#supported-features)
|
29
|
+
- [Connection layer](#connection-layer)
|
30
|
+
- [Authentication layer](#authentication-layer)
|
31
|
+
- [Transport layer](#transport-layer)
|
32
|
+
- [Contributing](#contributing)
|
33
|
+
- [Code of Conduct](#code-of-conduct)
|
34
|
+
- [License](#license)
|
35
|
+
|
10
36
|
## Installation
|
11
37
|
|
12
38
|
Add this line to your application's Gemfile:
|
@@ -84,6 +110,21 @@ To disable logging, you can un-initialize `HrrRbSsh::Logger`.
|
|
84
110
|
HrrRbSsh::Logger.uninitialize
|
85
111
|
```
|
86
112
|
|
113
|
+
#### Registering pre-generated secret keys for server host key
|
114
|
+
|
115
|
+
By default, server host keys are generated everytime the gem is loaded. To use pre-generated keys, it is possible to register the keys in HrrRbSsh::Transport through `options` variable. The secret key value must be PEM or DER format string. The below is an example of registering ecdsa-sha2-nistp256 secret key. The supported server host key algorithms are listed later in this document.
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
options['transport_server_secret_host_keys'] = {}
|
119
|
+
options['transport_server_secret_host_keys']['ecdsa-sha2-nistp256'] = <<-'EOB'
|
120
|
+
-----BEGIN EC PRIVATE KEY-----
|
121
|
+
MHcCAQEEIFFtGZHk6A8anZkLCJan9YBlB63uCIN/ZcQNCaJout8loAoGCCqGSM49
|
122
|
+
AwEHoUQDQgAEk8m548Xga+XGEmRx7P71xGlxCfgjPj3XVOw+fXPXRgA03a5yDJEp
|
123
|
+
OfeosJOO9twerD7pPhmXREkygblPsEXaVA==
|
124
|
+
-----END EC PRIVATE KEY-----
|
125
|
+
EOB
|
126
|
+
```
|
127
|
+
|
87
128
|
#### Defining authentications
|
88
129
|
|
89
130
|
By default, any authentications get failed. To allow users to login to the SSH service, at least one of the authentication methods must be defined and registered into the instance of HrrRbSsh::Authentication through `options` variable.
|
@@ -225,16 +266,11 @@ p HrrRbSsh::Transport::EncryptionAlgorithm.list_supported
|
|
225
266
|
p HrrRbSsh::Transport::EncryptionAlgorithm.list_preferred
|
226
267
|
# => ["aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-cbc", "3des-cbc", "blowfish-cbc", "cast128-cbc", "aes192-cbc", "aes256-cbc", "arcfour"]
|
227
268
|
|
228
|
-
p HrrRbSsh::Transport::EncryptionAlgorithm.list_supported
|
229
|
-
# => ["none", "3des-cbc", "blowfish-cbc", "aes128-cbc", "aes192-cbc", "aes256-cbc", "arcfour", "cast128-cbc", "aes128-ctr", "aes192-ctr", "aes256-ctr"]
|
230
|
-
HrrRbSsh::Transport::ServerHostKeyAlgorithm.list_preferred
|
231
|
-
# => ["ecdsa-sha2-nistp521", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp256", "ssh-rsa", "ssh-dss"]
|
232
|
-
|
233
269
|
p HrrRbSsh::Transport::ServerHostKeyAlgorithm.list_supported
|
234
270
|
# => ["ssh-dss", "ssh-rsa", "ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp521"]
|
235
|
-
p HrrRbSsh::Transport::
|
236
|
-
# => ["
|
237
|
-
|
271
|
+
p HrrRbSsh::Transport::ServerHostKeyAlgorithm.list_preferred
|
272
|
+
# => ["ecdsa-sha2-nistp521", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp256", "ssh-rsa", "ssh-dss"]
|
273
|
+
|
238
274
|
p HrrRbSsh::Transport::KexAlgorithm.list_supported
|
239
275
|
# => ["diffie-hellman-group1-sha1", "diffie-hellman-group14-sha1", "diffie-hellman-group-exchange-sha1", "diffie-hellman-group-exchange-sha256", "diffie-hellman-group14-sha256", "diffie-hellman-group15-sha512", "diffie-hellman-group16-sha512", "diffie-hellman-group17-sha512", "diffie-hellman-group18-sha512", "ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521"]
|
240
276
|
p HrrRbSsh::Transport::KexAlgorithm.list_preferred
|
data/demo/server.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
# vim: et ts=2 sw=2
|
3
3
|
|
4
|
+
require 'etc'
|
4
5
|
require 'logger'
|
5
6
|
require 'socket'
|
6
7
|
|
@@ -27,10 +28,14 @@ auth_none = HrrRbSsh::Authentication::Authenticator.new { |context|
|
|
27
28
|
false
|
28
29
|
}
|
29
30
|
auth_publickey = HrrRbSsh::Authentication::Authenticator.new { |context|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
users = ['user1', 'user2']
|
32
|
+
users.any?{ |username|
|
33
|
+
passwd = Etc.getpwnam(username)
|
34
|
+
homedir = passwd.dir
|
35
|
+
authorized_keys = HrrRbSsh::Compat::OpenSSH::AuthorizedKeys.new(File.read(File.join(homedir, '.ssh', 'authorized_keys')))
|
36
|
+
authorized_keys.any?{ |public_key|
|
37
|
+
context.verify username, public_key.algorithm_name, public_key.to_pem
|
38
|
+
}
|
34
39
|
}
|
35
40
|
}
|
36
41
|
auth_password = HrrRbSsh::Authentication::Authenticator.new { |context|
|
@@ -52,6 +57,15 @@ options['transport_preferred_kex_algorithms'] = tran_preferred_kex_a
|
|
52
57
|
options['transport_preferred_mac_algorithms'] = tran_preferred_mac_algorithms
|
53
58
|
options['transport_preferred_compression_algorithms'] = tran_preferred_compression_algorithms
|
54
59
|
|
60
|
+
options['transport_server_secret_host_keys'] = {}
|
61
|
+
options['transport_server_secret_host_keys']['ecdsa-sha2-nistp256'] = <<-'EOB'
|
62
|
+
-----BEGIN EC PRIVATE KEY-----
|
63
|
+
MHcCAQEEIFFtGZHk6A8anZkLCJan9YBlB63uCIN/ZcQNCaJout8loAoGCCqGSM49
|
64
|
+
AwEHoUQDQgAEk8m548Xga+XGEmRx7P71xGlxCfgjPj3XVOw+fXPXRgA03a5yDJEp
|
65
|
+
OfeosJOO9twerD7pPhmXREkygblPsEXaVA==
|
66
|
+
-----END EC PRIVATE KEY-----
|
67
|
+
EOB
|
68
|
+
|
55
69
|
options['authentication_none_authenticator'] = auth_none
|
56
70
|
options['authentication_publickey_authenticator'] = auth_publickey
|
57
71
|
options['authentication_password_authenticator'] = auth_password
|
data/lib/hrr_rb_ssh/codable.rb
CHANGED
@@ -35,28 +35,27 @@ module HrrRbSsh
|
|
35
35
|
}.join
|
36
36
|
end
|
37
37
|
|
38
|
-
def
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
decoded_message + decode_recursively(payload_io, decoded_message)
|
57
|
-
end
|
38
|
+
def decode_recursively payload_io, message=nil
|
39
|
+
if message.class == Array and message.size == 0
|
40
|
+
[]
|
41
|
+
else
|
42
|
+
definition = case message
|
43
|
+
when nil
|
44
|
+
common_definition
|
45
|
+
when Array
|
46
|
+
conditional_definition(message)
|
47
|
+
end
|
48
|
+
decoded_message = definition.map{ |data_type, field_name|
|
49
|
+
[
|
50
|
+
field_name,
|
51
|
+
data_type.decode( payload_io )
|
52
|
+
]
|
53
|
+
}
|
54
|
+
decoded_message + decode_recursively(payload_io, decoded_message)
|
58
55
|
end
|
56
|
+
end
|
59
57
|
|
58
|
+
def decode payload, complementary_message={}
|
60
59
|
payload_io = StringIO.new payload
|
61
60
|
decoded_message = decode_recursively(payload_io).to_h
|
62
61
|
if complementary_message.any?
|
@@ -66,6 +66,13 @@ module HrrRbSsh
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def wait_until_senders_closed
|
69
|
+
[@w_io_out, @w_io_err].each{ |io|
|
70
|
+
begin
|
71
|
+
io.close
|
72
|
+
rescue IOError # for compatibility for Ruby version < 2.3
|
73
|
+
Thread.pass
|
74
|
+
end
|
75
|
+
}
|
69
76
|
[@out_sender_thread, @err_sender_thread].select{ |t| t.instance_of? Thread }.each(&:join)
|
70
77
|
end
|
71
78
|
|
@@ -163,7 +170,7 @@ module HrrRbSsh
|
|
163
170
|
break
|
164
171
|
end
|
165
172
|
begin
|
166
|
-
data = @r_io_out.readpartial(
|
173
|
+
data = @r_io_out.readpartial(10240)
|
167
174
|
sendable_size = [data.size, @remote_window_size].min
|
168
175
|
sending_data = data[0, sendable_size]
|
169
176
|
send_channel_data sending_data if sendable_size > 0
|
@@ -195,7 +202,7 @@ module HrrRbSsh
|
|
195
202
|
break
|
196
203
|
end
|
197
204
|
begin
|
198
|
-
data = @r_io_err.readpartial(
|
205
|
+
data = @r_io_err.readpartial(10240)
|
199
206
|
sendable_size = [data.size, @remote_window_size].min
|
200
207
|
sending_data = data[0, sendable_size]
|
201
208
|
send_channel_extended_data sending_data if sendable_size > 0
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
# vim: et ts=2 sw=2
|
3
3
|
|
4
|
+
require 'etc'
|
4
5
|
require 'hrr_rb_ssh/logger'
|
5
6
|
require 'hrr_rb_ssh/connection/request_handler'
|
6
7
|
|
@@ -11,15 +12,124 @@ module HrrRbSsh
|
|
11
12
|
def initialize
|
12
13
|
@logger = HrrRbSsh::Logger.new self.class.name
|
13
14
|
@proc = Proc.new { |context|
|
15
|
+
ptm = context.vars[:ptm]
|
16
|
+
pts = context.vars[:pts]
|
17
|
+
|
14
18
|
context.chain_proc { |chain|
|
19
|
+
passwd = Etc.getpwnam(context.username)
|
20
|
+
|
21
|
+
env = context.vars.fetch(:env, Hash.new)
|
22
|
+
env['USER'] = passwd.name
|
23
|
+
env['HOME'] = passwd.dir
|
24
|
+
env['SHELL'] = passwd.shell
|
25
|
+
|
26
|
+
program = context.command
|
27
|
+
|
28
|
+
args = Array.new
|
29
|
+
|
30
|
+
options = Hash.new
|
31
|
+
options[:unsetenv_others] = true
|
32
|
+
options[:close_others] = true
|
33
|
+
unless ptm
|
34
|
+
options[:in] = context.io[0]
|
35
|
+
options[:out] = context.io[1]
|
36
|
+
options[:err] = context.io[2]
|
37
|
+
end
|
38
|
+
|
15
39
|
pid = fork do
|
16
40
|
Process.setsid
|
17
|
-
|
18
|
-
|
41
|
+
Dir.chdir passwd.dir
|
42
|
+
Process.gid = passwd.gid
|
43
|
+
Process.egid = passwd.gid
|
44
|
+
Process.uid = passwd.uid
|
45
|
+
Process.euid = passwd.uid
|
46
|
+
if ptm
|
47
|
+
STDIN.reopen pts, 'r'
|
48
|
+
STDOUT.reopen pts, 'w'
|
49
|
+
STDERR.reopen pts, 'w'
|
50
|
+
pts.close
|
51
|
+
end
|
52
|
+
exec env, program, *args, options
|
53
|
+
end
|
54
|
+
|
55
|
+
unless ptm
|
56
|
+
pid, status = Process.waitpid2 pid
|
57
|
+
status.exitstatus
|
58
|
+
else
|
59
|
+
pts.close
|
60
|
+
|
61
|
+
ptm_read_thread = Thread.start {
|
62
|
+
loop do
|
63
|
+
begin
|
64
|
+
context.io[1].write ptm.readpartial(10240)
|
65
|
+
rescue EOFError => e
|
66
|
+
context.logger.info { "ptm is EOF in ptm_read_thread" }
|
67
|
+
break
|
68
|
+
rescue IOError => e
|
69
|
+
context.logger.warn { "IO Error in ptm_read_thread" }
|
70
|
+
break
|
71
|
+
rescue Errno::EIO => e
|
72
|
+
context.logger.info { "EIO Error in ptm_read_thread" }
|
73
|
+
break
|
74
|
+
rescue => e
|
75
|
+
context.logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
76
|
+
break
|
77
|
+
end
|
78
|
+
end
|
79
|
+
}
|
80
|
+
ptm_write_thread = Thread.start {
|
81
|
+
loop do
|
82
|
+
begin
|
83
|
+
ptm.write context.io[0].readpartial(10240)
|
84
|
+
rescue EOFError => e
|
85
|
+
context.logger.info { "IO is EOF in ptm_write_thread" }
|
86
|
+
break
|
87
|
+
rescue IOError => e
|
88
|
+
context.logger.warn { "IO Error in ptm_write_thread" }
|
89
|
+
break
|
90
|
+
rescue Errno::EIO => e
|
91
|
+
context.logger.info { "EIO Error in ptm_read_thread" }
|
92
|
+
break
|
93
|
+
rescue => e
|
94
|
+
context.logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
95
|
+
break
|
96
|
+
end
|
97
|
+
end
|
98
|
+
}
|
99
|
+
|
100
|
+
begin
|
101
|
+
pid, status = Process.waitpid2 pid
|
102
|
+
context.logger.info { "program exited with status #{status.inspect}" }
|
103
|
+
status.exitstatus
|
104
|
+
ensure
|
105
|
+
unless status
|
106
|
+
context.logger.info { "exiting program" }
|
107
|
+
Process.kill :TERM, pid
|
108
|
+
begin
|
109
|
+
Timeout.timeout(1) do
|
110
|
+
pid, status = Process.waitpid2 pid
|
111
|
+
end
|
112
|
+
rescue Timeout::Error
|
113
|
+
context.logger.warn { "force exiting program" }
|
114
|
+
Process.kill :KILL, pid
|
115
|
+
pid, status = Process.waitpid2 pid
|
116
|
+
end
|
117
|
+
context.logger.info { "program exited with status #{status.inspect}" }
|
118
|
+
end
|
119
|
+
begin
|
120
|
+
ptm_read_thread.join
|
121
|
+
rescue => e
|
122
|
+
context.logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
123
|
+
end
|
124
|
+
begin
|
125
|
+
ptm_write_thread.exit
|
126
|
+
ptm_write_thread.join
|
127
|
+
rescue => e
|
128
|
+
context.logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
129
|
+
end
|
130
|
+
context.logger.info { "proc chain finished" }
|
131
|
+
end
|
19
132
|
end
|
20
|
-
context.io.each{ |io| io.close }
|
21
|
-
pid, status = Process.waitpid2 pid
|
22
|
-
status.exitstatus
|
23
133
|
}
|
24
134
|
}
|
25
135
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
# vim: et ts=2 sw=2
|
3
3
|
|
4
|
+
require 'etc'
|
5
|
+
require 'fileutils'
|
4
6
|
require 'pty'
|
5
7
|
require 'io/console'
|
6
8
|
require 'hrr_rb_ssh/logger'
|
@@ -13,20 +15,44 @@ module HrrRbSsh
|
|
13
15
|
def initialize
|
14
16
|
@logger = HrrRbSsh::Logger.new self.class.name
|
15
17
|
@proc = Proc.new { |context|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
begin
|
19
|
+
ptm, pts = PTY.open
|
20
|
+
passwd = Etc.getpwnam(context.username)
|
21
|
+
FileUtils.chown passwd.uid, -1, pts
|
22
|
+
FileUtils.chmod 'u+rw,g+w', pts
|
23
|
+
ptm.winsize = [context.terminal_height_rows, context.terminal_width_characters, context.terminal_width_pixels, context.terminal_height_pixels]
|
24
|
+
context.vars[:ptm] = ptm
|
25
|
+
context.vars[:pts] = pts
|
26
|
+
context.vars[:env] ||= Hash.new
|
27
|
+
context.vars[:env]['TERM'] = context.term_environment_variable_value
|
28
|
+
context.chain_proc { |chain|
|
29
|
+
begin
|
30
|
+
chain.call_next
|
31
|
+
ensure
|
32
|
+
begin
|
33
|
+
context.vars[:ptm].close
|
34
|
+
rescue
|
35
|
+
end
|
36
|
+
begin
|
37
|
+
context.vars[:pts].close
|
38
|
+
rescue
|
39
|
+
end
|
40
|
+
end
|
41
|
+
}
|
42
|
+
rescue => e
|
23
43
|
begin
|
24
|
-
|
25
|
-
|
26
|
-
context.vars[:ptm].close
|
27
|
-
context.vars[:pts].close
|
44
|
+
ptm.close
|
45
|
+
rescue
|
28
46
|
end
|
29
|
-
|
47
|
+
begin
|
48
|
+
pts.close
|
49
|
+
rescue
|
50
|
+
end
|
51
|
+
context.chain_proc{ |chain|
|
52
|
+
exitstatus = 1
|
53
|
+
}
|
54
|
+
raise e
|
55
|
+
end
|
30
56
|
}
|
31
57
|
end
|
32
58
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
# vim: et ts=2 sw=2
|
3
3
|
|
4
|
+
require 'etc'
|
4
5
|
require 'timeout'
|
5
6
|
require 'hrr_rb_ssh/logger'
|
6
7
|
require 'hrr_rb_ssh/connection/request_handler'
|
@@ -15,56 +16,76 @@ module HrrRbSsh
|
|
15
16
|
ptm = context.vars[:ptm]
|
16
17
|
pts = context.vars[:pts]
|
17
18
|
|
18
|
-
context.io[2].close # never use err output in shell handler
|
19
|
-
|
20
19
|
context.chain_proc { |chain|
|
20
|
+
passwd = Etc.getpwnam(context.username)
|
21
|
+
|
22
|
+
env = context.vars.fetch(:env, Hash.new)
|
23
|
+
env['USER'] = passwd.name
|
24
|
+
env['HOME'] = passwd.dir
|
25
|
+
env['SHELL'] = passwd.shell
|
26
|
+
|
27
|
+
program = [passwd.shell, passwd.shell.split('/').last.sub(/^/,'-')]
|
28
|
+
|
29
|
+
args = Array.new
|
30
|
+
|
31
|
+
options = Hash.new
|
32
|
+
options[:unsetenv_others] = true
|
33
|
+
options[:close_others] = true
|
34
|
+
|
21
35
|
pid = fork do
|
22
36
|
ptm.close
|
23
37
|
Process.setsid
|
38
|
+
Dir.chdir passwd.dir
|
39
|
+
Process.gid = passwd.gid
|
40
|
+
Process.egid = passwd.gid
|
41
|
+
Process.uid = passwd.uid
|
42
|
+
Process.euid = passwd.uid
|
24
43
|
STDIN.reopen pts, 'r'
|
25
44
|
STDOUT.reopen pts, 'w'
|
26
45
|
STDERR.reopen pts, 'w'
|
27
46
|
pts.close
|
28
|
-
|
29
|
-
exec context.vars[:env], 'login', '-pf', context.username
|
47
|
+
exec env, program, *args, options
|
30
48
|
end
|
31
49
|
|
32
50
|
pts.close
|
33
51
|
|
34
|
-
|
35
|
-
threads.push Thread.start {
|
52
|
+
ptm_read_thread = Thread.start {
|
36
53
|
loop do
|
37
54
|
begin
|
38
|
-
context.io[1].write ptm.readpartial(
|
55
|
+
context.io[1].write ptm.readpartial(10240)
|
39
56
|
rescue EOFError => e
|
40
|
-
context.logger.info { "ptm is EOF" }
|
57
|
+
context.logger.info { "ptm is EOF in ptm_read_thread" }
|
41
58
|
break
|
42
59
|
rescue IOError => e
|
43
|
-
context.logger.warn { "IO
|
60
|
+
context.logger.warn { "IO Error in ptm_read_thread" }
|
61
|
+
break
|
62
|
+
rescue Errno::EIO => e
|
63
|
+
context.logger.info { "EIO Error in ptm_read_thread" }
|
44
64
|
break
|
45
65
|
rescue => e
|
46
66
|
context.logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
47
67
|
break
|
48
68
|
end
|
49
69
|
end
|
50
|
-
context.io[1].close
|
51
70
|
}
|
52
|
-
|
71
|
+
ptm_write_thread = Thread.start {
|
53
72
|
loop do
|
54
73
|
begin
|
55
|
-
ptm.write context.io[0].readpartial(
|
74
|
+
ptm.write context.io[0].readpartial(10240)
|
56
75
|
rescue EOFError => e
|
57
|
-
context.logger.info { "IO is EOF" }
|
76
|
+
context.logger.info { "IO is EOF in ptm_write_thread" }
|
58
77
|
break
|
59
78
|
rescue IOError => e
|
60
|
-
context.logger.warn { "IO
|
79
|
+
context.logger.warn { "IO Error in ptm_write_thread" }
|
80
|
+
break
|
81
|
+
rescue Errno::EIO => e
|
82
|
+
context.logger.info { "EIO Error in ptm_read_thread" }
|
61
83
|
break
|
62
84
|
rescue => e
|
63
85
|
context.logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
64
86
|
break
|
65
87
|
end
|
66
88
|
end
|
67
|
-
ptm.close
|
68
89
|
}
|
69
90
|
|
70
91
|
begin
|
@@ -86,13 +107,16 @@ module HrrRbSsh
|
|
86
107
|
end
|
87
108
|
context.logger.info { "shell exited with status #{status.inspect}" }
|
88
109
|
end
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
110
|
+
begin
|
111
|
+
ptm_read_thread.join
|
112
|
+
rescue => e
|
113
|
+
context.logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
114
|
+
end
|
115
|
+
begin
|
116
|
+
ptm_write_thread.exit
|
117
|
+
ptm_write_thread.join
|
118
|
+
rescue => e
|
119
|
+
context.logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
96
120
|
end
|
97
121
|
context.logger.info { "proc chain finished" }
|
98
122
|
end
|
@@ -12,7 +12,7 @@ module HrrRbSsh
|
|
12
12
|
def initialize
|
13
13
|
@logger = HrrRbSsh::Logger.new self.class.name
|
14
14
|
@proc = Proc.new { |context|
|
15
|
-
context.vars[:ptm].winsize = [context.terminal_height_rows, context.terminal_width_columns]
|
15
|
+
context.vars[:ptm].winsize = [context.terminal_height_rows, context.terminal_width_columns, context.terminal_width_pixels, context.terminal_height_pixels]
|
16
16
|
}
|
17
17
|
end
|
18
18
|
end
|
data/lib/hrr_rb_ssh/transport.rb
CHANGED
@@ -53,6 +53,7 @@ module HrrRbSsh
|
|
53
53
|
def initialize io, mode, options={}
|
54
54
|
@io = io
|
55
55
|
@mode = mode
|
56
|
+
@options = options
|
56
57
|
|
57
58
|
@logger = HrrRbSsh::Logger.new self.class.name
|
58
59
|
|
@@ -76,7 +77,7 @@ module HrrRbSsh
|
|
76
77
|
@acceptable_services = Array.new
|
77
78
|
|
78
79
|
update_supported_algorithms
|
79
|
-
update_preferred_algorithms
|
80
|
+
update_preferred_algorithms
|
80
81
|
initialize_local_algorithms
|
81
82
|
initialize_algorithms
|
82
83
|
end
|
@@ -185,6 +186,8 @@ module HrrRbSsh
|
|
185
186
|
@logger.info { "close transport" }
|
186
187
|
@closed = true
|
187
188
|
disconnect
|
189
|
+
@incoming_compression_algorithm.close
|
190
|
+
@outgoing_compression_algorithm.close
|
188
191
|
@logger.info { "transport closed" }
|
189
192
|
end
|
190
193
|
|
@@ -254,12 +257,12 @@ module HrrRbSsh
|
|
254
257
|
@supported_compression_algorithms = HrrRbSsh::Transport::CompressionAlgorithm.list_supported
|
255
258
|
end
|
256
259
|
|
257
|
-
def update_preferred_algorithms
|
258
|
-
@preferred_kex_algorithms = options['transport_preferred_kex_algorithms'] || HrrRbSsh::Transport::KexAlgorithm.list_preferred
|
259
|
-
@preferred_server_host_key_algorithms = options['transport_preferred_server_host_key_algorithms'] || HrrRbSsh::Transport::ServerHostKeyAlgorithm.list_preferred
|
260
|
-
@preferred_encryption_algorithms = options['transport_preferred_encryption_algorithms'] || HrrRbSsh::Transport::EncryptionAlgorithm.list_preferred
|
261
|
-
@preferred_mac_algorithms = options['transport_preferred_mac_algorithms'] || HrrRbSsh::Transport::MacAlgorithm.list_preferred
|
262
|
-
@preferred_compression_algorithms = options['transport_preferred_compression_algorithms'] || HrrRbSsh::Transport::CompressionAlgorithm.list_preferred
|
260
|
+
def update_preferred_algorithms
|
261
|
+
@preferred_kex_algorithms = @options['transport_preferred_kex_algorithms'] || HrrRbSsh::Transport::KexAlgorithm.list_preferred
|
262
|
+
@preferred_server_host_key_algorithms = @options['transport_preferred_server_host_key_algorithms'] || HrrRbSsh::Transport::ServerHostKeyAlgorithm.list_preferred
|
263
|
+
@preferred_encryption_algorithms = @options['transport_preferred_encryption_algorithms'] || HrrRbSsh::Transport::EncryptionAlgorithm.list_preferred
|
264
|
+
@preferred_mac_algorithms = @options['transport_preferred_mac_algorithms'] || HrrRbSsh::Transport::MacAlgorithm.list_preferred
|
265
|
+
@preferred_compression_algorithms = @options['transport_preferred_compression_algorithms'] || HrrRbSsh::Transport::CompressionAlgorithm.list_preferred
|
263
266
|
|
264
267
|
check_if_preferred_algorithms_are_supported
|
265
268
|
end
|
@@ -430,8 +433,9 @@ module HrrRbSsh
|
|
430
433
|
server_host_key_algorithm_name = @local_server_host_key_algorithms.find{ |a| @remote_server_host_key_algorithms.include? a } or raise
|
431
434
|
end
|
432
435
|
|
436
|
+
server_secret_host_key = @options.fetch('transport_server_secret_host_keys', {}).fetch(server_host_key_algorithm_name, nil)
|
433
437
|
@kex_algorithm = HrrRbSsh::Transport::KexAlgorithm[kex_algorithm_name].new
|
434
|
-
@server_host_key_algorithm = HrrRbSsh::Transport::ServerHostKeyAlgorithm[server_host_key_algorithm_name].new
|
438
|
+
@server_host_key_algorithm = HrrRbSsh::Transport::ServerHostKeyAlgorithm[server_host_key_algorithm_name].new server_secret_host_key
|
435
439
|
end
|
436
440
|
|
437
441
|
def update_encryption_mac_compression_algorithms
|
@@ -479,6 +483,8 @@ module HrrRbSsh
|
|
479
483
|
incoming_compression_algorithm_name = compression_algorithm_c_to_s_name
|
480
484
|
outgoing_compression_algorithm_name = compression_algorithm_s_to_c_name
|
481
485
|
end
|
486
|
+
@incoming_compression_algorithm.close
|
487
|
+
@outgoing_compression_algorithm.close
|
482
488
|
@incoming_compression_algorithm = HrrRbSsh::Transport::CompressionAlgorithm[incoming_compression_algorithm_name].new Direction::INCOMING
|
483
489
|
@outgoing_compression_algorithm = HrrRbSsh::Transport::CompressionAlgorithm[outgoing_compression_algorithm_name].new Direction::OUTGOING
|
484
490
|
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
# vim: et ts=2 sw=2
|
3
3
|
|
4
4
|
require 'hrr_rb_ssh/logger'
|
5
|
+
require 'hrr_rb_ssh/openssl_secure_random'
|
5
6
|
|
6
7
|
module HrrRbSsh
|
7
8
|
class Transport
|
@@ -11,17 +12,11 @@ module HrrRbSsh
|
|
11
12
|
PREFERENCE = 30
|
12
13
|
DIGEST = 'sha256'
|
13
14
|
IDENTIFIER = 'nistp256'
|
14
|
-
SECRET_KEY =
|
15
|
-
-----BEGIN EC PRIVATE KEY-----
|
16
|
-
MHcCAQEEIB+8vCekxXfgw+Nz10ZykUGaI+X6ftdGG6b2UX2iz7oEoAoGCCqGSM49
|
17
|
-
AwEHoUQDQgAEt1em9ko6A2kZFFwVtKgQ0xpggZg17EJQmhFz7ObGNsZ8VIFEc0Hg
|
18
|
-
SpNC6qrqdhUfVAjsF9y5O/3Z/LGh/lNTig==
|
19
|
-
-----END EC PRIVATE KEY-----
|
20
|
-
EOB
|
15
|
+
SECRET_KEY = OpenSSL::PKey::EC.new('prime256v1').generate_key.to_pem
|
21
16
|
|
22
|
-
def initialize
|
17
|
+
def initialize secret_key=nil
|
23
18
|
@logger = HrrRbSsh::Logger.new(self.class.name)
|
24
|
-
@algorithm = OpenSSL::PKey::EC.new SECRET_KEY
|
19
|
+
@algorithm = OpenSSL::PKey::EC.new (secret_key || self.class::SECRET_KEY)
|
25
20
|
end
|
26
21
|
|
27
22
|
def server_public_host_key
|
@@ -2,6 +2,7 @@
|
|
2
2
|
# vim: et ts=2 sw=2
|
3
3
|
|
4
4
|
require 'hrr_rb_ssh/logger'
|
5
|
+
require 'hrr_rb_ssh/openssl_secure_random'
|
5
6
|
|
6
7
|
module HrrRbSsh
|
7
8
|
class Transport
|
@@ -11,18 +12,11 @@ module HrrRbSsh
|
|
11
12
|
PREFERENCE = 40
|
12
13
|
DIGEST = 'sha384'
|
13
14
|
IDENTIFIER = 'nistp384'
|
14
|
-
SECRET_KEY =
|
15
|
-
-----BEGIN EC PRIVATE KEY-----
|
16
|
-
MIGkAgEBBDCKZ6ulBka9rUw+gqKiQdVBG6fzH1klswyMrxrzCcfwRfoc5CGnj8e7
|
17
|
-
emk+IHyUsd6gBwYFK4EEACKhZANiAATnWMWRgfp3DFiBmdT7LunyBk9YIBYqPsrk
|
18
|
-
Zil+AWvlISusiW2JcZVB+Hz79tyrgzfwp6n6k9r5s31EIGTGf/n7UMwISrUCfcx+
|
19
|
-
xVrnYV8pOoy+dcUiGb9okf1jc41bLHc=
|
20
|
-
-----END EC PRIVATE KEY-----
|
21
|
-
EOB
|
15
|
+
SECRET_KEY = OpenSSL::PKey::EC.new('secp384r1').generate_key.to_pem
|
22
16
|
|
23
|
-
def initialize
|
17
|
+
def initialize secret_key=nil
|
24
18
|
@logger = HrrRbSsh::Logger.new(self.class.name)
|
25
|
-
@algorithm = OpenSSL::PKey::EC.new SECRET_KEY
|
19
|
+
@algorithm = OpenSSL::PKey::EC.new (secret_key || self.class::SECRET_KEY)
|
26
20
|
end
|
27
21
|
|
28
22
|
def server_public_host_key
|
@@ -2,6 +2,7 @@
|
|
2
2
|
# vim: et ts=2 sw=2
|
3
3
|
|
4
4
|
require 'hrr_rb_ssh/logger'
|
5
|
+
require 'hrr_rb_ssh/openssl_secure_random'
|
5
6
|
|
6
7
|
module HrrRbSsh
|
7
8
|
class Transport
|
@@ -11,19 +12,11 @@ module HrrRbSsh
|
|
11
12
|
PREFERENCE = 50
|
12
13
|
DIGEST = 'sha512'
|
13
14
|
IDENTIFIER = 'nistp521'
|
14
|
-
SECRET_KEY =
|
15
|
-
-----BEGIN EC PRIVATE KEY-----
|
16
|
-
MIHcAgEBBEIByLZ82qYoJid43PwFAdhr3mSH7SalBTdrK8H6h4p3RKEisAsVhmVb
|
17
|
-
Sx+uGtgKVxxZT5s9tjr7W7Aqc6We5Fg9z7igBwYFK4EEACOhgYkDgYYABAFLHJ3H
|
18
|
-
6HBJyJFsN2PRsjJyRMfYE57BB8dmZgwTsHuSAXBkj+2g4ucwtF240zAWw6JOYdqE
|
19
|
-
V5O4BMNxGfYj+0ceKABJ4MgfUXQ3a1cXn8Dk2Q2uibbfVi7tQ7ET4k/A6B9f/Zwq
|
20
|
-
/zEM5OVWhfyc+vuEg+TfTtTqgVI2zJpLI7+mSjB/5Q==
|
21
|
-
-----END EC PRIVATE KEY-----
|
22
|
-
EOB
|
15
|
+
SECRET_KEY = OpenSSL::PKey::EC.new('secp521r1').generate_key.to_pem
|
23
16
|
|
24
|
-
def initialize
|
17
|
+
def initialize secret_key=nil
|
25
18
|
@logger = HrrRbSsh::Logger.new(self.class.name)
|
26
|
-
@algorithm = OpenSSL::PKey::EC.new SECRET_KEY
|
19
|
+
@algorithm = OpenSSL::PKey::EC.new (secret_key || self.class::SECRET_KEY)
|
27
20
|
end
|
28
21
|
|
29
22
|
def server_public_host_key
|
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
require 'hrr_rb_ssh/logger'
|
5
5
|
require 'hrr_rb_ssh/data_type'
|
6
|
+
require 'hrr_rb_ssh/openssl_secure_random'
|
6
7
|
|
7
8
|
module HrrRbSsh
|
8
9
|
class Transport
|
@@ -11,24 +12,11 @@ module HrrRbSsh
|
|
11
12
|
NAME = 'ssh-dss'
|
12
13
|
PREFERENCE = 10
|
13
14
|
DIGEST = 'sha1'
|
14
|
-
SECRET_KEY =
|
15
|
-
-----BEGIN DSA PRIVATE KEY-----
|
16
|
-
MIIBuwIBAAKBgQD3fQ6cwTtOJpVI0iASOQZxkhwPRNy7UwovQkEK6bXW33HaCebO
|
17
|
-
PnNiY/rR4uFhjvHRzF8KnC8xk3fNo4ZJQJlaEHv6qySiXHeX1fw/eo/uzM5WafLd
|
18
|
-
oaRtE2muky1i3FBCiboXDlNcwuA/efsOE5qsGBbk6svw+8pGolHmOZFSvQIVAN2G
|
19
|
-
ZxtE9Kqqh6z48/VulQZsrh5hAoGAH3191okH8kUwP3dinp5j5YtNzrJ20sBXNNZG
|
20
|
-
0aWjtS2xjSjIXjnlkiwhhvcUcCEkUQ507exvSLgf4dyV/V4+nf5Q5zjLztiSMe9D
|
21
|
-
qhTRIR23lsDu0OdITQihTu+Y4GEvNLUL9r2P1aoF/sde97xzzqmXPKx0UL1nNzcL
|
22
|
-
dnAdjjMCgYAa1dRvXe65jufPk0kRwhewRSScfg+YK4DOLUYGalsjHZbXtXqHKNpB
|
23
|
-
YkTlWKMg6QVREN0+5aNY1z1aJAbNboLz55YBnS9tOBYzvsXQF7ZP1ECMO6m4I8DI
|
24
|
-
wxt35i8hEVOJc+8x/xtmogzbjepar+1UycJQTMjhvqCW7RF4LuepvwIVANELTvnl
|
25
|
-
MRl/p42OrQzL/chRPvRf
|
26
|
-
-----END DSA PRIVATE KEY-----
|
27
|
-
EOB
|
15
|
+
SECRET_KEY = OpenSSL::PKey::DSA.new(1024).to_pem
|
28
16
|
|
29
|
-
def initialize
|
17
|
+
def initialize secret_key=nil
|
30
18
|
@logger = HrrRbSsh::Logger.new(self.class.name)
|
31
|
-
@dss = OpenSSL::PKey::DSA.new SECRET_KEY
|
19
|
+
@dss = OpenSSL::PKey::DSA.new (secret_key || self.class::SECRET_KEY)
|
32
20
|
end
|
33
21
|
|
34
22
|
def server_public_host_key
|
@@ -2,6 +2,7 @@
|
|
2
2
|
# vim: et ts=2 sw=2
|
3
3
|
|
4
4
|
require 'hrr_rb_ssh/logger'
|
5
|
+
require 'hrr_rb_ssh/openssl_secure_random'
|
5
6
|
|
6
7
|
module HrrRbSsh
|
7
8
|
class Transport
|
@@ -10,39 +11,11 @@ module HrrRbSsh
|
|
10
11
|
NAME = 'ssh-rsa'
|
11
12
|
PREFERENCE = 20
|
12
13
|
DIGEST = 'sha1'
|
13
|
-
SECRET_KEY =
|
14
|
-
-----BEGIN RSA PRIVATE KEY-----
|
15
|
-
MIIEpAIBAAKCAQEA71zHt9RvbXmxuOCWPKR65iBHO+a8M7Mfo4vRCs/dorZN7XL1
|
16
|
-
lYwjclvo0X1T39BRX+qJ2m4HB+7Vlef9YF7spYKm6czuSCYmJjD5X+PW5QYSGED1
|
17
|
-
fFSXwjTdDwJi1OKS4kL0Dd6zcSjlFxfjVLNCyUcix36XgDpoBLBFkDZd5P2ow3J6
|
18
|
-
WNanBasXrckjCk4M3kFclvmxl1O56bbV9VZq51ZqLjv/ZhOrE3WIPfrJGdZssODa
|
19
|
-
DnI6tM1puwZGVba9VaI8FfnuJcacJ3T9oEoXPY5W+kPZAw6dOARXnJTg+oZk/dBD
|
20
|
-
Bgej0aMO+1XM7HKz5BiqbhGGSXGas5zoefHbNwIDAQABAoIBAQDP2aQ/2EOuL8eI
|
21
|
-
/9TV8goafRr+RB1XU4r8zHOIzPnryhyfPX1OEDPToUXpa8gCiPWwsYxlVbfbRqTH
|
22
|
-
mHzoS2V5T5u7WE3t7tqfvVU+1C0OERhzYS0KeraRWLBA0VSbAeiEe5lL1f/CGr3c
|
23
|
-
MM0iBsvO1mu4ChBqs80RjTPKx7r/FStpWtqWN4kn+Bhj06qCqhftnudZdYFTHa/G
|
24
|
-
ia4YWOUH6dSIZKpE7oG53Gm/2ZdK2YiAgMOdrTQkvRzxuIa/RHaETj21hKpetmI7
|
25
|
-
TfS26RbU2t1Bf/fdFhtTqoAz+CrZEH7Z407ZO45fdc31zJAFIK2Zf3CDVnKwih3t
|
26
|
-
O0bEVSSpAoGBAP/zEWaTivdQtcemMRhFQBySgnStov+dsxnGBnTkWxVIU7VoFgyg
|
27
|
-
mgNRlWUxMf12mlfqBVRpx0/ALggHf5KFmbAZ+3qvKSLmfIVM5E9l5NKbZnCWtIqq
|
28
|
-
1DN9kHPPOZn3uYvOs9Cpn7S6sa+rVZ82Mg8EZMsPesvFMOjrgNbMQxt7AoGBAO9o
|
29
|
-
38VM0+M09sAgOhmqv+Esa2gUGw5n18o/fdmlZdnA+D2ntgr70AD6JUCSYrZgTJRq
|
30
|
-
HNMuKrbD6HyaPjVaxYJVCFJIcfV+nViZdE8cHh9WXQ/JP/T6nvNajCC8StvoQg4I
|
31
|
-
vAZFTzChoe2yrOsWXezn9QAecQ8L2WHDLImpayR1AoGADoc1jaUCVld2egas8ru7
|
32
|
-
j+OhFA5nGitRZz0eULRFl0eruLhXyA+1rkqLOFs6gzCgQi0+cDQw5A38jugeDasX
|
33
|
-
ti9DXwtiQmDi4I4kx3z5KBs6DVoAlX5s3R9be7dfhaXSGmV5P3bhYdjXDSmkio0A
|
34
|
-
+mk9b2lJhxeCVzZG8epWRNECgYB2KzGoVQ+Q6ieRFVcYLCuhnSc2rBXeumrMrSIV
|
35
|
-
N4paPOFKrWkxarF0igOxJ5AJrOafqvCnW/ZBV9l9BzUFaNRsTERbON7m6aQIg1Xh
|
36
|
-
ZmOH3Dz6+b7T0JB8VYks70OT38Qa4TzNa5B21JD0nmizcMrTkHphoKT1ZEfb9VYa
|
37
|
-
bMExsQKBgQDoSpo/ZP8+dwR1A/gcu2K5Ie47c3WgKw7qQMarxqzTeS8Xu6/KAn+J
|
38
|
-
Ka2zIvoHhxlhXFBRhp+FIaFlYRR38gHeNxCoUylpboCUyMkHOsOP43AiKsmbNK20
|
39
|
-
vzTNM3SFzgt3bHkdEtDLc64aoBX+dHOot6u71XLZrshnHPtiZ0C/ZA==
|
40
|
-
-----END RSA PRIVATE KEY-----
|
41
|
-
EOB
|
14
|
+
SECRET_KEY = OpenSSL::PKey::RSA.new(2048).to_pem
|
42
15
|
|
43
|
-
def initialize
|
16
|
+
def initialize secret_key=nil
|
44
17
|
@logger = HrrRbSsh::Logger.new(self.class.name)
|
45
|
-
@rsa = OpenSSL::PKey::RSA.new SECRET_KEY
|
18
|
+
@rsa = OpenSSL::PKey::RSA.new (secret_key || self.class::SECRET_KEY)
|
46
19
|
end
|
47
20
|
|
48
21
|
def server_public_host_key
|
data/lib/hrr_rb_ssh/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hrr_rb_ssh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- hirura
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-05-
|
11
|
+
date: 2018-05-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -193,6 +193,7 @@ files:
|
|
193
193
|
- lib/hrr_rb_ssh/message/098_ssh_msg_channel_request.rb
|
194
194
|
- lib/hrr_rb_ssh/message/099_ssh_msg_channel_success.rb
|
195
195
|
- lib/hrr_rb_ssh/message/100_ssh_msg_channel_failure.rb
|
196
|
+
- lib/hrr_rb_ssh/openssl_secure_random.rb
|
196
197
|
- lib/hrr_rb_ssh/subclass_with_preference_listable.rb
|
197
198
|
- lib/hrr_rb_ssh/transport.rb
|
198
199
|
- lib/hrr_rb_ssh/transport/compression_algorithm.rb
|