| 
									
										
										
										
											2016-07-07 02:59:55 +08:00
										 |  |  | package sftp | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | import ( | 
					
						
							|  |  |  | 	"encoding" | 
					
						
							| 
									
										
										
										
											2021-06-05 05:18:41 +08:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // all incoming packets
 | 
					
						
							| 
									
										
										
										
											2017-03-14 09:24:32 +08:00
										 |  |  | type requestPacket interface { | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | 	encoding.BinaryUnmarshaler | 
					
						
							|  |  |  | 	id() uint32 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-26 02:52:07 +08:00
										 |  |  | type responsePacket interface { | 
					
						
							| 
									
										
										
										
											2016-07-19 02:50:45 +08:00
										 |  |  | 	encoding.BinaryMarshaler | 
					
						
							| 
									
										
										
										
											2017-03-15 08:43:51 +08:00
										 |  |  | 	id() uint32 | 
					
						
							| 
									
										
										
										
											2016-07-19 02:50:45 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-07-12 04:56:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | // interfaces to group types
 | 
					
						
							| 
									
										
										
										
											2016-07-07 02:59:55 +08:00
										 |  |  | type hasPath interface { | 
					
						
							| 
									
										
										
										
											2017-03-14 09:24:32 +08:00
										 |  |  | 	requestPacket | 
					
						
							| 
									
										
										
										
											2016-07-07 02:59:55 +08:00
										 |  |  | 	getPath() string | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type hasHandle interface { | 
					
						
							| 
									
										
										
										
											2017-03-14 09:24:32 +08:00
										 |  |  | 	requestPacket | 
					
						
							| 
									
										
										
										
											2016-07-07 02:59:55 +08:00
										 |  |  | 	getHandle() string | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-14 06:54:55 +08:00
										 |  |  | type notReadOnly interface { | 
					
						
							|  |  |  | 	notReadOnly() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-07 02:59:55 +08:00
										 |  |  | //// define types by adding methods
 | 
					
						
							|  |  |  | // hasPath
 | 
					
						
							| 
									
										
										
										
											2021-02-22 20:00:27 +08:00
										 |  |  | 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 } | 
					
						
							| 
									
										
										
										
											2016-07-07 02:59:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-22 20:00:27 +08:00
										 |  |  | func (p *sshFxpExtendedPacketPosixRename) getPath() string { return p.Oldpath } | 
					
						
							|  |  |  | func (p *sshFxpExtendedPacketHardlink) getPath() string    { return p.Oldpath } | 
					
						
							| 
									
										
										
										
											2018-01-06 10:06:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-25 03:23:18 +08:00
										 |  |  | // getHandle
 | 
					
						
							| 
									
										
										
										
											2021-02-22 20:00:27 +08:00
										 |  |  | 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 } | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-14 06:54:55 +08:00
										 |  |  | // notReadOnly
 | 
					
						
							| 
									
										
										
										
											2021-02-22 20:00:27 +08:00
										 |  |  | 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()    {} | 
					
						
							| 
									
										
										
										
											2017-03-14 06:54:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-12 04:56:47 +08:00
										 |  |  | // some packets with ID are missing id()
 | 
					
						
							| 
									
										
										
										
											2021-02-22 20:00:27 +08:00
										 |  |  | 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 } | 
					
						
							| 
									
										
										
										
											2016-07-12 03:57:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | // take raw incoming packet data and build packet objects
 | 
					
						
							| 
									
										
										
										
											2017-03-14 09:24:32 +08:00
										 |  |  | func makePacket(p rxPacket) (requestPacket, error) { | 
					
						
							|  |  |  | 	var pkt requestPacket | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | 	switch p.pktType { | 
					
						
							| 
									
										
										
										
											2019-08-30 23:04:37 +08:00
										 |  |  | 	case sshFxpInit: | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | 		pkt = &sshFxInitPacket{} | 
					
						
							| 
									
										
										
										
											2019-08-30 23:04:37 +08:00
										 |  |  | 	case sshFxpLstat: | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | 		pkt = &sshFxpLstatPacket{} | 
					
						
							| 
									
										
										
										
											2019-08-30 23:04:37 +08:00
										 |  |  | 	case sshFxpOpen: | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | 		pkt = &sshFxpOpenPacket{} | 
					
						
							| 
									
										
										
										
											2019-08-30 23:04:37 +08:00
										 |  |  | 	case sshFxpClose: | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | 		pkt = &sshFxpClosePacket{} | 
					
						
							| 
									
										
										
										
											2019-08-30 23:04:37 +08:00
										 |  |  | 	case sshFxpRead: | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | 		pkt = &sshFxpReadPacket{} | 
					
						
							| 
									
										
										
										
											2019-08-30 23:04:37 +08:00
										 |  |  | 	case sshFxpWrite: | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | 		pkt = &sshFxpWritePacket{} | 
					
						
							| 
									
										
										
										
											2019-08-30 23:04:37 +08:00
										 |  |  | 	case sshFxpFstat: | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | 		pkt = &sshFxpFstatPacket{} | 
					
						
							| 
									
										
										
										
											2019-08-30 23:04:37 +08:00
										 |  |  | 	case sshFxpSetstat: | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | 		pkt = &sshFxpSetstatPacket{} | 
					
						
							| 
									
										
										
										
											2019-08-30 23:04:37 +08:00
										 |  |  | 	case sshFxpFsetstat: | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | 		pkt = &sshFxpFsetstatPacket{} | 
					
						
							| 
									
										
										
										
											2019-08-30 23:04:37 +08:00
										 |  |  | 	case sshFxpOpendir: | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | 		pkt = &sshFxpOpendirPacket{} | 
					
						
							| 
									
										
										
										
											2019-08-30 23:04:37 +08:00
										 |  |  | 	case sshFxpReaddir: | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | 		pkt = &sshFxpReaddirPacket{} | 
					
						
							| 
									
										
										
										
											2019-08-30 23:04:37 +08:00
										 |  |  | 	case sshFxpRemove: | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | 		pkt = &sshFxpRemovePacket{} | 
					
						
							| 
									
										
										
										
											2019-08-30 23:04:37 +08:00
										 |  |  | 	case sshFxpMkdir: | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | 		pkt = &sshFxpMkdirPacket{} | 
					
						
							| 
									
										
										
										
											2019-08-30 23:04:37 +08:00
										 |  |  | 	case sshFxpRmdir: | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | 		pkt = &sshFxpRmdirPacket{} | 
					
						
							| 
									
										
										
										
											2019-08-30 23:04:37 +08:00
										 |  |  | 	case sshFxpRealpath: | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | 		pkt = &sshFxpRealpathPacket{} | 
					
						
							| 
									
										
										
										
											2019-08-30 23:04:37 +08:00
										 |  |  | 	case sshFxpStat: | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | 		pkt = &sshFxpStatPacket{} | 
					
						
							| 
									
										
										
										
											2019-08-30 23:04:37 +08:00
										 |  |  | 	case sshFxpRename: | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | 		pkt = &sshFxpRenamePacket{} | 
					
						
							| 
									
										
										
										
											2019-08-30 23:04:37 +08:00
										 |  |  | 	case sshFxpReadlink: | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | 		pkt = &sshFxpReadlinkPacket{} | 
					
						
							| 
									
										
										
										
											2019-08-30 23:04:37 +08:00
										 |  |  | 	case sshFxpSymlink: | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | 		pkt = &sshFxpSymlinkPacket{} | 
					
						
							| 
									
										
										
										
											2019-08-30 23:04:37 +08:00
										 |  |  | 	case sshFxpExtended: | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | 		pkt = &sshFxpExtendedPacket{} | 
					
						
							|  |  |  | 	default: | 
					
						
							| 
									
										
										
										
											2021-06-05 05:18:41 +08:00
										 |  |  | 		return nil, fmt.Errorf("unhandled packet type: %s", p.pktType) | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if err := pkt.UnmarshalBinary(p.pktBytes); err != nil { | 
					
						
							| 
									
										
										
										
											2018-03-19 22:32:22 +08:00
										 |  |  | 		// Return partially unpacked packet to allow callers to return
 | 
					
						
							|  |  |  | 		// error messages appropriately with necessary id() method.
 | 
					
						
							|  |  |  | 		return pkt, err | 
					
						
							| 
									
										
										
										
											2016-07-09 03:38:35 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return pkt, nil | 
					
						
							|  |  |  | } |