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
@@ -0,0 +1,84 @@
|
|
1
|
+
module HrrRbSftp
|
2
|
+
class Protocol
|
3
|
+
module Version3
|
4
|
+
class Extensions
|
5
|
+
|
6
|
+
#
|
7
|
+
# This class implements hardlink@openssh.com version 1 extension format and responder.
|
8
|
+
#
|
9
|
+
class HardlinkAtOpensshCom < Extension
|
10
|
+
|
11
|
+
#
|
12
|
+
# Represents hardlink@openssh.com version 1 extension name.
|
13
|
+
#
|
14
|
+
EXTENSION_NAME = "hardlink@openssh.com"
|
15
|
+
|
16
|
+
#
|
17
|
+
# Represents hardlink@openssh.com version 1 extension data.
|
18
|
+
#
|
19
|
+
EXTENSION_DATA = "1"
|
20
|
+
|
21
|
+
#
|
22
|
+
# Represents SSH_FXP_EXTENDED packet additional format for hardlink@openssh.com version 1 extension.
|
23
|
+
#
|
24
|
+
REQUEST_FORMAT = {
|
25
|
+
:"extended-request" => {
|
26
|
+
"hardlink@openssh.com" => [
|
27
|
+
[DataTypes::String, :"oldpath"],
|
28
|
+
[DataTypes::String, :"newpath"],
|
29
|
+
],
|
30
|
+
},
|
31
|
+
}
|
32
|
+
|
33
|
+
#
|
34
|
+
# Responds to SSH_FXP_EXTENDED request with hardlink@openssh.com extended-request.
|
35
|
+
#
|
36
|
+
# @param request [Hash{Symbol=>Object}] SSH_FXP_EXTENDED request represented in Hash.
|
37
|
+
# @return [Hash{Symbol=>Object}] Response represented in Hash. Its type is SSH_FXP_STATUS.
|
38
|
+
#
|
39
|
+
def respond_to request
|
40
|
+
begin
|
41
|
+
log_debug { "File.link(#{request[:"oldpath"].inspect}, #{request[:"newpath"].inspect})" }
|
42
|
+
File.link(request[:"oldpath"], request[:"newpath"])
|
43
|
+
{
|
44
|
+
:"type" => Packets::SSH_FXP_STATUS::TYPE,
|
45
|
+
:"request-id" => request[:"request-id"],
|
46
|
+
:"code" => Packets::SSH_FXP_STATUS::SSH_FX_OK,
|
47
|
+
:"error message" => "Success",
|
48
|
+
:"language tag" => "",
|
49
|
+
}
|
50
|
+
rescue Errno::ENOENT => e
|
51
|
+
log_debug { e.message }
|
52
|
+
{
|
53
|
+
:"type" => Packets::SSH_FXP_STATUS::TYPE,
|
54
|
+
:"request-id" => request[:"request-id"],
|
55
|
+
:"code" => Packets::SSH_FXP_STATUS::SSH_FX_NO_SUCH_FILE,
|
56
|
+
:"error message" => "No such file or directory",
|
57
|
+
:"language tag" => "",
|
58
|
+
}
|
59
|
+
rescue Errno::EACCES => e
|
60
|
+
log_debug { e.message }
|
61
|
+
{
|
62
|
+
:"type" => Packets::SSH_FXP_STATUS::TYPE,
|
63
|
+
:"request-id" => request[:"request-id"],
|
64
|
+
:"code" => Packets::SSH_FXP_STATUS::SSH_FX_PERMISSION_DENIED,
|
65
|
+
:"error message" => "Permission denied",
|
66
|
+
:"language tag" => "",
|
67
|
+
}
|
68
|
+
rescue Errno::EEXIST => e
|
69
|
+
log_debug { e.message }
|
70
|
+
{
|
71
|
+
:"type" => Packets::SSH_FXP_STATUS::TYPE,
|
72
|
+
:"request-id" => request[:"request-id"],
|
73
|
+
:"code" => Packets::SSH_FXP_STATUS::SSH_FX_FAILURE,
|
74
|
+
:"error message" => "File exists",
|
75
|
+
:"language tag" => "",
|
76
|
+
}
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
@@ -0,0 +1,132 @@
|
|
1
|
+
module HrrRbSftp
|
2
|
+
class Protocol
|
3
|
+
module Version3
|
4
|
+
class Extensions
|
5
|
+
|
6
|
+
#
|
7
|
+
# This class implements lsetstat@openssh.com version 1 extension format and responder.
|
8
|
+
#
|
9
|
+
class LsetstatAtOpensshCom < Extension
|
10
|
+
|
11
|
+
#
|
12
|
+
# Represents lsetstat@openssh.com version 1 extension name.
|
13
|
+
#
|
14
|
+
EXTENSION_NAME = "lsetstat@openssh.com"
|
15
|
+
|
16
|
+
#
|
17
|
+
# Represents lsetstat@openssh.com version 1 extension data.
|
18
|
+
#
|
19
|
+
EXTENSION_DATA = "1"
|
20
|
+
|
21
|
+
#
|
22
|
+
# Represents SSH_FXP_EXTENDED packet additional format for lsetstat@openssh.com version 1 extension.
|
23
|
+
#
|
24
|
+
REQUEST_FORMAT = {
|
25
|
+
:"extended-request" => {
|
26
|
+
"lsetstat@openssh.com" => [
|
27
|
+
[DataTypes::String, :"path" ],
|
28
|
+
[DataTypes::Attrs, :"attrs"],
|
29
|
+
],
|
30
|
+
},
|
31
|
+
}
|
32
|
+
|
33
|
+
#
|
34
|
+
# Responds to SSH_FXP_EXTENDED request with lsetstat@openssh.com extended-request.
|
35
|
+
#
|
36
|
+
# @param request [Hash{Symbol=>Object}] SSH_FXP_EXTENDED request represented in Hash.
|
37
|
+
# @return [Hash{Symbol=>Object}] Response represented in Hash. Its type is SSH_FXP_STATUS.
|
38
|
+
#
|
39
|
+
def respond_to request
|
40
|
+
begin
|
41
|
+
path = request[:"path"]
|
42
|
+
attrs = request[:"attrs"]
|
43
|
+
raise BadMessageError, "Invalid file attribute: size" if attrs.has_key?(:"size")
|
44
|
+
if attrs.has_key?(:"atime") && attrs.has_key?(:"mtime")
|
45
|
+
raise FileLutimeUnsupportedError, "File.lutime is not supported on this Ruby version" unless File.respond_to?(:lutime)
|
46
|
+
log_debug { "File.lutime(#{attrs[:"atime"].inspect}, #{attrs[:"mtime"].inspect}, #{path.inspect})" }
|
47
|
+
File.lutime(attrs[:"atime"], attrs[:"mtime"], path)
|
48
|
+
end
|
49
|
+
if attrs.has_key?(:"uid") && attrs.has_key?(:"gid")
|
50
|
+
log_debug { "File.lchown(#{attrs[:"uid"].inspect}, #{attrs[:"gid"].inspect}, #{path.inspect})" }
|
51
|
+
File.lchown(attrs[:"uid"], attrs[:"gid"], path)
|
52
|
+
end
|
53
|
+
if attrs.has_key?(:"permissions")
|
54
|
+
log_debug { "File.lchmod(#{attrs[:"permissions"].inspect}, #{path.inspect})" }
|
55
|
+
File.lchmod(attrs[:"permissions"], path)
|
56
|
+
end
|
57
|
+
{
|
58
|
+
:"type" => Packets::SSH_FXP_STATUS::TYPE,
|
59
|
+
:"request-id" => request[:"request-id"],
|
60
|
+
:"code" => Packets::SSH_FXP_STATUS::SSH_FX_OK,
|
61
|
+
:"error message" => "Success",
|
62
|
+
:"language tag" => "",
|
63
|
+
}
|
64
|
+
rescue BadMessageError => e
|
65
|
+
log_debug { e.message }
|
66
|
+
{
|
67
|
+
:"type" => Packets::SSH_FXP_STATUS::TYPE,
|
68
|
+
:"request-id" => request[:"request-id"],
|
69
|
+
:"code" => Packets::SSH_FXP_STATUS::SSH_FX_BAD_MESSAGE,
|
70
|
+
:"error message" => "Bad message",
|
71
|
+
:"language tag" => "",
|
72
|
+
}
|
73
|
+
rescue FileLutimeUnsupportedError => e
|
74
|
+
log_debug { e.message }
|
75
|
+
{
|
76
|
+
:"type" => Packets::SSH_FXP_STATUS::TYPE,
|
77
|
+
:"request-id" => request[:"request-id"],
|
78
|
+
:"code" => Packets::SSH_FXP_STATUS::SSH_FX_FAILURE,
|
79
|
+
:"error message" => e.message,
|
80
|
+
:"language tag" => "",
|
81
|
+
}
|
82
|
+
rescue Errno::ENOENT => e
|
83
|
+
log_debug { e.message }
|
84
|
+
{
|
85
|
+
:"type" => Packets::SSH_FXP_STATUS::TYPE,
|
86
|
+
:"request-id" => request[:"request-id"],
|
87
|
+
:"code" => Packets::SSH_FXP_STATUS::SSH_FX_NO_SUCH_FILE,
|
88
|
+
:"error message" => "No such file or directory",
|
89
|
+
:"language tag" => "",
|
90
|
+
}
|
91
|
+
rescue Errno::EACCES, Errno::EPERM => e
|
92
|
+
log_debug { e.message }
|
93
|
+
{
|
94
|
+
:"type" => Packets::SSH_FXP_STATUS::TYPE,
|
95
|
+
:"request-id" => request[:"request-id"],
|
96
|
+
:"code" => Packets::SSH_FXP_STATUS::SSH_FX_PERMISSION_DENIED,
|
97
|
+
:"error message" => "Permission denied",
|
98
|
+
:"language tag" => "",
|
99
|
+
}
|
100
|
+
rescue NotImplementedError => e
|
101
|
+
log_debug { e.message }
|
102
|
+
{
|
103
|
+
:"type" => Packets::SSH_FXP_STATUS::TYPE,
|
104
|
+
:"request-id" => request[:"request-id"],
|
105
|
+
:"code" => Packets::SSH_FXP_STATUS::SSH_FX_FAILURE,
|
106
|
+
:"error message" => e.message,
|
107
|
+
:"language tag" => "",
|
108
|
+
}
|
109
|
+
rescue => e
|
110
|
+
log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
111
|
+
{
|
112
|
+
:"type" => Packets::SSH_FXP_STATUS::TYPE,
|
113
|
+
:"request-id" => request[:"request-id"],
|
114
|
+
:"code" => Packets::SSH_FXP_STATUS::SSH_FX_FAILURE,
|
115
|
+
:"error message" => e.message,
|
116
|
+
:"language tag" => "",
|
117
|
+
}
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
class BadMessageError < StandardError
|
122
|
+
end
|
123
|
+
|
124
|
+
class FileLutimeUnsupportedError < StandardError
|
125
|
+
end
|
126
|
+
|
127
|
+
private_constant :BadMessageError, :FileLutimeUnsupportedError
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module HrrRbSftp
|
2
|
+
class Protocol
|
3
|
+
module Version3
|
4
|
+
class Extensions
|
5
|
+
|
6
|
+
#
|
7
|
+
# This class implements posix-rename@openssh.com version 1 extension format and responder.
|
8
|
+
#
|
9
|
+
class PosixRenameAtOpensshCom < Extension
|
10
|
+
|
11
|
+
#
|
12
|
+
# Represents posix-rename@openssh.com version 1 extension name.
|
13
|
+
#
|
14
|
+
EXTENSION_NAME = "posix-rename@openssh.com"
|
15
|
+
|
16
|
+
#
|
17
|
+
# Represents posix-rename@openssh.com version 1 extension data.
|
18
|
+
#
|
19
|
+
EXTENSION_DATA = "1"
|
20
|
+
|
21
|
+
#
|
22
|
+
# Represents SSH_FXP_EXTENDED packet additional format for posix-rename@openssh.com version 1 extension.
|
23
|
+
#
|
24
|
+
REQUEST_FORMAT = {
|
25
|
+
:"extended-request" => {
|
26
|
+
"posix-rename@openssh.com" => [
|
27
|
+
[DataTypes::String, :"oldpath"],
|
28
|
+
[DataTypes::String, :"newpath"],
|
29
|
+
],
|
30
|
+
},
|
31
|
+
}
|
32
|
+
|
33
|
+
#
|
34
|
+
# Responds to SSH_FXP_EXTENDED request with posix-rename@openssh.com extended-request.
|
35
|
+
#
|
36
|
+
# @param request [Hash{Symbol=>Object}] SSH_FXP_EXTENDED request represented in Hash.
|
37
|
+
# @return [Hash{Symbol=>Object}] Response represented in Hash. Its type is SSH_FXP_STATUS.
|
38
|
+
#
|
39
|
+
def respond_to request
|
40
|
+
begin
|
41
|
+
oldpath = request[:"oldpath"]
|
42
|
+
newpath = request[:"newpath"]
|
43
|
+
log_debug { "File.rename(#{oldpath.inspect}, #{newpath.inspect})" }
|
44
|
+
File.rename(oldpath, newpath)
|
45
|
+
{
|
46
|
+
:"type" => Packets::SSH_FXP_STATUS::TYPE,
|
47
|
+
:"request-id" => request[:"request-id"],
|
48
|
+
:"code" => Packets::SSH_FXP_STATUS::SSH_FX_OK,
|
49
|
+
:"error message" => "Success",
|
50
|
+
:"language tag" => "",
|
51
|
+
}
|
52
|
+
rescue Errno::ENOENT => e
|
53
|
+
log_debug { e.message }
|
54
|
+
{
|
55
|
+
:"type" => Packets::SSH_FXP_STATUS::TYPE,
|
56
|
+
:"request-id" => request[:"request-id"],
|
57
|
+
:"code" => Packets::SSH_FXP_STATUS::SSH_FX_NO_SUCH_FILE,
|
58
|
+
:"error message" => "No such file or directory",
|
59
|
+
:"language tag" => "",
|
60
|
+
}
|
61
|
+
rescue Errno::EACCES => e
|
62
|
+
log_debug { e.message }
|
63
|
+
{
|
64
|
+
:"type" => Packets::SSH_FXP_STATUS::TYPE,
|
65
|
+
:"request-id" => request[:"request-id"],
|
66
|
+
:"code" => Packets::SSH_FXP_STATUS::SSH_FX_PERMISSION_DENIED,
|
67
|
+
:"error message" => "Permission denied",
|
68
|
+
:"language tag" => "",
|
69
|
+
}
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module HrrRbSftp
|
2
|
+
class Protocol
|
3
|
+
module Version3
|
4
|
+
|
5
|
+
#
|
6
|
+
# This class implements SFTP protocol version 3 packet types, formats, and responders.
|
7
|
+
#
|
8
|
+
class Packets < Version2::Packets
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
require "hrr_rb_sftp/protocol/version3/packets/014_ssh_fxp_mkdir"
|
15
|
+
require "hrr_rb_sftp/protocol/version3/packets/019_ssh_fxp_readlink"
|
16
|
+
require "hrr_rb_sftp/protocol/version3/packets/020_ssh_fxp_symlink"
|
17
|
+
require "hrr_rb_sftp/protocol/version3/packets/101_ssh_fxp_status"
|
18
|
+
require "hrr_rb_sftp/protocol/version3/packets/200_ssh_fxp_extended"
|
19
|
+
require "hrr_rb_sftp/protocol/version3/packets/201_ssh_fxp_extended_reply"
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module HrrRbSftp
|
2
|
+
class Protocol
|
3
|
+
module Version3
|
4
|
+
class Packets
|
5
|
+
|
6
|
+
#
|
7
|
+
# This class implements SFTP protocol version 3 SSH_FXP_MKDIR packet type, format, and responder.
|
8
|
+
#
|
9
|
+
class SSH_FXP_MKDIR < Version2::Packets::SSH_FXP_MKDIR
|
10
|
+
|
11
|
+
#
|
12
|
+
# Represents SSH_FXP_MKDIR packet format.
|
13
|
+
#
|
14
|
+
FORMAT = [
|
15
|
+
[DataTypes::Byte, :"type" ],
|
16
|
+
[DataTypes::Uint32, :"request-id"],
|
17
|
+
[DataTypes::String, :"path" ],
|
18
|
+
[DataTypes::Attrs, :"attrs" ],
|
19
|
+
]
|
20
|
+
|
21
|
+
#
|
22
|
+
# Responds to SSH_FXP_MKDIR request.
|
23
|
+
#
|
24
|
+
# @param request [Hash{Symbol=>Object}] SSH_FXP_MKDIR request represented in Hash.
|
25
|
+
# @return [Hash{Symbol=>Object}] Response represented in Hash. Its type is SSH_FXP_STATUS.
|
26
|
+
#
|
27
|
+
def respond_to request
|
28
|
+
begin
|
29
|
+
args = [request[:"path"]]
|
30
|
+
if request[:"attrs"].has_key?(:"permissions")
|
31
|
+
args.push request[:"attrs"][:"permissions"]
|
32
|
+
end
|
33
|
+
log_debug { "Dir.mkdir(#{args.map(&:inspect).join(", ")})" }
|
34
|
+
Dir.mkdir(*args)
|
35
|
+
{
|
36
|
+
:"type" => Packets::SSH_FXP_STATUS::TYPE,
|
37
|
+
:"request-id" => request[:"request-id"],
|
38
|
+
:"code" => Packets::SSH_FXP_STATUS::SSH_FX_OK,
|
39
|
+
:"error message" => "Success",
|
40
|
+
:"language tag" => "",
|
41
|
+
}
|
42
|
+
rescue Errno::EACCES => e
|
43
|
+
log_debug { e.message }
|
44
|
+
{
|
45
|
+
:"type" => Packets::SSH_FXP_STATUS::TYPE,
|
46
|
+
:"request-id" => request[:"request-id"],
|
47
|
+
:"code" => Packets::SSH_FXP_STATUS::SSH_FX_PERMISSION_DENIED,
|
48
|
+
:"error message" => "Permission denied",
|
49
|
+
:"language tag" => "",
|
50
|
+
}
|
51
|
+
rescue Errno::EEXIST => e
|
52
|
+
log_debug { e.message }
|
53
|
+
{
|
54
|
+
:"type" => Packets::SSH_FXP_STATUS::TYPE,
|
55
|
+
:"request-id" => request[:"request-id"],
|
56
|
+
:"code" => Packets::SSH_FXP_STATUS::SSH_FX_FAILURE,
|
57
|
+
:"error message" => "File exists",
|
58
|
+
:"language tag" => "",
|
59
|
+
}
|
60
|
+
rescue => e
|
61
|
+
log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
62
|
+
{
|
63
|
+
:"type" => Packets::SSH_FXP_STATUS::TYPE,
|
64
|
+
:"request-id" => request[:"request-id"],
|
65
|
+
:"code" => Packets::SSH_FXP_STATUS::SSH_FX_FAILURE,
|
66
|
+
:"error message" => e.message,
|
67
|
+
:"language tag" => "",
|
68
|
+
}
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module HrrRbSftp
|
2
|
+
class Protocol
|
3
|
+
module Version3
|
4
|
+
class Packets
|
5
|
+
|
6
|
+
#
|
7
|
+
# This class implements SFTP protocol version 1 SSH_FXP_READLINK packet type, format, and responder.
|
8
|
+
#
|
9
|
+
class SSH_FXP_READLINK < Packets::Packet
|
10
|
+
|
11
|
+
#
|
12
|
+
# Represents SSH_FXP_READLINK packet type.
|
13
|
+
#
|
14
|
+
TYPE = 19
|
15
|
+
|
16
|
+
#
|
17
|
+
# Represents SSH_FXP_READLINK packet format.
|
18
|
+
#
|
19
|
+
FORMAT = [
|
20
|
+
[DataTypes::Byte, :"type" ],
|
21
|
+
[DataTypes::Uint32, :"request-id"],
|
22
|
+
[DataTypes::String, :"path" ],
|
23
|
+
]
|
24
|
+
|
25
|
+
#
|
26
|
+
# Responds to SSH_FXP_READLINK request.
|
27
|
+
#
|
28
|
+
# @param request [Hash{Symbol=>Object}] SSH_FXP_READLINK request represented in Hash.
|
29
|
+
# @return [Hash{Symbol=>Object}] Response represented in Hash. In case of success, its type is SSH_FXP_NAME. In other cases, its type is SSH_FXP_STATUS.
|
30
|
+
#
|
31
|
+
def respond_to request
|
32
|
+
begin
|
33
|
+
log_debug { "realpath = File.realpath(#{request[:"path"].inspect})" }
|
34
|
+
realpath = File.realpath(request[:"path"])
|
35
|
+
{
|
36
|
+
:"type" => Packets::SSH_FXP_NAME::TYPE,
|
37
|
+
:"request-id" => request[:"request-id"],
|
38
|
+
:"count" => 1,
|
39
|
+
:"filename[0]" => realpath,
|
40
|
+
:"longname[0]" => realpath,
|
41
|
+
:"attrs[0]" => {},
|
42
|
+
}
|
43
|
+
rescue Errno::ENOENT => e
|
44
|
+
log_debug { e.message }
|
45
|
+
{
|
46
|
+
:"type" => Packets::SSH_FXP_STATUS::TYPE,
|
47
|
+
:"request-id" => request[:"request-id"],
|
48
|
+
:"code" => Packets::SSH_FXP_STATUS::SSH_FX_NO_SUCH_FILE,
|
49
|
+
:"error message" => "No such file or directory",
|
50
|
+
:"language tag" => "",
|
51
|
+
}
|
52
|
+
rescue Errno::EACCES => e
|
53
|
+
log_debug { e.message }
|
54
|
+
{
|
55
|
+
:"type" => Packets::SSH_FXP_STATUS::TYPE,
|
56
|
+
:"request-id" => request[:"request-id"],
|
57
|
+
:"code" => Packets::SSH_FXP_STATUS::SSH_FX_PERMISSION_DENIED,
|
58
|
+
:"error message" => "Permission denied",
|
59
|
+
:"language tag" => "",
|
60
|
+
}
|
61
|
+
rescue => e
|
62
|
+
log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
63
|
+
{
|
64
|
+
:"type" => Packets::SSH_FXP_STATUS::TYPE,
|
65
|
+
:"request-id" => request[:"request-id"],
|
66
|
+
:"code" => Packets::SSH_FXP_STATUS::SSH_FX_FAILURE,
|
67
|
+
:"error message" => e.message,
|
68
|
+
:"language tag" => "",
|
69
|
+
}
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|