forked from hirochachacha/go-smb2
-
Notifications
You must be signed in to change notification settings - Fork 4
/
tree_conn.go
113 lines (91 loc) · 2.28 KB
/
tree_conn.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package smb2
import (
"context"
"fmt"
. "github.com/LeakIX/go-smb2/lib/smb2"
)
type treeConn struct {
*session
treeId uint32
shareFlags uint32
// path string
// shareType uint8
// capabilities uint32
// maximalAccess uint32
}
func treeConnect(s *session, path string, flags uint16, ctx context.Context) (*treeConn, error) {
req := &TreeConnectRequest{
Flags: flags,
Path: path,
}
req.CreditCharge = 1
rr, err := s.send(req, ctx)
if err != nil {
return nil, err
}
pkt, err := s.recv(rr)
if err != nil {
return nil, err
}
res, err := accept(SMB2_TREE_CONNECT, pkt)
if err != nil {
return nil, err
}
r := TreeConnectResponseDecoder(res)
if r.IsInvalid() {
return nil, &InvalidResponseError{"broken tree connect response format"}
}
tc := &treeConn{
session: s,
treeId: PacketCodec(pkt).TreeId(),
shareFlags: r.ShareFlags(),
// path: path,
// shareType: r.ShareType(),
// capabilities: r.Capabilities(),
// maximalAccess: r.MaximalAccess(),
}
return tc, nil
}
func (tc *treeConn) disconnect(ctx context.Context) error {
req := new(TreeDisconnectRequest)
req.CreditCharge = 1
res, err := tc.sendRecv(SMB2_TREE_DISCONNECT, req, ctx)
if err != nil {
return err
}
r := TreeDisconnectResponseDecoder(res)
if r.IsInvalid() {
return &InvalidResponseError{"broken tree disconnect response format"}
}
return nil
}
func (tc *treeConn) sendRecv(cmd uint16, req Packet, ctx context.Context) (res []byte, err error) {
rr, err := tc.send(req, ctx)
if err != nil {
return nil, err
}
pkt, err := tc.recv(rr)
if err != nil {
return nil, err
}
return accept(cmd, pkt)
}
func (tc *treeConn) send(req Packet, ctx context.Context) (rr *requestResponse, err error) {
return tc.sendWith(req, tc, ctx)
}
func (tc *treeConn) recv(rr *requestResponse) (pkt []byte, err error) {
pkt, err = tc.session.recv(rr)
if err != nil {
return nil, err
}
if rr.asyncId != 0 {
if asyncId := PacketCodec(pkt).AsyncId(); asyncId != rr.asyncId {
return nil, &InvalidResponseError{fmt.Sprintf("expected async id: %v, got %v", rr.asyncId, asyncId)}
}
} else {
if treeId := PacketCodec(pkt).TreeId(); treeId != tc.treeId {
return nil, &InvalidResponseError{fmt.Sprintf("expected tree id: %v, got %v", tc.treeId, treeId)}
}
}
return pkt, err
}