1package filexfer 2 3// LStatPacket defines the SSH_FXP_LSTAT packet. 4type LStatPacket struct { 5 Path string 6} 7 8// Type returns the SSH_FXP_xy value associated with this packet type. 9func (p *LStatPacket) Type() PacketType { 10 return PacketTypeLStat 11} 12 13// MarshalPacket returns p as a two-part binary encoding of p. 14func (p *LStatPacket) MarshalPacket(reqid uint32, b []byte) (header, payload []byte, err error) { 15 buf := NewBuffer(b) 16 if buf.Cap() < 9 { 17 size := 4 + len(p.Path) // string(path) 18 buf = NewMarshalBuffer(size) 19 } 20 21 buf.StartPacket(PacketTypeLStat, reqid) 22 buf.AppendString(p.Path) 23 24 return buf.Packet(payload) 25} 26 27// UnmarshalPacketBody unmarshals the packet body from the given Buffer. 28// It is assumed that the uint32(request-id) has already been consumed. 29func (p *LStatPacket) UnmarshalPacketBody(buf *Buffer) (err error) { 30 if p.Path, err = buf.ConsumeString(); err != nil { 31 return err 32 } 33 34 return nil 35} 36 37// SetstatPacket defines the SSH_FXP_SETSTAT packet. 38type SetstatPacket struct { 39 Path string 40 Attrs Attributes 41} 42 43// Type returns the SSH_FXP_xy value associated with this packet type. 44func (p *SetstatPacket) Type() PacketType { 45 return PacketTypeSetstat 46} 47 48// MarshalPacket returns p as a two-part binary encoding of p. 49func (p *SetstatPacket) MarshalPacket(reqid uint32, b []byte) (header, payload []byte, err error) { 50 buf := NewBuffer(b) 51 if buf.Cap() < 9 { 52 size := 4 + len(p.Path) + p.Attrs.Len() // string(path) + ATTRS(attrs) 53 buf = NewMarshalBuffer(size) 54 } 55 56 buf.StartPacket(PacketTypeSetstat, reqid) 57 buf.AppendString(p.Path) 58 59 p.Attrs.MarshalInto(buf) 60 61 return buf.Packet(payload) 62} 63 64// UnmarshalPacketBody unmarshals the packet body from the given Buffer. 65// It is assumed that the uint32(request-id) has already been consumed. 66func (p *SetstatPacket) UnmarshalPacketBody(buf *Buffer) (err error) { 67 if p.Path, err = buf.ConsumeString(); err != nil { 68 return err 69 } 70 71 return p.Attrs.UnmarshalFrom(buf) 72} 73 74// RemovePacket defines the SSH_FXP_REMOVE packet. 75type RemovePacket struct { 76 Path string 77} 78 79// Type returns the SSH_FXP_xy value associated with this packet type. 80func (p *RemovePacket) Type() PacketType { 81 return PacketTypeRemove 82} 83 84// MarshalPacket returns p as a two-part binary encoding of p. 85func (p *RemovePacket) MarshalPacket(reqid uint32, b []byte) (header, payload []byte, err error) { 86 buf := NewBuffer(b) 87 if buf.Cap() < 9 { 88 size := 4 + len(p.Path) // string(path) 89 buf = NewMarshalBuffer(size) 90 } 91 92 buf.StartPacket(PacketTypeRemove, reqid) 93 buf.AppendString(p.Path) 94 95 return buf.Packet(payload) 96} 97 98// UnmarshalPacketBody unmarshals the packet body from the given Buffer. 99// It is assumed that the uint32(request-id) has already been consumed. 100func (p *RemovePacket) UnmarshalPacketBody(buf *Buffer) (err error) { 101 if p.Path, err = buf.ConsumeString(); err != nil { 102 return err 103 } 104 105 return nil 106} 107 108// MkdirPacket defines the SSH_FXP_MKDIR packet. 109type MkdirPacket struct { 110 Path string 111 Attrs Attributes 112} 113 114// Type returns the SSH_FXP_xy value associated with this packet type. 115func (p *MkdirPacket) Type() PacketType { 116 return PacketTypeMkdir 117} 118 119// MarshalPacket returns p as a two-part binary encoding of p. 120func (p *MkdirPacket) MarshalPacket(reqid uint32, b []byte) (header, payload []byte, err error) { 121 buf := NewBuffer(b) 122 if buf.Cap() < 9 { 123 size := 4 + len(p.Path) + p.Attrs.Len() // string(path) + ATTRS(attrs) 124 buf = NewMarshalBuffer(size) 125 } 126 127 buf.StartPacket(PacketTypeMkdir, reqid) 128 buf.AppendString(p.Path) 129 130 p.Attrs.MarshalInto(buf) 131 132 return buf.Packet(payload) 133} 134 135// UnmarshalPacketBody unmarshals the packet body from the given Buffer. 136// It is assumed that the uint32(request-id) has already been consumed. 137func (p *MkdirPacket) UnmarshalPacketBody(buf *Buffer) (err error) { 138 if p.Path, err = buf.ConsumeString(); err != nil { 139 return err 140 } 141 142 return p.Attrs.UnmarshalFrom(buf) 143} 144 145// RmdirPacket defines the SSH_FXP_RMDIR packet. 146type RmdirPacket struct { 147 Path string 148} 149 150// Type returns the SSH_FXP_xy value associated with this packet type. 151func (p *RmdirPacket) Type() PacketType { 152 return PacketTypeRmdir 153} 154 155// MarshalPacket returns p as a two-part binary encoding of p. 156func (p *RmdirPacket) MarshalPacket(reqid uint32, b []byte) (header, payload []byte, err error) { 157 buf := NewBuffer(b) 158 if buf.Cap() < 9 { 159 size := 4 + len(p.Path) // string(path) 160 buf = NewMarshalBuffer(size) 161 } 162 163 buf.StartPacket(PacketTypeRmdir, reqid) 164 buf.AppendString(p.Path) 165 166 return buf.Packet(payload) 167} 168 169// UnmarshalPacketBody unmarshals the packet body from the given Buffer. 170// It is assumed that the uint32(request-id) has already been consumed. 171func (p *RmdirPacket) UnmarshalPacketBody(buf *Buffer) (err error) { 172 if p.Path, err = buf.ConsumeString(); err != nil { 173 return err 174 } 175 176 return nil 177} 178 179// RealPathPacket defines the SSH_FXP_REALPATH packet. 180type RealPathPacket struct { 181 Path string 182} 183 184// Type returns the SSH_FXP_xy value associated with this packet type. 185func (p *RealPathPacket) Type() PacketType { 186 return PacketTypeRealPath 187} 188 189// MarshalPacket returns p as a two-part binary encoding of p. 190func (p *RealPathPacket) MarshalPacket(reqid uint32, b []byte) (header, payload []byte, err error) { 191 buf := NewBuffer(b) 192 if buf.Cap() < 9 { 193 size := 4 + len(p.Path) // string(path) 194 buf = NewMarshalBuffer(size) 195 } 196 197 buf.StartPacket(PacketTypeRealPath, reqid) 198 buf.AppendString(p.Path) 199 200 return buf.Packet(payload) 201} 202 203// UnmarshalPacketBody unmarshals the packet body from the given Buffer. 204// It is assumed that the uint32(request-id) has already been consumed. 205func (p *RealPathPacket) UnmarshalPacketBody(buf *Buffer) (err error) { 206 if p.Path, err = buf.ConsumeString(); err != nil { 207 return err 208 } 209 210 return nil 211} 212 213// StatPacket defines the SSH_FXP_STAT packet. 214type StatPacket struct { 215 Path string 216} 217 218// Type returns the SSH_FXP_xy value associated with this packet type. 219func (p *StatPacket) Type() PacketType { 220 return PacketTypeStat 221} 222 223// MarshalPacket returns p as a two-part binary encoding of p. 224func (p *StatPacket) MarshalPacket(reqid uint32, b []byte) (header, payload []byte, err error) { 225 buf := NewBuffer(b) 226 if buf.Cap() < 9 { 227 size := 4 + len(p.Path) // string(path) 228 buf = NewMarshalBuffer(size) 229 } 230 231 buf.StartPacket(PacketTypeStat, reqid) 232 buf.AppendString(p.Path) 233 234 return buf.Packet(payload) 235} 236 237// UnmarshalPacketBody unmarshals the packet body from the given Buffer. 238// It is assumed that the uint32(request-id) has already been consumed. 239func (p *StatPacket) UnmarshalPacketBody(buf *Buffer) (err error) { 240 if p.Path, err = buf.ConsumeString(); err != nil { 241 return err 242 } 243 244 return nil 245} 246 247// RenamePacket defines the SSH_FXP_RENAME packet. 248type RenamePacket struct { 249 OldPath string 250 NewPath string 251} 252 253// Type returns the SSH_FXP_xy value associated with this packet type. 254func (p *RenamePacket) Type() PacketType { 255 return PacketTypeRename 256} 257 258// MarshalPacket returns p as a two-part binary encoding of p. 259func (p *RenamePacket) MarshalPacket(reqid uint32, b []byte) (header, payload []byte, err error) { 260 buf := NewBuffer(b) 261 if buf.Cap() < 9 { 262 // string(oldpath) + string(newpath) 263 size := 4 + len(p.OldPath) + 4 + len(p.NewPath) 264 buf = NewMarshalBuffer(size) 265 } 266 267 buf.StartPacket(PacketTypeRename, reqid) 268 buf.AppendString(p.OldPath) 269 buf.AppendString(p.NewPath) 270 271 return buf.Packet(payload) 272} 273 274// UnmarshalPacketBody unmarshals the packet body from the given Buffer. 275// It is assumed that the uint32(request-id) has already been consumed. 276func (p *RenamePacket) UnmarshalPacketBody(buf *Buffer) (err error) { 277 if p.OldPath, err = buf.ConsumeString(); err != nil { 278 return err 279 } 280 281 if p.NewPath, err = buf.ConsumeString(); err != nil { 282 return err 283 } 284 285 return nil 286} 287 288// ReadLinkPacket defines the SSH_FXP_READLINK packet. 289type ReadLinkPacket struct { 290 Path string 291} 292 293// Type returns the SSH_FXP_xy value associated with this packet type. 294func (p *ReadLinkPacket) Type() PacketType { 295 return PacketTypeReadLink 296} 297 298// MarshalPacket returns p as a two-part binary encoding of p. 299func (p *ReadLinkPacket) MarshalPacket(reqid uint32, b []byte) (header, payload []byte, err error) { 300 buf := NewBuffer(b) 301 if buf.Cap() < 9 { 302 size := 4 + len(p.Path) // string(path) 303 buf = NewMarshalBuffer(size) 304 } 305 306 buf.StartPacket(PacketTypeReadLink, reqid) 307 buf.AppendString(p.Path) 308 309 return buf.Packet(payload) 310} 311 312// UnmarshalPacketBody unmarshals the packet body from the given Buffer. 313// It is assumed that the uint32(request-id) has already been consumed. 314func (p *ReadLinkPacket) UnmarshalPacketBody(buf *Buffer) (err error) { 315 if p.Path, err = buf.ConsumeString(); err != nil { 316 return err 317 } 318 319 return nil 320} 321 322// SymlinkPacket defines the SSH_FXP_SYMLINK packet. 323// 324// The order of the arguments to the SSH_FXP_SYMLINK method was inadvertently reversed. 325// Unfortunately, the reversal was not noticed until the server was widely deployed. 326// Covered in Section 3.1 of https://github.com/openssh/openssh-portable/blob/master/PROTOCOL 327type SymlinkPacket struct { 328 LinkPath string 329 TargetPath string 330} 331 332// Type returns the SSH_FXP_xy value associated with this packet type. 333func (p *SymlinkPacket) Type() PacketType { 334 return PacketTypeSymlink 335} 336 337// MarshalPacket returns p as a two-part binary encoding of p. 338func (p *SymlinkPacket) MarshalPacket(reqid uint32, b []byte) (header, payload []byte, err error) { 339 buf := NewBuffer(b) 340 if buf.Cap() < 9 { 341 // string(targetpath) + string(linkpath) 342 size := 4 + len(p.TargetPath) + 4 + len(p.LinkPath) 343 buf = NewMarshalBuffer(size) 344 } 345 346 buf.StartPacket(PacketTypeSymlink, reqid) 347 348 // Arguments were inadvertently reversed. 349 buf.AppendString(p.TargetPath) 350 buf.AppendString(p.LinkPath) 351 352 return buf.Packet(payload) 353} 354 355// UnmarshalPacketBody unmarshals the packet body from the given Buffer. 356// It is assumed that the uint32(request-id) has already been consumed. 357func (p *SymlinkPacket) UnmarshalPacketBody(buf *Buffer) (err error) { 358 // Arguments were inadvertently reversed. 359 if p.TargetPath, err = buf.ConsumeString(); err != nil { 360 return err 361 } 362 363 if p.LinkPath, err = buf.ConsumeString(); err != nil { 364 return err 365 } 366 367 return nil 368} 369