revive inspect

This commit is contained in:
mo 2020-04-22 10:32:03 +08:00
parent f77e659826
commit e32bb8ac76
10 changed files with 98 additions and 49 deletions

@ -48,7 +48,7 @@ func (a NoAuthAuthenticator) GetCode() uint8 {
} }
// Authenticate implement interface Authenticator // Authenticate implement interface Authenticator
func (a NoAuthAuthenticator) Authenticate(reader io.Reader, writer io.Writer, userAddr string) (*AuthContext, error) { func (a NoAuthAuthenticator) Authenticate(_ io.Reader, writer io.Writer, _ string) (*AuthContext, error) {
_, err := writer.Write([]byte{VersionSocks5, MethodNoAuth}) _, err := writer.Write([]byte{VersionSocks5, MethodNoAuth})
return &AuthContext{MethodNoAuth, nil}, err return &AuthContext{MethodNoAuth, nil}, err
} }

@ -3,14 +3,14 @@ package socks5
// CredentialStore is used to support user/pass authentication optional network addr // CredentialStore is used to support user/pass authentication optional network addr
// if you want to limit user network addr,you can refuse it. // if you want to limit user network addr,you can refuse it.
type CredentialStore interface { type CredentialStore interface {
Valid(user, password, userIP string) bool Valid(user, password, userAddr string) bool
} }
// StaticCredentials enables using a map directly as a credential store // StaticCredentials enables using a map directly as a credential store
type StaticCredentials map[string]string type StaticCredentials map[string]string
// Valid implement interface CredentialStore // Valid implement interface CredentialStore
func (s StaticCredentials) Valid(user, password, userAddr string) bool { func (s StaticCredentials) Valid(user, password, _ string) bool {
pass, ok := s[user] pass, ok := s[user]
if !ok { if !ok {
return false return false

1
go.sum

@ -2,5 +2,6 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

@ -1,7 +1,6 @@
package socks5 package socks5
import ( import (
"bytes"
"fmt" "fmt"
"io" "io"
"net" "net"
@ -25,26 +24,25 @@ const (
// reply status // reply status
const ( const (
successReply uint8 = iota RepSuccess uint8 = iota
serverFailure RepServerFailure
ruleFailure RepRuleFailure
networkUnreachable RepNetworkUnreachable
hostUnreachable RepHostUnreachable
connectionRefused RepConnectionRefused
ttlExpired RepTTLExpired
commandNotSupported RepCommandNotSupported
addrTypeNotSupported RepAddrTypeNotSupported
// 0x09 - 0xff unassigned // 0x09 - 0xff unassigned
) )
// head len defined // head len defined
const ( const (
headVERLen = 1 headVERLen = 1
headCMDLen = 1 headCMDLen = 1
headRSVLen = 1 headRSVLen = 1
headATYPLen = 1 headATYPLen = 1
headPORTLen = 2 headPORTLen = 2
headDomainAddrLen = 1
) )
// AddrSpec is used to return the target AddrSpec // AddrSpec is used to return the target AddrSpec
@ -153,7 +151,6 @@ func Parse(r io.Reader) (hd Header, err error) {
// Bytes returns a slice of header // Bytes returns a slice of header
func (h Header) Bytes() (b []byte) { func (h Header) Bytes() (b []byte) {
bytes.Buffer{}.Bytes()
b = append(b, h.Version) b = append(b, h.Version)
b = append(b, h.Command) b = append(b, h.Command)
hiPort, loPort := breakPort(h.Address.Port) hiPort, loPort := breakPort(h.Address.Port)

@ -71,7 +71,7 @@ func (s *Server) handleRequest(write io.Writer, req *Request) error {
if dest.FQDN != "" { if dest.FQDN != "" {
_ctx, addr, err := s.resolver.Resolve(ctx, dest.FQDN) _ctx, addr, err := s.resolver.Resolve(ctx, dest.FQDN)
if err != nil { if err != nil {
if err := SendReply(write, req.Header, hostUnreachable); err != nil { if err := SendReply(write, req.Header, RepHostUnreachable); err != nil {
return fmt.Errorf("failed to send reply, %v", err) return fmt.Errorf("failed to send reply, %v", err)
} }
return fmt.Errorf("failed to resolve destination[%v], %v", dest.FQDN, err) return fmt.Errorf("failed to resolve destination[%v], %v", dest.FQDN, err)
@ -89,7 +89,7 @@ func (s *Server) handleRequest(write io.Writer, req *Request) error {
// Check if this is allowed // Check if this is allowed
_ctx, ok := s.rules.Allow(ctx, req) _ctx, ok := s.rules.Allow(ctx, req)
if !ok { if !ok {
if err := SendReply(write, req.Header, ruleFailure); err != nil { if err := SendReply(write, req.Header, RepRuleFailure); err != nil {
return fmt.Errorf("failed to send reply, %v", err) return fmt.Errorf("failed to send reply, %v", err)
} }
return fmt.Errorf("bind to %v blocked by rules", req.RawDestAddr) return fmt.Errorf("bind to %v blocked by rules", req.RawDestAddr)
@ -114,7 +114,7 @@ func (s *Server) handleRequest(write io.Writer, req *Request) error {
} }
return s.handleAssociate(ctx, write, req) return s.handleAssociate(ctx, write, req)
default: default:
if err := SendReply(write, req.Header, commandNotSupported); err != nil { if err := SendReply(write, req.Header, RepCommandNotSupported); err != nil {
return fmt.Errorf("failed to send reply, %v", err) return fmt.Errorf("failed to send reply, %v", err)
} }
return fmt.Errorf("unsupported command[%v]", req.Command) return fmt.Errorf("unsupported command[%v]", req.Command)
@ -133,11 +133,11 @@ func (s *Server) handleConnect(ctx context.Context, writer io.Writer, req *Reque
target, err := dial(ctx, "tcp", req.DestAddr.Address()) target, err := dial(ctx, "tcp", req.DestAddr.Address())
if err != nil { if err != nil {
msg := err.Error() msg := err.Error()
resp := hostUnreachable resp := RepHostUnreachable
if strings.Contains(msg, "refused") { if strings.Contains(msg, "refused") {
resp = connectionRefused resp = RepConnectionRefused
} else if strings.Contains(msg, "network is unreachable") { } else if strings.Contains(msg, "network is unreachable") {
resp = networkUnreachable resp = RepNetworkUnreachable
} }
if err := SendReply(writer, req.Header, resp); err != nil { if err := SendReply(writer, req.Header, resp); err != nil {
return fmt.Errorf("failed to send reply, %v", err) return fmt.Errorf("failed to send reply, %v", err)
@ -147,7 +147,7 @@ func (s *Server) handleConnect(ctx context.Context, writer io.Writer, req *Reque
defer target.Close() defer target.Close()
// Send success // Send success
if err := SendReply(writer, req.Header, successReply, target.LocalAddr()); err != nil { if err := SendReply(writer, req.Header, RepSuccess, target.LocalAddr()); err != nil {
return fmt.Errorf("failed to send reply, %v", err) return fmt.Errorf("failed to send reply, %v", err)
} }
@ -169,9 +169,9 @@ func (s *Server) handleConnect(ctx context.Context, writer io.Writer, req *Reque
} }
// handleBind is used to handle a connect command // handleBind is used to handle a connect command
func (s *Server) handleBind(ctx context.Context, writer io.Writer, req *Request) error { func (s *Server) handleBind(_ context.Context, writer io.Writer, req *Request) error {
// TODO: Support bind // TODO: Support bind
if err := SendReply(writer, req.Header, commandNotSupported); err != nil { if err := SendReply(writer, req.Header, RepCommandNotSupported); err != nil {
return fmt.Errorf("failed to send reply: %v", err) return fmt.Errorf("failed to send reply: %v", err)
} }
return nil return nil
@ -189,11 +189,11 @@ func (s *Server) handleAssociate(ctx context.Context, writer io.Writer, req *Req
target, err := dial(ctx, "udp", req.DestAddr.Address()) target, err := dial(ctx, "udp", req.DestAddr.Address())
if err != nil { if err != nil {
msg := err.Error() msg := err.Error()
resp := hostUnreachable resp := RepHostUnreachable
if strings.Contains(msg, "refused") { if strings.Contains(msg, "refused") {
resp = connectionRefused resp = RepConnectionRefused
} else if strings.Contains(msg, "network is unreachable") { } else if strings.Contains(msg, "network is unreachable") {
resp = networkUnreachable resp = RepNetworkUnreachable
} }
if err := SendReply(writer, req.Header, resp); err != nil { if err := SendReply(writer, req.Header, resp); err != nil {
return fmt.Errorf("failed to send reply, %v", err) return fmt.Errorf("failed to send reply, %v", err)
@ -204,7 +204,7 @@ func (s *Server) handleAssociate(ctx context.Context, writer io.Writer, req *Req
targetUDP, ok := target.(*net.UDPConn) targetUDP, ok := target.(*net.UDPConn)
if !ok { if !ok {
if err := SendReply(writer, req.Header, serverFailure); err != nil { if err := SendReply(writer, req.Header, RepServerFailure); err != nil {
return fmt.Errorf("failed to send reply, %v", err) return fmt.Errorf("failed to send reply, %v", err)
} }
return fmt.Errorf("dial udp invalid") return fmt.Errorf("dial udp invalid")
@ -212,7 +212,7 @@ func (s *Server) handleAssociate(ctx context.Context, writer io.Writer, req *Req
bindLn, err := net.ListenUDP("udp", nil) bindLn, err := net.ListenUDP("udp", nil)
if err != nil { if err != nil {
if err := SendReply(writer, req.Header, serverFailure); err != nil { if err := SendReply(writer, req.Header, RepServerFailure); err != nil {
return fmt.Errorf("failed to send reply, %v", err) return fmt.Errorf("failed to send reply, %v", err)
} }
return fmt.Errorf("listen udp failed, %v", err) return fmt.Errorf("listen udp failed, %v", err)
@ -221,7 +221,7 @@ func (s *Server) handleAssociate(ctx context.Context, writer io.Writer, req *Req
s.logger.Errorf("target addr %v, listen addr: %s", targetUDP.RemoteAddr(), bindLn.LocalAddr()) s.logger.Errorf("target addr %v, listen addr: %s", targetUDP.RemoteAddr(), bindLn.LocalAddr())
// send BND.ADDR and BND.PORT, client must // send BND.ADDR and BND.PORT, client must
if err = SendReply(writer, req.Header, successReply, bindLn.LocalAddr()); err != nil { if err = SendReply(writer, req.Header, RepSuccess, bindLn.LocalAddr()); err != nil {
return fmt.Errorf("failed to send reply, %v", err) return fmt.Errorf("failed to send reply, %v", err)
} }

@ -44,7 +44,7 @@ func TestRequest_Connect(t *testing.T) {
if !bytes.Equal(buf, []byte("ping")) { if !bytes.Equal(buf, []byte("ping")) {
t.Fatalf("bad: %v", buf) t.Fatalf("bad: %v", buf)
} }
conn.Write([]byte("pong")) _, _ = conn.Write([]byte("pong"))
}() }()
lAddr := l.Addr().(*net.TCPAddr) lAddr := l.Addr().(*net.TCPAddr)
@ -120,7 +120,7 @@ func TestRequest_Connect_RuleFail(t *testing.T) {
if !bytes.Equal(buf, []byte("ping")) { if !bytes.Equal(buf, []byte("ping")) {
t.Fatalf("bad: %v", buf) t.Fatalf("bad: %v", buf)
} }
conn.Write([]byte("pong")) _, _ = conn.Write([]byte("pong"))
}() }()
lAddr := l.Addr().(*net.TCPAddr) lAddr := l.Addr().(*net.TCPAddr)

4
revive.sh Executable file

@ -0,0 +1,4 @@
#!/usr/bin/env bash
revive -config revive.toml -formatter friendly ./...
golangci-lint run

44
revive.toml Normal file

@ -0,0 +1,44 @@
ignoreGeneratedHeader = false
severity = "error"
confidence = 0.8
errorCode = 0
warningCode = 0
[rule.blank-imports]
[rule.context-as-argument]
[rule.context-keys-type]
[rule.dot-imports]
[rule.error-return]
[rule.error-strings]
[rule.error-naming]
[rule.exported]
[rule.if-return]
[rule.increment-decrement]
[rule.var-naming]
[rule.var-declaration]
[rule.package-comments]
[rule.range]
[rule.time-naming]
[rule.unexported-return]
[rule.indent-error-flow]
[rule.errorf]
[rule.empty-block]
[rule.superfluous-else]
[rule.unused-parameter]
[rule.unreachable-code]
[rule.redefines-builtin-id]
[rule.receiver-naming]
# Currently this makes too much noise, but should add it in
# and perhaps ignore it in a few files
#[rule.confusing-naming]
# severity = "warning"
#[rule.confusing-results]
# severity = "warning"
#[rule.unused-parameter]
# severity = "warning"
#[rule.deep-exit]
# severity = "warning"
#[rule.flag-parameter]
# severity = "warning"

@ -101,7 +101,10 @@ func (s *Server) Serve(l net.Listener) error {
return err return err
} }
s.submit(func() { s.submit(func() {
s.ServeConn(conn) err := s.ServeConn(conn)
if err != nil {
s.logger.Errorf("server conn %v", err)
}
}) })
} }
} }
@ -137,7 +140,7 @@ func (s *Server) ServeConn(conn net.Conn) (err error) {
request, err := NewRequest(bufConn) request, err := NewRequest(bufConn)
if err != nil { if err != nil {
if err == errUnrecognizedAddrType { if err == errUnrecognizedAddrType {
if err := SendReply(conn, Header{Version: version[0]}, addrTypeNotSupported); err != nil { if err := SendReply(conn, Header{Version: version[0]}, RepAddrTypeNotSupported); err != nil {
return fmt.Errorf("failed to send reply, %v", err) return fmt.Errorf("failed to send reply, %v", err)
} }
} }

@ -33,7 +33,7 @@ func TestSOCKS5_Connect(t *testing.T) {
if !bytes.Equal(buf, []byte("ping")) { if !bytes.Equal(buf, []byte("ping")) {
t.Fatalf("bad: %v", buf) t.Fatalf("bad: %v", buf)
} }
conn.Write([]byte("pong")) _, _ = conn.Write([]byte("pong"))
}() }()
lAddr := l.Addr().(*net.TCPAddr) lAddr := l.Addr().(*net.TCPAddr)
@ -89,7 +89,7 @@ func TestSOCKS5_Connect(t *testing.T) {
} }
rspHead := Header{ rspHead := Header{
Version: VersionSocks5, Version: VersionSocks5,
Command: successReply, Command: RepSuccess,
Reserved: 0, Reserved: 0,
Address: AddrSpec{ Address: AddrSpec{
"", "",
@ -102,7 +102,7 @@ func TestSOCKS5_Connect(t *testing.T) {
expected = append(expected, []byte("pong")...) expected = append(expected, []byte("pong")...)
out := make([]byte, len(expected)) out := make([]byte, len(expected))
conn.SetDeadline(time.Now().Add(time.Second)) _ = conn.SetDeadline(time.Now().Add(time.Second))
if _, err := io.ReadFull(conn, out); err != nil { if _, err := io.ReadFull(conn, out); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -140,7 +140,7 @@ func TestSOCKS5_Associate(t *testing.T) {
if !bytes.Equal(buf[:n], []byte("ping")) { if !bytes.Equal(buf[:n], []byte("ping")) {
t.Fatalf("bad: %v", buf) t.Fatalf("bad: %v", buf)
} }
l.WriteTo([]byte("pong"), remote) _, _ = l.WriteTo([]byte("pong"), remote)
} }
}() }()
@ -190,7 +190,7 @@ func TestSOCKS5_Associate(t *testing.T) {
} }
out := make([]byte, len(expected)) out := make([]byte, len(expected))
conn.SetDeadline(time.Now().Add(time.Second)) _ = conn.SetDeadline(time.Now().Add(time.Second))
if _, err := io.ReadFull(conn, out); err != nil { if _, err := io.ReadFull(conn, out); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -203,7 +203,7 @@ func TestSOCKS5_Associate(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("bad response header: %v", err) t.Fatalf("bad response header: %v", err)
} }
if rspHead.Version != VersionSocks5 && rspHead.Command != successReply { if rspHead.Version != VersionSocks5 && rspHead.Command != RepSuccess {
t.Fatalf("parse success but bad header: %v", rspHead) t.Fatalf("parse success but bad header: %v", rspHead)
} }
@ -217,10 +217,10 @@ func TestSOCKS5_Associate(t *testing.T) {
t.Fatalf("bad dial: %v", err) t.Fatalf("bad dial: %v", err)
} }
// Send a ping // Send a ping
udpConn.Write(append([]byte{0, 0, 0, ATYPIPv4, 0, 0, 0, 0, 0, 0}, []byte("ping")...)) _, _ = udpConn.Write(append([]byte{0, 0, 0, ATYPIPv4, 0, 0, 0, 0, 0, 0}, []byte("ping")...))
response := make([]byte, 1024) response := make([]byte, 1024)
n, _, err := udpConn.ReadFrom(response) n, _, err := udpConn.ReadFrom(response)
if !bytes.Equal(response[n-4:n], []byte("pong")) { if err != nil || !bytes.Equal(response[n-4:n], []byte("pong")) {
t.Fatalf("bad udp read: %v", string(response[:n])) t.Fatalf("bad udp read: %v", string(response[:n]))
} }
time.Sleep(time.Second * 1) time.Sleep(time.Second * 1)
@ -278,10 +278,10 @@ func Test_SocksWithProxy(t *testing.T) {
} }
// Send a ping // Send a ping
conn.Write([]byte("ping")) _, _ = conn.Write([]byte("ping"))
out := make([]byte, 4) out := make([]byte, 4)
conn.SetDeadline(time.Now().Add(time.Second)) _ = conn.SetDeadline(time.Now().Add(time.Second))
if _, err := io.ReadFull(conn, out); err != nil { if _, err := io.ReadFull(conn, out); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }