aboutsummaryrefslogtreecommitdiff
path: root/sftp/packet_typing.go
diff options
context:
space:
mode:
Diffstat (limited to 'sftp/packet_typing.go')
-rw-r--r--sftp/packet_typing.go135
1 files changed, 135 insertions, 0 deletions
diff --git a/sftp/packet_typing.go b/sftp/packet_typing.go
new file mode 100644
index 0000000..f4f9052
--- /dev/null
+++ b/sftp/packet_typing.go
@@ -0,0 +1,135 @@
+package sftp
+
+import (
+ "encoding"
+ "fmt"
+)
+
+// all incoming packets
+type requestPacket interface {
+ encoding.BinaryUnmarshaler
+ id() uint32
+}
+
+type responsePacket interface {
+ encoding.BinaryMarshaler
+ id() uint32
+}
+
+// interfaces to group types
+type hasPath interface {
+ requestPacket
+ getPath() string
+}
+
+type hasHandle interface {
+ requestPacket
+ getHandle() string
+}
+
+type notReadOnly interface {
+ notReadOnly()
+}
+
+//// define types by adding methods
+// hasPath
+func (p *sshFxpLstatPacket) getPath() string { return p.Path }
+func (p *sshFxpStatPacket) getPath() string { return p.Path }
+func (p *sshFxpRmdirPacket) getPath() string { return p.Path }
+func (p *sshFxpReadlinkPacket) getPath() string { return p.Path }
+func (p *sshFxpRealpathPacket) getPath() string { return p.Path }
+func (p *sshFxpMkdirPacket) getPath() string { return p.Path }
+func (p *sshFxpSetstatPacket) getPath() string { return p.Path }
+func (p *sshFxpStatvfsPacket) getPath() string { return p.Path }
+func (p *sshFxpRemovePacket) getPath() string { return p.Filename }
+func (p *sshFxpRenamePacket) getPath() string { return p.Oldpath }
+func (p *sshFxpSymlinkPacket) getPath() string { return p.Targetpath }
+func (p *sshFxpOpendirPacket) getPath() string { return p.Path }
+func (p *sshFxpOpenPacket) getPath() string { return p.Path }
+
+func (p *sshFxpExtendedPacketPosixRename) getPath() string { return p.Oldpath }
+func (p *sshFxpExtendedPacketHardlink) getPath() string { return p.Oldpath }
+
+// getHandle
+func (p *sshFxpFstatPacket) getHandle() string { return p.Handle }
+func (p *sshFxpFsetstatPacket) getHandle() string { return p.Handle }
+func (p *sshFxpReadPacket) getHandle() string { return p.Handle }
+func (p *sshFxpWritePacket) getHandle() string { return p.Handle }
+func (p *sshFxpReaddirPacket) getHandle() string { return p.Handle }
+func (p *sshFxpClosePacket) getHandle() string { return p.Handle }
+
+// notReadOnly
+func (p *sshFxpWritePacket) notReadOnly() {}
+func (p *sshFxpSetstatPacket) notReadOnly() {}
+func (p *sshFxpFsetstatPacket) notReadOnly() {}
+func (p *sshFxpRemovePacket) notReadOnly() {}
+func (p *sshFxpMkdirPacket) notReadOnly() {}
+func (p *sshFxpRmdirPacket) notReadOnly() {}
+func (p *sshFxpRenamePacket) notReadOnly() {}
+func (p *sshFxpSymlinkPacket) notReadOnly() {}
+func (p *sshFxpExtendedPacketPosixRename) notReadOnly() {}
+func (p *sshFxpExtendedPacketHardlink) notReadOnly() {}
+
+// some packets with ID are missing id()
+func (p *sshFxpDataPacket) id() uint32 { return p.ID }
+func (p *sshFxpStatusPacket) id() uint32 { return p.ID }
+func (p *sshFxpStatResponse) id() uint32 { return p.ID }
+func (p *sshFxpNamePacket) id() uint32 { return p.ID }
+func (p *sshFxpHandlePacket) id() uint32 { return p.ID }
+func (p *StatVFS) id() uint32 { return p.ID }
+func (p *sshFxVersionPacket) id() uint32 { return 0 }
+
+// take raw incoming packet data and build packet objects
+func makePacket(p rxPacket) (requestPacket, error) {
+ var pkt requestPacket
+ switch p.pktType {
+ case sshFxpInit:
+ pkt = &sshFxInitPacket{}
+ case sshFxpLstat:
+ pkt = &sshFxpLstatPacket{}
+ case sshFxpOpen:
+ pkt = &sshFxpOpenPacket{}
+ case sshFxpClose:
+ pkt = &sshFxpClosePacket{}
+ case sshFxpRead:
+ pkt = &sshFxpReadPacket{}
+ case sshFxpWrite:
+ pkt = &sshFxpWritePacket{}
+ case sshFxpFstat:
+ pkt = &sshFxpFstatPacket{}
+ case sshFxpSetstat:
+ pkt = &sshFxpSetstatPacket{}
+ case sshFxpFsetstat:
+ pkt = &sshFxpFsetstatPacket{}
+ case sshFxpOpendir:
+ pkt = &sshFxpOpendirPacket{}
+ case sshFxpReaddir:
+ pkt = &sshFxpReaddirPacket{}
+ case sshFxpRemove:
+ pkt = &sshFxpRemovePacket{}
+ case sshFxpMkdir:
+ pkt = &sshFxpMkdirPacket{}
+ case sshFxpRmdir:
+ pkt = &sshFxpRmdirPacket{}
+ case sshFxpRealpath:
+ pkt = &sshFxpRealpathPacket{}
+ case sshFxpStat:
+ pkt = &sshFxpStatPacket{}
+ case sshFxpRename:
+ pkt = &sshFxpRenamePacket{}
+ case sshFxpReadlink:
+ pkt = &sshFxpReadlinkPacket{}
+ case sshFxpSymlink:
+ pkt = &sshFxpSymlinkPacket{}
+ case sshFxpExtended:
+ pkt = &sshFxpExtendedPacket{}
+ default:
+ return nil, fmt.Errorf("unhandled packet type: %s", p.pktType)
+ }
+ if err := pkt.UnmarshalBinary(p.pktBytes); err != nil {
+ // Return partially unpacked packet to allow callers to return
+ // error messages appropriately with necessary id() method.
+ return pkt, err
+ }
+ return pkt, nil
+}