hrr_rb_ssh 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +27 -0
- data/.rspec +3 -0
- data/.travis.yml +22 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/LICENSE +201 -0
- data/README.md +47 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/demo/server.rb +134 -0
- data/hrr_rb_ssh.gemspec +27 -0
- data/lib/hrr_rb_ssh/authentication/authenticator.rb +16 -0
- data/lib/hrr_rb_ssh/authentication/method/none/context.rb +28 -0
- data/lib/hrr_rb_ssh/authentication/method/none.rb +38 -0
- data/lib/hrr_rb_ssh/authentication/method/password/context.rb +29 -0
- data/lib/hrr_rb_ssh/authentication/method/password.rb +37 -0
- data/lib/hrr_rb_ssh/authentication/method.rb +21 -0
- data/lib/hrr_rb_ssh/authentication.rb +107 -0
- data/lib/hrr_rb_ssh/closed_authentication_error.rb +7 -0
- data/lib/hrr_rb_ssh/closed_connection_error.rb +7 -0
- data/lib/hrr_rb_ssh/closed_transport_error.rb +7 -0
- data/lib/hrr_rb_ssh/compat.rb +65 -0
- data/lib/hrr_rb_ssh/connection/channel/proc_chain/chain_context.rb +22 -0
- data/lib/hrr_rb_ssh/connection/channel/proc_chain.rb +25 -0
- data/lib/hrr_rb_ssh/connection/channel/session/env/context.rb +43 -0
- data/lib/hrr_rb_ssh/connection/channel/session/env.rb +31 -0
- data/lib/hrr_rb_ssh/connection/channel/session/exec/context.rb +41 -0
- data/lib/hrr_rb_ssh/connection/channel/session/exec.rb +31 -0
- data/lib/hrr_rb_ssh/connection/channel/session/pty_req/context.rb +50 -0
- data/lib/hrr_rb_ssh/connection/channel/session/pty_req.rb +31 -0
- data/lib/hrr_rb_ssh/connection/channel/session/shell/context.rb +37 -0
- data/lib/hrr_rb_ssh/connection/channel/session/shell.rb +31 -0
- data/lib/hrr_rb_ssh/connection/channel/session/subsystem/context.rb +40 -0
- data/lib/hrr_rb_ssh/connection/channel/session/subsystem.rb +31 -0
- data/lib/hrr_rb_ssh/connection/channel/session.rb +31 -0
- data/lib/hrr_rb_ssh/connection/channel.rb +278 -0
- data/lib/hrr_rb_ssh/connection/request_handler.rb +18 -0
- data/lib/hrr_rb_ssh/connection.rb +170 -0
- data/lib/hrr_rb_ssh/logger.rb +52 -0
- data/lib/hrr_rb_ssh/message/001_ssh_msg_disconnect.rb +44 -0
- data/lib/hrr_rb_ssh/message/002_ssh_msg_ignore.rb +24 -0
- data/lib/hrr_rb_ssh/message/003_ssh_msg_unimplemented.rb +24 -0
- data/lib/hrr_rb_ssh/message/004_ssh_msg_debug.rb +26 -0
- data/lib/hrr_rb_ssh/message/005_ssh_msg_service_request.rb +24 -0
- data/lib/hrr_rb_ssh/message/006_ssh_msg_service_accept.rb +24 -0
- data/lib/hrr_rb_ssh/message/020_ssh_msg_kexinit.rb +51 -0
- data/lib/hrr_rb_ssh/message/021_ssh_msg_newkeys.rb +23 -0
- data/lib/hrr_rb_ssh/message/030_ssh_msg_kexdh_init.rb +24 -0
- data/lib/hrr_rb_ssh/message/031_ssh_msg_kexdh_reply.rb +26 -0
- data/lib/hrr_rb_ssh/message/050_ssh_msg_userauth_request.rb +58 -0
- data/lib/hrr_rb_ssh/message/051_ssh_msg_userauth_failure.rb +25 -0
- data/lib/hrr_rb_ssh/message/052_ssh_msg_userauth_success.rb +23 -0
- data/lib/hrr_rb_ssh/message/060_ssh_msg_userauth_pk_ok.rb +25 -0
- data/lib/hrr_rb_ssh/message/080_ssh_msg_global_request.rb +47 -0
- data/lib/hrr_rb_ssh/message/081_ssh_msg_request_success.rb +36 -0
- data/lib/hrr_rb_ssh/message/082_ssh_msg_request_failure.rb +23 -0
- data/lib/hrr_rb_ssh/message/090_ssh_msg_channel_open.rb +67 -0
- data/lib/hrr_rb_ssh/message/091_ssh_msg_channel_open_confirmation.rb +67 -0
- data/lib/hrr_rb_ssh/message/092_ssh_msg_channel_open_failure.rb +34 -0
- data/lib/hrr_rb_ssh/message/093_ssh_msg_channel_window_adjust.rb +25 -0
- data/lib/hrr_rb_ssh/message/094_ssh_msg_channel_data.rb +25 -0
- data/lib/hrr_rb_ssh/message/095_ssh_msg_channel_extended_data.rb +30 -0
- data/lib/hrr_rb_ssh/message/096_ssh_msg_channel_eof.rb +24 -0
- data/lib/hrr_rb_ssh/message/097_ssh_msg_channel_close.rb +24 -0
- data/lib/hrr_rb_ssh/message/098_ssh_msg_channel_request.rb +139 -0
- data/lib/hrr_rb_ssh/message/099_ssh_msg_channel_success.rb +24 -0
- data/lib/hrr_rb_ssh/message/100_ssh_msg_channel_failure.rb +24 -0
- data/lib/hrr_rb_ssh/message/codable.rb +67 -0
- data/lib/hrr_rb_ssh/message.rb +36 -0
- data/lib/hrr_rb_ssh/transport/compression_algorithm/none.rb +33 -0
- data/lib/hrr_rb_ssh/transport/compression_algorithm/zlib.rb +38 -0
- data/lib/hrr_rb_ssh/transport/compression_algorithm.rb +22 -0
- data/lib/hrr_rb_ssh/transport/constant.rb +11 -0
- data/lib/hrr_rb_ssh/transport/data_type.rb +163 -0
- data/lib/hrr_rb_ssh/transport/encryption_algorithm/aes_128_cbc.rb +73 -0
- data/lib/hrr_rb_ssh/transport/encryption_algorithm/none.rb +49 -0
- data/lib/hrr_rb_ssh/transport/encryption_algorithm.rb +22 -0
- data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman.rb +129 -0
- data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group14_sha1.rb +42 -0
- data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group1_sha1.rb +34 -0
- data/lib/hrr_rb_ssh/transport/kex_algorithm.rb +22 -0
- data/lib/hrr_rb_ssh/transport/mac_algorithm/hmac_sha1.rb +45 -0
- data/lib/hrr_rb_ssh/transport/mac_algorithm/none.rb +40 -0
- data/lib/hrr_rb_ssh/transport/mac_algorithm.rb +22 -0
- data/lib/hrr_rb_ssh/transport/mode.rb +11 -0
- data/lib/hrr_rb_ssh/transport/receiver.rb +75 -0
- data/lib/hrr_rb_ssh/transport/sender.rb +57 -0
- data/lib/hrr_rb_ssh/transport/sequence_number.rb +22 -0
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_rsa.rb +108 -0
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm.rb +21 -0
- data/lib/hrr_rb_ssh/transport.rb +459 -0
- data/lib/hrr_rb_ssh/version.rb +6 -0
- data/lib/hrr_rb_ssh.rb +13 -0
- metadata +193 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
# vim: et ts=2 sw=2
|
|
3
|
+
|
|
4
|
+
require 'hrr_rb_ssh/logger'
|
|
5
|
+
require 'hrr_rb_ssh/message/codable'
|
|
6
|
+
|
|
7
|
+
module HrrRbSsh
|
|
8
|
+
module Message
|
|
9
|
+
module SSH_MSG_CHANNEL_EXTENDED_DATA
|
|
10
|
+
module DataTypeCode
|
|
11
|
+
SSH_EXTENDED_DATA_STDERR = 1
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class << self
|
|
15
|
+
include Codable
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
ID = self.name.split('::').last
|
|
19
|
+
VALUE = 95
|
|
20
|
+
|
|
21
|
+
DEFINITION = [
|
|
22
|
+
# [Data Type, Field Name]
|
|
23
|
+
['byte', 'SSH_MSG_CHANNEL_EXTENDED_DATA'],
|
|
24
|
+
['uint32', 'recipient channel'],
|
|
25
|
+
['uint32', 'data type code'],
|
|
26
|
+
['string', 'data'],
|
|
27
|
+
]
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
# vim: et ts=2 sw=2
|
|
3
|
+
|
|
4
|
+
require 'hrr_rb_ssh/logger'
|
|
5
|
+
require 'hrr_rb_ssh/message/codable'
|
|
6
|
+
|
|
7
|
+
module HrrRbSsh
|
|
8
|
+
module Message
|
|
9
|
+
module SSH_MSG_CHANNEL_EOF
|
|
10
|
+
class << self
|
|
11
|
+
include Codable
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
ID = self.name.split('::').last
|
|
15
|
+
VALUE = 96
|
|
16
|
+
|
|
17
|
+
DEFINITION = [
|
|
18
|
+
# [Data Type, Field Name]
|
|
19
|
+
['byte', 'SSH_MSG_CHANNEL_EOF'],
|
|
20
|
+
['uint32', 'recipient channel'],
|
|
21
|
+
]
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
# vim: et ts=2 sw=2
|
|
3
|
+
|
|
4
|
+
require 'hrr_rb_ssh/logger'
|
|
5
|
+
require 'hrr_rb_ssh/message/codable'
|
|
6
|
+
|
|
7
|
+
module HrrRbSsh
|
|
8
|
+
module Message
|
|
9
|
+
module SSH_MSG_CHANNEL_CLOSE
|
|
10
|
+
class << self
|
|
11
|
+
include Codable
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
ID = self.name.split('::').last
|
|
15
|
+
VALUE = 97
|
|
16
|
+
|
|
17
|
+
DEFINITION = [
|
|
18
|
+
# [Data Type, Field Name]
|
|
19
|
+
['byte', 'SSH_MSG_CHANNEL_CLOSE'],
|
|
20
|
+
['uint32', 'recipient channel'],
|
|
21
|
+
]
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
# vim: et ts=2 sw=2
|
|
3
|
+
|
|
4
|
+
require 'hrr_rb_ssh/logger'
|
|
5
|
+
require 'hrr_rb_ssh/message/codable'
|
|
6
|
+
|
|
7
|
+
module HrrRbSsh
|
|
8
|
+
module Message
|
|
9
|
+
module SSH_MSG_CHANNEL_REQUEST
|
|
10
|
+
module SignalName
|
|
11
|
+
ABRT = 'ABRT'
|
|
12
|
+
ALRM = 'ALRM'
|
|
13
|
+
FPE = 'FPE'
|
|
14
|
+
HUP = 'HUP'
|
|
15
|
+
ILL = 'ILL'
|
|
16
|
+
INT = 'INT'
|
|
17
|
+
KILL = 'KILL'
|
|
18
|
+
PIPE = 'PIPE'
|
|
19
|
+
QUIT = 'QUIT'
|
|
20
|
+
SEGV = 'SEGV'
|
|
21
|
+
TERM = 'TERM'
|
|
22
|
+
USR1 = 'USR1'
|
|
23
|
+
USR2 = 'USR2'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
class << self
|
|
27
|
+
include Codable
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
ID = self.name.split('::').last
|
|
31
|
+
VALUE = 98
|
|
32
|
+
|
|
33
|
+
DEFINITION = [
|
|
34
|
+
# [Data Type, Field Name]
|
|
35
|
+
['byte', 'SSH_MSG_CHANNEL_REQUEST'],
|
|
36
|
+
['uint32', 'recipient channel'],
|
|
37
|
+
['string', 'request type'],
|
|
38
|
+
['boolean', 'want reply'],
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
PTY_REQ_DEFINITION = [
|
|
42
|
+
# [Data Type, Field Name]
|
|
43
|
+
# ['string', 'request type' : "pty-req"],
|
|
44
|
+
['string', 'TERM environment variable value'],
|
|
45
|
+
['uint32', 'terminal width, characters'],
|
|
46
|
+
['uint32', 'terminal height, rows'],
|
|
47
|
+
['uint32', 'terminal width, pixels'],
|
|
48
|
+
['uint32', 'terminal height, pixels'],
|
|
49
|
+
['string', 'encoded terminal modes'],
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
X11_REQ_DEFINITION = [
|
|
53
|
+
# [Data Type, Field Name]
|
|
54
|
+
# ['string', 'request type' : "x11-req"],
|
|
55
|
+
['boolean', 'single connection'],
|
|
56
|
+
['string', 'x11 authentication protocol'],
|
|
57
|
+
['string', 'x11 authentication cookie'],
|
|
58
|
+
['uint32', 'x11 screen number'],
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
ENV_DEFINITION = [
|
|
62
|
+
# [Data Type, Field Name]
|
|
63
|
+
# ['string', 'request type' : "env"],
|
|
64
|
+
['string', 'variable name'],
|
|
65
|
+
['string', 'variable value'],
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
SHELL_DEFINITION = [
|
|
69
|
+
# [Data Type, Field Name]
|
|
70
|
+
# ['string', 'request type' : "shell"],
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
EXEC_DEFINITION = [
|
|
74
|
+
# [Data Type, Field Name]
|
|
75
|
+
# ['string', 'request type' : "exec"],
|
|
76
|
+
['string', 'command'],
|
|
77
|
+
]
|
|
78
|
+
|
|
79
|
+
SUBSYSTEM_DEFINITION = [
|
|
80
|
+
# [Data Type, Field Name]
|
|
81
|
+
# ['string', 'request type' : "subsystem"],
|
|
82
|
+
['string', 'subsystem name'],
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
WINDOW_CHANGE_DEFINITION = [
|
|
86
|
+
# [Data Type, Field Name]
|
|
87
|
+
# ['string', 'request type' : "window-change"],
|
|
88
|
+
['uint32', 'terminal width, columns'],
|
|
89
|
+
['uint32', 'terminal height, rows'],
|
|
90
|
+
['uint32', 'terminal width, pixels'],
|
|
91
|
+
['uint32', 'terminal height, pixels'],
|
|
92
|
+
]
|
|
93
|
+
|
|
94
|
+
XON_XOFF_DEFINITION = [
|
|
95
|
+
# [Data Type, Field Name]
|
|
96
|
+
# ['string', 'request type' : "xon-xoff"],
|
|
97
|
+
['boolean', 'client can do'],
|
|
98
|
+
]
|
|
99
|
+
|
|
100
|
+
SIGNAL_DEFINITION = [
|
|
101
|
+
# [Data Type, Field Name]
|
|
102
|
+
# ['string', 'request type' : "signal"],
|
|
103
|
+
['string', 'signal name'],
|
|
104
|
+
]
|
|
105
|
+
|
|
106
|
+
EXIT_STATUS_DEFINITION = [
|
|
107
|
+
# [Data Type, Field Name]
|
|
108
|
+
# ['string', 'request type' : "exit-status"],
|
|
109
|
+
['uint32', 'exit status'],
|
|
110
|
+
]
|
|
111
|
+
|
|
112
|
+
EXIT_SIGNAL_DEFINITION = [
|
|
113
|
+
# [Data Type, Field Name]
|
|
114
|
+
# ['string', 'request type' : "exit-signal"],
|
|
115
|
+
['string', 'signal name'],
|
|
116
|
+
['boolean', 'core dumped'],
|
|
117
|
+
['string', 'error message'],
|
|
118
|
+
['string', 'language tag'],
|
|
119
|
+
]
|
|
120
|
+
|
|
121
|
+
CONDITIONAL_DEFINITION = {
|
|
122
|
+
# Field Name => {Field Value => Conditional Definition}
|
|
123
|
+
'request type' => {
|
|
124
|
+
'pty-req' => PTY_REQ_DEFINITION,
|
|
125
|
+
'x11-req' => X11_REQ_DEFINITION,
|
|
126
|
+
'env' => ENV_DEFINITION,
|
|
127
|
+
'shell' => SHELL_DEFINITION,
|
|
128
|
+
'exec' => EXEC_DEFINITION,
|
|
129
|
+
'subsystem' => SUBSYSTEM_DEFINITION,
|
|
130
|
+
'window-change' => WINDOW_CHANGE_DEFINITION,
|
|
131
|
+
'xon-xoff' => XON_XOFF_DEFINITION,
|
|
132
|
+
'signal' => SIGNAL_DEFINITION,
|
|
133
|
+
'exit-status' => EXIT_STATUS_DEFINITION,
|
|
134
|
+
'exit-signal' => EXIT_SIGNAL_DEFINITION,
|
|
135
|
+
},
|
|
136
|
+
}
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
# vim: et ts=2 sw=2
|
|
3
|
+
|
|
4
|
+
require 'hrr_rb_ssh/logger'
|
|
5
|
+
require 'hrr_rb_ssh/message/codable'
|
|
6
|
+
|
|
7
|
+
module HrrRbSsh
|
|
8
|
+
module Message
|
|
9
|
+
module SSH_MSG_CHANNEL_SUCCESS
|
|
10
|
+
class << self
|
|
11
|
+
include Codable
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
ID = self.name.split('::').last
|
|
15
|
+
VALUE = 99
|
|
16
|
+
|
|
17
|
+
DEFINITION = [
|
|
18
|
+
# [Data Type, Field Name]
|
|
19
|
+
['byte', 'SSH_MSG_CHANNEL_SUCCESS'],
|
|
20
|
+
['uint32', 'recipient channel'],
|
|
21
|
+
]
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
# vim: et ts=2 sw=2
|
|
3
|
+
|
|
4
|
+
require 'hrr_rb_ssh/logger'
|
|
5
|
+
require 'hrr_rb_ssh/message/codable'
|
|
6
|
+
|
|
7
|
+
module HrrRbSsh
|
|
8
|
+
module Message
|
|
9
|
+
module SSH_MSG_CHANNEL_FAILURE
|
|
10
|
+
class << self
|
|
11
|
+
include Codable
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
ID = self.name.split('::').last
|
|
15
|
+
VALUE = 100
|
|
16
|
+
|
|
17
|
+
DEFINITION = [
|
|
18
|
+
# [Data Type, Field Name]
|
|
19
|
+
['byte', 'SSH_MSG_CHANNEL_FAILURE'],
|
|
20
|
+
['uint32', 'recipient channel'],
|
|
21
|
+
]
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
# vim: et ts=2 sw=2
|
|
3
|
+
|
|
4
|
+
require 'hrr_rb_ssh/logger'
|
|
5
|
+
require 'hrr_rb_ssh/transport/data_type'
|
|
6
|
+
|
|
7
|
+
module HrrRbSsh
|
|
8
|
+
module Message
|
|
9
|
+
module Codable
|
|
10
|
+
def logger
|
|
11
|
+
@logger ||= HrrRbSsh::Logger.new self.name
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def common_definition
|
|
15
|
+
self::DEFINITION
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def conditional_definition message
|
|
19
|
+
message.inject([]){ |a, (k,v)|
|
|
20
|
+
field_name = k
|
|
21
|
+
field_value = if v.instance_of? ::Proc then v.call else v end
|
|
22
|
+
a + ((self::CONDITIONAL_DEFINITION rescue {}).fetch(field_name, {})[field_value] || [])
|
|
23
|
+
}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def encode message, complementary_message={}
|
|
27
|
+
logger.debug('encoding message: ' + message.inspect)
|
|
28
|
+
definition = common_definition + conditional_definition(message.merge complementary_message)
|
|
29
|
+
definition.map{ |data_type, field_name|
|
|
30
|
+
field_value = if message[field_name].instance_of? ::Proc then message[field_name].call else message[field_name] end
|
|
31
|
+
HrrRbSsh::Transport::DataType[data_type].encode( field_value )
|
|
32
|
+
}.join
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def decode payload, complementary_message={}
|
|
36
|
+
def decode_recursively payload_io, message=nil
|
|
37
|
+
if message.class == Array and message.size == 0
|
|
38
|
+
[]
|
|
39
|
+
else
|
|
40
|
+
definition = case message
|
|
41
|
+
when nil
|
|
42
|
+
common_definition
|
|
43
|
+
when Array
|
|
44
|
+
conditional_definition(message)
|
|
45
|
+
end
|
|
46
|
+
decoded_message = definition.map{ |data_type, field_name|
|
|
47
|
+
[
|
|
48
|
+
field_name,
|
|
49
|
+
HrrRbSsh::Transport::DataType[data_type].decode( payload_io )
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
decoded_message + decode_recursively(payload_io, decoded_message)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
payload_io = StringIO.new payload
|
|
58
|
+
decoded_message = decode_recursively(payload_io).to_h
|
|
59
|
+
if complementary_message.any?
|
|
60
|
+
decoded_message.merge! decode_recursively(payload_io, complementary_message.to_a).to_h
|
|
61
|
+
end
|
|
62
|
+
logger.debug('decoded message: ' + decoded_message.inspect)
|
|
63
|
+
decoded_message
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
# vim: et ts=2 sw=2
|
|
3
|
+
|
|
4
|
+
require 'hrr_rb_ssh/message/001_ssh_msg_disconnect'
|
|
5
|
+
require 'hrr_rb_ssh/message/002_ssh_msg_ignore'
|
|
6
|
+
require 'hrr_rb_ssh/message/003_ssh_msg_unimplemented'
|
|
7
|
+
require 'hrr_rb_ssh/message/004_ssh_msg_debug'
|
|
8
|
+
require 'hrr_rb_ssh/message/005_ssh_msg_service_request'
|
|
9
|
+
require 'hrr_rb_ssh/message/006_ssh_msg_service_accept'
|
|
10
|
+
require 'hrr_rb_ssh/message/020_ssh_msg_kexinit'
|
|
11
|
+
require 'hrr_rb_ssh/message/021_ssh_msg_newkeys'
|
|
12
|
+
require 'hrr_rb_ssh/message/030_ssh_msg_kexdh_init'
|
|
13
|
+
require 'hrr_rb_ssh/message/031_ssh_msg_kexdh_reply'
|
|
14
|
+
require 'hrr_rb_ssh/message/050_ssh_msg_userauth_request'
|
|
15
|
+
require 'hrr_rb_ssh/message/051_ssh_msg_userauth_failure'
|
|
16
|
+
require 'hrr_rb_ssh/message/052_ssh_msg_userauth_success'
|
|
17
|
+
require 'hrr_rb_ssh/message/060_ssh_msg_userauth_pk_ok'
|
|
18
|
+
require 'hrr_rb_ssh/message/080_ssh_msg_global_request.rb'
|
|
19
|
+
require 'hrr_rb_ssh/message/081_ssh_msg_request_success.rb'
|
|
20
|
+
require 'hrr_rb_ssh/message/082_ssh_msg_request_failure.rb'
|
|
21
|
+
require 'hrr_rb_ssh/message/090_ssh_msg_channel_open.rb'
|
|
22
|
+
require 'hrr_rb_ssh/message/091_ssh_msg_channel_open_confirmation.rb'
|
|
23
|
+
require 'hrr_rb_ssh/message/092_ssh_msg_channel_open_failure.rb'
|
|
24
|
+
require 'hrr_rb_ssh/message/093_ssh_msg_channel_window_adjust.rb'
|
|
25
|
+
require 'hrr_rb_ssh/message/094_ssh_msg_channel_data.rb'
|
|
26
|
+
require 'hrr_rb_ssh/message/095_ssh_msg_channel_extended_data.rb'
|
|
27
|
+
require 'hrr_rb_ssh/message/096_ssh_msg_channel_eof.rb'
|
|
28
|
+
require 'hrr_rb_ssh/message/097_ssh_msg_channel_close.rb'
|
|
29
|
+
require 'hrr_rb_ssh/message/098_ssh_msg_channel_request.rb'
|
|
30
|
+
require 'hrr_rb_ssh/message/099_ssh_msg_channel_success.rb'
|
|
31
|
+
require 'hrr_rb_ssh/message/100_ssh_msg_channel_failure.rb'
|
|
32
|
+
|
|
33
|
+
module HrrRbSsh
|
|
34
|
+
module Message
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
# vim: et ts=2 sw=2
|
|
3
|
+
|
|
4
|
+
require 'hrr_rb_ssh/logger'
|
|
5
|
+
|
|
6
|
+
module HrrRbSsh
|
|
7
|
+
class Transport
|
|
8
|
+
class CompressionAlgorithm
|
|
9
|
+
name_list = [
|
|
10
|
+
'none'
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
class None
|
|
14
|
+
def initialize
|
|
15
|
+
@logger = HrrRbSsh::Logger.new self.class.name
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def deflate data
|
|
19
|
+
data
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def inflate data
|
|
23
|
+
data
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
@@list ||= Hash.new
|
|
28
|
+
name_list.each do |name|
|
|
29
|
+
@@list[name] = None
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
# vim: et ts=2 sw=2
|
|
3
|
+
|
|
4
|
+
require 'zlib'
|
|
5
|
+
|
|
6
|
+
require 'hrr_rb_ssh/logger'
|
|
7
|
+
|
|
8
|
+
module HrrRbSsh
|
|
9
|
+
class Transport
|
|
10
|
+
class CompressionAlgorithm
|
|
11
|
+
name_list = [
|
|
12
|
+
'zlib'
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
class Zlib
|
|
16
|
+
def initialize
|
|
17
|
+
@logger = HrrRbSsh::Logger.new self.class.name
|
|
18
|
+
|
|
19
|
+
@deflator = ::Zlib::Deflate.new
|
|
20
|
+
@inflator = ::Zlib::Inflate.new
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def deflate data
|
|
24
|
+
@deflator.deflate(data, ::Zlib::SYNC_FLUSH)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def inflate data
|
|
28
|
+
@inflator.inflate(data)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
@@list ||= Hash.new
|
|
33
|
+
name_list.each do |name|
|
|
34
|
+
@@list[name] = Zlib
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
# vim: et ts=2 sw=2
|
|
3
|
+
|
|
4
|
+
require 'hrr_rb_ssh/logger'
|
|
5
|
+
require 'hrr_rb_ssh/transport/compression_algorithm/none'
|
|
6
|
+
require 'hrr_rb_ssh/transport/compression_algorithm/zlib'
|
|
7
|
+
|
|
8
|
+
module HrrRbSsh
|
|
9
|
+
class Transport
|
|
10
|
+
class CompressionAlgorithm
|
|
11
|
+
@@list ||= Hash.new
|
|
12
|
+
|
|
13
|
+
def self.[] key
|
|
14
|
+
@@list[key]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.name_list
|
|
18
|
+
@@list.keys
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
# vim: et ts=2 sw=2
|
|
3
|
+
|
|
4
|
+
require 'openssl'
|
|
5
|
+
|
|
6
|
+
require 'hrr_rb_ssh/logger'
|
|
7
|
+
|
|
8
|
+
module HrrRbSsh
|
|
9
|
+
class Transport
|
|
10
|
+
module DataType
|
|
11
|
+
def self.[] key
|
|
12
|
+
case key
|
|
13
|
+
when 'byte'
|
|
14
|
+
Byte
|
|
15
|
+
when 'boolean'
|
|
16
|
+
Boolean
|
|
17
|
+
when 'uint32'
|
|
18
|
+
Uint32
|
|
19
|
+
when 'uint64'
|
|
20
|
+
Uint64
|
|
21
|
+
when 'string'
|
|
22
|
+
String
|
|
23
|
+
when 'mpint'
|
|
24
|
+
Mpint
|
|
25
|
+
when 'name-list'
|
|
26
|
+
NameList
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
class Byte
|
|
31
|
+
def self.encode arg
|
|
32
|
+
case arg
|
|
33
|
+
when 0x00..0xff
|
|
34
|
+
[arg].pack("C")
|
|
35
|
+
else
|
|
36
|
+
raise
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def self.decode io
|
|
41
|
+
io.read(1).unpack("C")[0]
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
class Boolean
|
|
46
|
+
def self.encode arg
|
|
47
|
+
case arg
|
|
48
|
+
when false
|
|
49
|
+
[0].pack("C")
|
|
50
|
+
when true
|
|
51
|
+
[1].pack("C")
|
|
52
|
+
else
|
|
53
|
+
raise
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def self.decode io
|
|
58
|
+
if 0 == io.read(1).unpack("C")[0]
|
|
59
|
+
false
|
|
60
|
+
else
|
|
61
|
+
true
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
class Uint32
|
|
67
|
+
def self.encode arg
|
|
68
|
+
case arg
|
|
69
|
+
when 0x0000_0000..0xffff_ffff
|
|
70
|
+
[arg].pack("N")
|
|
71
|
+
else
|
|
72
|
+
raise
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def self.decode io
|
|
77
|
+
io.read(4).unpack("N")[0]
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
class Uint64
|
|
82
|
+
def self.encode arg
|
|
83
|
+
case arg
|
|
84
|
+
when 0x0000_0000_0000_0000..0xffff_ffff_ffff_ffff
|
|
85
|
+
[arg >> 32].pack("N") + [arg & 0x0000_0000_ffff_ffff].pack("N")
|
|
86
|
+
else
|
|
87
|
+
raise
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def self.decode io
|
|
92
|
+
(io.read(4).unpack("N")[0] << 32) + (io.read(4).unpack("N")[0])
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
class String
|
|
97
|
+
def self.encode arg
|
|
98
|
+
raise unless arg.kind_of? ::String
|
|
99
|
+
raise if arg.length > 0xffff_ffff
|
|
100
|
+
[arg.length, arg].pack("Na*")
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def self.decode io
|
|
104
|
+
length = io.read(4).unpack("N")[0]
|
|
105
|
+
io.read(length).unpack("a*")[0]
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
class Mpint
|
|
110
|
+
def self.encode arg
|
|
111
|
+
raise unless arg.kind_of? ::Integer
|
|
112
|
+
raise if arg.size > 0xffff_ffff
|
|
113
|
+
bn = ::OpenSSL::BN.new(arg)
|
|
114
|
+
|
|
115
|
+
if bn < 0
|
|
116
|
+
# get 2's complement
|
|
117
|
+
tc = bn.to_i & ((1 << (bn.num_bytes * 8)) - 1)
|
|
118
|
+
# get hex representation
|
|
119
|
+
hex_str = "%x" % tc
|
|
120
|
+
|
|
121
|
+
if tc[(bn.num_bytes * 8) - 1] == 1
|
|
122
|
+
[bn.num_bytes, hex_str].pack("NH*")
|
|
123
|
+
else
|
|
124
|
+
[bn.num_bytes + 1, "ff" + hex_str].pack("NH*")
|
|
125
|
+
end
|
|
126
|
+
else
|
|
127
|
+
bn.to_s(0)
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def self.decode io
|
|
132
|
+
length = io.read(4).unpack("N")[0]
|
|
133
|
+
hex_str = io.read(length).unpack("H*")[0]
|
|
134
|
+
# get temporal integer value
|
|
135
|
+
value = hex_str.hex
|
|
136
|
+
|
|
137
|
+
if length == 0
|
|
138
|
+
0
|
|
139
|
+
elsif value[(length * 8) - 1] == 0
|
|
140
|
+
value
|
|
141
|
+
else
|
|
142
|
+
num_bytes = if hex_str.start_with?("ff") then length - 1 else length end
|
|
143
|
+
- (((~ value) & ((1 << (num_bytes * 8)) - 1)) + 1)
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
class NameList
|
|
149
|
+
def self.encode arg
|
|
150
|
+
raise unless arg.kind_of? Array
|
|
151
|
+
raise unless (arg.map(&:class) - [::String]).empty?
|
|
152
|
+
raise if arg.join(',').length > 0xffff_ffff
|
|
153
|
+
[arg.join(',').length, arg.join(',')].pack("Na*")
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def self.decode io
|
|
157
|
+
length = io.read(4).unpack("N")[0]
|
|
158
|
+
io.read(length).unpack("a*")[0].split(',')
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|