hrr_rb_ssh 0.1.1 → 0.1.2

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 (86) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/demo/server.rb +23 -3
  4. data/hrr_rb_ssh.gemspec +2 -2
  5. data/lib/hrr_rb_ssh/authentication/method/method.rb +34 -0
  6. data/lib/hrr_rb_ssh/authentication/method/none.rb +5 -14
  7. data/lib/hrr_rb_ssh/authentication/method/password.rb +6 -12
  8. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/algorithm.rb +41 -0
  9. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/codable.rb +33 -0
  10. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_dss.rb +105 -0
  11. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_rsa.rb +85 -0
  12. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm.rb +28 -0
  13. data/lib/hrr_rb_ssh/authentication/method/publickey.rb +9 -25
  14. data/lib/hrr_rb_ssh/authentication/method.rb +12 -9
  15. data/lib/hrr_rb_ssh/connection/channel/channel_type/channel_type.rb +30 -0
  16. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/env/context.rb +46 -0
  17. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/env.rb +34 -0
  18. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/exec/context.rb +44 -0
  19. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/exec.rb +34 -0
  20. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/pty_req/context.rb +54 -0
  21. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/pty_req.rb +34 -0
  22. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/request_type.rb +34 -0
  23. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/shell/context.rb +41 -0
  24. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/shell.rb +34 -0
  25. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/subsystem/context.rb +44 -0
  26. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/subsystem.rb +34 -0
  27. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type.rb +33 -0
  28. data/lib/hrr_rb_ssh/connection/channel/channel_type/session.rb +30 -0
  29. data/lib/hrr_rb_ssh/connection/channel/channel_type.rb +25 -0
  30. data/lib/hrr_rb_ssh/connection/channel.rb +2 -12
  31. data/lib/hrr_rb_ssh/transport/compression_algorithm/compression_algorithm.rb +34 -0
  32. data/lib/hrr_rb_ssh/transport/compression_algorithm/functionable.rb +31 -0
  33. data/lib/hrr_rb_ssh/transport/compression_algorithm/none.rb +7 -19
  34. data/lib/hrr_rb_ssh/transport/compression_algorithm/unfunctionable.rb +20 -0
  35. data/lib/hrr_rb_ssh/transport/compression_algorithm/zlib.rb +7 -24
  36. data/lib/hrr_rb_ssh/transport/compression_algorithm.rb +11 -9
  37. data/lib/hrr_rb_ssh/transport/direction.rb +11 -0
  38. data/lib/hrr_rb_ssh/transport/encryption_algorithm/aes128_cbc.rb +19 -0
  39. data/lib/hrr_rb_ssh/transport/encryption_algorithm/aes128_ctr.rb +19 -0
  40. data/lib/hrr_rb_ssh/transport/encryption_algorithm/aes192_cbc.rb +19 -0
  41. data/lib/hrr_rb_ssh/transport/encryption_algorithm/aes192_ctr.rb +19 -0
  42. data/lib/hrr_rb_ssh/transport/encryption_algorithm/aes256_cbc.rb +19 -0
  43. data/lib/hrr_rb_ssh/transport/encryption_algorithm/aes256_ctr.rb +19 -0
  44. data/lib/hrr_rb_ssh/transport/encryption_algorithm/arcfour.rb +19 -0
  45. data/lib/hrr_rb_ssh/transport/encryption_algorithm/blowfish_cbc.rb +19 -0
  46. data/lib/hrr_rb_ssh/transport/encryption_algorithm/cast128_cbc.rb +19 -0
  47. data/lib/hrr_rb_ssh/transport/encryption_algorithm/encryption_algorithm.rb +34 -0
  48. data/lib/hrr_rb_ssh/transport/encryption_algorithm/functionable.rb +61 -0
  49. data/lib/hrr_rb_ssh/transport/encryption_algorithm/none.rb +6 -33
  50. data/lib/hrr_rb_ssh/transport/encryption_algorithm/three_des_cbc.rb +19 -0
  51. data/lib/hrr_rb_ssh/transport/encryption_algorithm/unfunctionable.rb +35 -0
  52. data/lib/hrr_rb_ssh/transport/encryption_algorithm.rb +20 -9
  53. data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman.rb +3 -4
  54. data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group14_sha1.rb +4 -8
  55. data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group1_sha1.rb +4 -8
  56. data/lib/hrr_rb_ssh/transport/kex_algorithm/kex_algorithm.rb +34 -0
  57. data/lib/hrr_rb_ssh/transport/kex_algorithm.rb +10 -9
  58. data/lib/hrr_rb_ssh/transport/mac_algorithm/functionable.rb +32 -0
  59. data/lib/hrr_rb_ssh/transport/mac_algorithm/hmac_md5.rb +21 -0
  60. data/lib/hrr_rb_ssh/transport/mac_algorithm/hmac_md5_96.rb +21 -0
  61. data/lib/hrr_rb_ssh/transport/mac_algorithm/hmac_sha1.rb +5 -29
  62. data/lib/hrr_rb_ssh/transport/mac_algorithm/hmac_sha1_96.rb +21 -0
  63. data/lib/hrr_rb_ssh/transport/mac_algorithm/mac_algorithm.rb +34 -0
  64. data/lib/hrr_rb_ssh/transport/mac_algorithm/none.rb +6 -22
  65. data/lib/hrr_rb_ssh/transport/mac_algorithm/unfunctionable.rb +24 -0
  66. data/lib/hrr_rb_ssh/transport/mac_algorithm.rb +14 -9
  67. data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/server_host_key_algorithm.rb +34 -0
  68. data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_dss.rb +106 -0
  69. data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_rsa.rb +4 -11
  70. data/lib/hrr_rb_ssh/transport/server_host_key_algorithm.rb +10 -8
  71. data/lib/hrr_rb_ssh/transport.rb +23 -15
  72. data/lib/hrr_rb_ssh/version.rb +1 -1
  73. metadata +51 -17
  74. data/lib/hrr_rb_ssh/authentication/method/publickey/ssh_rsa.rb +0 -116
  75. data/lib/hrr_rb_ssh/connection/channel/session/env/context.rb +0 -43
  76. data/lib/hrr_rb_ssh/connection/channel/session/env.rb +0 -31
  77. data/lib/hrr_rb_ssh/connection/channel/session/exec/context.rb +0 -41
  78. data/lib/hrr_rb_ssh/connection/channel/session/exec.rb +0 -31
  79. data/lib/hrr_rb_ssh/connection/channel/session/pty_req/context.rb +0 -50
  80. data/lib/hrr_rb_ssh/connection/channel/session/pty_req.rb +0 -31
  81. data/lib/hrr_rb_ssh/connection/channel/session/shell/context.rb +0 -37
  82. data/lib/hrr_rb_ssh/connection/channel/session/shell.rb +0 -31
  83. data/lib/hrr_rb_ssh/connection/channel/session/subsystem/context.rb +0 -40
  84. data/lib/hrr_rb_ssh/connection/channel/session/subsystem.rb +0 -31
  85. data/lib/hrr_rb_ssh/connection/channel/session.rb +0 -31
  86. data/lib/hrr_rb_ssh/transport/encryption_algorithm/aes_128_cbc.rb +0 -73
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: af60a04fe1efba55f720ee23fd252e624d3c2ba955f36462e5ef766f6ad8acaa
4
- data.tar.gz: 5be5463dbc89b27652abd85ad6e4ef5d87f0639f8a32df370b0677d20dcbb39b
3
+ metadata.gz: a15e10f1895dfd1a8e0159fc18355de0128cc033bbe5f5ee49e483e2de7bc1e3
4
+ data.tar.gz: 6e1cb80d55521f431dff77735cb843c37fdc440640ffd9ae958119fdd9eb96d3
5
5
  SHA512:
