msg_file_tree_connect.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. package smb
  2. import (
  3. "errors"
  4. "fmt"
  5. "strings"
  6. "imuslab.com/smb/driver/mod/smb/encoder"
  7. )
  8. func init() {
  9. commandRequestMap[CommandTreeConnect] = func() DataI {
  10. return &TreeConnectRequest{}
  11. }
  12. }
  13. // TreeConnect
  14. type TreeConnectRequest struct {
  15. Header
  16. StructureSize uint16
  17. TreeFlags uint16 //Flags/Reserved
  18. PathOffset uint16 `smb:"offset:Path"`
  19. PathLength uint16 `smb:"len:Path"`
  20. Path []byte
  21. }
  22. type request_TreeConnect_Extension struct {
  23. TreeConnectContextOffset uint32 `smb:"offset:TreeConnectContext"`
  24. TreeConnectContextCount uint16 `smb:"len:TreeConnectContext"`
  25. Reserved []byte `smb:"fixed:10"`
  26. PathNameOffset uint16 `smb:"offset:PathName"`
  27. PathNameLength uint16 `smb:"len:PathName"`
  28. TreeConnectContextsOffset uint16 `smb:"offset:TreeConnectContexts"`
  29. TreeConnectContextsLength uint16 `smb:"len:TreeConnectContexts"`
  30. TreeConnectContext []byte
  31. PathName []byte
  32. TreeConnectContexts *requset_TREE_CONNECT_CONTEXT
  33. }
  34. type requset_TREE_CONNECT_CONTEXT struct {
  35. ContextType uint16
  36. DataLength uint16
  37. Reserved uint32
  38. Data []byte
  39. }
  40. type AccessMask uint32
  41. const (
  42. //2.2.13.1.1
  43. FILE_READ_DATA AccessMask = 0x00000001
  44. FILE_WRITE_DATA AccessMask = 0x00000002
  45. FILE_APPEND_DATA AccessMask = 0x00000004
  46. FILE_READ_EA AccessMask = 0x00000008
  47. FILE_WRITE_EA AccessMask = 0x00000010
  48. FILE_DELETE_CHILD AccessMask = 0x00000040
  49. FILE_EXECUTE AccessMask = 0x00000020
  50. FILE_READ_ATTRIBUTES AccessMask = 0x00000080
  51. FILE_WRITE_ATTRIBUTES AccessMask = 0x00000100
  52. DELETE AccessMask = 0x00010000
  53. READ_CONTROL AccessMask = 0x00020000
  54. WRITE_DAC AccessMask = 0x00040000
  55. WRITE_OWNER AccessMask = 0x00080000
  56. SYNCHRONIZE AccessMask = 0x00100000
  57. ACCESS_SYSTEM_SECURITY AccessMask = 0x01000000
  58. MAXIMUM_ALLOWED AccessMask = 0x02000000
  59. GENERIC_ALL AccessMask = 0x10000000
  60. GENERIC_EXECUTE AccessMask = 0x20000000
  61. GENERIC_WRITE AccessMask = 0x40000000
  62. GENERIC_READ AccessMask = 0x80000000
  63. )
  64. var AllAccessMask = (FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_READ_EA |
  65. FILE_WRITE_EA | FILE_DELETE_CHILD | FILE_EXECUTE | FILE_READ_ATTRIBUTES |
  66. FILE_WRITE_ATTRIBUTES |
  67. DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER |
  68. SYNCHRONIZE)
  69. var _ encoder.BinaryMarshallable = (AccessMask)(0)
  70. func (c AccessMask) MarshalBinary(meta *encoder.Metadata) ([]byte, error) {
  71. return MarshalBinary(c, meta, c)
  72. }
  73. func (c AccessMask) UnmarshalBinary(data []byte, meta *encoder.Metadata) (interface{}, error) {
  74. return UnmarshalBinary(c, data, meta, c)
  75. }
  76. type TreeConnectResponse struct {
  77. Header
  78. StructureSize uint16
  79. ShareType uint8
  80. Reserved byte
  81. ShareFlags uint32 //cache policy
  82. Capabilities uint32
  83. Access_Mask AccessMask //MaximalAccess
  84. }
  85. const (
  86. SMB2_TREE_CONNECT_FLAG_CLUSTER_RECONNECT uint16 = 1 << iota
  87. SMB2_TREE_CONNECT_FLAG_REDIRECT_TO_OWNER
  88. SMB2_TREE_CONNECT_FLAG_EXTENSION_PRESENT
  89. )
  90. // var treeId uint32 = 0
  91. var NamedPipeShareName = "IPC$"
  92. func (data *TreeConnectRequest) ServerAction(ctx *DataCtx) (interface{}, error) {
  93. data.Header.Flags = SMB2_FLAGS_RESPONSE
  94. if data.TreeFlags&SMB2_TREE_CONNECT_FLAG_EXTENSION_PRESENT == SMB2_TREE_CONNECT_FLAG_EXTENSION_PRESENT {
  95. fmt.Printf("SMB2_TREE_CONNECT_FLAG_EXTENSION_PRESENT")
  96. }
  97. path, err := encoder.FromUnicode(data.Path)
  98. if err != nil {
  99. return nil, err
  100. }
  101. if true {
  102. if path[0] != '\\' || path[1] != '\\' {
  103. panic(fmt.Errorf("invalid sdsdfsf '%s'", path))
  104. }
  105. path = path[2:]
  106. inx := strings.IndexByte(path, '\\')
  107. if inx < 0 {
  108. panic(fmt.Errorf("invalid sdsdfsf43"))
  109. }
  110. path = path[inx+1:]
  111. fmt.Printf("path: %v", path)
  112. }
  113. path = strings.ToUpper(path)
  114. fmt.Printf("path: %v", path)
  115. // tid := atomic.AddUint32(&ctx.s.treeId, 1)
  116. // tree := CreateTree(tid, path, "./")
  117. // ctx.s.addTrees([]*Tree{tree})
  118. SMB2_SHARE_TYPE_DISK := uint8(1)
  119. SMB2_SHARE_TYPE_PIPE := uint8(2)
  120. SMB2_SHAREFLAG_NO_CACHING := uint32(0x00000030)
  121. SMB2_SHAREFLAG_ACCESS_BASED_DIRECTORY_ENUM := uint32(0x00000800)
  122. Access_Mask := (FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_READ_EA |
  123. FILE_WRITE_EA | FILE_DELETE_CHILD | FILE_EXECUTE | FILE_READ_ATTRIBUTES |
  124. FILE_WRITE_ATTRIBUTES |
  125. DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER |
  126. SYNCHRONIZE | ACCESS_SYSTEM_SECURITY)
  127. ShareType := SMB2_SHARE_TYPE_DISK
  128. ShareFlags := SMB2_SHAREFLAG_NO_CACHING | SMB2_SHAREFLAG_ACCESS_BASED_DIRECTORY_ENUM
  129. if path == NamedPipeShareName {
  130. ShareFlags = SMB2_SHAREFLAG_NO_CACHING
  131. ShareType = SMB2_SHARE_TYPE_PIPE
  132. }
  133. anchor := ctx.session.GetAnchor(path)
  134. if anchor == nil {
  135. return ERR(data.Header, STATUS_NETWORK_NAME_DELETED)
  136. }
  137. data.Header.TreeID = anchor.tid
  138. data.Header.Status = StatusOk
  139. ctx.session.SetActiveAnchorKey(path)
  140. resp := TreeConnectResponse{
  141. Header: data.Header,
  142. StructureSize: 0x0010,
  143. ShareType: ShareType,
  144. ShareFlags: ShareFlags,
  145. Access_Mask: Access_Mask,
  146. }
  147. resp.Header.Status = StatusOk
  148. resp.Header.Signature = make([]byte, 16)
  149. resp.Header.Credits = 33
  150. return &resp, nil
  151. }
  152. func (requestSetUp2 *TreeConnectRequest) ClientAction(s *SessionC, negRes *TreeConnectResponse) error {
  153. return nil
  154. }
  155. func NewTreeConnectReq(s *SessionC, name string) (TreeConnectRequest, error) {
  156. header := s.newHeader(CommandTreeConnect)
  157. path := fmt.Sprintf("\\\\%s\\%s", s.options.Host, name)
  158. return TreeConnectRequest{
  159. Header: header,
  160. StructureSize: 9,
  161. TreeFlags: 0,
  162. PathOffset: 0,
  163. PathLength: 0,
  164. Path: encoder.ToUnicode(path),
  165. }, nil
  166. }
  167. func NewTreeConnectRes() (TreeConnectResponse, error) {
  168. return TreeConnectResponse{}, nil
  169. }
  170. func (s *SessionC) TreeConnect(name string) error {
  171. s.Debug("Sending TreeConnect request ["+name+"]", nil)
  172. req, err := NewTreeConnectReq(s, name)
  173. var res TreeConnectResponse
  174. if err = s.RPC(req, &res); err != nil {
  175. return err
  176. }
  177. if res.Header.Status != StatusOk {
  178. return errors.New("Failed to connect to tree: " + StatusMap[res.Header.Status])
  179. }
  180. s.trees[name] = res.Header.TreeID
  181. s.Debug("Completed TreeConnect ["+name+"]", nil)
  182. return nil
  183. }