diff options
Diffstat (limited to 'sftp/packet_typing.go')
-rw-r--r-- | sftp/packet_typing.go | 135 |
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 +} |