| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- package smb
- import (
- "bufio"
- "encoding/hex"
- "fmt"
- "net"
- "os"
- "runtime"
- "sync/atomic"
- "time"
- "github.com/izouxv/logx"
- "golang.org/x/net/webdav"
- )
- var treeIdX = uint32(0)
- func NewAnchor(name, rootpath string) *Anchor {
- return &Anchor{Name: name, RootPath: rootpath, tid: atomic.AddUint32(&treeId, 1)}
- }
- type Handler struct {
- *webdav.Handler
- // symlink WIP
- }
- type Anchor struct {
- Name string
- RootPath string
- tid uint32
- Handle *Handler
- }
- type GetPwdFunc func(name string) (password string, err error)
- type GetAnchorFun func(userName string) (anchors []*Anchor, err error)
- type Config struct {
- // Port int
- Pwd GetPwdFunc
- Tree GetAnchorFun
- Handle func(string) *Handler
- }
- type ServerI interface {
- Start(PORT int)
- }
- func NewServer(config *Config) ServerI {
- return &server{config: config, sessions: make(map[uint64]SessionS)}
- }
- type server struct {
- config *Config
- sessions map[uint64]SessionS
- }
- func (s *server) Start(PORT int) {
- // PORT := s.config.Port
- getPwd := s.config.Pwd
- getTree := s.config.Tree
- l, err := net.Listen("tcp", fmt.Sprintf(":%d", PORT))
- if err != nil {
- fmt.Println("Error listening:", err.Error())
- os.Exit(1)
- }
- // Close the listener when the application closes.
- defer l.Close()
- fmt.Printf("Listening on %v port\n", PORT)
- for {
- // Listen for an incoming connection.
- conn, err := l.Accept()
- if err != nil {
- fmt.Println("Error accepting: ", err.Error())
- os.Exit(1)
- }
- fmt.Printf("IP: %v", conn.RemoteAddr().String())
- // Handle connections in a new goroutine.
- go s.HandleConnection(conn, getPwd, getTree)
- }
- }
- func (s *server) HandleConnection(conn net.Conn, getPwd GetPwdFunc, getTree GetAnchorFun) {
- remoteAddr := conn.RemoteAddr()
- defer func() {
- if err := recover(); err != nil {
- b := make([]byte, 4000, 4000)
- n := runtime.Stack(b, false)
- fmt.Printf("%s\n", b[:n])
- fmt.Printf("Error(%v): %s\n\n", remoteAddr, err)
- }
- }()
- defer conn.Close()
- session := NewSessionServer(true, conn, getPwd, getTree)
- if err := session.NegotiateProtocolServer(); err != nil {
- logx.Infof("login failed, %v, err: %v", session.IsAuthenticated, err)
- // time.Sleep(time.Second)
- // conn.Close()
- return
- }
- if !session.IsAuthenticated {
- logx.Infof("login failed, %v", session.IsAuthenticated)
- time.Sleep(time.Second)
- conn.Close()
- return
- }
- logx.Infof("login suc, %v", session.IsAuthenticated)
- rw := bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn))
- for {
- reqMsg, _, err := session.Recv(rw)
- if err != nil {
- return
- }
- respBuf, cmd, stat := ActionFunc(NewDataCtx(session, conn, s.config.Handle), reqMsg)
- if stat != StatusOk {
- return
- }
- if false {
- fmt.Printf("\n\n\ncmd: %v req:\n%vresp:\n%v", cmd.String(), hex.Dump(reqMsg), hex.Dump(respBuf))
- }
- session.Send(respBuf, rw)
- }
- }
|