hrr_rb_sftp 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.
Files changed (72) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +25 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +7 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +135 -0
  9. data/Rakefile +6 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +8 -0
  12. data/demo/hrr_rb_sftp_server.rb +23 -0
  13. data/demo/instantiate_hrr_rb_sftp_server.rb +67 -0
  14. data/demo/spawn_hrr_rb_sftp_server.rb +66 -0
  15. data/hrr_rb_sftp.gemspec +26 -0
  16. data/lib/hrr_rb_sftp.rb +13 -0
  17. data/lib/hrr_rb_sftp/loggable.rb +41 -0
  18. data/lib/hrr_rb_sftp/protocol.rb +62 -0
  19. data/lib/hrr_rb_sftp/protocol/common.rb +10 -0
  20. data/lib/hrr_rb_sftp/protocol/common/data_type.rb +15 -0
  21. data/lib/hrr_rb_sftp/protocol/common/data_type/byte.rb +22 -0
  22. data/lib/hrr_rb_sftp/protocol/common/data_type/extension_pair.rb +23 -0
  23. data/lib/hrr_rb_sftp/protocol/common/data_type/extension_pairs.rb +24 -0
  24. data/lib/hrr_rb_sftp/protocol/common/data_type/string.rb +24 -0
  25. data/lib/hrr_rb_sftp/protocol/common/data_type/uint32.rb +22 -0
  26. data/lib/hrr_rb_sftp/protocol/common/data_type/uint64.rb +22 -0
  27. data/lib/hrr_rb_sftp/protocol/common/packet.rb +11 -0
  28. data/lib/hrr_rb_sftp/protocol/common/packet/001_ssh_fxp_init.rb +18 -0
  29. data/lib/hrr_rb_sftp/protocol/common/packet/002_ssh_fxp_version.rb +19 -0
  30. data/lib/hrr_rb_sftp/protocol/common/packetable.rb +72 -0
  31. data/lib/hrr_rb_sftp/protocol/version1.rb +10 -0
  32. data/lib/hrr_rb_sftp/protocol/version1/data_type.rb +11 -0
  33. data/lib/hrr_rb_sftp/protocol/version1/data_type/attrs.rb +54 -0
  34. data/lib/hrr_rb_sftp/protocol/version1/packet.rb +29 -0
  35. data/lib/hrr_rb_sftp/protocol/version1/packet/003_ssh_fxp_open.rb +109 -0
  36. data/lib/hrr_rb_sftp/protocol/version1/packet/004_ssh_fxp_close.rb +44 -0
  37. data/lib/hrr_rb_sftp/protocol/version1/packet/005_ssh_fxp_read.rb +53 -0
  38. data/lib/hrr_rb_sftp/protocol/version1/packet/006_ssh_fxp_write.rb +46 -0
  39. data/lib/hrr_rb_sftp/protocol/version1/packet/007_ssh_fxp_lstat.rb +62 -0
  40. data/lib/hrr_rb_sftp/protocol/version1/packet/008_ssh_fxp_fstat.rb +48 -0
  41. data/lib/hrr_rb_sftp/protocol/version1/packet/009_ssh_fxp_setstat.rb +63 -0
  42. data/lib/hrr_rb_sftp/protocol/version1/packet/010_ssh_fxp_fsetstat.rb +48 -0
  43. data/lib/hrr_rb_sftp/protocol/version1/packet/011_ssh_fxp_opendir.rb +65 -0
  44. data/lib/hrr_rb_sftp/protocol/version1/packet/012_ssh_fxp_readdir.rb +134 -0
  45. data/lib/hrr_rb_sftp/protocol/version1/packet/013_ssh_fxp_remove.rb +57 -0
  46. data/lib/hrr_rb_sftp/protocol/version1/packet/014_ssh_fxp_mkdir.rb +57 -0
  47. data/lib/hrr_rb_sftp/protocol/version1/packet/015_ssh_fxp_rmdir.rb +73 -0
  48. data/lib/hrr_rb_sftp/protocol/version1/packet/016_ssh_fxp_realpath.rb +30 -0
  49. data/lib/hrr_rb_sftp/protocol/version1/packet/017_ssh_fxp_stat.rb +62 -0
  50. data/lib/hrr_rb_sftp/protocol/version1/packet/101_ssh_fxp_status.rb +29 -0
  51. data/lib/hrr_rb_sftp/protocol/version1/packet/102_ssh_fxp_handle.rb +19 -0
  52. data/lib/hrr_rb_sftp/protocol/version1/packet/103_ssh_fxp_data.rb +19 -0
  53. data/lib/hrr_rb_sftp/protocol/version1/packet/104_ssh_fxp_name.rb +33 -0
  54. data/lib/hrr_rb_sftp/protocol/version1/packet/105_ssh_fxp_attrs.rb +19 -0
  55. data/lib/hrr_rb_sftp/protocol/version2.rb +10 -0
  56. data/lib/hrr_rb_sftp/protocol/version2/data_type.rb +9 -0
  57. data/lib/hrr_rb_sftp/protocol/version2/packet.rb +11 -0
  58. data/lib/hrr_rb_sftp/protocol/version2/packet/018_ssh_fxp_rename.rb +70 -0
  59. data/lib/hrr_rb_sftp/protocol/version3.rb +10 -0
  60. data/lib/hrr_rb_sftp/protocol/version3/data_type.rb +9 -0
  61. data/lib/hrr_rb_sftp/protocol/version3/packet.rb +16 -0
  62. data/lib/hrr_rb_sftp/protocol/version3/packet/014_ssh_fxp_mkdir.rb +58 -0
  63. data/lib/hrr_rb_sftp/protocol/version3/packet/019_ssh_fxp_readlink.rb +57 -0
  64. data/lib/hrr_rb_sftp/protocol/version3/packet/020_ssh_fxp_symlink.rb +58 -0
  65. data/lib/hrr_rb_sftp/protocol/version3/packet/101_ssh_fxp_status.rb +31 -0
  66. data/lib/hrr_rb_sftp/protocol/version3/packet/200_ssh_fxp_extended.rb +34 -0
  67. data/lib/hrr_rb_sftp/protocol/version3/packet/201_ssh_fxp_extended_reply.rb +23 -0
  68. data/lib/hrr_rb_sftp/receiver.rb +22 -0
  69. data/lib/hrr_rb_sftp/sender.rb +13 -0
  70. data/lib/hrr_rb_sftp/server.rb +96 -0
  71. data/lib/hrr_rb_sftp/version.rb +3 -0
  72. metadata +114 -0
