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.
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