hrr_rb_sftp 0.1.0 → 0.2.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 +4 -4
- data/README.md +23 -0
- data/lib/hrr_rb_sftp.rb +79 -1
- data/lib/hrr_rb_sftp/loggable.rb +34 -0
- data/lib/hrr_rb_sftp/protocol.rb +39 -33
- data/lib/hrr_rb_sftp/protocol/common.rb +6 -3
- data/lib/hrr_rb_sftp/protocol/common/data_types.rb +19 -0
- data/lib/hrr_rb_sftp/protocol/common/data_types/byte.rb +40 -0
- data/lib/hrr_rb_sftp/protocol/common/data_types/extension_pair.rb +41 -0
- data/lib/hrr_rb_sftp/protocol/common/data_types/extension_pairs.rb +42 -0
- data/lib/hrr_rb_sftp/protocol/common/data_types/string.rb +42 -0
- data/lib/hrr_rb_sftp/protocol/common/data_types/uint32.rb +40 -0
- data/lib/hrr_rb_sftp/protocol/common/data_types/uint64.rb +40 -0
- data/lib/hrr_rb_sftp/protocol/common/packets.rb +16 -0
- data/lib/hrr_rb_sftp/protocol/common/packets/001_ssh_fxp_init.rb +27 -0
- data/lib/hrr_rb_sftp/protocol/common/packets/002_ssh_fxp_version.rb +28 -0
- data/lib/hrr_rb_sftp/protocol/common/packets/packet.rb +96 -0
- data/lib/hrr_rb_sftp/protocol/version1.rb +11 -3
- data/lib/hrr_rb_sftp/protocol/version1/data_types.rb +15 -0
- data/lib/hrr_rb_sftp/protocol/version1/data_types/attrs.rb +91 -0
- data/lib/hrr_rb_sftp/protocol/version1/packets.rb +72 -0
- data/lib/hrr_rb_sftp/protocol/version1/{packet → packets}/003_ssh_fxp_open.rb +94 -43
- data/lib/hrr_rb_sftp/protocol/version1/packets/004_ssh_fxp_close.rb +61 -0
- data/lib/hrr_rb_sftp/protocol/version1/packets/005_ssh_fxp_read.rb +72 -0
- data/lib/hrr_rb_sftp/protocol/version1/packets/006_ssh_fxp_write.rb +64 -0
- data/lib/hrr_rb_sftp/protocol/version1/{packet → packets}/007_ssh_fxp_lstat.rb +27 -9
- data/lib/hrr_rb_sftp/protocol/version1/{packet → packets}/008_ssh_fxp_fstat.rb +26 -9
- data/lib/hrr_rb_sftp/protocol/version1/packets/009_ssh_fxp_setstat.rb +92 -0
- data/lib/hrr_rb_sftp/protocol/version1/packets/010_ssh_fxp_fsetstat.rb +85 -0
- data/lib/hrr_rb_sftp/protocol/version1/{packet → packets}/011_ssh_fxp_opendir.rb +32 -11
- data/lib/hrr_rb_sftp/protocol/version1/{packet → packets}/012_ssh_fxp_readdir.rb +73 -49
- data/lib/hrr_rb_sftp/protocol/version1/{packet → packets}/013_ssh_fxp_remove.rb +27 -9
- data/lib/hrr_rb_sftp/protocol/version1/{packet → packets}/014_ssh_fxp_mkdir.rb +28 -10
- data/lib/hrr_rb_sftp/protocol/version1/{packet → packets}/015_ssh_fxp_rmdir.rb +32 -12
- data/lib/hrr_rb_sftp/protocol/version1/packets/016_ssh_fxp_realpath.rb +47 -0
- data/lib/hrr_rb_sftp/protocol/version1/{packet → packets}/017_ssh_fxp_stat.rb +27 -9
- data/lib/hrr_rb_sftp/protocol/version1/packets/101_ssh_fxp_status.rb +73 -0
- data/lib/hrr_rb_sftp/protocol/version1/packets/102_ssh_fxp_handle.rb +28 -0
- data/lib/hrr_rb_sftp/protocol/version1/packets/103_ssh_fxp_data.rb +28 -0
- data/lib/hrr_rb_sftp/protocol/version1/packets/104_ssh_fxp_name.rb +48 -0
- data/lib/hrr_rb_sftp/protocol/version1/packets/105_ssh_fxp_attrs.rb +28 -0
- data/lib/hrr_rb_sftp/protocol/version1/packets/packet.rb +57 -0
- data/lib/hrr_rb_sftp/protocol/version2.rb +11 -3
- data/lib/hrr_rb_sftp/protocol/version2/data_types.rb +13 -0
- data/lib/hrr_rb_sftp/protocol/version2/packets.rb +14 -0
- data/lib/hrr_rb_sftp/protocol/version2/packets/018_ssh_fxp_rename.rb +91 -0
- data/lib/hrr_rb_sftp/protocol/version3.rb +12 -3
- data/lib/hrr_rb_sftp/protocol/version3/data_types.rb +13 -0
- data/lib/hrr_rb_sftp/protocol/version3/extensions.rb +94 -0
- data/lib/hrr_rb_sftp/protocol/version3/extensions/extension.rb +58 -0
- data/lib/hrr_rb_sftp/protocol/version3/extensions/fsync_at_openssh_com.rb +59 -0
- data/lib/hrr_rb_sftp/protocol/version3/extensions/hardlink_at_openssh_com.rb +84 -0
- data/lib/hrr_rb_sftp/protocol/version3/extensions/lsetstat_at_openssh_com.rb +132 -0
- data/lib/hrr_rb_sftp/protocol/version3/extensions/posix_rename_at_openssh_com.rb +76 -0
- data/lib/hrr_rb_sftp/protocol/version3/packets.rb +19 -0
- data/lib/hrr_rb_sftp/protocol/version3/packets/014_ssh_fxp_mkdir.rb +75 -0
- data/lib/hrr_rb_sftp/protocol/version3/packets/019_ssh_fxp_readlink.rb +76 -0
- data/lib/hrr_rb_sftp/protocol/version3/packets/020_ssh_fxp_symlink.rb +76 -0
- data/lib/hrr_rb_sftp/protocol/version3/packets/101_ssh_fxp_status.rb +25 -0
- data/lib/hrr_rb_sftp/protocol/version3/packets/200_ssh_fxp_extended.rb +95 -0
- data/lib/hrr_rb_sftp/protocol/version3/packets/201_ssh_fxp_extended_reply.rb +60 -0
- data/lib/hrr_rb_sftp/receiver.rb +17 -2
- data/lib/hrr_rb_sftp/sender.rb +15 -1
- data/lib/hrr_rb_sftp/server.rb +43 -12
- data/lib/hrr_rb_sftp/version.rb +5 -1
- metadata +54 -47
- data/lib/hrr_rb_sftp/protocol/common/data_type.rb +0 -15
- data/lib/hrr_rb_sftp/protocol/common/data_type/byte.rb +0 -22
- data/lib/hrr_rb_sftp/protocol/common/data_type/extension_pair.rb +0 -23
- data/lib/hrr_rb_sftp/protocol/common/data_type/extension_pairs.rb +0 -24
- data/lib/hrr_rb_sftp/protocol/common/data_type/string.rb +0 -24
- data/lib/hrr_rb_sftp/protocol/common/data_type/uint32.rb +0 -22
- data/lib/hrr_rb_sftp/protocol/common/data_type/uint64.rb +0 -22
- data/lib/hrr_rb_sftp/protocol/common/packet.rb +0 -11
- data/lib/hrr_rb_sftp/protocol/common/packet/001_ssh_fxp_init.rb +0 -18
- data/lib/hrr_rb_sftp/protocol/common/packet/002_ssh_fxp_version.rb +0 -19
- data/lib/hrr_rb_sftp/protocol/common/packetable.rb +0 -72
- data/lib/hrr_rb_sftp/protocol/version1/data_type.rb +0 -11
- data/lib/hrr_rb_sftp/protocol/version1/data_type/attrs.rb +0 -54
- data/lib/hrr_rb_sftp/protocol/version1/packet.rb +0 -29
- data/lib/hrr_rb_sftp/protocol/version1/packet/004_ssh_fxp_close.rb +0 -44
- data/lib/hrr_rb_sftp/protocol/version1/packet/005_ssh_fxp_read.rb +0 -53
- data/lib/hrr_rb_sftp/protocol/version1/packet/006_ssh_fxp_write.rb +0 -46
- data/lib/hrr_rb_sftp/protocol/version1/packet/009_ssh_fxp_setstat.rb +0 -63
- data/lib/hrr_rb_sftp/protocol/version1/packet/010_ssh_fxp_fsetstat.rb +0 -48
- data/lib/hrr_rb_sftp/protocol/version1/packet/016_ssh_fxp_realpath.rb +0 -30
- data/lib/hrr_rb_sftp/protocol/version1/packet/101_ssh_fxp_status.rb +0 -29
- data/lib/hrr_rb_sftp/protocol/version1/packet/102_ssh_fxp_handle.rb +0 -19
- data/lib/hrr_rb_sftp/protocol/version1/packet/103_ssh_fxp_data.rb +0 -19
- data/lib/hrr_rb_sftp/protocol/version1/packet/104_ssh_fxp_name.rb +0 -33
- data/lib/hrr_rb_sftp/protocol/version1/packet/105_ssh_fxp_attrs.rb +0 -19
- data/lib/hrr_rb_sftp/protocol/version2/data_type.rb +0 -9
- data/lib/hrr_rb_sftp/protocol/version2/packet.rb +0 -11
- data/lib/hrr_rb_sftp/protocol/version2/packet/018_ssh_fxp_rename.rb +0 -70
- data/lib/hrr_rb_sftp/protocol/version3/data_type.rb +0 -9
- data/lib/hrr_rb_sftp/protocol/version3/packet.rb +0 -16
- data/lib/hrr_rb_sftp/protocol/version3/packet/014_ssh_fxp_mkdir.rb +0 -58
- data/lib/hrr_rb_sftp/protocol/version3/packet/019_ssh_fxp_readlink.rb +0 -57
- data/lib/hrr_rb_sftp/protocol/version3/packet/020_ssh_fxp_symlink.rb +0 -58
- data/lib/hrr_rb_sftp/protocol/version3/packet/101_ssh_fxp_status.rb +0 -31
- data/lib/hrr_rb_sftp/protocol/version3/packet/200_ssh_fxp_extended.rb +0 -34
- data/lib/hrr_rb_sftp/protocol/version3/packet/201_ssh_fxp_extended_reply.rb +0 -23
@@ -1,73 +1,88 @@
|
|
1
1
|
module HrrRbSftp
|
2
2
|
class Protocol
|
3
|
-
|
4
|
-
|
5
|
-
class SSH_FXP_OPEN
|
6
|
-
include Common::Packetable
|
3
|
+
module Version1
|
4
|
+
class Packets
|
7
5
|
|
6
|
+
#
|
7
|
+
# This class implements SFTP protocol version 1 SSH_FXP_OPEN packet type, format, and responder.
|
8
|
+
#
|
9
|
+
class SSH_FXP_OPEN < Packet
|
10
|
+
|
11
|
+
#
|
12
|
+
# Represents SSH_FXP_OPEN packet type.
|
13
|
+
#
|
8
14
|
TYPE = 3
|
9
15
|
|
16
|
+
#
|
17
|
+
# Represents SSH_FXP_OPEN packet format.
|
18
|
+
#
|
10
19
|
FORMAT = [
|
11
|
-
[
|
12
|
-
[
|
13
|
-
[
|
14
|
-
[
|
15
|
-
[
|
20
|
+
[DataTypes::Byte, :"type" ],
|
21
|
+
[DataTypes::Uint32, :"request-id"],
|
22
|
+
[DataTypes::String, :"filename" ],
|
23
|
+
[DataTypes::Uint32, :"pflags" ],
|
24
|
+
[DataTypes::Attrs, :"attrs" ],
|
16
25
|
]
|
17
26
|
|
27
|
+
#
|
28
|
+
# Represents SSH_FXF_READ flag.
|
29
|
+
#
|
18
30
|
SSH_FXF_READ = 0x00000001
|
31
|
+
|
32
|
+
#
|
33
|
+
# Represents SSH_FXF_WRITE flag.
|
34
|
+
#
|
19
35
|
SSH_FXF_WRITE = 0x00000002
|
36
|
+
|
37
|
+
#
|
38
|
+
# Represents SSH_FXF_APPEND flag.
|
39
|
+
#
|
20
40
|
SSH_FXF_APPEND = 0x00000004
|
41
|
+
|
42
|
+
#
|
43
|
+
# Represents SSH_FXF_CREAT flag.
|
44
|
+
#
|
21
45
|
SSH_FXF_CREAT = 0x00000008
|
22
|
-
SSH_FXF_TRUNC = 0x00000010
|
23
|
-
SSH_FXF_EXCL = 0x00000020
|
24
46
|
|
25
|
-
|
26
|
-
|
47
|
+
#
|
48
|
+
# Represents SSH_FXF_TRUNC flag.
|
49
|
+
#
|
50
|
+
SSH_FXF_TRUNC = 0x00000010
|
27
51
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
elsif (pflags & SSH_FXF_READ) == SSH_FXF_READ
|
33
|
-
flags |= ::File::RDONLY
|
34
|
-
elsif (pflags & SSH_FXF_WRITE) == SSH_FXF_WRITE
|
35
|
-
flags |= ::File::WRONLY
|
36
|
-
else
|
37
|
-
raise Error, "At least SSH_FXF_READ or SSH_FXF_READ must be specified"
|
38
|
-
end
|
39
|
-
if (pflags & SSH_FXF_APPEND) == SSH_FXF_APPEND
|
40
|
-
flags |= ::File::APPEND
|
41
|
-
end
|
42
|
-
if (pflags & SSH_FXF_CREAT) == SSH_FXF_CREAT
|
43
|
-
flags |= ::File::CREAT
|
44
|
-
flags |= ::File::TRUNC if (pflags & SSH_FXF_TRUNC) == SSH_FXF_TRUNC
|
45
|
-
flags |= ::File::EXCL if (pflags & SSH_FXF_EXCL ) == SSH_FXF_EXCL
|
46
|
-
elsif (pflags & SSH_FXF_TRUNC) == SSH_FXF_TRUNC
|
47
|
-
raise Error, "SSH_FXF_CREAT MUST also be specified when SSH_FXF_TRUNC is specified"
|
48
|
-
elsif (pflags & SSH_FXF_EXCL) == SSH_FXF_EXCL
|
49
|
-
raise Error, "SSH_FXF_CREAT MUST also be specified when SSH_FXF_EXCL is specified"
|
50
|
-
end
|
51
|
-
flags |= ::File::BINARY
|
52
|
-
flags
|
53
|
-
end
|
52
|
+
#
|
53
|
+
# Represents SSH_FXF_EXCL flag.
|
54
|
+
#
|
55
|
+
SSH_FXF_EXCL = 0x00000020
|
54
56
|
|
57
|
+
#
|
58
|
+
# Responds to SSH_FXP_OPEN request.
|
59
|
+
#
|
60
|
+
# @param request [Hash{Symbol=>Object}] SSH_FXP_OPEN request represented in Hash.
|
61
|
+
# Only permissions attribute is taken care of.
|
62
|
+
# When attrs field contains attributes other than permissions are ignored
|
63
|
+
# and they are expected to be taken care of by subsequent SSH_FXP_SETSTAT and/or SSH_FXP_FSETSTAT requests.
|
64
|
+
# @return [Hash{Symbol=>Object}] Response represented in Hash. In case of success, its type is SSH_FXP_HANDLE. In other cases, its type is SSH_FXP_STATUS.
|
65
|
+
#
|
55
66
|
def respond_to request
|
56
67
|
begin
|
57
68
|
flags = convert_pflags_to_flags request[:"pflags"]
|
58
69
|
args = [request[:"filename"], flags]
|
59
|
-
if request[:"attrs"].has_key?(:"permissions")
|
70
|
+
if (flags & ::File::CREAT == ::File::CREAT) && request[:"attrs"].has_key?(:"permissions")
|
60
71
|
args.push request[:"attrs"][:"permissions"]
|
61
72
|
end
|
73
|
+
log_debug { "file = File.open(#{args.map(&:inspect).join(", ")})" }
|
62
74
|
file = ::File.open(*args)
|
75
|
+
log_debug { "handle = #{file.object_id.to_s(16).inspect}" }
|
63
76
|
handle = file.object_id.to_s(16)
|
64
|
-
|
77
|
+
log_debug { "handles[#{handle.inspect}] = file" }
|
78
|
+
handles[handle] = file
|
65
79
|
{
|
66
80
|
:"type" => SSH_FXP_HANDLE::TYPE,
|
67
81
|
:"request-id" => request[:"request-id"],
|
68
82
|
:"handle" => handle,
|
69
83
|
}
|
70
84
|
rescue Error => e
|
85
|
+
log_debug { e.message }
|
71
86
|
{
|
72
87
|
:"type" => SSH_FXP_STATUS::TYPE,
|
73
88
|
:"request-id" => request[:"request-id"],
|
@@ -75,7 +90,8 @@ module HrrRbSftp
|
|
75
90
|
:"error message" => e.message,
|
76
91
|
:"language tag" => "",
|
77
92
|
}
|
78
|
-
rescue Errno::ENOENT
|
93
|
+
rescue Errno::ENOENT => e
|
94
|
+
log_debug { e.message }
|
79
95
|
{
|
80
96
|
:"type" => SSH_FXP_STATUS::TYPE,
|
81
97
|
:"request-id" => request[:"request-id"],
|
@@ -83,7 +99,8 @@ module HrrRbSftp
|
|
83
99
|
:"error message" => "No such file or directory",
|
84
100
|
:"language tag" => "",
|
85
101
|
}
|
86
|
-
rescue Errno::EACCES
|
102
|
+
rescue Errno::EACCES => e
|
103
|
+
log_debug { e.message }
|
87
104
|
{
|
88
105
|
:"type" => SSH_FXP_STATUS::TYPE,
|
89
106
|
:"request-id" => request[:"request-id"],
|
@@ -102,6 +119,40 @@ module HrrRbSftp
|
|
102
119
|
}
|
103
120
|
end
|
104
121
|
end
|
122
|
+
|
123
|
+
class Error < StandardError
|
124
|
+
end
|
125
|
+
|
126
|
+
private_constant :Error
|
127
|
+
|
128
|
+
private
|
129
|
+
|
130
|
+
def convert_pflags_to_flags pflags
|
131
|
+
flags = 0
|
132
|
+
if ((pflags & SSH_FXF_READ) == SSH_FXF_READ) && ((pflags & SSH_FXF_WRITE) == SSH_FXF_WRITE)
|
133
|
+
flags |= ::File::RDWR
|
134
|
+
elsif (pflags & SSH_FXF_READ) == SSH_FXF_READ
|
135
|
+
flags |= ::File::RDONLY
|
136
|
+
elsif (pflags & SSH_FXF_WRITE) == SSH_FXF_WRITE
|
137
|
+
flags |= ::File::WRONLY
|
138
|
+
else
|
139
|
+
raise Error, "At least SSH_FXF_READ or SSH_FXF_READ must be specified"
|
140
|
+
end
|
141
|
+
if (pflags & SSH_FXF_APPEND) == SSH_FXF_APPEND
|
142
|
+
flags |= ::File::APPEND
|
143
|
+
end
|
144
|
+
if (pflags & SSH_FXF_CREAT) == SSH_FXF_CREAT
|
145
|
+
flags |= ::File::CREAT
|
146
|
+
flags |= ::File::TRUNC if (pflags & SSH_FXF_TRUNC) == SSH_FXF_TRUNC
|
147
|
+
flags |= ::File::EXCL if (pflags & SSH_FXF_EXCL ) == SSH_FXF_EXCL
|
148
|
+
elsif (pflags & SSH_FXF_TRUNC) == SSH_FXF_TRUNC
|
149
|
+
raise Error, "SSH_FXF_CREAT MUST also be specified when SSH_FXF_TRUNC is specified"
|
150
|
+
elsif (pflags & SSH_FXF_EXCL) == SSH_FXF_EXCL
|
151
|
+
raise Error, "SSH_FXF_CREAT MUST also be specified when SSH_FXF_EXCL is specified"
|
152
|
+
end
|
153
|
+
flags |= ::File::BINARY
|
154
|
+
flags
|
155
|
+
end
|
105
156
|
end
|
106
157
|
end
|
107
158
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module HrrRbSftp
|
2
|
+
class Protocol
|
3
|
+
module Version1
|
4
|
+
class Packets
|
5
|
+
|
6
|
+
#
|
7
|
+
# This class implements SFTP protocol version 1 SSH_FXP_CLOSE packet type, format, and responder.
|
8
|
+
#
|
9
|
+
class SSH_FXP_CLOSE < Packet
|
10
|
+
|
11
|
+
#
|
12
|
+
# Represents SSH_FXP_CLOSE packet type.
|
13
|
+
#
|
14
|
+
TYPE = 4
|
15
|
+
|
16
|
+
#
|
17
|
+
# Represents SSH_FXP_CLOSE packet format.
|
18
|
+
#
|
19
|
+
FORMAT = [
|
20
|
+
[DataTypes::Byte, :"type" ],
|
21
|
+
[DataTypes::Uint32, :"request-id"],
|
22
|
+
[DataTypes::String, :"handle" ],
|
23
|
+
]
|
24
|
+
|
25
|
+
#
|
26
|
+
# Responds to SSH_FXP_CLOSE request.
|
27
|
+
#
|
28
|
+
# @param request [Hash{Symbol=>Object}] SSH_FXP_CLOSE request represented in Hash.
|
29
|
+
# @return [Hash{Symbol=>Object}] Response represented in Hash. Its type is SSH_FXP_STATUS.
|
30
|
+
#
|
31
|
+
def respond_to request
|
32
|
+
begin
|
33
|
+
raise "Specified handle does not exist" unless handles.has_key?(request[:"handle"])
|
34
|
+
handle = request[:"handle"]
|
35
|
+
log_debug { "handles[#{handle.inspect}].close" }
|
36
|
+
handles[handle].close rescue nil
|
37
|
+
log_debug { "handles.delete(#{handle.inspect})" }
|
38
|
+
handles.delete(handle)
|
39
|
+
{
|
40
|
+
:"type" => SSH_FXP_STATUS::TYPE,
|
41
|
+
:"request-id" => request[:"request-id"],
|
42
|
+
:"code" => SSH_FXP_STATUS::SSH_FX_OK,
|
43
|
+
:"error message" => "Success",
|
44
|
+
:"language tag" => "",
|
45
|
+
}
|
46
|
+
rescue => e
|
47
|
+
log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
48
|
+
{
|
49
|
+
:"type" => SSH_FXP_STATUS::TYPE,
|
50
|
+
:"request-id" => request[:"request-id"],
|
51
|
+
:"code" => SSH_FXP_STATUS::SSH_FX_FAILURE,
|
52
|
+
:"error message" => e.message,
|
53
|
+
:"language tag" => "",
|
54
|
+
}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module HrrRbSftp
|
2
|
+
class Protocol
|
3
|
+
module Version1
|
4
|
+
class Packets
|
5
|
+
|
6
|
+
#
|
7
|
+
# This class implements SFTP protocol version 1 SSH_FXP_READ packet type, format, and responder.
|
8
|
+
#
|
9
|
+
class SSH_FXP_READ < Packet
|
10
|
+
|
11
|
+
#
|
12
|
+
# Represents SSH_FXP_READ packet type.
|
13
|
+
#
|
14
|
+
TYPE = 5
|
15
|
+
|
16
|
+
#
|
17
|
+
# Represents SSH_FXP_READ packet format.
|
18
|
+
#
|
19
|
+
FORMAT = [
|
20
|
+
[DataTypes::Byte, :"type" ],
|
21
|
+
[DataTypes::Uint32, :"request-id"],
|
22
|
+
[DataTypes::String, :"handle" ],
|
23
|
+
[DataTypes::Uint64, :"offset" ],
|
24
|
+
[DataTypes::Uint32, :"len" ],
|
25
|
+
]
|
26
|
+
|
27
|
+
#
|
28
|
+
# Responds to SSH_FXP_READ request.
|
29
|
+
#
|
30
|
+
# @param request [Hash{Symbol=>Object}] SSH_FXP_READ request represented in Hash.
|
31
|
+
# @return [Hash{Symbol=>Object}] Response represented in Hash. In case of success, its type is SSH_FXP_DATA. In other cases, its type is SSH_FXP_STATUS.
|
32
|
+
#
|
33
|
+
def respond_to request
|
34
|
+
begin
|
35
|
+
raise "Specified handle does not exist" unless handles.has_key?(request[:"handle"])
|
36
|
+
log_debug { "file = handles[#{request[:"handle"].inspect}]" }
|
37
|
+
file = handles[request[:"handle"]]
|
38
|
+
log_debug { "file.pos = #{request[:"offset"].inspect}" }
|
39
|
+
file.pos = request[:"offset"]
|
40
|
+
unless file.eof?
|
41
|
+
log_debug { "data = file.read(#{request[:"len"].inspect})" }
|
42
|
+
data = file.read(request[:"len"])
|
43
|
+
{
|
44
|
+
:"type" => SSH_FXP_DATA::TYPE,
|
45
|
+
:"request-id" => request[:"request-id"],
|
46
|
+
:"data" => data,
|
47
|
+
}
|
48
|
+
else
|
49
|
+
{
|
50
|
+
:"type" => SSH_FXP_STATUS::TYPE,
|
51
|
+
:"request-id" => request[:"request-id"],
|
52
|
+
:"code" => SSH_FXP_STATUS::SSH_FX_EOF,
|
53
|
+
:"error message" => "End of file",
|
54
|
+
:"language tag" => "",
|
55
|
+
}
|
56
|
+
end
|
57
|
+
rescue => e
|
58
|
+
log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
59
|
+
{
|
60
|
+
:"type" => SSH_FXP_STATUS::TYPE,
|
61
|
+
:"request-id" => request[:"request-id"],
|
62
|
+
:"code" => SSH_FXP_STATUS::SSH_FX_FAILURE,
|
63
|
+
:"error message" => e.message,
|
64
|
+
:"language tag" => "",
|
65
|
+
}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module HrrRbSftp
|
2
|
+
class Protocol
|
3
|
+
module Version1
|
4
|
+
class Packets
|
5
|
+
|
6
|
+
#
|
7
|
+
# This class implements SFTP protocol version 1 SSH_FXP_WRITE packet type, format, and responder.
|
8
|
+
#
|
9
|
+
class SSH_FXP_WRITE < Packet
|
10
|
+
|
11
|
+
#
|
12
|
+
# Represents SSH_FXP_WRITE packet type.
|
13
|
+
#
|
14
|
+
TYPE = 6
|
15
|
+
|
16
|
+
#
|
17
|
+
# Represents SSH_FXP_WRITE packet format.
|
18
|
+
#
|
19
|
+
FORMAT = [
|
20
|
+
[DataTypes::Byte, :"type" ],
|
21
|
+
[DataTypes::Uint32, :"request-id"],
|
22
|
+
[DataTypes::String, :"handle" ],
|
23
|
+
[DataTypes::Uint64, :"offset" ],
|
24
|
+
[DataTypes::String, :"data" ],
|
25
|
+
]
|
26
|
+
|
27
|
+
#
|
28
|
+
# Responds to SSH_FXP_WRITE request.
|
29
|
+
#
|
30
|
+
# @param request [Hash{Symbol=>Object}] SSH_FXP_WRITE request represented in Hash.
|
31
|
+
# @return [Hash{Symbol=>Object}] Response represented in Hash. Its type is SSH_FXP_STATUS.
|
32
|
+
#
|
33
|
+
def respond_to request
|
34
|
+
begin
|
35
|
+
raise "Specified handle does not exist" unless handles.has_key?(request[:"handle"])
|
36
|
+
log_debug { "file = handles[#{request[:"handle"].inspect}]" }
|
37
|
+
file = handles[request[:"handle"]]
|
38
|
+
log_debug { "file.pos = #{request[:"offset"].inspect}" }
|
39
|
+
file.pos = request[:"offset"]
|
40
|
+
log_debug { "file.write(#{request[:"data"].inspect})" }
|
41
|
+
file.write(request[:"data"])
|
42
|
+
{
|
43
|
+
:"type" => SSH_FXP_STATUS::TYPE,
|
44
|
+
:"request-id" => request[:"request-id"],
|
45
|
+
:"code" => SSH_FXP_STATUS::SSH_FX_OK,
|
46
|
+
:"error message" => "Success",
|
47
|
+
:"language tag" => "",
|
48
|
+
}
|
49
|
+
rescue => e
|
50
|
+
log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
51
|
+
{
|
52
|
+
:"type" => SSH_FXP_STATUS::TYPE,
|
53
|
+
:"request-id" => request[:"request-id"],
|
54
|
+
:"code" => SSH_FXP_STATUS::SSH_FX_FAILURE,
|
55
|
+
:"error message" => e.message,
|
56
|
+
:"language tag" => "",
|
57
|
+
}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -1,20 +1,36 @@
|
|
1
1
|
module HrrRbSftp
|
2
2
|
class Protocol
|
3
|
-
|
4
|
-
|
5
|
-
class SSH_FXP_LSTAT
|
6
|
-
include Common::Packetable
|
3
|
+
module Version1
|
4
|
+
class Packets
|
7
5
|
|
6
|
+
#
|
7
|
+
# This class implements SFTP protocol version 1 SSH_FXP_LSTAT packet type, format, and responder.
|
8
|
+
#
|
9
|
+
class SSH_FXP_LSTAT < Packet
|
10
|
+
|
11
|
+
#
|
12
|
+
# Represents SSH_FXP_LSTAT packet type.
|
13
|
+
#
|
8
14
|
TYPE = 7
|
9
15
|
|
16
|
+
#
|
17
|
+
# Represents SSH_FXP_LSTAT packet format.
|
18
|
+
#
|
10
19
|
FORMAT = [
|
11
|
-
[
|
12
|
-
[
|
13
|
-
[
|
20
|
+
[DataTypes::Byte, :"type" ],
|
21
|
+
[DataTypes::Uint32, :"request-id"],
|
22
|
+
[DataTypes::String, :"path" ],
|
14
23
|
]
|
15
24
|
|
25
|
+
#
|
26
|
+
# Responds to SSH_FXP_LSTAT request.
|
27
|
+
#
|
28
|
+
# @param request [Hash{Symbol=>Object}] SSH_FXP_LSTAT request represented in Hash.
|
29
|
+
# @return [Hash{Symbol=>Object}] Response represented in Hash. In case of success, its type is SSH_FXP_ATTRS. In other cases, its type is SSH_FXP_STATUS.
|
30
|
+
#
|
16
31
|
def respond_to request
|
17
32
|
begin
|
33
|
+
log_debug { "File.lstat(#{request[:"path"].inspect})" }
|
18
34
|
stat = File.lstat(request[:"path"])
|
19
35
|
attrs = Hash.new
|
20
36
|
attrs[:"size"] = stat.size if stat.size
|
@@ -28,7 +44,8 @@ module HrrRbSftp
|
|
28
44
|
:"request-id" => request[:"request-id"],
|
29
45
|
:"attrs" => attrs,
|
30
46
|
}
|
31
|
-
rescue Errno::ENOENT
|
47
|
+
rescue Errno::ENOENT => e
|
48
|
+
log_debug { e.message }
|
32
49
|
{
|
33
50
|
:"type" => SSH_FXP_STATUS::TYPE,
|
34
51
|
:"request-id" => request[:"request-id"],
|
@@ -36,7 +53,8 @@ module HrrRbSftp
|
|
36
53
|
:"error message" => "No such file or directory",
|
37
54
|
:"language tag" => "",
|
38
55
|
}
|
39
|
-
rescue Errno::EACCES
|
56
|
+
rescue Errno::EACCES => e
|
57
|
+
log_debug { e.message }
|
40
58
|
{
|
41
59
|
:"type" => SSH_FXP_STATUS::TYPE,
|
42
60
|
:"request-id" => request[:"request-id"],
|