hrr_rb_ssh 0.1.4 → 0.1.5
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.
- checksums.yaml +4 -4
- data/demo/server.rb +10 -2
- data/lib/hrr_rb_ssh/authentication/method/none.rb +1 -1
- data/lib/hrr_rb_ssh/authentication/method/password.rb +2 -2
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp256/ecdsa_signature_blob.rb +27 -0
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp256/public_key_blob.rb +28 -0
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp256/signature.rb +27 -0
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp256/signature_blob.rb +33 -0
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp256.rb +84 -0
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp384/ecdsa_signature_blob.rb +27 -0
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp384/public_key_blob.rb +28 -0
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp384/signature.rb +27 -0
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp384/signature_blob.rb +33 -0
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp384.rb +84 -0
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp521/ecdsa_signature_blob.rb +27 -0
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp521/public_key_blob.rb +28 -0
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp521/signature.rb +27 -0
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp521/signature_blob.rb +33 -0
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp521.rb +84 -0
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_dss/public_key_blob.rb +5 -5
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_dss/signature.rb +2 -2
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_dss/signature_blob.rb +8 -8
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_dss.rb +24 -24
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_rsa/public_key_blob.rb +3 -3
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_rsa/signature.rb +2 -2
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_rsa/signature_blob.rb +8 -8
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_rsa.rb +19 -19
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm.rb +3 -0
- data/lib/hrr_rb_ssh/authentication/method/publickey/context.rb +7 -7
- data/lib/hrr_rb_ssh/authentication/method/publickey.rb +7 -7
- data/lib/hrr_rb_ssh/authentication.rb +6 -6
- data/lib/hrr_rb_ssh/codable.rb +7 -2
- data/lib/hrr_rb_ssh/connection/channel/channel_type/direct_tcpip.rb +102 -0
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/proc_chain/chain_context.rb +26 -0
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/proc_chain.rb +29 -0
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/env/context.rb +2 -2
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/exec/context.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/pty_req/context.rb +6 -6
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/subsystem/context.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/window_change/context.rb +4 -4
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session.rb +42 -0
- data/lib/hrr_rb_ssh/connection/channel/channel_type.rb +1 -0
- data/lib/hrr_rb_ssh/connection/channel.rb +50 -63
- data/lib/hrr_rb_ssh/connection/request_handler/reference_shell_request_handler.rb +29 -9
- data/lib/hrr_rb_ssh/connection.rb +22 -27
- data/lib/hrr_rb_ssh/message/001_ssh_msg_disconnect.rb +4 -4
- data/lib/hrr_rb_ssh/message/002_ssh_msg_ignore.rb +2 -2
- data/lib/hrr_rb_ssh/message/003_ssh_msg_unimplemented.rb +2 -2
- data/lib/hrr_rb_ssh/message/004_ssh_msg_debug.rb +4 -4
- data/lib/hrr_rb_ssh/message/005_ssh_msg_service_request.rb +2 -2
- data/lib/hrr_rb_ssh/message/006_ssh_msg_service_accept.rb +2 -2
- data/lib/hrr_rb_ssh/message/020_ssh_msg_kexinit.rb +29 -29
- data/lib/hrr_rb_ssh/message/021_ssh_msg_newkeys.rb +1 -1
- data/lib/hrr_rb_ssh/message/030_ssh_msg_kex_dh_gex_request_old.rb +2 -2
- data/lib/hrr_rb_ssh/message/030_ssh_msg_kexdh_init.rb +2 -2
- data/lib/hrr_rb_ssh/message/030_ssh_msg_kexecdh_init.rb +24 -0
- data/lib/hrr_rb_ssh/message/031_ssh_msg_kex_dh_gex_group.rb +3 -3
- data/lib/hrr_rb_ssh/message/031_ssh_msg_kexdh_reply.rb +4 -4
- data/lib/hrr_rb_ssh/message/031_ssh_msg_kexecdh_reply.rb +26 -0
- data/lib/hrr_rb_ssh/message/032_ssh_msg_kex_dh_gex_init.rb +2 -2
- data/lib/hrr_rb_ssh/message/033_ssh_msg_kex_dh_gex_reply.rb +4 -4
- data/lib/hrr_rb_ssh/message/034_ssh_msg_kex_dh_gex_request.rb +4 -4
- data/lib/hrr_rb_ssh/message/050_ssh_msg_userauth_request.rb +17 -17
- data/lib/hrr_rb_ssh/message/051_ssh_msg_userauth_failure.rb +3 -3
- data/lib/hrr_rb_ssh/message/052_ssh_msg_userauth_success.rb +1 -1
- data/lib/hrr_rb_ssh/message/060_ssh_msg_userauth_pk_ok.rb +3 -3
- data/lib/hrr_rb_ssh/message/080_ssh_msg_global_request.rb +12 -12
- data/lib/hrr_rb_ssh/message/081_ssh_msg_request_success.rb +5 -5
- data/lib/hrr_rb_ssh/message/082_ssh_msg_request_failure.rb +1 -1
- data/lib/hrr_rb_ssh/message/090_ssh_msg_channel_open.rb +24 -24
- data/lib/hrr_rb_ssh/message/091_ssh_msg_channel_open_confirmation.rb +14 -24
- data/lib/hrr_rb_ssh/message/092_ssh_msg_channel_open_failure.rb +5 -5
- data/lib/hrr_rb_ssh/message/093_ssh_msg_channel_window_adjust.rb +3 -3
- data/lib/hrr_rb_ssh/message/094_ssh_msg_channel_data.rb +3 -3
- data/lib/hrr_rb_ssh/message/095_ssh_msg_channel_extended_data.rb +4 -4
- data/lib/hrr_rb_ssh/message/096_ssh_msg_channel_eof.rb +2 -2
- data/lib/hrr_rb_ssh/message/097_ssh_msg_channel_close.rb +2 -2
- data/lib/hrr_rb_ssh/message/098_ssh_msg_channel_request.rb +51 -51
- data/lib/hrr_rb_ssh/message/099_ssh_msg_channel_success.rb +2 -2
- data/lib/hrr_rb_ssh/message/100_ssh_msg_channel_failure.rb +2 -2
- data/lib/hrr_rb_ssh/message.rb +2 -0
- data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman/h0.rb +8 -8
- data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman.rb +13 -13
- data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange/h0.rb +13 -13
- data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb +24 -24
- data/lib/hrr_rb_ssh/transport/kex_algorithm/elliptic_curve_diffie_hellman/h0.rb +29 -0
- data/lib/hrr_rb_ssh/transport/kex_algorithm/elliptic_curve_diffie_hellman.rb +132 -0
- data/lib/hrr_rb_ssh/transport/kex_algorithm/elliptic_curve_diffie_hellman_sha2_nistp256.rb +18 -0
- data/lib/hrr_rb_ssh/transport/kex_algorithm/elliptic_curve_diffie_hellman_sha2_nistp384.rb +18 -0
- data/lib/hrr_rb_ssh/transport/kex_algorithm/elliptic_curve_diffie_hellman_sha2_nistp521.rb +18 -0
- data/lib/hrr_rb_ssh/transport/kex_algorithm.rb +3 -0
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp256/ecdsa_signature_blob.rb +23 -0
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp256/public_key_blob.rb +25 -0
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp256/signature.rb +23 -0
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp256.rb +79 -0
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp384/ecdsa_signature_blob.rb +23 -0
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp384/public_key_blob.rb +25 -0
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp384/signature.rb +23 -0
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp384.rb +80 -0
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp521/ecdsa_signature_blob.rb +23 -0
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp521/public_key_blob.rb +25 -0
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp521/signature.rb +23 -0
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp521.rb +81 -0
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_dss/public_key_blob.rb +5 -5
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_dss/signature.rb +2 -2
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_dss.rb +9 -9
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_rsa/public_key_blob.rb +3 -3
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_rsa/signature.rb +2 -2
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_rsa.rb +6 -6
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm.rb +3 -0
- data/lib/hrr_rb_ssh/transport.rb +30 -30
- data/lib/hrr_rb_ssh/version.rb +1 -1
- metadata +39 -4
- data/lib/hrr_rb_ssh/connection/channel/proc_chain/chain_context.rb +0 -22
- data/lib/hrr_rb_ssh/connection/channel/proc_chain.rb +0 -25
@@ -0,0 +1,84 @@
|
|
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
|
+
class Authentication
|
9
|
+
class Method
|
10
|
+
class Publickey
|
11
|
+
class Algorithm
|
12
|
+
class EcdsaSha2Nistp521 < Algorithm
|
13
|
+
NAME = 'ecdsa-sha2-nistp521'
|
14
|
+
PREFERENCE = 50
|
15
|
+
DIGEST = 'sha512'
|
16
|
+
IDENTIFIER = 'nistp521'
|
17
|
+
CURVE_NAME = 'secp521r1'
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
@logger = HrrRbSsh::Logger.new(self.class.name)
|
21
|
+
end
|
22
|
+
|
23
|
+
def verify_public_key public_key_algorithm_name, public_key, public_key_blob
|
24
|
+
public_key = case public_key
|
25
|
+
when String
|
26
|
+
OpenSSL::PKey::EC.new(public_key)
|
27
|
+
when OpenSSL::PKey::EC
|
28
|
+
public_key
|
29
|
+
else
|
30
|
+
return false
|
31
|
+
end
|
32
|
+
public_key_message = {
|
33
|
+
:'public key algorithm name' => public_key_algorithm_name,
|
34
|
+
:'[identifier]' => self.class::IDENTIFIER,
|
35
|
+
:'Q' => public_key.public_key.to_bn.to_s(2)
|
36
|
+
}
|
37
|
+
public_key_blob == PublicKeyBlob.encode(public_key_message)
|
38
|
+
end
|
39
|
+
|
40
|
+
def verify_signature session_id, message
|
41
|
+
signature_message = Signature.decode message[:'signature']
|
42
|
+
signature_algorithm = signature_message[:'public key algorithm name']
|
43
|
+
signature_blob = signature_message[:'signature blob']
|
44
|
+
|
45
|
+
public_key = PublicKeyBlob.decode message[:'public key blob']
|
46
|
+
algorithm = OpenSSL::PKey::EC.new(self.class::CURVE_NAME)
|
47
|
+
algorithm.public_key = OpenSSL::PKey::EC::Point.new(algorithm.group, OpenSSL::BN.new(public_key[:'Q'], 2))
|
48
|
+
|
49
|
+
data_message = {
|
50
|
+
:'session identifier' => session_id,
|
51
|
+
:'message number' => message[:'message number'],
|
52
|
+
:'user name' => message[:'user name'],
|
53
|
+
:'service name' => message[:'service name'],
|
54
|
+
:'method name' => message[:'method name'],
|
55
|
+
:'with signature' => message[:'with signature'],
|
56
|
+
:'public key algorithm name' => message[:'public key algorithm name'],
|
57
|
+
:'public key blob' => message[:'public key blob'],
|
58
|
+
}
|
59
|
+
data_blob = SignatureBlob.encode data_message
|
60
|
+
|
61
|
+
hash = OpenSSL::Digest.digest(DIGEST, data_blob)
|
62
|
+
ecdsa_signature_blob = EcdsaSignatureBlob.decode signature_blob
|
63
|
+
sign_r = ecdsa_signature_blob[:'r']
|
64
|
+
sign_s = ecdsa_signature_blob[:'s']
|
65
|
+
sign_asn1 = OpenSSL::ASN1::Sequence.new(
|
66
|
+
[
|
67
|
+
OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(sign_r)),
|
68
|
+
OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(sign_s)),
|
69
|
+
]
|
70
|
+
)
|
71
|
+
sign_der = sign_asn1.to_der
|
72
|
+
(signature_algorithm == message[:'public key algorithm name']) && algorithm.dsa_verify_asn1(hash, sign_der)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
require 'hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp521/public_key_blob'
|
82
|
+
require 'hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp521/signature_blob'
|
83
|
+
require 'hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp521/signature'
|
84
|
+
require 'hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp521/ecdsa_signature_blob'
|
@@ -15,11 +15,11 @@ module HrrRbSsh
|
|
15
15
|
include Codable
|
16
16
|
end
|
17
17
|
DEFINITION = [
|
18
|
-
[DataType::String, 'public key algorithm name'],
|
19
|
-
[DataType::Mpint, 'p'],
|
20
|
-
[DataType::Mpint, 'q'],
|
21
|
-
[DataType::Mpint, 'g'],
|
22
|
-
[DataType::Mpint, 'y'],
|
18
|
+
[DataType::String, :'public key algorithm name'],
|
19
|
+
[DataType::Mpint, :'p'],
|
20
|
+
[DataType::Mpint, :'q'],
|
21
|
+
[DataType::Mpint, :'g'],
|
22
|
+
[DataType::Mpint, :'y'],
|
23
23
|
]
|
24
24
|
end
|
25
25
|
end
|
@@ -15,8 +15,8 @@ module HrrRbSsh
|
|
15
15
|
include Codable
|
16
16
|
end
|
17
17
|
DEFINITION = [
|
18
|
-
[DataType::String, 'public key algorithm name'],
|
19
|
-
[DataType::String, 'signature blob'],
|
18
|
+
[DataType::String, :'public key algorithm name'],
|
19
|
+
[DataType::String, :'signature blob'],
|
20
20
|
]
|
21
21
|
end
|
22
22
|
end
|
@@ -15,14 +15,14 @@ module HrrRbSsh
|
|
15
15
|
include Codable
|
16
16
|
end
|
17
17
|
DEFINITION = [
|
18
|
-
[DataType::String, 'session identifier'],
|
19
|
-
[DataType::Byte, 'message number'],
|
20
|
-
[DataType::String, 'user name'],
|
21
|
-
[DataType::String, 'service name'],
|
22
|
-
[DataType::String, 'method name'],
|
23
|
-
[DataType::Boolean, 'with signature'],
|
24
|
-
[DataType::String, 'public key algorithm name'],
|
25
|
-
[DataType::String, 'public key blob'],
|
18
|
+
[DataType::String, :'session identifier'],
|
19
|
+
[DataType::Byte, :'message number'],
|
20
|
+
[DataType::String, :'user name'],
|
21
|
+
[DataType::String, :'service name'],
|
22
|
+
[DataType::String, :'method name'],
|
23
|
+
[DataType::Boolean, :'with signature'],
|
24
|
+
[DataType::String, :'public key algorithm name'],
|
25
|
+
[DataType::String, :'public key blob'],
|
26
26
|
]
|
27
27
|
end
|
28
28
|
end
|
@@ -28,44 +28,44 @@ module HrrRbSsh
|
|
28
28
|
return false
|
29
29
|
end
|
30
30
|
public_key_message = {
|
31
|
-
'public key algorithm name' => public_key_algorithm_name,
|
32
|
-
'p' => public_key.p.to_i,
|
33
|
-
'g' => public_key.g.to_i,
|
34
|
-
'q' => public_key.q.to_i,
|
35
|
-
'y' => public_key.pub_key.to_i,
|
31
|
+
:'public key algorithm name' => public_key_algorithm_name,
|
32
|
+
:'p' => public_key.p.to_i,
|
33
|
+
:'g' => public_key.g.to_i,
|
34
|
+
:'q' => public_key.q.to_i,
|
35
|
+
:'y' => public_key.pub_key.to_i,
|
36
36
|
}
|
37
37
|
public_key_blob == PublicKeyBlob.encode(public_key_message)
|
38
38
|
end
|
39
39
|
|
40
40
|
def verify_signature session_id, message
|
41
|
-
signature_message = Signature.decode message['signature']
|
42
|
-
signature_algorithm = signature_message['public key algorithm name']
|
43
|
-
signature_blob = signature_message['signature blob']
|
41
|
+
signature_message = Signature.decode message[:'signature']
|
42
|
+
signature_algorithm = signature_message[:'public key algorithm name']
|
43
|
+
signature_blob = signature_message[:'signature blob']
|
44
44
|
|
45
|
-
public_key = PublicKeyBlob.decode message['public key blob']
|
45
|
+
public_key = PublicKeyBlob.decode message[:'public key blob']
|
46
46
|
algorithm = OpenSSL::PKey::DSA.new
|
47
47
|
if algorithm.respond_to?(:set_pqg)
|
48
|
-
algorithm.set_pqg public_key['p'], public_key['q'], public_key['g']
|
48
|
+
algorithm.set_pqg public_key[:'p'], public_key[:'q'], public_key[:'g']
|
49
49
|
else
|
50
|
-
algorithm.p = public_key['p']
|
51
|
-
algorithm.q = public_key['q']
|
52
|
-
algorithm.g = public_key['g']
|
50
|
+
algorithm.p = public_key[:'p']
|
51
|
+
algorithm.q = public_key[:'q']
|
52
|
+
algorithm.g = public_key[:'g']
|
53
53
|
end
|
54
54
|
if algorithm.respond_to?(:set_key)
|
55
|
-
algorithm.set_key public_key['y'], nil
|
55
|
+
algorithm.set_key public_key[:'y'], nil
|
56
56
|
else
|
57
|
-
algorithm.pub_key = public_key['y']
|
57
|
+
algorithm.pub_key = public_key[:'y']
|
58
58
|
end
|
59
59
|
|
60
60
|
data_message = {
|
61
|
-
'session identifier' => session_id,
|
62
|
-
'message number' => message['message number'],
|
63
|
-
'user name' => message['user name'],
|
64
|
-
'service name' => message['service name'],
|
65
|
-
'method name' => message['method name'],
|
66
|
-
'with signature' => message['with signature'],
|
67
|
-
'public key algorithm name' => message['public key algorithm name'],
|
68
|
-
'public key blob' => message['public key blob'],
|
61
|
+
:'session identifier' => session_id,
|
62
|
+
:'message number' => message[:'message number'],
|
63
|
+
:'user name' => message[:'user name'],
|
64
|
+
:'service name' => message[:'service name'],
|
65
|
+
:'method name' => message[:'method name'],
|
66
|
+
:'with signature' => message[:'with signature'],
|
67
|
+
:'public key algorithm name' => message[:'public key algorithm name'],
|
68
|
+
:'public key blob' => message[:'public key blob'],
|
69
69
|
}
|
70
70
|
data_blob = SignatureBlob.encode data_message
|
71
71
|
|
@@ -79,7 +79,7 @@ module HrrRbSsh
|
|
79
79
|
]
|
80
80
|
)
|
81
81
|
sign_der = sign_asn1.to_der
|
82
|
-
(signature_algorithm == message['public key algorithm name']) && algorithm.sysverify(hash, sign_der)
|
82
|
+
(signature_algorithm == message[:'public key algorithm name']) && algorithm.sysverify(hash, sign_der)
|
83
83
|
end
|
84
84
|
end
|
85
85
|
end
|
@@ -15,9 +15,9 @@ module HrrRbSsh
|
|
15
15
|
include Codable
|
16
16
|
end
|
17
17
|
DEFINITION = [
|
18
|
-
[DataType::String, 'public key algorithm name'],
|
19
|
-
[DataType::Mpint, 'e'],
|
20
|
-
[DataType::Mpint, 'n'],
|
18
|
+
[DataType::String, :'public key algorithm name'],
|
19
|
+
[DataType::Mpint, :'e'],
|
20
|
+
[DataType::Mpint, :'n'],
|
21
21
|
]
|
22
22
|
end
|
23
23
|
end
|
@@ -15,8 +15,8 @@ module HrrRbSsh
|
|
15
15
|
include Codable
|
16
16
|
end
|
17
17
|
DEFINITION = [
|
18
|
-
[DataType::String, 'public key algorithm name'],
|
19
|
-
[DataType::String, 'signature blob'],
|
18
|
+
[DataType::String, :'public key algorithm name'],
|
19
|
+
[DataType::String, :'signature blob'],
|
20
20
|
]
|
21
21
|
end
|
22
22
|
end
|
@@ -15,14 +15,14 @@ module HrrRbSsh
|
|
15
15
|
include Codable
|
16
16
|
end
|
17
17
|
DEFINITION = [
|
18
|
-
[DataType::String, 'session identifier'],
|
19
|
-
[DataType::Byte, 'message number'],
|
20
|
-
[DataType::String, 'user name'],
|
21
|
-
[DataType::String, 'service name'],
|
22
|
-
[DataType::String, 'method name'],
|
23
|
-
[DataType::Boolean, 'with signature'],
|
24
|
-
[DataType::String, 'public key algorithm name'],
|
25
|
-
[DataType::String, 'public key blob'],
|
18
|
+
[DataType::String, :'session identifier'],
|
19
|
+
[DataType::Byte, :'message number'],
|
20
|
+
[DataType::String, :'user name'],
|
21
|
+
[DataType::String, :'service name'],
|
22
|
+
[DataType::String, :'method name'],
|
23
|
+
[DataType::Boolean, :'with signature'],
|
24
|
+
[DataType::String, :'public key algorithm name'],
|
25
|
+
[DataType::String, :'public key blob'],
|
26
26
|
]
|
27
27
|
end
|
28
28
|
end
|
@@ -28,40 +28,40 @@ module HrrRbSsh
|
|
28
28
|
return false
|
29
29
|
end
|
30
30
|
public_key_message = {
|
31
|
-
'public key algorithm name' => public_key_algorithm_name,
|
32
|
-
'e' => public_key.e.to_i,
|
33
|
-
'n' => public_key.n.to_i,
|
31
|
+
:'public key algorithm name' => public_key_algorithm_name,
|
32
|
+
:'e' => public_key.e.to_i,
|
33
|
+
:'n' => public_key.n.to_i,
|
34
34
|
}
|
35
35
|
public_key_blob == PublicKeyBlob.encode(public_key_message)
|
36
36
|
end
|
37
37
|
|
38
38
|
def verify_signature session_id, message
|
39
|
-
signature_message = Signature.decode message['signature']
|
40
|
-
signature_algorithm = signature_message['public key algorithm name']
|
41
|
-
signature_blob = signature_message['signature blob']
|
39
|
+
signature_message = Signature.decode message[:'signature']
|
40
|
+
signature_algorithm = signature_message[:'public key algorithm name']
|
41
|
+
signature_blob = signature_message[:'signature blob']
|
42
42
|
|
43
|
-
public_key = PublicKeyBlob.decode message['public key blob']
|
43
|
+
public_key = PublicKeyBlob.decode message[:'public key blob']
|
44
44
|
algorithm = OpenSSL::PKey::RSA.new
|
45
45
|
if algorithm.respond_to?(:set_key)
|
46
|
-
algorithm.set_key public_key['n'], public_key['e'], nil
|
46
|
+
algorithm.set_key public_key[:'n'], public_key[:'e'], nil
|
47
47
|
else
|
48
|
-
algorithm.e = public_key['e']
|
49
|
-
algorithm.n = public_key['n']
|
48
|
+
algorithm.e = public_key[:'e']
|
49
|
+
algorithm.n = public_key[:'n']
|
50
50
|
end
|
51
51
|
|
52
52
|
data_message = {
|
53
|
-
'session identifier' => session_id,
|
54
|
-
'message number' => message['message number'],
|
55
|
-
'user name' => message['user name'],
|
56
|
-
'service name' => message['service name'],
|
57
|
-
'method name' => message['method name'],
|
58
|
-
'with signature' => message['with signature'],
|
59
|
-
'public key algorithm name' => message['public key algorithm name'],
|
60
|
-
'public key blob' => message['public key blob'],
|
53
|
+
:'session identifier' => session_id,
|
54
|
+
:'message number' => message[:'message number'],
|
55
|
+
:'user name' => message[:'user name'],
|
56
|
+
:'service name' => message[:'service name'],
|
57
|
+
:'method name' => message[:'method name'],
|
58
|
+
:'with signature' => message[:'with signature'],
|
59
|
+
:'public key algorithm name' => message[:'public key algorithm name'],
|
60
|
+
:'public key blob' => message[:'public key blob'],
|
61
61
|
}
|
62
62
|
data_blob = SignatureBlob.encode data_message
|
63
63
|
|
64
|
-
(signature_algorithm == message['public key algorithm name']) && algorithm.verify(DIGEST, signature_blob, data_blob)
|
64
|
+
(signature_algorithm == message[:'public key algorithm name']) && algorithm.verify(DIGEST, signature_blob, data_blob)
|
65
65
|
end
|
66
66
|
end
|
67
67
|
end
|
@@ -20,3 +20,6 @@ end
|
|
20
20
|
|
21
21
|
require 'hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_dss'
|
22
22
|
require 'hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_rsa'
|
23
|
+
require 'hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp256'
|
24
|
+
require 'hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp384'
|
25
|
+
require 'hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp521'
|
@@ -25,13 +25,13 @@ module HrrRbSsh
|
|
25
25
|
@session_id = session_id
|
26
26
|
@message = message
|
27
27
|
|
28
|
-
@message_number = message['message number']
|
29
|
-
@service_name = message['service name']
|
30
|
-
@method_name = message['method name']
|
31
|
-
@with_signature = message['with signature']
|
32
|
-
@public_key_algorithm_name = message['public key algorithm name']
|
33
|
-
@public_key_blob = message['public key blob']
|
34
|
-
@signature = message['signature']
|
28
|
+
@message_number = message[:'message number']
|
29
|
+
@service_name = message[:'service name']
|
30
|
+
@method_name = message[:'method name']
|
31
|
+
@with_signature = message[:'with signature']
|
32
|
+
@public_key_algorithm_name = message[:'public key algorithm name']
|
33
|
+
@public_key_blob = message[:'public key blob']
|
34
|
+
@signature = message[:'signature']
|
35
35
|
end
|
36
36
|
|
37
37
|
def verify username, public_key_algorithm_name, public_key
|
@@ -17,18 +17,18 @@ module HrrRbSsh
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def authenticate userauth_request_message
|
20
|
-
public_key_algorithm_name = userauth_request_message['public key algorithm name']
|
20
|
+
public_key_algorithm_name = userauth_request_message[:'public key algorithm name']
|
21
21
|
unless Algorithm.list_preferred.include?(public_key_algorithm_name)
|
22
22
|
@logger.info("unsupported public key algorithm: #{public_key_algorithm_name}")
|
23
23
|
return false
|
24
24
|
end
|
25
|
-
unless userauth_request_message['with signature']
|
25
|
+
unless userauth_request_message[:'with signature']
|
26
26
|
@logger.info("public key algorithm is ok, require signature")
|
27
|
-
public_key_blob = userauth_request_message['public key blob']
|
27
|
+
public_key_blob = userauth_request_message[:'public key blob']
|
28
28
|
userauth_pk_ok_message public_key_algorithm_name, public_key_blob
|
29
29
|
else
|
30
30
|
@logger.info("verify signature")
|
31
|
-
username = userauth_request_message['user name']
|
31
|
+
username = userauth_request_message[:'user name']
|
32
32
|
algorithm = Algorithm[public_key_algorithm_name].new
|
33
33
|
context = Context.new(username, algorithm, @session_id, userauth_request_message)
|
34
34
|
@authenticator.authenticate context
|
@@ -37,9 +37,9 @@ module HrrRbSsh
|
|
37
37
|
|
38
38
|
def userauth_pk_ok_message public_key_algorithm_name, public_key_blob
|
39
39
|
message = {
|
40
|
-
'message number' => HrrRbSsh::Message::SSH_MSG_USERAUTH_PK_OK::VALUE,
|
41
|
-
'public key algorithm name from the request' => public_key_algorithm_name,
|
42
|
-
'public key blob from the request' => public_key_blob,
|
40
|
+
:'message number' => HrrRbSsh::Message::SSH_MSG_USERAUTH_PK_OK::VALUE,
|
41
|
+
:'public key algorithm name from the request' => public_key_algorithm_name,
|
42
|
+
:'public key blob from the request' => public_key_blob,
|
43
43
|
}
|
44
44
|
payload = HrrRbSsh::Message::SSH_MSG_USERAUTH_PK_OK.encode message
|
45
45
|
end
|
@@ -68,14 +68,14 @@ module HrrRbSsh
|
|
68
68
|
case payload[0,1].unpack("C")[0]
|
69
69
|
when HrrRbSsh::Message::SSH_MSG_USERAUTH_REQUEST::VALUE
|
70
70
|
userauth_request_message = HrrRbSsh::Message::SSH_MSG_USERAUTH_REQUEST.decode payload
|
71
|
-
method_name = userauth_request_message['method name']
|
71
|
+
method_name = userauth_request_message[:'method name']
|
72
72
|
method = Method[method_name].new({'session id' => @transport.session_id}.merge(@options))
|
73
73
|
result = method.authenticate(userauth_request_message)
|
74
74
|
case result
|
75
75
|
when TrueClass
|
76
76
|
@logger.info("verified")
|
77
77
|
send_userauth_success
|
78
|
-
@username = userauth_request_message['user name']
|
78
|
+
@username = userauth_request_message[:'user name']
|
79
79
|
@closed = false
|
80
80
|
break
|
81
81
|
when FalseClass
|
@@ -94,9 +94,9 @@ module HrrRbSsh
|
|
94
94
|
|
95
95
|
def send_userauth_failure
|
96
96
|
message = {
|
97
|
-
'message number' => HrrRbSsh::Message::SSH_MSG_USERAUTH_FAILURE::VALUE,
|
98
|
-
'authentications that can continue' => Method.list_preferred,
|
99
|
-
'partial success' => false,
|
97
|
+
:'message number' => HrrRbSsh::Message::SSH_MSG_USERAUTH_FAILURE::VALUE,
|
98
|
+
:'authentications that can continue' => Method.list_preferred,
|
99
|
+
:'partial success' => false,
|
100
100
|
}
|
101
101
|
payload = HrrRbSsh::Message::SSH_MSG_USERAUTH_FAILURE.encode message
|
102
102
|
@transport.send payload
|
@@ -104,7 +104,7 @@ module HrrRbSsh
|
|
104
104
|
|
105
105
|
def send_userauth_success
|
106
106
|
message = {
|
107
|
-
'message number' => HrrRbSsh::Message::SSH_MSG_USERAUTH_SUCCESS::VALUE,
|
107
|
+
:'message number' => HrrRbSsh::Message::SSH_MSG_USERAUTH_SUCCESS::VALUE,
|
108
108
|
}
|
109
109
|
payload = HrrRbSsh::Message::SSH_MSG_USERAUTH_SUCCESS.encode message
|
110
110
|
@transport.send payload
|
data/lib/hrr_rb_ssh/codable.rb
CHANGED
@@ -25,8 +25,13 @@ module HrrRbSsh
|
|
25
25
|
logger.debug('encoding message: ' + message.inspect)
|
26
26
|
definition = common_definition + conditional_definition(message.merge complementary_message)
|
27
27
|
definition.map{ |data_type, field_name|
|
28
|
-
|
29
|
-
|
28
|
+
begin
|
29
|
+
field_value = if message[field_name].instance_of? ::Proc then message[field_name].call else message[field_name] end
|
30
|
+
data_type.encode( field_value )
|
31
|
+
rescue => e
|
32
|
+
logger.debug("'field_name', 'field_value': #{field_name.inspect}, #{field_value.inspect}")
|
33
|
+
raise e
|
34
|
+
end
|
30
35
|
}.join
|
31
36
|
end
|
32
37
|
|
@@ -0,0 +1,102 @@
|
|
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
|
+
class ChannelType
|
10
|
+
class DirectTcpip < ChannelType
|
11
|
+
NAME = 'direct-tcpip'
|
12
|
+
|
13
|
+
def initialize connection, channel, message
|
14
|
+
@logger = HrrRbSsh::Logger.new self.class.name
|
15
|
+
@connection = connection
|
16
|
+
@channel = channel
|
17
|
+
@host_to_connect = message[:'host to connect']
|
18
|
+
@port_to_connect = message[:'port to connect']
|
19
|
+
@originator_IP_address = message[:'originator IP address']
|
20
|
+
@originator_port = message[:'originator port']
|
21
|
+
end
|
22
|
+
|
23
|
+
def start
|
24
|
+
@socket = TCPSocket.new @host_to_connect, @port_to_connect
|
25
|
+
@sender_thread = sender_thread
|
26
|
+
@receiver_thread = receiver_thread
|
27
|
+
end
|
28
|
+
|
29
|
+
def close
|
30
|
+
begin
|
31
|
+
if @sender_thread_finished && @receiver_thread_finished
|
32
|
+
@logger.info("closing direct-tcpip")
|
33
|
+
@socket.close
|
34
|
+
@channel.close from=:channel_type_instance
|
35
|
+
@logger.info("direct-tcpip closed")
|
36
|
+
end
|
37
|
+
rescue => e
|
38
|
+
@logger.error([e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def sender_thread
|
43
|
+
Thread.new(@socket){ |s|
|
44
|
+
begin
|
45
|
+
loop do
|
46
|
+
begin
|
47
|
+
@channel.request_handler_io.write s.readpartial(10240)
|
48
|
+
rescue EOFError
|
49
|
+
@logger.info("socket is EOF")
|
50
|
+
@channel.request_handler_io.close_write
|
51
|
+
break
|
52
|
+
rescue IOError
|
53
|
+
@logger.info("socket is closed")
|
54
|
+
@channel.request_handler_io.close_write
|
55
|
+
break
|
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
|
+
@channel.request_handler_io.close_write
|
59
|
+
break
|
60
|
+
end
|
61
|
+
end
|
62
|
+
@logger.info("finishing sender thread")
|
63
|
+
@sender_thread_finished = true
|
64
|
+
close
|
65
|
+
ensure
|
66
|
+
@logger.info("sender thread finished")
|
67
|
+
end
|
68
|
+
}
|
69
|
+
end
|
70
|
+
|
71
|
+
def receiver_thread
|
72
|
+
Thread.new(@socket){ |s|
|
73
|
+
begin
|
74
|
+
loop do
|
75
|
+
begin
|
76
|
+
s.write @channel.request_handler_io.readpartial(10240)
|
77
|
+
rescue EOFError
|
78
|
+
@logger.info("io is EOF")
|
79
|
+
s.close_write
|
80
|
+
break
|
81
|
+
rescue IOError
|
82
|
+
@logger.info("socket is closed")
|
83
|
+
break
|
84
|
+
rescue => e
|
85
|
+
@logger.error([e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join)
|
86
|
+
s.close_write
|
87
|
+
break
|
88
|
+
end
|
89
|
+
end
|
90
|
+
@logger.info("finishing receiver thread")
|
91
|
+
@receiver_thread_finished = true
|
92
|
+
close
|
93
|
+
ensure
|
94
|
+
@logger.info("receiver thread finished")
|
95
|
+
end
|
96
|
+
}
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,26 @@
|
|
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
|
+
class ChannelType
|
10
|
+
class Session
|
11
|
+
class ProcChain
|
12
|
+
class ChainContext
|
13
|
+
def initialize proc_chain
|
14
|
+
@logger = HrrRbSsh::Logger.new self.class.name
|
15
|
+
@proc_chain = proc_chain
|
16
|
+
end
|
17
|
+
def call_next *args
|
18
|
+
@proc_chain.call_next *args
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# vim: et ts=2 sw=2
|
3
|
+
|
4
|
+
require 'hrr_rb_ssh/logger'
|
5
|
+
require 'hrr_rb_ssh/connection/channel/channel_type/session/proc_chain/chain_context'
|
6
|
+
|
7
|
+
module HrrRbSsh
|
8
|
+
class Connection
|
9
|
+
class Channel
|
10
|
+
class ChannelType
|
11
|
+
class Session
|
12
|
+
class ProcChain
|
13
|
+
def initialize
|
14
|
+
@logger = HrrRbSsh::Logger.new self.class.name
|
15
|
+
@q = Queue.new
|
16
|
+
end
|
17
|
+
def connect next_proc
|
18
|
+
@q.enq next_proc if next_proc
|
19
|
+
end
|
20
|
+
def call_next *args
|
21
|
+
next_proc = @q.deq
|
22
|
+
next_proc.call ChainContext.new(self), *args
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -29,8 +29,8 @@ module HrrRbSsh
|
|
29
29
|
@variables = variables
|
30
30
|
@vars = variables
|
31
31
|
|
32
|
-
@variable_name = message['variable name']
|
33
|
-
@variable_value = message['variable value']
|
32
|
+
@variable_name = message[:'variable name']
|
33
|
+
@variable_value = message[:'variable value']
|
34
34
|
end
|
35
35
|
|
36
36
|
def chain_proc &block
|