hrr_rb_ssh 0.1.9 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +12 -2
- data/README.md +11 -9
- data/demo/echo_server.rb +50 -42
- data/demo/server.rb +81 -62
- data/demo/subsystem_echo_server.rb +54 -47
- data/lib/hrr_rb_ssh/{transport/server_host_key_algorithm/ecdsa_sha2_nistp521 → algorithm/publickey/ecdsa_sha2}/ecdsa_signature_blob.rb +3 -3
- data/lib/hrr_rb_ssh/{transport/server_host_key_algorithm/ecdsa_sha2_nistp256 → algorithm/publickey/ecdsa_sha2}/public_key_blob.rb +5 -6
- data/lib/hrr_rb_ssh/{transport/server_host_key_algorithm/ecdsa_sha2_nistp256 → algorithm/publickey/ecdsa_sha2}/signature.rb +5 -5
- data/lib/hrr_rb_ssh/algorithm/publickey/ecdsa_sha2.rb +85 -0
- data/lib/hrr_rb_ssh/algorithm/publickey/ecdsa_sha2_nistp256.rb +19 -0
- data/lib/hrr_rb_ssh/algorithm/publickey/ecdsa_sha2_nistp384.rb +19 -0
- data/lib/hrr_rb_ssh/algorithm/publickey/ecdsa_sha2_nistp521.rb +19 -0
- data/lib/hrr_rb_ssh/{transport/server_host_key_algorithm → algorithm/publickey}/ssh_dss/public_key_blob.rb +3 -3
- data/lib/hrr_rb_ssh/{transport/server_host_key_algorithm → algorithm/publickey}/ssh_dss/signature.rb +4 -4
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_dss.rb +90 -0
- data/lib/hrr_rb_ssh/{transport/server_host_key_algorithm → algorithm/publickey}/ssh_rsa/public_key_blob.rb +3 -4
- data/lib/hrr_rb_ssh/{transport/server_host_key_algorithm → algorithm/publickey}/ssh_rsa/signature.rb +4 -4
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_rsa.rb +67 -0
- data/lib/hrr_rb_ssh/algorithm/publickey.rb +32 -0
- data/lib/hrr_rb_ssh/algorithm.rb +9 -0
- data/lib/hrr_rb_ssh/authentication/method/none/context.rb +1 -1
- data/lib/hrr_rb_ssh/authentication/method/none.rb +1 -1
- data/lib/hrr_rb_ssh/authentication/method/password/context.rb +1 -1
- data/lib/hrr_rb_ssh/authentication/method/password.rb +1 -1
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp256.rb +2 -65
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp384.rb +2 -65
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp521.rb +2 -65
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/functionable.rb +54 -0
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/signature_blob.rb +31 -0
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_dss.rb +2 -73
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_rsa.rb +2 -55
- data/lib/hrr_rb_ssh/authentication/method/publickey.rb +3 -3
- data/lib/hrr_rb_ssh/authentication.rb +15 -15
- data/lib/hrr_rb_ssh/codable.rb +1 -1
- data/lib/hrr_rb_ssh/compat/openssh/public_key.rb +3 -40
- data/lib/hrr_rb_ssh/compat/ruby/array.rb +14 -0
- data/lib/hrr_rb_ssh/compat/ruby/openssl/bn.rb +20 -0
- data/lib/hrr_rb_ssh/compat/ruby/openssl.rb +4 -0
- data/lib/hrr_rb_ssh/compat/ruby/queue.rb +38 -0
- data/lib/hrr_rb_ssh/compat/ruby.rb +6 -0
- data/lib/hrr_rb_ssh/compat.rb +1 -63
- data/lib/hrr_rb_ssh/connection/channel/channel_type/direct_tcpip.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/forwarded_tcpip.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/proc_chain/chain_context.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/proc_chain.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/env/context.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/env.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/exec/context.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/exec.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/pty_req/context.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/pty_req.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/shell/context.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/shell.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/subsystem/context.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/subsystem.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/window_change/context.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/window_change.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel.rb +22 -22
- data/lib/hrr_rb_ssh/connection/global_request_handler.rb +1 -1
- data/lib/hrr_rb_ssh/connection/request_handler/reference_env_request_handler.rb +1 -1
- data/lib/hrr_rb_ssh/connection/request_handler/reference_exec_request_handler.rb +3 -56
- data/lib/hrr_rb_ssh/connection/request_handler/reference_pty_req_request_handler.rb +50 -13
- data/lib/hrr_rb_ssh/connection/request_handler/reference_shell_request_handler.rb +3 -56
- data/lib/hrr_rb_ssh/connection/request_handler/reference_window_change_request_handler.rb +1 -1
- data/lib/hrr_rb_ssh/connection/request_handler.rb +1 -1
- data/lib/hrr_rb_ssh/connection.rb +40 -40
- data/lib/hrr_rb_ssh/data_type.rb +0 -3
- data/lib/hrr_rb_ssh/error/closed_authentication.rb +9 -0
- data/lib/hrr_rb_ssh/{closed_transport_error.rb → error/closed_connection.rb} +3 -1
- data/lib/hrr_rb_ssh/{closed_authentication_error.rb → error/closed_transport.rb} +3 -1
- data/lib/hrr_rb_ssh/error.rb +11 -0
- data/lib/hrr_rb_ssh/{closed_connection_error.rb → mode.rb} +3 -1
- data/lib/hrr_rb_ssh/server.rb +23 -0
- data/lib/hrr_rb_ssh/transport/compression_algorithm/functionable.rb +1 -1
- data/lib/hrr_rb_ssh/transport/compression_algorithm/unfunctionable.rb +1 -1
- data/lib/hrr_rb_ssh/transport/encryption_algorithm/functionable.rb +3 -3
- data/lib/hrr_rb_ssh/transport/encryption_algorithm/unfunctionable.rb +1 -1
- data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman.rb +8 -48
- data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb +11 -51
- data/lib/hrr_rb_ssh/transport/kex_algorithm/elliptic_curve_diffie_hellman.rb +8 -48
- data/lib/hrr_rb_ssh/transport/kex_algorithm/iv_computable.rb +57 -0
- data/lib/hrr_rb_ssh/transport/mac_algorithm/functionable.rb +2 -2
- data/lib/hrr_rb_ssh/transport/mac_algorithm/unfunctionable.rb +1 -1
- data/lib/hrr_rb_ssh/transport/receiver.rb +1 -1
- data/lib/hrr_rb_ssh/transport/sender.rb +1 -1
- data/lib/hrr_rb_ssh/transport/sequence_number.rb +1 -1
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp256.rb +2 -56
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp384.rb +2 -56
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp521.rb +2 -56
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/functionable.rb +29 -0
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_dss.rb +2 -50
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_rsa.rb +2 -31
- data/lib/hrr_rb_ssh/transport.rb +83 -81
- data/lib/hrr_rb_ssh/version.rb +1 -1
- data/lib/hrr_rb_ssh.rb +4 -0
- metadata +32 -37
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp256/ecdsa_signature_blob.rb +0 -27
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp256/public_key_blob.rb +0 -28
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp256/signature.rb +0 -27
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp256/signature_blob.rb +0 -33
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp384/ecdsa_signature_blob.rb +0 -27
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp384/public_key_blob.rb +0 -28
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp384/signature.rb +0 -27
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp384/signature_blob.rb +0 -33
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp521/ecdsa_signature_blob.rb +0 -27
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp521/public_key_blob.rb +0 -28
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp521/signature.rb +0 -27
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp521/signature_blob.rb +0 -33
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_dss/public_key_blob.rb +0 -30
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_dss/signature.rb +0 -27
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_dss/signature_blob.rb +0 -33
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_rsa/public_key_blob.rb +0 -28
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_rsa/signature.rb +0 -27
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_rsa/signature_blob.rb +0 -33
- data/lib/hrr_rb_ssh/transport/mode.rb +0 -11
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp256/ecdsa_signature_blob.rb +0 -23
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp384/ecdsa_signature_blob.rb +0 -23
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp384/public_key_blob.rb +0 -25
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp384/signature.rb +0 -23
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp521/public_key_blob.rb +0 -25
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp521/signature.rb +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fa22df4a3d01a18e8f66b69b73f5b189233de3d4c755f1d371f15043c0202c8f
|
4
|
+
data.tar.gz: e426371cf62d6d6705915a58b5811774e984be1f55b1e2f11db5925d0f14d08f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3e47080fab89ae9eafab849adf065dfa4a2f58f18f189aaef269d4b8d50729acad8d7d0c5306e462e583200878da878b84b4579a63788e8dd9859501102c1440
|
7
|
+
data.tar.gz: 974b64d45859b689e6965d98ab749375ed082f6bbc72bc1ee59c1c2e6a8e59ca8bf7e25ff1304a6e9eb415763457dc9678447e363300d3106c63a84a7a9bbd03
|
data/.travis.yml
CHANGED
@@ -10,8 +10,18 @@ rvm:
|
|
10
10
|
- 2.3
|
11
11
|
- 2.4
|
12
12
|
- 2.5
|
13
|
-
|
14
|
-
|
13
|
+
- ruby-head
|
14
|
+
os:
|
15
|
+
- linux
|
16
|
+
matrix:
|
17
|
+
allow_failures:
|
18
|
+
- rvm: ruby-head
|
19
|
+
before_install:
|
20
|
+
- gem update --system --no-document
|
21
|
+
- gem update --no-document
|
22
|
+
install:
|
23
|
+
- gem install bundler --no-document
|
24
|
+
- bundle install --path vendor/bundle
|
15
25
|
before_script:
|
16
26
|
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
17
27
|
- chmod +x ./cc-test-reporter
|
data/README.md
CHANGED
@@ -72,13 +72,18 @@ The library is to run on a socket IO. To start SSH server, running a server IO a
|
|
72
72
|
```ruby
|
73
73
|
options = Hash.new
|
74
74
|
server = TCPServer.new 10022
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
75
|
+
loop do
|
76
|
+
Thread.new(server.accept) do |io|
|
77
|
+
pid = fork do
|
78
|
+
begin
|
79
|
+
server = HrrRbSsh::Server.new io, options
|
80
|
+
server.start
|
81
|
+
ensure
|
82
|
+
io.close
|
83
|
+
end
|
84
|
+
end
|
81
85
|
io.close
|
86
|
+
Process.waitpid pid
|
82
87
|
end
|
83
88
|
end
|
84
89
|
```
|
@@ -216,7 +221,6 @@ It is also possible to define customized request handlers. For instance, echo se
|
|
216
221
|
|
217
222
|
```ruby
|
218
223
|
conn_echo = HrrRbSsh::Connection::RequestHandler.new { |context|
|
219
|
-
context.io[2].close
|
220
224
|
context.chain_proc { |chain|
|
221
225
|
begin
|
222
226
|
loop do
|
@@ -228,8 +232,6 @@ conn_echo = HrrRbSsh::Connection::RequestHandler.new { |context|
|
|
228
232
|
rescue => e
|
229
233
|
logger.error([e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join)
|
230
234
|
exitstatus = 1
|
231
|
-
ensure
|
232
|
-
context.io[1].close
|
233
235
|
end
|
234
236
|
exitstatus
|
235
237
|
}
|
data/demo/echo_server.rb
CHANGED
@@ -4,60 +4,68 @@
|
|
4
4
|
require 'logger'
|
5
5
|
require 'socket'
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
logger = Logger.new STDOUT
|
16
|
-
logger.level = Logger::INFO
|
17
|
-
HrrRbSsh::Logger.initialize logger
|
7
|
+
def start_service io, logger=nil
|
8
|
+
begin
|
9
|
+
require 'hrr_rb_ssh'
|
10
|
+
rescue LoadError
|
11
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
12
|
+
require 'hrr_rb_ssh'
|
13
|
+
end
|
18
14
|
|
15
|
+
HrrRbSsh::Logger.initialize logger if logger
|
19
16
|
|
20
|
-
auth_password = HrrRbSsh::Authentication::Authenticator.new { |context|
|
21
|
-
|
22
|
-
}
|
17
|
+
auth_password = HrrRbSsh::Authentication::Authenticator.new { |context|
|
18
|
+
true # accept any user and password
|
19
|
+
}
|
23
20
|
|
24
|
-
conn_echo = HrrRbSsh::Connection::RequestHandler.new { |context|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
21
|
+
conn_echo = HrrRbSsh::Connection::RequestHandler.new { |context|
|
22
|
+
context.chain_proc { |chain|
|
23
|
+
begin
|
24
|
+
loop do
|
25
|
+
buf = context.io[0].readpartial(10240)
|
26
|
+
break if buf.include?(0x04.chr) # break if ^D
|
27
|
+
context.io[1].write buf
|
28
|
+
end
|
29
|
+
exitstatus = 0
|
30
|
+
rescue => e
|
31
|
+
logger.error([e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join)
|
32
|
+
exitstatus = 1
|
32
33
|
end
|
33
|
-
exitstatus
|
34
|
-
|
35
|
-
logger.error([e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join)
|
36
|
-
exitstatus = 1
|
37
|
-
ensure
|
38
|
-
context.io[1].close
|
39
|
-
end
|
40
|
-
exitstatus
|
34
|
+
exitstatus
|
35
|
+
}
|
41
36
|
}
|
42
|
-
}
|
43
37
|
|
44
|
-
options = {}
|
45
|
-
options['authentication_password_authenticator'] = auth_password
|
46
|
-
options['connection_channel_request_shell'] = conn_echo
|
38
|
+
options = {}
|
39
|
+
options['authentication_password_authenticator'] = auth_password
|
40
|
+
options['connection_channel_request_shell'] = conn_echo
|
41
|
+
|
42
|
+
server = HrrRbSsh::Server.new io, options
|
43
|
+
server.start
|
44
|
+
end
|
47
45
|
|
46
|
+
logger = Logger.new STDOUT
|
47
|
+
logger.level = Logger::INFO
|
48
48
|
|
49
49
|
server = TCPServer.new 10022
|
50
|
-
|
51
|
-
|
50
|
+
loop do
|
51
|
+
Thread.new(server.accept) do |io|
|
52
52
|
begin
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
53
|
+
pid = fork do
|
54
|
+
begin
|
55
|
+
start_service io, logger
|
56
|
+
rescue => e
|
57
|
+
logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
58
|
+
exit false
|
59
|
+
end
|
60
|
+
end
|
61
|
+
logger.info { "process #{pid} started" }
|
62
|
+
io.close rescue nil
|
63
|
+
pid, status = Process.waitpid2 pid
|
57
64
|
rescue => e
|
58
|
-
logger.error
|
65
|
+
logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
59
66
|
ensure
|
60
|
-
|
67
|
+
status ||= nil
|
68
|
+
logger.info { "process #{pid} finished with status #{status.inspect}" }
|
61
69
|
end
|
62
70
|
end
|
63
71
|
end
|
data/demo/server.rb
CHANGED
@@ -1,89 +1,108 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
# vim: et ts=2 sw=2
|
3
3
|
|
4
|
-
require 'etc'
|
5
4
|
require 'logger'
|
6
5
|
require 'socket'
|
7
6
|
|
8
|
-
begin
|
9
|
-
require 'hrr_rb_ssh'
|
10
|
-
rescue LoadError
|
11
|
-
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
12
|
-
require 'hrr_rb_ssh'
|
13
|
-
end
|
14
7
|
|
8
|
+
def start_service io, logger=nil
|
9
|
+
require 'etc'
|
15
10
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
11
|
+
begin
|
12
|
+
require 'hrr_rb_ssh'
|
13
|
+
rescue LoadError
|
14
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
15
|
+
require 'hrr_rb_ssh'
|
16
|
+
end
|
17
|
+
|
18
|
+
HrrRbSsh::Logger.initialize logger if logger
|
19
|
+
|
20
|
+
tran_preferred_encryption_algorithms = %w(aes128-ctr aes192-ctr aes256-ctr aes128-cbc 3des-cbc blowfish-cbc cast128-cbc aes192-cbc aes256-cbc arcfour)
|
21
|
+
tran_preferred_server_host_key_algorithms = %w(ecdsa-sha2-nistp521 ecdsa-sha2-nistp384 ecdsa-sha2-nistp256 ssh-rsa ssh-dss)
|
22
|
+
tran_preferred_kex_algorithms = %w(ecdh-sha2-nistp521 ecdh-sha2-nistp384 ecdh-sha2-nistp256 diffie-hellman-group14-sha1 diffie-hellman-group1-sha1)
|
23
|
+
tran_preferred_mac_algorithms = %w(hmac-sha2-512 hmac-sha2-256 hmac-sha1 hmac-md5 hmac-sha1-96 hmac-md5-96)
|
24
|
+
tran_preferred_compression_algorithms = %w(none zlib)
|
25
|
+
|
26
|
+
auth_none = HrrRbSsh::Authentication::Authenticator.new { |context|
|
27
|
+
false
|
28
|
+
}
|
29
|
+
auth_publickey = HrrRbSsh::Authentication::Authenticator.new { |context|
|
30
|
+
users = ['user1', 'user2']
|
31
|
+
users.any?{ |username|
|
32
|
+
passwd = Etc.getpwnam(username)
|
33
|
+
homedir = passwd.dir
|
34
|
+
authorized_keys = HrrRbSsh::Compat::OpenSSH::AuthorizedKeys.new(File.read(File.join(homedir, '.ssh', 'authorized_keys')))
|
35
|
+
authorized_keys.any?{ |public_key|
|
36
|
+
context.verify username, public_key.algorithm_name, public_key.to_pem
|
37
|
+
}
|
38
38
|
}
|
39
39
|
}
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
40
|
+
auth_password = HrrRbSsh::Authentication::Authenticator.new { |context|
|
41
|
+
user_and_pass = [
|
42
|
+
['user1', 'password1'],
|
43
|
+
['user2', 'password2'],
|
44
|
+
]
|
45
|
+
user_and_pass.any? { |user, pass|
|
46
|
+
context.verify user, pass
|
47
|
+
}
|
48
48
|
}
|
49
|
-
}
|
50
49
|
|
51
50
|
|
52
|
-
options = {}
|
51
|
+
options = {}
|
53
52
|
|
54
|
-
options['transport_preferred_encryption_algorithms'] = tran_preferred_encryption_algorithms
|
55
|
-
options['transport_preferred_server_host_key_algorithms'] = tran_preferred_server_host_key_algorithms
|
56
|
-
options['transport_preferred_kex_algorithms'] = tran_preferred_kex_algorithms
|
57
|
-
options['transport_preferred_mac_algorithms'] = tran_preferred_mac_algorithms
|
58
|
-
options['transport_preferred_compression_algorithms'] = tran_preferred_compression_algorithms
|
53
|
+
options['transport_preferred_encryption_algorithms'] = tran_preferred_encryption_algorithms
|
54
|
+
options['transport_preferred_server_host_key_algorithms'] = tran_preferred_server_host_key_algorithms
|
55
|
+
options['transport_preferred_kex_algorithms'] = tran_preferred_kex_algorithms
|
56
|
+
options['transport_preferred_mac_algorithms'] = tran_preferred_mac_algorithms
|
57
|
+
options['transport_preferred_compression_algorithms'] = tran_preferred_compression_algorithms
|
59
58
|
|
60
|
-
options['transport_server_secret_host_keys'] = {}
|
61
|
-
options['transport_server_secret_host_keys']['ecdsa-sha2-nistp256'] = <<-'EOB'
|
59
|
+
options['transport_server_secret_host_keys'] = {}
|
60
|
+
options['transport_server_secret_host_keys']['ecdsa-sha2-nistp256'] = <<-'EOB'
|
62
61
|
-----BEGIN EC PRIVATE KEY-----
|
63
62
|
MHcCAQEEIFFtGZHk6A8anZkLCJan9YBlB63uCIN/ZcQNCaJout8loAoGCCqGSM49
|
64
63
|
AwEHoUQDQgAEk8m548Xga+XGEmRx7P71xGlxCfgjPj3XVOw+fXPXRgA03a5yDJEp
|
65
64
|
OfeosJOO9twerD7pPhmXREkygblPsEXaVA==
|
66
65
|
-----END EC PRIVATE KEY-----
|
67
|
-
EOB
|
66
|
+
EOB
|
68
67
|
|
69
|
-
options['authentication_none_authenticator'] = auth_none
|
70
|
-
options['authentication_publickey_authenticator'] = auth_publickey
|
71
|
-
options['authentication_password_authenticator'] = auth_password
|
68
|
+
options['authentication_none_authenticator'] = auth_none
|
69
|
+
options['authentication_publickey_authenticator'] = auth_publickey
|
70
|
+
options['authentication_password_authenticator'] = auth_password
|
72
71
|
|
73
|
-
options['connection_channel_request_pty_req'] = HrrRbSsh::Connection::RequestHandler::ReferencePtyReqRequestHandler.new
|
74
|
-
options['connection_channel_request_env'] = HrrRbSsh::Connection::RequestHandler::ReferenceEnvRequestHandler.new
|
75
|
-
options['connection_channel_request_shell'] = HrrRbSsh::Connection::RequestHandler::ReferenceShellRequestHandler.new
|
76
|
-
options['connection_channel_request_exec'] = HrrRbSsh::Connection::RequestHandler::ReferenceExecRequestHandler.new
|
77
|
-
options['connection_channel_request_window_change'] = HrrRbSsh::Connection::RequestHandler::ReferenceWindowChangeRequestHandler.new
|
72
|
+
options['connection_channel_request_pty_req'] = HrrRbSsh::Connection::RequestHandler::ReferencePtyReqRequestHandler.new
|
73
|
+
options['connection_channel_request_env'] = HrrRbSsh::Connection::RequestHandler::ReferenceEnvRequestHandler.new
|
74
|
+
options['connection_channel_request_shell'] = HrrRbSsh::Connection::RequestHandler::ReferenceShellRequestHandler.new
|
75
|
+
options['connection_channel_request_exec'] = HrrRbSsh::Connection::RequestHandler::ReferenceExecRequestHandler.new
|
76
|
+
options['connection_channel_request_window_change'] = HrrRbSsh::Connection::RequestHandler::ReferenceWindowChangeRequestHandler.new
|
77
|
+
|
78
|
+
server = HrrRbSsh::Server.new io, options
|
79
|
+
server.start
|
80
|
+
end
|
78
81
|
|
79
82
|
|
83
|
+
logger = Logger.new STDOUT
|
84
|
+
logger.level = Logger::INFO
|
85
|
+
|
80
86
|
server = TCPServer.new 10022
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
87
|
+
loop do
|
88
|
+
Thread.new(server.accept) do |io|
|
89
|
+
begin
|
90
|
+
pid = fork do
|
91
|
+
begin
|
92
|
+
start_service io, logger
|
93
|
+
rescue => e
|
94
|
+
logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
95
|
+
exit false
|
96
|
+
end
|
97
|
+
end
|
98
|
+
logger.info { "process #{pid} started" }
|
99
|
+
io.close rescue nil
|
100
|
+
pid, status = Process.waitpid2 pid
|
101
|
+
rescue => e
|
102
|
+
logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
103
|
+
ensure
|
104
|
+
status ||= nil
|
105
|
+
logger.info { "process #{pid} finished with status #{status.inspect}" }
|
106
|
+
end
|
88
107
|
end
|
89
108
|
end
|
@@ -4,69 +4,76 @@
|
|
4
4
|
require 'logger'
|
5
5
|
require 'socket'
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
logger = Logger.new STDOUT
|
16
|
-
logger.level = Logger::INFO
|
17
|
-
HrrRbSsh::Logger.initialize logger
|
7
|
+
def start_service io, logger=nil
|
8
|
+
begin
|
9
|
+
require 'hrr_rb_ssh'
|
10
|
+
rescue LoadError
|
11
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
12
|
+
require 'hrr_rb_ssh'
|
13
|
+
end
|
18
14
|
|
15
|
+
HrrRbSsh::Logger.initialize logger if logger
|
19
16
|
|
20
|
-
auth_password = HrrRbSsh::Authentication::Authenticator.new { |context|
|
21
|
-
|
22
|
-
}
|
17
|
+
auth_password = HrrRbSsh::Authentication::Authenticator.new { |context|
|
18
|
+
true # accept any user and password
|
19
|
+
}
|
23
20
|
|
24
|
-
conn_echo = HrrRbSsh::Connection::RequestHandler.new { |context|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
21
|
+
conn_echo = HrrRbSsh::Connection::RequestHandler.new { |context|
|
22
|
+
context.chain_proc { |chain|
|
23
|
+
case context.subsystem_name
|
24
|
+
when 'echo'
|
25
|
+
begin
|
26
|
+
loop do
|
27
|
+
begin
|
28
|
+
buf = context.io[0].readpartial(10240)
|
29
|
+
rescue EOFError
|
30
|
+
break
|
31
|
+
end
|
32
|
+
context.io[1].write buf
|
35
33
|
end
|
36
|
-
|
34
|
+
exitstatus = 0
|
35
|
+
rescue => e
|
36
|
+
logger.error([e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join)
|
37
|
+
exitstatus = 1
|
37
38
|
end
|
39
|
+
else
|
38
40
|
exitstatus = 0
|
39
|
-
rescue => e
|
40
|
-
logger.error([e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join)
|
41
|
-
exitstatus = 1
|
42
|
-
ensure
|
43
|
-
context.io[1].close
|
44
41
|
end
|
45
|
-
|
46
|
-
|
47
|
-
exitstatus = 0
|
48
|
-
end
|
49
|
-
exitstatus
|
42
|
+
exitstatus
|
43
|
+
}
|
50
44
|
}
|
51
|
-
}
|
52
45
|
|
53
|
-
options = {}
|
54
|
-
options['authentication_password_authenticator'] = auth_password
|
55
|
-
options['connection_channel_request_subsystem'] = conn_echo
|
46
|
+
options = {}
|
47
|
+
options['authentication_password_authenticator'] = auth_password
|
48
|
+
options['connection_channel_request_subsystem'] = conn_echo
|
56
49
|
|
50
|
+
server = HrrRbSsh::Server.new io, options
|
51
|
+
server.start
|
52
|
+
end
|
53
|
+
|
54
|
+
logger = Logger.new STDOUT
|
55
|
+
logger.level = Logger::INFO
|
57
56
|
|
58
57
|
server = TCPServer.new 10022
|
59
58
|
while true
|
60
|
-
|
59
|
+
Thread.new(server.accept) do |io|
|
61
60
|
begin
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
61
|
+
pid = fork do
|
62
|
+
begin
|
63
|
+
start_service io, logger
|
64
|
+
rescue => e
|
65
|
+
logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
66
|
+
exit false
|
67
|
+
end
|
68
|
+
end
|
69
|
+
logger.info { "process #{pid} started" }
|
70
|
+
io.close rescue nil
|
71
|
+
pid, status = Process.waitpid2 pid
|
66
72
|
rescue => e
|
67
|
-
logger.error
|
73
|
+
logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
68
74
|
ensure
|
69
|
-
|
75
|
+
status ||= nil
|
76
|
+
logger.info { "process #{pid} finished with status #{status.inspect}" }
|
70
77
|
end
|
71
78
|
end
|
72
79
|
end
|
@@ -5,9 +5,9 @@ require 'hrr_rb_ssh/data_type'
|
|
5
5
|
require 'hrr_rb_ssh/codable'
|
6
6
|
|
7
7
|
module HrrRbSsh
|
8
|
-
|
9
|
-
class
|
10
|
-
|
8
|
+
module Algorithm
|
9
|
+
class Publickey
|
10
|
+
module EcdsaSha2
|
11
11
|
module EcdsaSignatureBlob
|
12
12
|
class << self
|
13
13
|
include Codable
|
@@ -5,16 +5,16 @@ require 'hrr_rb_ssh/data_type'
|
|
5
5
|
require 'hrr_rb_ssh/codable'
|
6
6
|
|
7
7
|
module HrrRbSsh
|
8
|
-
|
9
|
-
class
|
10
|
-
|
8
|
+
module Algorithm
|
9
|
+
class Publickey
|
10
|
+
module EcdsaSha2
|
11
11
|
module PublicKeyBlob
|
12
12
|
class << self
|
13
13
|
include Codable
|
14
14
|
end
|
15
15
|
DEFINITION = [
|
16
|
-
[DataType::String, :'
|
17
|
-
[DataType::String, :'
|
16
|
+
[DataType::String, :'public key algorithm name'],
|
17
|
+
[DataType::String, :'identifier'],
|
18
18
|
[DataType::String, :'Q'],
|
19
19
|
]
|
20
20
|
end
|
@@ -22,4 +22,3 @@ module HrrRbSsh
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
25
|
-
|
@@ -5,16 +5,16 @@ require 'hrr_rb_ssh/data_type'
|
|
5
5
|
require 'hrr_rb_ssh/codable'
|
6
6
|
|
7
7
|
module HrrRbSsh
|
8
|
-
|
9
|
-
class
|
10
|
-
|
8
|
+
module Algorithm
|
9
|
+
class Publickey
|
10
|
+
module EcdsaSha2
|
11
11
|
module Signature
|
12
12
|
class << self
|
13
13
|
include Codable
|
14
14
|
end
|
15
15
|
DEFINITION = [
|
16
|
-
[DataType::String, :'
|
17
|
-
[DataType::String, :'
|
16
|
+
[DataType::String, :'public key algorithm name'],
|
17
|
+
[DataType::String, :'ecdsa signature blob'],
|
18
18
|
]
|
19
19
|
end
|
20
20
|
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# vim: et ts=2 sw=2
|
3
|
+
|
4
|
+
require 'hrr_rb_ssh/logger'
|
5
|
+
require 'hrr_rb_ssh/data_type'
|
6
|
+
|
7
|
+
module HrrRbSsh
|
8
|
+
module Algorithm
|
9
|
+
class Publickey
|
10
|
+
module EcdsaSha2
|
11
|
+
def initialize arg
|
12
|
+
begin
|
13
|
+
new_by_key_str arg
|
14
|
+
rescue OpenSSL::PKey::ECError
|
15
|
+
new_by_public_key_blob arg
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def new_by_key_str key_str
|
20
|
+
@publickey = OpenSSL::PKey::EC.new(key_str.delete(0.chr))
|
21
|
+
end
|
22
|
+
|
23
|
+
def new_by_public_key_blob public_key_blob
|
24
|
+
public_key_blob_h = PublicKeyBlob.decode(public_key_blob)
|
25
|
+
@publickey = OpenSSL::PKey::EC.new(self.class::CURVE_NAME)
|
26
|
+
@publickey.public_key = OpenSSL::PKey::EC::Point.new(@publickey.group, OpenSSL::BN.new(public_key_blob_h[:'Q'], 2))
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_pem
|
30
|
+
@publickey.to_pem
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_public_key_blob
|
34
|
+
public_key_blob_h = {
|
35
|
+
:'public key algorithm name' => self.class::NAME,
|
36
|
+
:'identifier' => self.class::IDENTIFIER,
|
37
|
+
:'Q' => @publickey.public_key.to_bn.to_s(2)
|
38
|
+
}
|
39
|
+
PublicKeyBlob.encode(public_key_blob_h)
|
40
|
+
end
|
41
|
+
|
42
|
+
def ecdsa_signature_blob signature_blob
|
43
|
+
hash = OpenSSL::Digest.digest(self.class::DIGEST, signature_blob)
|
44
|
+
sign_der = @publickey.dsa_sign_asn1(hash)
|
45
|
+
sign_asn1 = OpenSSL::ASN1.decode(sign_der)
|
46
|
+
r = sign_asn1.value[0].value.to_i
|
47
|
+
s = sign_asn1.value[1].value.to_i
|
48
|
+
ecdsa_signature_blob_h = {
|
49
|
+
:'r' => r,
|
50
|
+
:'s' => s,
|
51
|
+
}
|
52
|
+
EcdsaSignatureBlob.encode ecdsa_signature_blob_h
|
53
|
+
end
|
54
|
+
|
55
|
+
def sign signature_blob
|
56
|
+
signature_h = {
|
57
|
+
:'public key algorithm name' => self.class::NAME,
|
58
|
+
:'ecdsa signature blob' => ecdsa_signature_blob(signature_blob),
|
59
|
+
}
|
60
|
+
Signature.encode signature_h
|
61
|
+
end
|
62
|
+
|
63
|
+
def verify signature, signature_blob
|
64
|
+
signature_h = Signature.decode signature
|
65
|
+
ecdsa_signature_blob_h = EcdsaSignatureBlob.decode signature_h[:'ecdsa signature blob']
|
66
|
+
r = ecdsa_signature_blob_h[:'r']
|
67
|
+
s = ecdsa_signature_blob_h[:'s']
|
68
|
+
sign_asn1 = OpenSSL::ASN1::Sequence.new(
|
69
|
+
[
|
70
|
+
OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(r)),
|
71
|
+
OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(s)),
|
72
|
+
]
|
73
|
+
)
|
74
|
+
sign_der = sign_asn1.to_der
|
75
|
+
hash = OpenSSL::Digest.digest(self.class::DIGEST, signature_blob)
|
76
|
+
signature_h[:'public key algorithm name'] == self.class::NAME && @publickey.dsa_verify_asn1(hash, sign_der)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
require 'hrr_rb_ssh/algorithm/publickey/ecdsa_sha2/public_key_blob'
|
84
|
+
require 'hrr_rb_ssh/algorithm/publickey/ecdsa_sha2/signature'
|
85
|
+
require 'hrr_rb_ssh/algorithm/publickey/ecdsa_sha2/ecdsa_signature_blob'
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# vim: et ts=2 sw=2
|
3
|
+
|
4
|
+
require 'hrr_rb_ssh/algorithm/publickey/ecdsa_sha2'
|
5
|
+
|
6
|
+
module HrrRbSsh
|
7
|
+
module Algorithm
|
8
|
+
class Publickey
|
9
|
+
class EcdsaSha2Nistp256 < Publickey
|
10
|
+
NAME = 'ecdsa-sha2-nistp256'
|
11
|
+
DIGEST = 'sha256'
|
12
|
+
IDENTIFIER = 'nistp256'
|
13
|
+
CURVE_NAME = 'prime256v1'
|
14
|
+
|
15
|
+
include EcdsaSha2
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|