From ca9002b5213d5b77f879039d4a751baf7717e116 Mon Sep 17 00:00:00 2001 From: ginuerzh Date: Tue, 13 Oct 2015 22:14:36 +0800 Subject: [PATCH] tls for socks5 is mandatory --- conn.go | 68 +++++++++++++++++++++++--------------------------------- socks.go | 50 ++++++++++++++++++----------------------- util.go | 11 ++++----- 3 files changed, 54 insertions(+), 75 deletions(-) diff --git a/conn.go b/conn.go index 7eb4fd2..b807f6d 100644 --- a/conn.go +++ b/conn.go @@ -2,7 +2,6 @@ package main import ( "bufio" - "bytes" "crypto/tls" "encoding/base64" "errors" @@ -15,41 +14,22 @@ import ( "net/url" "strconv" "strings" + "sync/atomic" ) -const ( - ConnHttp = "http" - ConnHttpConnect = "http-connect" - ConnSocks5 = "socks5" +var ( + connCounter int32 ) func listenAndServe(arg Args) error { var ln net.Listener var err error - if glog.V(3) { - b := bytes.Buffer{} - b.WriteString("listen on %s, use %s tunnel and %s protocol for data transport. ") - if arg.EncMeth == "tls" { - b.WriteString("for socks5, tls encrypt method is supported.") - } else { - b.WriteString("for socks5, tls encrypt method is NOT supported.") - } - protocol := arg.Protocol - if protocol == "" { - protocol = "http/socks5" - } - glog.Infof(b.String(), arg.Addr, arg.Transport, protocol) - - } - switch arg.Transport { case "ws": // websocket connection err = NewWs(arg).ListenAndServe() - if err != nil { - if glog.V(LFATAL) { - glog.Errorln(err) - } + if err != nil && glog.V(LFATAL) { + glog.Errorln(err) } return err case "tls": // tls connection @@ -78,9 +58,6 @@ func listenAndServe(arg Args) error { } continue } - if glog.V(LINFO) { - glog.Infoln("accept", conn.RemoteAddr()) - } go handleConn(conn, arg) } @@ -88,20 +65,30 @@ func listenAndServe(arg Args) error { } func handleConn(conn net.Conn, arg Args) { + atomic.AddInt32(&connCounter, 1) + if glog.V(LINFO) { + glog.Infof("%s connected, connections: %d", + conn.RemoteAddr(), atomic.LoadInt32(&connCounter)) + } + if glog.V(LINFO) { + defer func() { + glog.Infof("%s disconnected, connections: %d", + conn.RemoteAddr(), atomic.LoadInt32(&connCounter)) + }() + } + defer atomic.AddInt32(&connCounter, -1) defer conn.Close() selector := &serverSelector{ methods: []uint8{ gosocks5.MethodNoAuth, gosocks5.MethodUserPass, + MethodTLS, + MethodTLSAuth, }, arg: arg, } - if arg.EncMeth == "tls" { - selector.methods = append(selector.methods, MethodTLS, MethodTLSAuth) - } - switch arg.Protocol { case "ss": // shadowsocks return @@ -109,7 +96,7 @@ func handleConn(conn net.Conn, arg Args) { req, err := http.ReadRequest(bufio.NewReader(conn)) if err != nil { if glog.V(LWARNING) { - glog.Warningln(err) + glog.Warningln("http:", err) } return } @@ -135,7 +122,7 @@ func handleConn(conn net.Conn, arg Args) { n, err := io.ReadAtLeast(conn, b, 2) if err != nil { if glog.V(LWARNING) { - glog.Warningln(err) + glog.Warningln("client:", err) } return } @@ -182,7 +169,7 @@ func handleConn(conn net.Conn, arg Args) { req, err := http.ReadRequest(bufio.NewReader(newReqReader(b[:n], conn))) if err != nil { if glog.V(LWARNING) { - glog.Warningln(err) + glog.Warningln("http:", err) } return } @@ -292,11 +279,12 @@ func forward(conn net.Conn, arg Args) (net.Conn, error) { return nil, errors.New("Not implemented") case "socks", "socks5": selector := &clientSelector{ - methods: []uint8{gosocks5.MethodNoAuth, gosocks5.MethodUserPass}, - arg: arg, - } - if arg.EncMeth == "tls" { - selector.methods = []uint8{MethodTLS, MethodTLSAuth} + methods: []uint8{ + gosocks5.MethodNoAuth, + gosocks5.MethodUserPass, + MethodTLS, + }, + arg: arg, } c := gosocks5.ClientConn(conn, selector) if err := c.Handleshake(); err != nil { diff --git a/socks.go b/socks.go index 3a23d44..1ed9f72 100644 --- a/socks.go +++ b/socks.go @@ -45,7 +45,7 @@ func (selector *clientSelector) OnSelected(method uint8, conn net.Conn) (net.Con req := gosocks5.NewUserPassRequest(gosocks5.UserPassVer, username, password) if err := req.Write(conn); err != nil { if glog.V(LWARNING) { - glog.Warningln(err) + glog.Warningln("socks5 auth:", err) } return nil, err } @@ -56,7 +56,7 @@ func (selector *clientSelector) OnSelected(method uint8, conn net.Conn) (net.Con res, err := gosocks5.ReadUserPassResponse(conn) if err != nil { if glog.V(LWARNING) { - glog.Warningln(err) + glog.Warningln("socks5 auth:", err) } return nil, err } @@ -88,21 +88,14 @@ func (selector *serverSelector) Select(methods ...uint8) (method uint8) { glog.Infof("%d %d % d", gosocks5.Ver5, len(methods), methods) } - method = gosocks5.MethodNoAcceptable - + method = gosocks5.MethodNoAuth for _, m := range methods { - for _, mm := range selector.methods { - if m == mm { - method = m - goto out - } + if m == MethodTLS { + method = m + break } } -out: - if method == gosocks5.MethodNoAcceptable { - return - } // when user/pass is set, auth is mandatory if selector.arg.User != nil { if method == gosocks5.MethodNoAuth { @@ -133,7 +126,7 @@ func (selector *serverSelector) OnSelected(method uint8, conn net.Conn) (net.Con req, err := gosocks5.ReadUserPassRequest(conn) if err != nil { if glog.V(LWARNING) { - glog.Warningln(err) + glog.Warningln("socks5 auth:", err) } return nil, err } @@ -151,20 +144,23 @@ func (selector *serverSelector) OnSelected(method uint8, conn net.Conn) (net.Con resp := gosocks5.NewUserPassResponse(gosocks5.UserPassVer, gosocks5.Failure) if err := resp.Write(conn); err != nil { if glog.V(LWARNING) { - glog.Warningln(err) + glog.Warningln("socks5 auth:", err) } return nil, err } if glog.V(LDEBUG) { glog.Infoln(resp) } + if glog.V(LWARNING) { + glog.Warningln("socks5: proxy authentication required") + } return nil, gosocks5.ErrAuthFailure } resp := gosocks5.NewUserPassResponse(gosocks5.UserPassVer, gosocks5.Succeeded) if err := resp.Write(conn); err != nil { if glog.V(LWARNING) { - glog.Warningln(err) + glog.Warningln("socks5 auth:", err) } return nil, err } @@ -231,11 +227,11 @@ func handleSocks5Request(req *gosocks5.Request, conn net.Conn, arg Args) { glog.Warningln("socks5 connect:", err) } return - } else { - if glog.V(LDEBUG) { - glog.Infoln(rep) - } } + if glog.V(LDEBUG) { + glog.Infoln(rep) + } + Transport(conn, tconn) case gosocks5.CmdBind: l, err := net.ListenTCP("tcp", nil) @@ -268,10 +264,9 @@ func handleSocks5Request(req *gosocks5.Request, conn net.Conn, arg Args) { } l.Close() return - } else { - if glog.V(LDEBUG) { - glog.Infoln(rep) - } + } + if glog.V(LDEBUG) { + glog.Infoln(rep) } tconn, err := l.AcceptTCP() @@ -304,10 +299,9 @@ func handleSocks5Request(req *gosocks5.Request, conn net.Conn, arg Args) { glog.Warningln("socks5 bind accept:", err) } return - } else { - if glog.V(LDEBUG) { - glog.Infoln(rep) - } + } + if glog.V(LDEBUG) { + glog.Infoln(rep) } if err := Transport(conn, tconn); err != nil { diff --git a/util.go b/util.go index 11566c4..d3bccfb 100644 --- a/util.go +++ b/util.go @@ -73,7 +73,7 @@ func parseArgs(ss []string) (args []Args) { switch arg.Protocol { case "http", "socks", "socks5", "ss": default: - arg.Protocol = "" + arg.Protocol = "default" } switch arg.Transport { case "ws", "tls", "tcp": @@ -90,12 +90,9 @@ func parseArgs(ss []string) (args []Args) { arg.EncPass = mp[1] } - if arg.Transport == "tls" || arg.EncMeth == "tls" { - arg.Cert, err = tls.LoadX509KeyPair("cert.pem", "key.pem") - if err != nil { - if glog.V(LFATAL) { - glog.Errorln(err) - } + if arg.Cert, err = tls.LoadX509KeyPair("cert.pem", "key.pem"); err != nil { + if glog.V(LFATAL) { + glog.Fatalln(err) } } args = append(args, arg)