| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- package smb
- import (
- "errors"
- "fmt"
- "strings"
- "imuslab.com/smb/driver/mod/smb/encoder"
- )
- func init() {
- commandRequestMap[CommandTreeConnect] = func() DataI {
- return &TreeConnectRequest{}
- }
- }
- // TreeConnect
- type TreeConnectRequest struct {
- Header
- StructureSize uint16
- TreeFlags uint16 //Flags/Reserved
- PathOffset uint16 `smb:"offset:Path"`
- PathLength uint16 `smb:"len:Path"`
- Path []byte
- }
- type request_TreeConnect_Extension struct {
- TreeConnectContextOffset uint32 `smb:"offset:TreeConnectContext"`
- TreeConnectContextCount uint16 `smb:"len:TreeConnectContext"`
- Reserved []byte `smb:"fixed:10"`
- PathNameOffset uint16 `smb:"offset:PathName"`
- PathNameLength uint16 `smb:"len:PathName"`
- TreeConnectContextsOffset uint16 `smb:"offset:TreeConnectContexts"`
- TreeConnectContextsLength uint16 `smb:"len:TreeConnectContexts"`
- TreeConnectContext []byte
- PathName []byte
- TreeConnectContexts *requset_TREE_CONNECT_CONTEXT
- }
- type requset_TREE_CONNECT_CONTEXT struct {
- ContextType uint16
- DataLength uint16
- Reserved uint32
- Data []byte
- }
- type AccessMask uint32
- const (
- //2.2.13.1.1
- FILE_READ_DATA AccessMask = 0x00000001
- FILE_WRITE_DATA AccessMask = 0x00000002
- FILE_APPEND_DATA AccessMask = 0x00000004
- FILE_READ_EA AccessMask = 0x00000008
- FILE_WRITE_EA AccessMask = 0x00000010
- FILE_DELETE_CHILD AccessMask = 0x00000040
- FILE_EXECUTE AccessMask = 0x00000020
- FILE_READ_ATTRIBUTES AccessMask = 0x00000080
- FILE_WRITE_ATTRIBUTES AccessMask = 0x00000100
- DELETE AccessMask = 0x00010000
- READ_CONTROL AccessMask = 0x00020000
- WRITE_DAC AccessMask = 0x00040000
- WRITE_OWNER AccessMask = 0x00080000
- SYNCHRONIZE AccessMask = 0x00100000
- ACCESS_SYSTEM_SECURITY AccessMask = 0x01000000
- MAXIMUM_ALLOWED AccessMask = 0x02000000
- GENERIC_ALL AccessMask = 0x10000000
- GENERIC_EXECUTE AccessMask = 0x20000000
- GENERIC_WRITE AccessMask = 0x40000000
- GENERIC_READ AccessMask = 0x80000000
- )
- var AllAccessMask = (FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_READ_EA |
- FILE_WRITE_EA | FILE_DELETE_CHILD | FILE_EXECUTE | FILE_READ_ATTRIBUTES |
- FILE_WRITE_ATTRIBUTES |
- DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER |
- SYNCHRONIZE)
- var _ encoder.BinaryMarshallable = (AccessMask)(0)
- func (c AccessMask) MarshalBinary(meta *encoder.Metadata) ([]byte, error) {
- return MarshalBinary(c, meta, c)
- }
- func (c AccessMask) UnmarshalBinary(data []byte, meta *encoder.Metadata) (interface{}, error) {
- return UnmarshalBinary(c, data, meta, c)
- }
- type TreeConnectResponse struct {
- Header
- StructureSize uint16
- ShareType uint8
- Reserved byte
- ShareFlags uint32 //cache policy
- Capabilities uint32
- Access_Mask AccessMask //MaximalAccess
- }
- const (
- SMB2_TREE_CONNECT_FLAG_CLUSTER_RECONNECT uint16 = 1 << iota
- SMB2_TREE_CONNECT_FLAG_REDIRECT_TO_OWNER
- SMB2_TREE_CONNECT_FLAG_EXTENSION_PRESENT
- )
- // var treeId uint32 = 0
- var NamedPipeShareName = "IPC$"
- func (data *TreeConnectRequest) ServerAction(ctx *DataCtx) (interface{}, error) {
- data.Header.Flags = SMB2_FLAGS_RESPONSE
- if data.TreeFlags&SMB2_TREE_CONNECT_FLAG_EXTENSION_PRESENT == SMB2_TREE_CONNECT_FLAG_EXTENSION_PRESENT {
- fmt.Printf("SMB2_TREE_CONNECT_FLAG_EXTENSION_PRESENT")
- }
- path, err := encoder.FromUnicode(data.Path)
- if err != nil {
- return nil, err
- }
- if true {
- if path[0] != '\\' || path[1] != '\\' {
- panic(fmt.Errorf("invalid sdsdfsf '%s'", path))
- }
- path = path[2:]
- inx := strings.IndexByte(path, '\\')
- if inx < 0 {
- panic(fmt.Errorf("invalid sdsdfsf43"))
- }
- path = path[inx+1:]
- fmt.Printf("path: %v", path)
- }
- path = strings.ToUpper(path)
- fmt.Printf("path: %v", path)
- // tid := atomic.AddUint32(&ctx.s.treeId, 1)
- // tree := CreateTree(tid, path, "./")
- // ctx.s.addTrees([]*Tree{tree})
- SMB2_SHARE_TYPE_DISK := uint8(1)
- SMB2_SHARE_TYPE_PIPE := uint8(2)
- SMB2_SHAREFLAG_NO_CACHING := uint32(0x00000030)
- SMB2_SHAREFLAG_ACCESS_BASED_DIRECTORY_ENUM := uint32(0x00000800)
- Access_Mask := (FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_READ_EA |
- FILE_WRITE_EA | FILE_DELETE_CHILD | FILE_EXECUTE | FILE_READ_ATTRIBUTES |
- FILE_WRITE_ATTRIBUTES |
- DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER |
- SYNCHRONIZE | ACCESS_SYSTEM_SECURITY)
- ShareType := SMB2_SHARE_TYPE_DISK
- ShareFlags := SMB2_SHAREFLAG_NO_CACHING | SMB2_SHAREFLAG_ACCESS_BASED_DIRECTORY_ENUM
- if path == NamedPipeShareName {
- ShareFlags = SMB2_SHAREFLAG_NO_CACHING
- ShareType = SMB2_SHARE_TYPE_PIPE
- }
- anchor := ctx.session.GetAnchor(path)
- if anchor == nil {
- return ERR(data.Header, STATUS_NETWORK_NAME_DELETED)
- }
- data.Header.TreeID = anchor.tid
- data.Header.Status = StatusOk
- ctx.session.SetActiveAnchorKey(path)
- resp := TreeConnectResponse{
- Header: data.Header,
- StructureSize: 0x0010,
- ShareType: ShareType,
- ShareFlags: ShareFlags,
- Access_Mask: Access_Mask,
- }
- resp.Header.Status = StatusOk
- resp.Header.Signature = make([]byte, 16)
- resp.Header.Credits = 33
- return &resp, nil
- }
- func (requestSetUp2 *TreeConnectRequest) ClientAction(s *SessionC, negRes *TreeConnectResponse) error {
- return nil
- }
- func NewTreeConnectReq(s *SessionC, name string) (TreeConnectRequest, error) {
- header := s.newHeader(CommandTreeConnect)
- path := fmt.Sprintf("\\\\%s\\%s", s.options.Host, name)
- return TreeConnectRequest{
- Header: header,
- StructureSize: 9,
- TreeFlags: 0,
- PathOffset: 0,
- PathLength: 0,
- Path: encoder.ToUnicode(path),
- }, nil
- }
- func NewTreeConnectRes() (TreeConnectResponse, error) {
- return TreeConnectResponse{}, nil
- }
- func (s *SessionC) TreeConnect(name string) error {
- s.Debug("Sending TreeConnect request ["+name+"]", nil)
- req, err := NewTreeConnectReq(s, name)
- var res TreeConnectResponse
- if err = s.RPC(req, &res); err != nil {
- return err
- }
- if res.Header.Status != StatusOk {
- return errors.New("Failed to connect to tree: " + StatusMap[res.Header.Status])
- }
- s.trees[name] = res.Header.TreeID
- s.Debug("Completed TreeConnect ["+name+"]", nil)
- return nil
- }
|