hrr_rb_ssh 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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