tls for socks5 is mandatory

This commit is contained in:
ginuerzh 2015-10-13 22:14:36 +08:00
parent f88eecbe37
commit ca9002b521
3 changed files with 54 additions and 75 deletions

68
conn.go
View File

@ -2,7 +2,6 @@ package main
import ( import (
"bufio" "bufio"
"bytes"
"crypto/tls" "crypto/tls"
"encoding/base64" "encoding/base64"
"errors" "errors"
@ -15,41 +14,22 @@ import (
"net/url" "net/url"
"strconv" "strconv"
"strings" "strings"
"sync/atomic"
) )
const ( var (
ConnHttp = "http" connCounter int32
ConnHttpConnect = "http-connect"
ConnSocks5 = "socks5"
) )
func listenAndServe(arg Args) error { func listenAndServe(arg Args) error {
var ln net.Listener var ln net.Listener
var err error 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 { switch arg.Transport {
case "ws": // websocket connection case "ws": // websocket connection
err = NewWs(arg).ListenAndServe() err = NewWs(arg).ListenAndServe()
if err != nil { if err != nil && glog.V(LFATAL) {
if glog.V(LFATAL) { glog.Errorln(err)
glog.Errorln(err)
}
} }
return err return err
case "tls": // tls connection case "tls": // tls connection
@ -78,9 +58,6 @@ func listenAndServe(arg Args) error {
} }
continue continue
} }
if glog.V(LINFO) {
glog.Infoln("accept", conn.RemoteAddr())
}
go handleConn(conn, arg) go handleConn(conn, arg)
} }
@ -88,20 +65,30 @@ func listenAndServe(arg Args) error {
} }
func handleConn(conn net.Conn, arg Args) { 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() defer conn.Close()
selector := &serverSelector{ selector := &serverSelector{
methods: []uint8{ methods: []uint8{
gosocks5.MethodNoAuth, gosocks5.MethodNoAuth,
gosocks5.MethodUserPass, gosocks5.MethodUserPass,
MethodTLS,
MethodTLSAuth,
}, },
arg: arg, arg: arg,
} }
if arg.EncMeth == "tls" {
selector.methods = append(selector.methods, MethodTLS, MethodTLSAuth)
}
switch arg.Protocol { switch arg.Protocol {
case "ss": // shadowsocks case "ss": // shadowsocks
return return
@ -109,7 +96,7 @@ func handleConn(conn net.Conn, arg Args) {
req, err := http.ReadRequest(bufio.NewReader(conn)) req, err := http.ReadRequest(bufio.NewReader(conn))
if err != nil { if err != nil {
if glog.V(LWARNING) { if glog.V(LWARNING) {
glog.Warningln(err) glog.Warningln("http:", err)
} }
return return
} }
@ -135,7 +122,7 @@ func handleConn(conn net.Conn, arg Args) {
n, err := io.ReadAtLeast(conn, b, 2) n, err := io.ReadAtLeast(conn, b, 2)
if err != nil { if err != nil {
if glog.V(LWARNING) { if glog.V(LWARNING) {
glog.Warningln(err) glog.Warningln("client:", err)
} }
return return
} }
@ -182,7 +169,7 @@ func handleConn(conn net.Conn, arg Args) {
req, err := http.ReadRequest(bufio.NewReader(newReqReader(b[:n], conn))) req, err := http.ReadRequest(bufio.NewReader(newReqReader(b[:n], conn)))
if err != nil { if err != nil {
if glog.V(LWARNING) { if glog.V(LWARNING) {
glog.Warningln(err) glog.Warningln("http:", err)
} }
return return
} }
@ -292,11 +279,12 @@ func forward(conn net.Conn, arg Args) (net.Conn, error) {
return nil, errors.New("Not implemented") return nil, errors.New("Not implemented")
case "socks", "socks5": case "socks", "socks5":
selector := &clientSelector{ selector := &clientSelector{
methods: []uint8{gosocks5.MethodNoAuth, gosocks5.MethodUserPass}, methods: []uint8{
arg: arg, gosocks5.MethodNoAuth,
} gosocks5.MethodUserPass,
if arg.EncMeth == "tls" { MethodTLS,
selector.methods = []uint8{MethodTLS, MethodTLSAuth} },
arg: arg,
} }
c := gosocks5.ClientConn(conn, selector) c := gosocks5.ClientConn(conn, selector)
if err := c.Handleshake(); err != nil { if err := c.Handleshake(); err != nil {

View File

@ -45,7 +45,7 @@ func (selector *clientSelector) OnSelected(method uint8, conn net.Conn) (net.Con
req := gosocks5.NewUserPassRequest(gosocks5.UserPassVer, username, password) req := gosocks5.NewUserPassRequest(gosocks5.UserPassVer, username, password)
if err := req.Write(conn); err != nil { if err := req.Write(conn); err != nil {
if glog.V(LWARNING) { if glog.V(LWARNING) {
glog.Warningln(err) glog.Warningln("socks5 auth:", err)
} }
return nil, err return nil, err
} }
@ -56,7 +56,7 @@ func (selector *clientSelector) OnSelected(method uint8, conn net.Conn) (net.Con
res, err := gosocks5.ReadUserPassResponse(conn) res, err := gosocks5.ReadUserPassResponse(conn)
if err != nil { if err != nil {
if glog.V(LWARNING) { if glog.V(LWARNING) {
glog.Warningln(err) glog.Warningln("socks5 auth:", err)
} }
return nil, 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) glog.Infof("%d %d % d", gosocks5.Ver5, len(methods), methods)
} }
method = gosocks5.MethodNoAcceptable method = gosocks5.MethodNoAuth
for _, m := range methods { for _, m := range methods {
for _, mm := range selector.methods { if m == MethodTLS {
if m == mm { method = m
method = m break
goto out
}
} }
} }
out:
if method == gosocks5.MethodNoAcceptable {
return
}
// when user/pass is set, auth is mandatory // when user/pass is set, auth is mandatory
if selector.arg.User != nil { if selector.arg.User != nil {
if method == gosocks5.MethodNoAuth { if method == gosocks5.MethodNoAuth {
@ -133,7 +126,7 @@ func (selector *serverSelector) OnSelected(method uint8, conn net.Conn) (net.Con
req, err := gosocks5.ReadUserPassRequest(conn) req, err := gosocks5.ReadUserPassRequest(conn)
if err != nil { if err != nil {
if glog.V(LWARNING) { if glog.V(LWARNING) {
glog.Warningln(err) glog.Warningln("socks5 auth:", err)
} }
return nil, 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) resp := gosocks5.NewUserPassResponse(gosocks5.UserPassVer, gosocks5.Failure)
if err := resp.Write(conn); err != nil { if err := resp.Write(conn); err != nil {
if glog.V(LWARNING) { if glog.V(LWARNING) {
glog.Warningln(err) glog.Warningln("socks5 auth:", err)
} }
return nil, err return nil, err
} }
if glog.V(LDEBUG) { if glog.V(LDEBUG) {
glog.Infoln(resp) glog.Infoln(resp)
} }
if glog.V(LWARNING) {
glog.Warningln("socks5: proxy authentication required")
}
return nil, gosocks5.ErrAuthFailure return nil, gosocks5.ErrAuthFailure
} }
resp := gosocks5.NewUserPassResponse(gosocks5.UserPassVer, gosocks5.Succeeded) resp := gosocks5.NewUserPassResponse(gosocks5.UserPassVer, gosocks5.Succeeded)
if err := resp.Write(conn); err != nil { if err := resp.Write(conn); err != nil {
if glog.V(LWARNING) { if glog.V(LWARNING) {
glog.Warningln(err) glog.Warningln("socks5 auth:", err)
} }
return nil, err return nil, err
} }
@ -231,11 +227,11 @@ func handleSocks5Request(req *gosocks5.Request, conn net.Conn, arg Args) {
glog.Warningln("socks5 connect:", err) glog.Warningln("socks5 connect:", err)
} }
return return
} else {
if glog.V(LDEBUG) {
glog.Infoln(rep)
}
} }
if glog.V(LDEBUG) {
glog.Infoln(rep)
}
Transport(conn, tconn) Transport(conn, tconn)
case gosocks5.CmdBind: case gosocks5.CmdBind:
l, err := net.ListenTCP("tcp", nil) l, err := net.ListenTCP("tcp", nil)
@ -268,10 +264,9 @@ func handleSocks5Request(req *gosocks5.Request, conn net.Conn, arg Args) {
} }
l.Close() l.Close()
return return
} else { }
if glog.V(LDEBUG) { if glog.V(LDEBUG) {
glog.Infoln(rep) glog.Infoln(rep)
}
} }
tconn, err := l.AcceptTCP() tconn, err := l.AcceptTCP()
@ -304,10 +299,9 @@ func handleSocks5Request(req *gosocks5.Request, conn net.Conn, arg Args) {
glog.Warningln("socks5 bind accept:", err) glog.Warningln("socks5 bind accept:", err)
} }
return return
} else { }
if glog.V(LDEBUG) { if glog.V(LDEBUG) {
glog.Infoln(rep) glog.Infoln(rep)
}
} }
if err := Transport(conn, tconn); err != nil { if err := Transport(conn, tconn); err != nil {

11
util.go
View File

@ -73,7 +73,7 @@ func parseArgs(ss []string) (args []Args) {
switch arg.Protocol { switch arg.Protocol {
case "http", "socks", "socks5", "ss": case "http", "socks", "socks5", "ss":
default: default:
arg.Protocol = "" arg.Protocol = "default"
} }
switch arg.Transport { switch arg.Transport {
case "ws", "tls", "tcp": case "ws", "tls", "tcp":
@ -90,12 +90,9 @@ func parseArgs(ss []string) (args []Args) {
arg.EncPass = mp[1] arg.EncPass = mp[1]
} }
if arg.Transport == "tls" || arg.EncMeth == "tls" { if arg.Cert, err = tls.LoadX509KeyPair("cert.pem", "key.pem"); err != nil {
arg.Cert, err = tls.LoadX509KeyPair("cert.pem", "key.pem") if glog.V(LFATAL) {
if err != nil { glog.Fatalln(err)
if glog.V(LFATAL) {
glog.Errorln(err)
}
} }
} }
args = append(args, arg) args = append(args, arg)