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

64
conn.go
View File

@ -2,7 +2,6 @@ package main
import (
"bufio"
"bytes"
"crypto/tls"
"encoding/base64"
"errors"
@ -15,42 +14,23 @@ 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) {
if err != nil && glog.V(LFATAL) {
glog.Errorln(err)
}
}
return err
case "tls": // tls connection
ln, err = tls.Listen("tcp", arg.Addr,
@ -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,12 +279,13 @@ 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},
methods: []uint8{
gosocks5.MethodNoAuth,
gosocks5.MethodUserPass,
MethodTLS,
},
arg: arg,
}
if arg.EncMeth == "tls" {
selector.methods = []uint8{MethodTLS, MethodTLSAuth}
}
c := gosocks5.ClientConn(conn, selector)
if err := c.Handleshake(); err != nil {
return nil, err

View File

@ -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 {
if m == MethodTLS {
method = m
goto out
}
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)
}
}
Transport(conn, tconn)
case gosocks5.CmdBind:
l, err := net.ListenTCP("tcp", nil)
@ -268,11 +264,10 @@ func handleSocks5Request(req *gosocks5.Request, conn net.Conn, arg Args) {
}
l.Close()
return
} else {
}
if glog.V(LDEBUG) {
glog.Infoln(rep)
}
}
tconn, err := l.AcceptTCP()
l.Close() // only accept one peer
@ -304,11 +299,10 @@ 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 err := Transport(conn, tconn); err != nil {
//log.Println(err)

View File

@ -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 arg.Cert, err = tls.LoadX509KeyPair("cert.pem", "key.pem"); err != nil {
if glog.V(LFATAL) {
glog.Errorln(err)
}
glog.Fatalln(err)
}
}
args = append(args, arg)