packet-typing.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. package sftp
  2. import (
  3. "encoding"
  4. "fmt"
  5. )
  6. // all incoming packets
  7. type requestPacket interface {
  8. encoding.BinaryUnmarshaler
  9. id() uint32
  10. }
  11. type responsePacket interface {
  12. encoding.BinaryMarshaler
  13. id() uint32
  14. }
  15. // interfaces to group types
  16. type hasPath interface {
  17. requestPacket
  18. getPath() string
  19. }
  20. type hasHandle interface {
  21. requestPacket
  22. getHandle() string
  23. }
  24. type notReadOnly interface {
  25. notReadOnly()
  26. }
  27. // // define types by adding methods
  28. // hasPath
  29. func (p *sshFxpLstatPacket) getPath() string { return p.Path }
  30. func (p *sshFxpStatPacket) getPath() string { return p.Path }
  31. func (p *sshFxpRmdirPacket) getPath() string { return p.Path }
  32. func (p *sshFxpReadlinkPacket) getPath() string { return p.Path }
  33. func (p *sshFxpRealpathPacket) getPath() string { return p.Path }
  34. func (p *sshFxpMkdirPacket) getPath() string { return p.Path }
  35. func (p *sshFxpSetstatPacket) getPath() string { return p.Path }
  36. func (p *sshFxpStatvfsPacket) getPath() string { return p.Path }
  37. func (p *sshFxpRemovePacket) getPath() string { return p.Filename }
  38. func (p *sshFxpRenamePacket) getPath() string { return p.Oldpath }
  39. func (p *sshFxpSymlinkPacket) getPath() string { return p.Targetpath }
  40. func (p *sshFxpOpendirPacket) getPath() string { return p.Path }
  41. func (p *sshFxpOpenPacket) getPath() string { return p.Path }
  42. func (p *sshFxpExtendedPacketPosixRename) getPath() string { return p.Oldpath }
  43. func (p *sshFxpExtendedPacketHardlink) getPath() string { return p.Oldpath }
  44. // getHandle
  45. func (p *sshFxpFstatPacket) getHandle() string { return p.Handle }
  46. func (p *sshFxpFsetstatPacket) getHandle() string { return p.Handle }
  47. func (p *sshFxpReadPacket) getHandle() string { return p.Handle }
  48. func (p *sshFxpWritePacket) getHandle() string { return p.Handle }
  49. func (p *sshFxpReaddirPacket) getHandle() string { return p.Handle }
  50. func (p *sshFxpClosePacket) getHandle() string { return p.Handle }
  51. // notReadOnly
  52. func (p *sshFxpWritePacket) notReadOnly() {}
  53. func (p *sshFxpSetstatPacket) notReadOnly() {}
  54. func (p *sshFxpFsetstatPacket) notReadOnly() {}
  55. func (p *sshFxpRemovePacket) notReadOnly() {}
  56. func (p *sshFxpMkdirPacket) notReadOnly() {}
  57. func (p *sshFxpRmdirPacket) notReadOnly() {}
  58. func (p *sshFxpRenamePacket) notReadOnly() {}
  59. func (p *sshFxpSymlinkPacket) notReadOnly() {}
  60. func (p *sshFxpExtendedPacketPosixRename) notReadOnly() {}
  61. func (p *sshFxpExtendedPacketHardlink) notReadOnly() {}
  62. // some packets with ID are missing id()
  63. func (p *sshFxpDataPacket) id() uint32 { return p.ID }
  64. func (p *sshFxpStatusPacket) id() uint32 { return p.ID }
  65. func (p *sshFxpStatResponse) id() uint32 { return p.ID }
  66. func (p *sshFxpNamePacket) id() uint32 { return p.ID }
  67. func (p *sshFxpHandlePacket) id() uint32 { return p.ID }
  68. func (p *StatVFS) id() uint32 { return p.ID }
  69. func (p *sshFxVersionPacket) id() uint32 { return 0 }
  70. // take raw incoming packet data and build packet objects
  71. func makePacket(p rxPacket) (requestPacket, error) {
  72. var pkt requestPacket
  73. switch p.pktType {
  74. case sshFxpInit:
  75. pkt = &sshFxInitPacket{}
  76. case sshFxpLstat:
  77. pkt = &sshFxpLstatPacket{}
  78. case sshFxpOpen:
  79. pkt = &sshFxpOpenPacket{}
  80. case sshFxpClose:
  81. pkt = &sshFxpClosePacket{}
  82. case sshFxpRead:
  83. pkt = &sshFxpReadPacket{}
  84. case sshFxpWrite:
  85. pkt = &sshFxpWritePacket{}
  86. case sshFxpFstat:
  87. pkt = &sshFxpFstatPacket{}
  88. case sshFxpSetstat:
  89. pkt = &sshFxpSetstatPacket{}
  90. case sshFxpFsetstat:
  91. pkt = &sshFxpFsetstatPacket{}
  92. case sshFxpOpendir:
  93. pkt = &sshFxpOpendirPacket{}
  94. case sshFxpReaddir:
  95. pkt = &sshFxpReaddirPacket{}
  96. case sshFxpRemove:
  97. pkt = &sshFxpRemovePacket{}
  98. case sshFxpMkdir:
  99. pkt = &sshFxpMkdirPacket{}
  100. case sshFxpRmdir:
  101. pkt = &sshFxpRmdirPacket{}
  102. case sshFxpRealpath:
  103. pkt = &sshFxpRealpathPacket{}
  104. case sshFxpStat:
  105. pkt = &sshFxpStatPacket{}
  106. case sshFxpRename:
  107. pkt = &sshFxpRenamePacket{}
  108. case sshFxpReadlink:
  109. pkt = &sshFxpReadlinkPacket{}
  110. case sshFxpSymlink:
  111. pkt = &sshFxpSymlinkPacket{}
  112. case sshFxpExtended:
  113. pkt = &sshFxpExtendedPacket{}
  114. default:
  115. return nil, fmt.Errorf("unhandled packet type: %s", p.pktType)
  116. }
  117. if err := pkt.UnmarshalBinary(p.pktBytes); err != nil {
  118. // Return partially unpacked packet to allow callers to return
  119. // error messages appropriately with necessary id() method.
  120. return pkt, err
  121. }
  122. return pkt, nil
  123. }