6
- metadata.gz: 500b7e3562f9d413c9698cc167e51e3c2635b4658a6667ddfbf0d717aec68711aa81f51df85b203d7a26e42f62b9d5bc4e11a2c86b2f81594f5458b6b64f5790
7
- data.tar.gz: cc7bcc38e495f362dec7bbfe7fdae03c743945e1093b09ae1122f0cd27a43c4ba274935cd390120b6a845307d3340d033e04ab94722cd79a66985687ae5f0b28
6
+ metadata.gz: b63d6c8658d97b862f81e9beed336d04768894fffe1339c86cd2f8f9c22310f5f1d1be1f7abc381a0a0a5bbb18fd9a343959355aa77d849c321041de954d3749
7
+ data.tar.gz: db9de741c096e3024231760c25e3d0ed04fee0a7d3083f1ad71b1deecbe389c401576f37c31714052408bca4c6431861e40f7ccafc04be8b4277c096147ef32f
data/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  [![Test Coverage](https://api.codeclimate.com/v1/badges/f5dfdb97d72f24ca5939/test_coverage)](https://codeclimate.com/github/hirura/hrr_rb_ssh/test_coverage)
6
6
  [![Gem Version](https://badge.fury.io/rb/hrr_rb_ssh.svg)](https://badge.fury.io/rb/hrr_rb_ssh)
7
7
 
8
- hrr_rb_ssh is a pure Ruby SSH2 server implementation.
8
+ hrr_rb_ssh is a pure Ruby SSH 2.0 server implementation.
9
9
 
10
10
  ## Installation
11
11
 
data/demo/server.rb CHANGED
@@ -23,8 +23,23 @@ auth_none = HrrRbSsh::Authentication::Authenticator.new { |context|
23
23
  }
24
24
  auth_publickey = HrrRbSsh::Authentication::Authenticator.new { |context|
25
25
  username = 'user1'
26
- public_key_algorithm_name = 'ssh-rsa'
27
- public_key = <<-'EOB'
26
+ dss_public_key_algorithm_name = 'ssh-dss'
27
+ dss_public_key = <<-'EOB'
28
+ -----BEGIN PUBLIC KEY-----
29
+ MIIBtzCCASwGByqGSM44BAEwggEfAoGBAKh2ZJp4ao8Xaexa0sk68VqMCaOaTi19
30
+ YIqo2+t2t8ve4QSHvk/NbFIDTGq90lHziakTqwKaaswWLB7cSRPTcXjLv16Zmazg
31
+ JRvh1jZ3ikuBME2G/B+EptlQ00dMa+5W/Acp2P6Cv5NRgA/tx0AyCJaItSpLXG+k
32
+ B+HMp9LQ8WotAhUAk/yyvpsY9sVSyeN3lHvg5Nsl568CgYEAj4rqF241ROP2olNh
33
+ VJUF0K5N4dSBCfcPnSPYuGPCi7qV229RISET3LOwrCXEUwSwlKoe/lLb2mcaeC84
34
+ NIeN6pQnRTE6zajJ9UUeGErOFRm1x6E+FMtlVp/fwUE1Ra+AscHVKwMUehz7sA6A
35
+ ZxJK7UvLs+R6s1eYhrES0bcorLIDgYQAAoGAd6XKzevlwzt6aCYdBRdN+BT4BQUw
36
+ /L3MVYG0kDV9WqPcyAFvLO54xAUf9LxYM0e8X8J5ECp4oEGOcK1ilXEw3LPMJGmY
37
+ IB56R9izS1t636kxnJTYNGQY+XvjAeuP7nC2WVNHNz7vXprT4Sq+hQaNkaKPu/3/
38
+ 48xJs2mYbxfyHCQ=
39
+ -----END PUBLIC KEY-----
40
+ EOB
41
+ rsa_public_key_algorithm_name = 'ssh-rsa'
42
+ rsa_public_key = <<-'EOB'
28
43
  -----BEGIN PUBLIC KEY-----
29
44
  MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3OnIQcRTdeTZFjhGcx8f
30
45
  ssCgeqzY47p5KhT/gKMz2nOANNLCBr9e6IGaRePew03St3Cn0ApikuGzPnWxSlBT
@@ -35,7 +50,12 @@ wqbQt4paM0aEuypWE+CaizA0I+El7f0y+59sUqTAN/7F9UlXaOBdd9SZkhACBrAR
35
50
  nQIDAQAB
36
51
  -----END PUBLIC KEY-----
37
52
  EOB
38
- context.verify username, public_key_algorithm_name, public_key
53
+ [
54
+ [dss_public_key_algorithm_name, dss_public_key],
55
+ [rsa_public_key_algorithm_name, rsa_public_key],
56
+ ].any? { |public_key_algorithm_name, public_key|
57
+ context.verify username, public_key_algorithm_name, public_key
58
+ }
39
59
  }
40
60
  auth_password = HrrRbSsh::Authentication::Authenticator.new { |context|
41
61
  user_and_pass = [
data/hrr_rb_ssh.gemspec CHANGED
@@ -7,8 +7,8 @@ Gem::Specification.new do |spec|
7
7
  spec.name = "hrr_rb_ssh"
8
8
  spec.version = HrrRbSsh::VERSION
9
9
  spec.license = 'Apache-2.0'
10
- spec.summary = %q{Pure Ruby SSH2 server implementation}
11
- spec.description = %q{Pure Ruby SSH2 server implementation}
10
+ spec.summary = %q{Pure Ruby SSH 2.0 server implementation}
11
+ spec.description = %q{Pure Ruby SSH 2.0 server implementation}
12
12
  spec.authors = ["hirura"]
13
13
  spec.email = ["hirura@gmail.com"]
14
14
  spec.homepage = "https://github.com/hirura/hrr_rb_ssh"
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'hrr_rb_ssh/logger'
5
+
6
+ module HrrRbSsh
7
+ class Authentication
8
+ module Method
9
+ class Method
10
+ @@list = Array.new
11
+
12
+ def self.inherited klass
13
+ @@list.push klass
14
+ end
15
+
16
+ def self.list
17
+ @@list
18
+ end
19
+
20
+ def self.name_list
21
+ @@list.map{ |klass| klass::NAME }
22
+ end
23
+
24
+ def self.[] key
25
+ @@list.find{ |klass| key == klass::NAME }
26
+ end
27
+
28
+ def initialize options
29
+ @logger = HrrRbSsh::Logger.new self.class.name
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,19 +1,16 @@
1
1
  # coding: utf-8
2
2
  # vim: et ts=2 sw=2
3
3
 
4
- require 'hrr_rb_ssh/logger'
5
- require 'hrr_rb_ssh/authentication/method/none/context'
4
+ require 'hrr_rb_ssh/authentication/method/method'
6
5
 
7
6
  module HrrRbSsh
8
7
  class Authentication
9
8
  module Method
10
- name_list = [
11
- 'none'
12
- ]
9
+ class None < Method
10
+ NAME = 'none'
13
11
 
14
- class None
15
12
  def initialize options
16
- @logger = HrrRbSsh::Logger.new self.class.name
13
+ super
17
14
 
18
15
  @authenticator = options.fetch( 'authentication_none_authenticator', Authenticator.new { false } )
19
16
  end
@@ -25,14 +22,8 @@ module HrrRbSsh
25
22
  @authenticator.authenticate context
26
23
  end
27
24
  end
28
-
29
- @@list ||= Hash.new
30
- name_list.each do |name|
31
- @@list[name] = None
32
- end
33
25
  end
34
26
  end
35
27
  end
36
28
 
37
-
38
-
29
+ require 'hrr_rb_ssh/authentication/method/none/context'
@@ -1,19 +1,16 @@
1
1
  # coding: utf-8
2
2
  # vim: et ts=2 sw=2
3
3
 
4
- require 'hrr_rb_ssh/logger'
5
- require 'hrr_rb_ssh/authentication/method/password/context'
4
+ require 'hrr_rb_ssh/authentication/method/method'
6
5
 
7
6
  module HrrRbSsh
8
7
  class Authentication
9
8
  module Method
10
- name_list = [
11
- 'password'
12
- ]
9
+ class Password < Method
10
+ NAME = 'password'
13
11
 
14
- class Password
15
12
  def initialize options
16
- @logger = HrrRbSsh::Logger.new self.class.name
13
+ super
17
14
 
18
15
  @authenticator = options.fetch( 'authentication_password_authenticator', Authenticator.new { false } )
19
16
  end
@@ -27,11 +24,8 @@ module HrrRbSsh
27
24
  @authenticator.authenticate context
28
25
  end
29
26
  end
30
-
31
- @@list ||= Hash.new
32
- name_list.each do |name|
33
- @@list[name] = Password
34
- end
35
27
  end
36
28
  end
37
29
  end
30
+
31
+ require 'hrr_rb_ssh/authentication/method/password/context'
@@ -0,0 +1,41 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'hrr_rb_ssh/logger'
5
+ require 'hrr_rb_ssh/authentication/method/publickey/algorithm/codable'
6
+
7
+ module HrrRbSsh
8
+ class Authentication
9
+ module Method
10
+ class Publickey
11
+ module Algorithm
12
+ class Algorithm
13
+ @@list = Array.new
14
+
15
+ def self.inherited klass
16
+ @@list.push klass
17
+ end
18
+
19
+ def self.list
20
+ @@list
21
+ end
22
+
23
+ def self.name_list
24
+ @@list.map{ |klass| klass::NAME }
25
+ end
26
+
27
+ def self.[] key
28
+ @@list.find{ |klass| key == klass::NAME }
29
+ end
30
+
31
+ def initialize
32
+ @logger = HrrRbSsh::Logger.new self.class.name
33
+ end
34
+
35
+ include Codable
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'hrr_rb_ssh/transport/data_type'
5
+
6
+ module HrrRbSsh
7
+ class Authentication
8
+ module Method
9
+ class Publickey
10
+ module Algorithm
11
+ module Codable
12
+ def encode definition, payload
13
+ definition.map{ |data_type, field_name|
14
+ field_value = if payload[field_name].instance_of? ::Proc then payload[field_name].call else payload[field_name] end
15
+ HrrRbSsh::Transport::DataType[data_type].encode(field_value)
16
+ }.join
17
+ end
18
+
19
+ def decode definition, payload
20
+ payload_io = StringIO.new payload, 'r'
21
+ definition.map{ |data_type, field_name|
22
+ [
23
+ field_name,
24
+ HrrRbSsh::Transport::DataType[data_type].decode(payload_io)
25
+ ]
26
+ }.to_h
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,105 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ module HrrRbSsh
5
+ class Authentication
6
+ module Method
7
+ class Publickey
8
+ module Algorithm
9
+ class SshDss < Algorithm
10
+ NAME = 'ssh-dss'
11
+ DIGEST = 'sha1'
12
+
13
+ PUBLIC_KEY_BLOB_DEFINITION = [
14
+ ['string', 'public key algorithm name'],
15
+ ['mpint', 'p'],
16
+ ['mpint', 'q'],
17
+ ['mpint', 'g'],
18
+ ['mpint', 'y'],
19
+ ]
20
+
21
+ SIGNATURE_DEFINITION = [
22
+ ['string', 'public key algorithm name'],
23
+ ['string', 'signature blob'],
24
+ ]
25
+
26
+ SIGNATURE_BLOB_DEFINITION = [
27
+ ['string', 'session identifier'],
28
+ ['byte', 'message number'],
29
+ ['string', 'user name'],
30
+ ['string', 'service name'],
31
+ ['string', 'method name'],
32
+ ['boolean', 'with signature'],
33
+ ['string', 'public key algorithm name'],
34
+ ['string', 'public key blob'],
35
+ ]
36
+
37
+ def verify_public_key public_key_algorithm_name, public_key, public_key_blob
38
+ public_key = case public_key
39
+ when String
40
+ OpenSSL::PKey::DSA.new(public_key)
41
+ when OpenSSL::PKey::DSA
42
+ public_key
43
+ else
44
+ return false
45
+ end
46
+ public_key_message = {
47
+ 'public key algorithm name' => public_key_algorithm_name,
48
+ 'p' => public_key.p.to_i,
49
+ 'g' => public_key.g.to_i,
50
+ 'q' => public_key.q.to_i,
51
+ 'y' => public_key.pub_key.to_i,
52
+ }
53
+ public_key_blob == encode(PUBLIC_KEY_BLOB_DEFINITION, public_key_message)
54
+ end
55
+
56
+ def verify_signature session_id, message
57
+ signature_message = decode SIGNATURE_DEFINITION, message['signature']
58
+ signature_algorithm = signature_message['public key algorithm name']
59
+ signature_blob = signature_message['signature blob']
60
+
61
+ public_key = decode PUBLIC_KEY_BLOB_DEFINITION, message['public key blob']
62
+ algorithm = OpenSSL::PKey::DSA.new
63
+ if algorithm.respond_to?(:set_pqg)
64
+ algorithm.set_pqg public_key['p'], public_key['q'], public_key['g']
65
+ else
66
+ algorithm.p = public_key['p']
67
+ algorithm.q = public_key['q']
68
+ algorithm.g = public_key['g']
69
+ end
70
+ if algorithm.respond_to?(:set_key)
71
+ algorithm.set_key public_key['y'], nil
72
+ else
73
+ algorithm.pub_key = public_key['y']
74
+ end
75
+
76
+ data_message = {
77
+ 'session identifier' => session_id,
78
+ 'message number' => message['message number'],
79
+ 'user name' => message['user name'],
80
+ 'service name' => message['service name'],
81
+ 'method name' => message['method name'],
82
+ 'with signature' => message['with signature'],
83
+ 'public key algorithm name' => message['public key algorithm name'],
84
+ 'public key blob' => message['public key blob'],
85
+ }
86
+ data_blob = encode SIGNATURE_BLOB_DEFINITION, data_message
87
+
88
+ hash = OpenSSL::Digest.digest(DIGEST, data_blob)
89
+ sign_r = signature_blob[ 0, 20]
90
+ sign_s = signature_blob[20, 20]
91
+ sign_asn1 = OpenSSL::ASN1::Sequence.new(
92
+ [
93
+ OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(sign_r, 2)),
94
+ OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(sign_s, 2)),
95
+ ]
96
+ )
97
+ sign_der = sign_asn1.to_der
98
+ (signature_algorithm == message['public key algorithm name']) && algorithm.sysverify(hash, sign_der)
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,85 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ module HrrRbSsh
5
+ class Authentication
6
+ module Method
7
+ class Publickey
8
+ module Algorithm
9
+ class SshRsa < Algorithm
10
+ NAME = 'ssh-rsa'
11
+ DIGEST = 'sha1'
12
+
13
+ PUBLIC_KEY_BLOB_DEFINITION = [
14
+ ['string', 'public key algorithm name'],
15
+ ['mpint', 'e'],
16
+ ['mpint', 'n'],
17
+ ]
18
+
19
+ SIGNATURE_DEFINITION = [
20
+ ['string', 'public key algorithm name'],
21
+ ['string', 'signature blob'],
22
+ ]
23
+
24
+ SIGNATURE_BLOB_DEFINITION = [
25
+ ['string', 'session identifier'],
26
+ ['byte', 'message number'],
27
+ ['string', 'user name'],
28
+ ['string', 'service name'],
29
+ ['string', 'method name'],
30
+ ['boolean', 'with signature'],
31
+ ['string', 'public key algorithm name'],
32
+ ['string', 'public key blob'],
33
+ ]
34
+
35
+ def verify_public_key public_key_algorithm_name, public_key, public_key_blob
36
+ public_key = case public_key
37
+ when String
38
+ OpenSSL::PKey::RSA.new(public_key)
39
+ when OpenSSL::PKey::RSA
40
+ public_key
41
+ else
42
+ return false
43
+ end
44
+ public_key_message = {
45
+ 'public key algorithm name' => public_key_algorithm_name,
46
+ 'e' => public_key.e.to_i,
47
+ 'n' => public_key.n.to_i,
48
+ }
49
+ public_key_blob == encode(PUBLIC_KEY_BLOB_DEFINITION, public_key_message)
50
+ end
51
+
52
+ def verify_signature session_id, message
53
+ signature_message = decode SIGNATURE_DEFINITION, message['signature']
54
+ signature_algorithm = signature_message['public key algorithm name']
55
+ signature_blob = signature_message['signature blob']
56
+
57
+ public_key = decode PUBLIC_KEY_BLOB_DEFINITION, message['public key blob']
58
+ algorithm = OpenSSL::PKey::RSA.new
59
+ if algorithm.respond_to?(:set_key)
60
+ algorithm.set_key public_key['n'], public_key['e'], nil
61
+ else
62
+ algorithm.e = public_key['e']
63
+ algorithm.n = public_key['n']
64
+ end
65
+
66
+ data_message = {
67
+ 'session identifier' => session_id,
68
+ 'message number' => message['message number'],
69
+ 'user name' => message['user name'],
70
+ 'service name' => message['service name'],
71
+ 'method name' => message['method name'],
72
+ 'with signature' => message['with signature'],
73
+ 'public key algorithm name' => message['public key algorithm name'],
74
+ 'public key blob' => message['public key blob'],
75
+ }
76
+ data_blob = encode SIGNATURE_BLOB_DEFINITION, data_message
77
+
78
+ (signature_algorithm == message['public key algorithm name']) && algorithm.verify(DIGEST, signature_blob, data_blob)
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ module HrrRbSsh
5
+ class Authentication
6
+ module Method
7
+ class Publickey
8
+ module Algorithm
9
+ def self.list
10
+ Algorithm.list
11
+ end
12
+
13
+ def self.name_list
14
+ Algorithm.name_list
15
+ end
16
+
17
+ def self.[] key
18
+ Algorithm[key]
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ require 'hrr_rb_ssh/authentication/method/publickey/algorithm/algorithm'
27
+ require 'hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_dss'
28
+ require 'hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_rsa'
@@ -1,30 +1,16 @@
1
1
  # coding: utf-8
2
2
  # vim: et ts=2 sw=2
3
3
 
4
- require 'hrr_rb_ssh/logger'
5
- require 'hrr_rb_ssh/authentication/method/publickey/context'
6
- require 'hrr_rb_ssh/authentication/method/publickey/ssh_rsa'
4
+ require 'hrr_rb_ssh/authentication/method/method'
7
5
 
8
6
  module HrrRbSsh
9
7
  class Authentication
10
8
  module Method
11
- name_list = [
12
- 'publickey'
13
- ]
14
-
15
- class Publickey
16
- @@algorithm_list ||= Hash.new
17
-
18
- def self.[] key
19
- @@algorithm_list[key]
20
- end
21
-
22
- def self.algorithm_name_list
23
- @@algorithm_list.keys
24
- end
9
+ class Publickey < Method
10
+ NAME = 'publickey'
25
11
 
26
12
  def initialize options
27
- @logger = HrrRbSsh::Logger.new self.class.name
13
+ super
28
14
 
29
15
  @session_id = options['session id']
30
16
  @authenticator = options.fetch( 'authentication_publickey_authenticator', Authenticator.new { false } )
@@ -32,7 +18,7 @@ module HrrRbSsh
32
18
 
33
19
  def authenticate userauth_request_message
34
20
  public_key_algorithm_name = userauth_request_message['public key algorithm name']
35
- unless @@algorithm_list.has_key?(public_key_algorithm_name)
21
+ unless Algorithm.name_list.include?(public_key_algorithm_name)
36
22
  @logger.info("unsupported public key algorithm: #{public_key_algorithm_name}")
37
23
  return false
38
24
  end
@@ -43,7 +29,7 @@ module HrrRbSsh
43
29
  else
44
30
  @logger.info("verify signature")
45
31
  username = userauth_request_message['user name']
46
- algorithm = @@algorithm_list[public_key_algorithm_name].new
32
+ algorithm = Algorithm[public_key_algorithm_name].new
47
33
  context = Context.new(username, algorithm, @session_id, userauth_request_message)
48
34
  @authenticator.authenticate context
49
35
  end
@@ -58,11 +44,9 @@ module HrrRbSsh
58
44
  payload = HrrRbSsh::Message::SSH_MSG_USERAUTH_PK_OK.encode message
59
45
  end
60
46
  end
61
-
62
- @@list ||= Hash.new
63
- name_list.each do |name|
64
- @@list[name] = Publickey
65
- end
66
47
  end
67
48
  end
68
49
  end
50
+
51
+ require 'hrr_rb_ssh/authentication/method/publickey/context'
52
+ require 'hrr_rb_ssh/authentication/method/publickey/algorithm'
@@ -1,22 +1,25 @@
1
1
  # coding: utf-8
2
2
  # vim: et ts=2 sw=2
3
3
 
4
- require 'hrr_rb_ssh/authentication/method/none'
5
- require 'hrr_rb_ssh/authentication/method/password'
6
- require 'hrr_rb_ssh/authentication/method/publickey'
7
-
8
4
  module HrrRbSsh
9
5
  class Authentication
10
6
  module Method
11
- @@list ||= Hash.new
12
-
13
- def self.[] key
14
- @@list[key]
7
+ def self.list
8
+ Method.list
15
9
  end
16
10
 
17
11
  def self.name_list
18
- @@list.keys
12
+ Method.name_list
13
+ end
14
+
15
+ def self.[] key
16
+ Method[key]
19
17
  end
20
18
  end
21
19
  end
22
20
  end
21
+
22
+ require 'hrr_rb_ssh/authentication/method/method'
23
+ require 'hrr_rb_ssh/authentication/method/none'
24
+ require 'hrr_rb_ssh/authentication/method/password'
25
+ require 'hrr_rb_ssh/authentication/method/publickey'
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ module HrrRbSsh
5
+ class Connection
6
+ class Channel
7
+ module ChannelType
8
+ class ChannelType
9
+ @@list = Array.new
10
+
11
+ def self.inherited klass
12
+ @@list.push klass
13
+ end
14
+
15
+ def self.list
16
+ @@list
17
+ end
18
+
19
+ def self.name_list
20
+ @@list.map{ |klass| klass::NAME }
21
+ end
22
+
23
+ def self.[] key
24
+ @@list.find{ |klass| key == klass::NAME }
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,46 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'hrr_rb_ssh/logger'
5
+
6
+ module HrrRbSsh
7
+ class Connection
8
+ class Channel
9
+ module ChannelType
10
+ class Session
11
+ module RequestType
12
+ class Env
13
+ class Context
14
+ attr_reader \
15
+ :logger,
16
+ :username,
17
+ :io,
18
+ :variables,
19
+ :vars,
20
+ :variable_name,
21
+ :variable_value
22
+
23
+ def initialize proc_chain, username, io, variables, message
24
+ @logger = HrrRbSsh::Logger.new self.class.name
25
+
26
+ @proc_chain = proc_chain
27
+ @username = username
28
+ @io = io
29
+ @variables = variables
30
+ @vars = variables
31
+
32
+ @variable_name = message['variable name']
33
+ @variable_value = message['variable value']
34
+ end
35
+
36
+ def chain_proc &block
37
+ @proc = block || @proc
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end