hrr_rb_ssh 0.1.9 → 0.2.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 (123) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +12 -2
  3. data/README.md +11 -9
  4. data/demo/echo_server.rb +50 -42
  5. data/demo/server.rb +81 -62
  6. data/demo/subsystem_echo_server.rb +54 -47
  7. data/lib/hrr_rb_ssh/{transport/server_host_key_algorithm/ecdsa_sha2_nistp521 → algorithm/publickey/ecdsa_sha2}/ecdsa_signature_blob.rb +3 -3
  8. data/lib/hrr_rb_ssh/{transport/server_host_key_algorithm/ecdsa_sha2_nistp256 → algorithm/publickey/ecdsa_sha2}/public_key_blob.rb +5 -6
  9. data/lib/hrr_rb_ssh/{transport/server_host_key_algorithm/ecdsa_sha2_nistp256 → algorithm/publickey/ecdsa_sha2}/signature.rb +5 -5
  10. data/lib/hrr_rb_ssh/algorithm/publickey/ecdsa_sha2.rb +85 -0
  11. data/lib/hrr_rb_ssh/algorithm/publickey/ecdsa_sha2_nistp256.rb +19 -0
  12. data/lib/hrr_rb_ssh/algorithm/publickey/ecdsa_sha2_nistp384.rb +19 -0
  13. data/lib/hrr_rb_ssh/algorithm/publickey/ecdsa_sha2_nistp521.rb +19 -0
  14. data/lib/hrr_rb_ssh/{transport/server_host_key_algorithm → algorithm/publickey}/ssh_dss/public_key_blob.rb +3 -3
  15. data/lib/hrr_rb_ssh/{transport/server_host_key_algorithm → algorithm/publickey}/ssh_dss/signature.rb +4 -4
  16. data/lib/hrr_rb_ssh/algorithm/publickey/ssh_dss.rb +90 -0
  17. data/lib/hrr_rb_ssh/{transport/server_host_key_algorithm → algorithm/publickey}/ssh_rsa/public_key_blob.rb +3 -4
  18. data/lib/hrr_rb_ssh/{transport/server_host_key_algorithm → algorithm/publickey}/ssh_rsa/signature.rb +4 -4
  19. data/lib/hrr_rb_ssh/algorithm/publickey/ssh_rsa.rb +67 -0
  20. data/lib/hrr_rb_ssh/algorithm/publickey.rb +32 -0
  21. data/lib/hrr_rb_ssh/algorithm.rb +9 -0
  22. data/lib/hrr_rb_ssh/authentication/method/none/context.rb +1 -1
  23. data/lib/hrr_rb_ssh/authentication/method/none.rb +1 -1
  24. data/lib/hrr_rb_ssh/authentication/method/password/context.rb +1 -1
  25. data/lib/hrr_rb_ssh/authentication/method/password.rb +1 -1
  26. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp256.rb +2 -65
  27. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp384.rb +2 -65
  28. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp521.rb +2 -65
  29. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/functionable.rb +54 -0
  30. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/signature_blob.rb +31 -0
  31. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_dss.rb +2 -73
  32. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_rsa.rb +2 -55
  33. data/lib/hrr_rb_ssh/authentication/method/publickey.rb +3 -3
  34. data/lib/hrr_rb_ssh/authentication.rb +15 -15
  35. data/lib/hrr_rb_ssh/codable.rb +1 -1
  36. data/lib/hrr_rb_ssh/compat/openssh/public_key.rb +3 -40
  37. data/lib/hrr_rb_ssh/compat/ruby/array.rb +14 -0
  38. data/lib/hrr_rb_ssh/compat/ruby/openssl/bn.rb +20 -0
  39. data/lib/hrr_rb_ssh/compat/ruby/openssl.rb +4 -0
  40. data/lib/hrr_rb_ssh/compat/ruby/queue.rb +38 -0
  41. data/lib/hrr_rb_ssh/compat/ruby.rb +6 -0
  42. data/lib/hrr_rb_ssh/compat.rb +1 -63
  43. data/lib/hrr_rb_ssh/connection/channel/channel_type/direct_tcpip.rb +1 -1
  44. data/lib/hrr_rb_ssh/connection/channel/channel_type/forwarded_tcpip.rb +1 -1
  45. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/proc_chain/chain_context.rb +1 -1
  46. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/proc_chain.rb +1 -1
  47. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/env/context.rb +1 -1
  48. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/env.rb +1 -1
  49. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/exec/context.rb +1 -1
  50. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/exec.rb +1 -1
  51. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/pty_req/context.rb +1 -1
  52. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/pty_req.rb +1 -1
  53. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/shell/context.rb +1 -1
  54. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/shell.rb +1 -1
  55. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/subsystem/context.rb +1 -1
  56. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/subsystem.rb +1 -1
  57. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/window_change/context.rb +1 -1
  58. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/window_change.rb +1 -1
  59. data/lib/hrr_rb_ssh/connection/channel/channel_type/session.rb +1 -1
  60. data/lib/hrr_rb_ssh/connection/channel.rb +22 -22
  61. data/lib/hrr_rb_ssh/connection/global_request_handler.rb +1 -1
  62. data/lib/hrr_rb_ssh/connection/request_handler/reference_env_request_handler.rb +1 -1
  63. data/lib/hrr_rb_ssh/connection/request_handler/reference_exec_request_handler.rb +3 -56
  64. data/lib/hrr_rb_ssh/connection/request_handler/reference_pty_req_request_handler.rb +50 -13
  65. data/lib/hrr_rb_ssh/connection/request_handler/reference_shell_request_handler.rb +3 -56
  66. data/lib/hrr_rb_ssh/connection/request_handler/reference_window_change_request_handler.rb +1 -1
  67. data/lib/hrr_rb_ssh/connection/request_handler.rb +1 -1
  68. data/lib/hrr_rb_ssh/connection.rb +40 -40
  69. data/lib/hrr_rb_ssh/data_type.rb +0 -3
  70. data/lib/hrr_rb_ssh/error/closed_authentication.rb +9 -0
  71. data/lib/hrr_rb_ssh/{closed_transport_error.rb → error/closed_connection.rb} +3 -1
  72. data/lib/hrr_rb_ssh/{closed_authentication_error.rb → error/closed_transport.rb} +3 -1
  73. data/lib/hrr_rb_ssh/error.rb +11 -0
  74. data/lib/hrr_rb_ssh/{closed_connection_error.rb → mode.rb} +3 -1
  75. data/lib/hrr_rb_ssh/server.rb +23 -0
  76. data/lib/hrr_rb_ssh/transport/compression_algorithm/functionable.rb +1 -1
  77. data/lib/hrr_rb_ssh/transport/compression_algorithm/unfunctionable.rb +1 -1
  78. data/lib/hrr_rb_ssh/transport/encryption_algorithm/functionable.rb +3 -3
  79. data/lib/hrr_rb_ssh/transport/encryption_algorithm/unfunctionable.rb +1 -1
  80. data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman.rb +8 -48
  81. data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb +11 -51
  82. data/lib/hrr_rb_ssh/transport/kex_algorithm/elliptic_curve_diffie_hellman.rb +8 -48
  83. data/lib/hrr_rb_ssh/transport/kex_algorithm/iv_computable.rb +57 -0
  84. data/lib/hrr_rb_ssh/transport/mac_algorithm/functionable.rb +2 -2
  85. data/lib/hrr_rb_ssh/transport/mac_algorithm/unfunctionable.rb +1 -1
  86. data/lib/hrr_rb_ssh/transport/receiver.rb +1 -1
  87. data/lib/hrr_rb_ssh/transport/sender.rb +1 -1
  88. data/lib/hrr_rb_ssh/transport/sequence_number.rb +1 -1
  89. data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp256.rb +2 -56
  90. data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp384.rb +2 -56
  91. data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp521.rb +2 -56
  92. data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/functionable.rb +29 -0
  93. data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_dss.rb +2 -50
  94. data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_rsa.rb +2 -31
  95. data/lib/hrr_rb_ssh/transport.rb +83 -81
  96. data/lib/hrr_rb_ssh/version.rb +1 -1
  97. data/lib/hrr_rb_ssh.rb +4 -0
  98. metadata +32 -37
  99. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp256/ecdsa_signature_blob.rb +0 -27
  100. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp256/public_key_blob.rb +0 -28
  101. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp256/signature.rb +0 -27
  102. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp256/signature_blob.rb +0 -33
  103. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp384/ecdsa_signature_blob.rb +0 -27
  104. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp384/public_key_blob.rb +0 -28
  105. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp384/signature.rb +0 -27
  106. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp384/signature_blob.rb +0 -33
  107. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp521/ecdsa_signature_blob.rb +0 -27
  108. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp521/public_key_blob.rb +0 -28
  109. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp521/signature.rb +0 -27
  110. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp521/signature_blob.rb +0 -33
  111. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_dss/public_key_blob.rb +0 -30
  112. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_dss/signature.rb +0 -27
  113. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_dss/signature_blob.rb +0 -33
  114. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_rsa/public_key_blob.rb +0 -28
  115. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_rsa/signature.rb +0 -27
  116. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_rsa/signature_blob.rb +0 -33
  117. data/lib/hrr_rb_ssh/transport/mode.rb +0 -11
  118. data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp256/ecdsa_signature_blob.rb +0 -23
  119. data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp384/ecdsa_signature_blob.rb +0 -23
  120. data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp384/public_key_blob.rb +0 -25
  121. data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp384/signature.rb +0 -23
  122. data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp521/public_key_blob.rb +0 -25
  123. 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: 895f28010a8eb2c1e18c12369fd4c10922ba5a69ef0527ce165c97529eae0739
