Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
"net"
"net/http"

"github.com/introspection3/socks5"
"github.com/miekg/dns"
"github.com/txthinking/socks5"
)

func ExampleServer() {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module github.com/txthinking/socks5
module github.com/introspection3/txthinkingsocks5

go 1.16

Expand Down
65 changes: 35 additions & 30 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,20 @@ var (

// Server is socks5 server wrapper
type Server struct {
UserName string
Password string
Method byte
SupportedCommands []byte
Addr string
ServerAddr net.Addr
UDPConn *net.UDPConn
UDPExchanges *cache.Cache
TCPTimeout int
UDPTimeout int
Handle Handler
AssociatedUDP *cache.Cache
UDPSrc *cache.Cache
RunnerGroup *runnergroup.RunnerGroup
MethodUsernamePasswordEnabled bool
Accounts map[string]string
Method byte
SupportedCommands []byte
Addr string
ServerAddr net.Addr
UDPConn *net.UDPConn
UDPExchanges *cache.Cache
TCPTimeout int
UDPTimeout int
Handle Handler
AssociatedUDP *cache.Cache
UDPSrc *cache.Cache
RunnerGroup *runnergroup.RunnerGroup
// RFC: [UDP ASSOCIATE] The server MAY use this information to limit access to the association. Default false, no limit.
LimitUDP bool
}
Expand All @@ -48,7 +48,7 @@ type UDPExchange struct {
}

// NewClassicServer return a server which allow none method
func NewClassicServer(addr, ip, username, password string, tcpTimeout, udpTimeout int) (*Server, error) {
func NewClassicServer(addr, ip string, accounts map[string]string, tcpTimeout, udpTimeout int) (*Server, error) {
_, p, err := net.SplitHostPort(addr)
if err != nil {
return nil, err
Expand All @@ -58,25 +58,29 @@ func NewClassicServer(addr, ip, username, password string, tcpTimeout, udpTimeou
return nil, err
}
m := MethodNone
if username != "" && password != "" {
var methodUsernamePasswordEnabled = false
if len(accounts) > 0 {
m = MethodUsernamePassword
methodUsernamePasswordEnabled = true

}
cs := cache.New(cache.NoExpiration, cache.NoExpiration)
cs1 := cache.New(cache.NoExpiration, cache.NoExpiration)
cs2 := cache.New(cache.NoExpiration, cache.NoExpiration)

s := &Server{
Method: m,
UserName: username,
Password: password,
SupportedCommands: []byte{CmdConnect, CmdUDP},
Addr: addr,
ServerAddr: saddr,
UDPExchanges: cs,
TCPTimeout: tcpTimeout,
UDPTimeout: udpTimeout,
AssociatedUDP: cs1,
UDPSrc: cs2,
RunnerGroup: runnergroup.New(),
Method: m,
Accounts: accounts,
MethodUsernamePasswordEnabled: methodUsernamePasswordEnabled,
SupportedCommands: []byte{CmdConnect, CmdUDP},
Addr: addr,
ServerAddr: saddr,
UDPExchanges: cs,
TCPTimeout: tcpTimeout,
UDPTimeout: udpTimeout,
AssociatedUDP: cs1,
UDPSrc: cs2,
RunnerGroup: runnergroup.New(),
}
return s, nil
}
Expand Down Expand Up @@ -107,12 +111,13 @@ func (s *Server) Negotiate(rw io.ReadWriter) error {
return err
}

if s.Method == MethodUsernamePassword {
if s.MethodUsernamePasswordEnabled {
urq, err := NewUserPassNegotiationRequestFrom(rw)
if err != nil {
return err
}
if string(urq.Uname) != s.UserName || string(urq.Passwd) != s.Password {
v, exist := s.Accounts[string(urq.Uname)]
if !exist || string(urq.Passwd) != v {
urp := NewUserPassNegotiationReply(UserPassStatusFailure)
if _, err := urp.WriteTo(rw); err != nil {
return err
Expand Down