@@ -0,0 +1,30 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ class Version1
4
+ module Packet
5
+ class SSH_FXP_REALPATH
6
+ include Common::Packetable
7
+
8
+ TYPE = 16
9
+
10
+ FORMAT = [
11
+ [DataType::Byte, :"type" ],
12
+ [DataType::Uint32, :"request-id"],
13
+ [DataType::String, :"path" ],
14
+ ]
15
+
16
+ def respond_to request
17
+ {
18
+ :"type" => SSH_FXP_NAME::TYPE,
19
+ :"request-id" => request[:"request-id"],
20
+ :"count" => 1,
21
+ :"filename[0]" => File.absolute_path(request[:"path"]),
22
+ :"longname[0]" => File.absolute_path(request[:"path"]),
23
+ :"attrs[0]" => {},
24
+ }
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,62 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ class Version1
4
+ module Packet
5
+ class SSH_FXP_STAT
6
+ include Common::Packetable
7
+
8
+ TYPE = 17
9
+
10
+ FORMAT = [
11
+ [DataType::Byte, :"type" ],
12
+ [DataType::Uint32, :"request-id"],
13
+ [DataType::String, :"path" ],
14
+ ]
15
+
16
+ def respond_to request
17
+ begin
18
+ stat = File.stat(request[:"path"])
19
+ attrs = Hash.new
20
+ attrs[:"size"] = stat.size if stat.size
21
+ attrs[:"uid"] = stat.uid if stat.uid
22
+ attrs[:"gid"] = stat.gid if stat.gid
23
+ attrs[:"permissions"] = stat.mode if stat.mode
24
+ attrs[:"atime"] = stat.atime.to_i if stat.atime
25
+ attrs[:"mtime"] = stat.mtime.to_i if stat.mtime
26
+ {
27
+ :"type" => SSH_FXP_ATTRS::TYPE,
28
+ :"request-id" => request[:"request-id"],
29
+ :"attrs" => attrs,
30
+ }
31
+ rescue Errno::ENOENT
32
+ {
33
+ :"type" => SSH_FXP_STATUS::TYPE,
34
+ :"request-id" => request[:"request-id"],
35
+ :"code" => SSH_FXP_STATUS::SSH_FX_NO_SUCH_FILE,
36
+ :"error message" => "No such file or directory",
37
+ :"language tag" => "",
38
+ }
39
+ rescue Errno::EACCES
40
+ {
41
+ :"type" => SSH_FXP_STATUS::TYPE,
42
+ :"request-id" => request[:"request-id"],
43
+ :"code" => SSH_FXP_STATUS::SSH_FX_PERMISSION_DENIED,
44
+ :"error message" => "Permission denied",
45
+ :"language tag" => "",
46
+ }
47
+ rescue => e
48
+ log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
49
+ {
50
+ :"type" => SSH_FXP_STATUS::TYPE,
51
+ :"request-id" => request[:"request-id"],
52
+ :"code" => SSH_FXP_STATUS::SSH_FX_FAILURE,
53
+ :"error message" => e.message,
54
+ :"language tag" => "",
55
+ }
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,29 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ class Version1
4
+ module Packet
5
+ class SSH_FXP_STATUS
6
+ include Common::Packetable
7
+
8
+ TYPE = 101
9
+
10
+ FORMAT = [
11
+ [DataType::Byte, :"type" ],
12
+ [DataType::Uint32, :"request-id"],
13
+ [DataType::Uint32, :"code" ],
14
+ ]
15
+
16
+ SSH_FX_OK = 0
17
+ SSH_FX_EOF = 1
18
+ SSH_FX_NO_SUCH_FILE = 2
19
+ SSH_FX_PERMISSION_DENIED = 3
20
+ SSH_FX_FAILURE = 4
21
+ SSH_FX_BAD_MESSAGE = 5
22
+ SSH_FX_NO_CONNECTION = 6
23
+ SSH_FX_CONNECTION_LOST = 7
24
+ SSH_FX_OP_UNSUPPORTED = 8
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,19 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ class Version1
4
+ module Packet
5
+ class SSH_FXP_HANDLE
6
+ include Common::Packetable
7
+
8
+ TYPE = 102
9
+
10
+ FORMAT = [
11
+ [DataType::Byte, :"type" ],
12
+ [DataType::Uint32, :"request-id"],
13
+ [DataType::String, :"handle" ],
14
+ ]
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ class Version1
4
+ module Packet
5
+ class SSH_FXP_DATA
6
+ include Common::Packetable
7
+
8
+ TYPE = 103
9
+
10
+ FORMAT = [
11
+ [DataType::Byte, :"type" ],
12
+ [DataType::Uint32, :"request-id"],
13
+ [DataType::String, :"data" ],
14
+ ]
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,33 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ class Version1
4
+ module Packet
5
+ class SSH_FXP_NAME
6
+ include Common::Packetable
7
+
8
+ TYPE = 104
9
+
10
+ FORMAT = [
11
+ [DataType::Byte, :"type" ],
12
+ [DataType::Uint32, :"request-id"],
13
+ [DataType::Uint32, :"count" ],
14
+ ]
15
+
16
+ PER_COUNT_FORMAT = Hash.new{ |hash, key|
17
+ Array.new(key){ |i|
18
+ [
19
+ [DataType::String, :"filename[#{i}]"],
20
+ [DataType::String, :"longname[#{i}]"],
21
+ [DataType::Attrs, :"attrs[#{i}]" ],
22
+ ]
23
+ }.inject(:+)
24
+ }
25
+
26
+ CONDITIONAL_FORMAT = {
27
+ :"count" => PER_COUNT_FORMAT,
28
+ }
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,19 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ class Version1
4
+ module Packet
5
+ class SSH_FXP_ATTRS
6
+ include Common::Packetable
7
+
8
+ TYPE = 105
9
+
10
+ FORMAT = [
11
+ [DataType::Byte, :"type" ],
12
+ [DataType::Uint32, :"request-id"],
13
+ [DataType::Attrs, :"attrs" ],
14
+ ]
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,10 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ class Version2
4
+ PROTOCOL_VERSION = 2
5
+ end
6
+ end
7
+ end
8
+
9
+ require "hrr_rb_sftp/protocol/version2/data_type"
10
+ require "hrr_rb_sftp/protocol/version2/packet"
@@ -0,0 +1,9 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ class Version2
4
+ module DataType
5
+ include Version1::DataType
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ class Version2
4
+ module Packet
5
+ include Version1::Packet
6
+ end
7
+ end
8
+ end
9
+ end
10
+
11
+ require "hrr_rb_sftp/protocol/version2/packet/018_ssh_fxp_rename"
@@ -0,0 +1,70 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ class Version2
4
+ module Packet
5
+ class SSH_FXP_RENAME
6
+ include Common::Packetable
7
+
8
+ TYPE = 18
9
+
10
+ FORMAT = [
11
+ [DataType::Byte, :"type" ],
12
+ [DataType::Uint32, :"request-id"],
13
+ [DataType::String, :"oldpath" ],
14
+ [DataType::String, :"newpath" ],
15
+ ]
16
+
17
+ def respond_to request
18
+ oldpath = request[:"oldpath"]
19
+ newpath = request[:"newpath"]
20
+ if File.exist?(newpath)
21
+ {
22
+ :"type" => Packet::SSH_FXP_STATUS::TYPE,
23
+ :"request-id" => request[:"request-id"],
24
+ :"code" => Packet::SSH_FXP_STATUS::SSH_FX_FAILURE,
25
+ :"error message" => "File exists",
26
+ :"language tag" => "",
27
+ }
28
+ else
29
+ begin
30
+ File.rename(oldpath, newpath)
31
+ {
32
+ :"type" => Packet::SSH_FXP_STATUS::TYPE,
33
+ :"request-id" => request[:"request-id"],
34
+ :"code" => Packet::SSH_FXP_STATUS::SSH_FX_OK,
35
+ :"error message" => "Success",
36
+ :"language tag" => "",
37
+ }
38
+ rescue Errno::ENOENT
39
+ {
40
+ :"type" => Packet::SSH_FXP_STATUS::TYPE,
41
+ :"request-id" => request[:"request-id"],
42
+ :"code" => Packet::SSH_FXP_STATUS::SSH_FX_NO_SUCH_FILE,
43
+ :"error message" => "No such file or directory",
44
+ :"language tag" => "",
45
+ }
46
+ rescue Errno::EACCES
47
+ {
48
+ :"type" => Packet::SSH_FXP_STATUS::TYPE,
49
+ :"request-id" => request[:"request-id"],
50
+ :"code" => Packet::SSH_FXP_STATUS::SSH_FX_PERMISSION_DENIED,
51
+ :"error message" => "Permission denied",
52
+ :"language tag" => "",
53
+ }
54
+ rescue => e
55
+ log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
56
+ {
57
+ :"type" => Packet::SSH_FXP_STATUS::TYPE,
58
+ :"request-id" => request[:"request-id"],
59
+ :"code" => Packet::SSH_FXP_STATUS::SSH_FX_FAILURE,
60
+ :"error message" => e.message,
61
+ :"language tag" => "",
62
+ }
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,10 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ class Version3
4
+ PROTOCOL_VERSION = 3
5
+ end
6
+ end
7
+ end
8
+
9
+ require "hrr_rb_sftp/protocol/version3/data_type"
10
+ require "hrr_rb_sftp/protocol/version3/packet"
@@ -0,0 +1,9 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ class Version3
4
+ module DataType
5
+ include Version2::DataType
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,16 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ class Version3
4
+ module Packet
5
+ include Version2::Packet
6
+ end
7
+ end
8
+ end
9
+ end
10
+
11
+ require "hrr_rb_sftp/protocol/version3/packet/014_ssh_fxp_mkdir"
12
+ require "hrr_rb_sftp/protocol/version3/packet/019_ssh_fxp_readlink"
13
+ require "hrr_rb_sftp/protocol/version3/packet/020_ssh_fxp_symlink"
14
+ require "hrr_rb_sftp/protocol/version3/packet/101_ssh_fxp_status"
15
+ require "hrr_rb_sftp/protocol/version3/packet/200_ssh_fxp_extended"
16
+ require "hrr_rb_sftp/protocol/version3/packet/201_ssh_fxp_extended_reply"
@@ -0,0 +1,58 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ class Version3
4
+ module Packet
5
+ class SSH_FXP_MKDIR
6
+ include Common::Packetable
7
+
8
+ TYPE = 14
9
+
10
+ FORMAT = [
11
+ [DataType::Byte, :"type" ],
12
+ [DataType::Uint32, :"request-id"],
13
+ [DataType::String, :"path" ],
14
+ [DataType::Attrs, :"attrs" ],
15
+ ]
16
+
17
+ def respond_to request
18
+ begin
19
+ Dir.mkdir request[:"path"]
20
+ {
21
+ :"type" => Packet::SSH_FXP_STATUS::TYPE,
22
+ :"request-id" => request[:"request-id"],
23
+ :"code" => Packet::SSH_FXP_STATUS::SSH_FX_OK,
24
+ :"error message" => "Success",
25
+ :"language tag" => "",
26
+ }
27
+ rescue Errno::EACCES
28
+ {
29
+ :"type" => Packet::SSH_FXP_STATUS::TYPE,
30
+ :"request-id" => request[:"request-id"],
31
+ :"code" => Packet::SSH_FXP_STATUS::SSH_FX_PERMISSION_DENIED,
32
+ :"error message" => "Permission denied",
33
+ :"language tag" => "",
34
+ }
35
+ rescue Errno::EEXIST
36
+ {
37
+ :"type" => Packet::SSH_FXP_STATUS::TYPE,
38
+ :"request-id" => request[:"request-id"],
39
+ :"code" => Packet::SSH_FXP_STATUS::SSH_FX_FAILURE,
40
+ :"error message" => "File exists",
41
+ :"language tag" => "",
42
+ }
43
+ rescue => e
44
+ log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
45
+ {
46
+ :"type" => Packet::SSH_FXP_STATUS::TYPE,
47
+ :"request-id" => request[:"request-id"],
48
+ :"code" => Packet::SSH_FXP_STATUS::SSH_FX_FAILURE,
49
+ :"error message" => e.message,
50
+ :"language tag" => "",
51
+ }
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,57 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ class Version3
4
+ module Packet
5
+ class SSH_FXP_READLINK
6
+ include Common::Packetable
7
+
8
+ TYPE = 19
9
+
10
+ FORMAT = [
11
+ [DataType::Byte, :"type" ],
12
+ [DataType::Uint32, :"request-id"],
13
+ [DataType::String, :"path" ],
14
+ ]
15
+
16
+ def respond_to request
17
+ begin
18
+ {
19
+ :"type" => Packet::SSH_FXP_NAME::TYPE,
20
+ :"request-id" => request[:"request-id"],
21
+ :"count" => 1,
22
+ :"filename[0]" => File.realpath(request[:"path"]),
23
+ :"longname[0]" => File.realpath(request[:"path"]),
24
+ :"attrs[0]" => {},
25
+ }
26
+ rescue Errno::ENOENT
27
+ {
28
+ :"type" => Packet::SSH_FXP_STATUS::TYPE,
29
+ :"request-id" => request[:"request-id"],
30
+ :"code" => Packet::SSH_FXP_STATUS::SSH_FX_NO_SUCH_FILE,
31
+ :"error message" => "No such file or directory",
32
+ :"language tag" => "",
33
+ }
34
+ rescue Errno::EACCES
35
+ {
36
+ :"type" => Packet::SSH_FXP_STATUS::TYPE,
37
+ :"request-id" => request[:"request-id"],
38
+ :"code" => Packet::SSH_FXP_STATUS::SSH_FX_PERMISSION_DENIED,
39
+ :"error message" => "Permission denied",
40
+ :"language tag" => "",
41
+ }
42
+ rescue => e
43
+ log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
44
+ {
45
+ :"type" => Packet::SSH_FXP_STATUS::TYPE,
46
+ :"request-id" => request[:"request-id"],
47
+ :"code" => Packet::SSH_FXP_STATUS::SSH_FX_FAILURE,
48
+ :"error message" => e.message,
49
+ :"language tag" => "",
50
+ }
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end