4
- data.tar.gz: c6a0669ea1e9561e007ae22259d111ce011589e383cc0ac73b7678d5668b14cc
3
+ metadata.gz: fa22df4a3d01a18e8f66b69b73f5b189233de3d4c755f1d371f15043c0202c8f
4
+ data.tar.gz: e426371cf62d6d6705915a58b5811774e984be1f55b1e2f11db5925d0f14d08f
5
5
  SHA512:
6
- metadata.gz: 3e41e26012c69eab8dbc2324fd71cd1212ebb56d87b76a30b4c7e59a4eba8627301bcfc18a26d42b7742784034f8ffbcf9ed06ca770a4717e05b7aac47e7780c
7
- data.tar.gz: efd75bcd9eb57930c867880010eb6ffc9cb307080f4478df3ffa6363cf46845be9f0aa13a273d1abc161cfab60250562ae8d87ab9db068f7afe6c76382244ed9
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
- before_install: gem install bundler -v 1.16.1
14
- install: bundle install --path vendor/bundle
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
- while true
76
- t = Thread.new(server.accept) do |io|
77
- tran = HrrRbSsh::Transport.new io, HrrRbSsh::Transport::Mode::SERVER, options
78
- auth = HrrRbSsh::Authentication.new tran, options
79
- conn = HrrRbSsh::Connection.new auth, options
80
- conn.start
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
- begin
8
- require 'hrr_rb_ssh'
9
- rescue LoadError
10
- $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
11
- require 'hrr_rb_ssh'
12
- end
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
- true # accept any user and password
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
- context.io[2].close
26
- context.chain_proc { |chain|
27
- begin
28
- loop do
29
- buf = context.io[0].readpartial(10240)
30
- break if buf.include?(0x04.chr) # break if ^D
31
- context.io[1].write buf
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 = 0
34
- rescue => e
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
- while true
51
- t = Thread.new(server.accept) do |io|
50
+ loop do
51
+ Thread.new(server.accept) do |io|
52
52
  begin
53
- tran = HrrRbSsh::Transport.new io, HrrRbSsh::Transport::Mode::SERVER
54
- auth = HrrRbSsh::Authentication.new tran, options
55
- conn = HrrRbSsh::Connection.new auth, options
56
- conn.start
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([e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join)
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
- io.close
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
- logger = Logger.new STDOUT
17
- logger.level = Logger::INFO
18
- HrrRbSsh::Logger.initialize logger
19
-
20
-
21
- tran_preferred_encryption_algorithms = %w(aes128-ctr aes192-ctr aes256-ctr aes128-cbc 3des-cbc blowfish-cbc cast128-cbc aes192-cbc aes256-cbc arcfour)
22
- tran_preferred_server_host_key_algorithms = %w(ecdsa-sha2-nistp521 ecdsa-sha2-nistp384 ecdsa-sha2-nistp256 ssh-rsa ssh-dss)
23
- tran_preferred_kex_algorithms = %w(ecdh-sha2-nistp521 ecdh-sha2-nistp384 ecdh-sha2-nistp256 diffie-hellman-group14-sha1 diffie-hellman-group1-sha1)
24
- tran_preferred_mac_algorithms = %w(hmac-sha2-512 hmac-sha2-256 hmac-sha1 hmac-md5 hmac-sha1-96 hmac-md5-96)
25
- tran_preferred_compression_algorithms = %w(none zlib)
26
-
27
- auth_none = HrrRbSsh::Authentication::Authenticator.new { |context|
28
- false
29
- }
30
- auth_publickey = HrrRbSsh::Authentication::Authenticator.new { |context|
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
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
- auth_password = HrrRbSsh::Authentication::Authenticator.new { |context|
42
- user_and_pass = [
43
- ['user1', 'password1'],
44
- ['user2', 'password2'],
45
- ]
46
- user_and_pass.any? { |user, pass|
47
- context.verify user, pass
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
- while true
82
- t = Thread.new(server.accept) do |io|
83
- tran = HrrRbSsh::Transport.new io, HrrRbSsh::Transport::Mode::SERVER, options
84
- auth = HrrRbSsh::Authentication.new tran, options
85
- conn = HrrRbSsh::Connection.new auth, options
86
- conn.start
87
- io.close
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
- begin
8
- require 'hrr_rb_ssh'
9
- rescue LoadError
10
- $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
11
- require 'hrr_rb_ssh'
12
- end
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
- true # accept any user and password
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
- context.io[2].close
26
- context.chain_proc { |chain|
27
- case context.subsystem_name
28
- when 'echo'
29
- begin
30
- loop do
31
- begin
32
- buf = context.io[0].readpartial(10240)
33
- rescue EOFError
34
- break
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
- context.io[1].write buf
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
- else
46
- context.io[1].close
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
- t = Thread.new(server.accept) do |io|
59
+ Thread.new(server.accept) do |io|
61
60
  begin
62
- tran = HrrRbSsh::Transport.new io, HrrRbSsh::Transport::Mode::SERVER
63
- auth = HrrRbSsh::Authentication.new tran, options
64
- conn = HrrRbSsh::Connection.new auth, options
65
- conn.start
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([e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join)
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
- io.close
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
- class Transport
9
- class ServerHostKeyAlgorithm
10
- class EcdsaSha2Nistp521
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
- class Transport
9
- class ServerHostKeyAlgorithm
10
- class EcdsaSha2Nistp256
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, :'ecdsa-sha2-[identifier]'],
17
- [DataType::String, :'[identifier]'],
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
- class Transport
9
- class ServerHostKeyAlgorithm
10
- class EcdsaSha2Nistp256
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, :'ecdsa-sha2-[identifier]'],
17
- [DataType::String, :'ecdsa_signature_blob'],
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