tls for socks5 is mandatory
This commit is contained in:
parent
f88eecbe37
commit
ca9002b521
64
conn.go
64
conn.go
@ -2,7 +2,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"errors"
|
"errors"
|
||||||
@ -15,42 +14,23 @@ 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
|
||||||
ln, err = tls.Listen("tcp", arg.Addr,
|
ln, err = tls.Listen("tcp", arg.Addr,
|
||||||
@ -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,12 +279,13 @@ 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{
|
||||||
|
gosocks5.MethodNoAuth,
|
||||||
|
gosocks5.MethodUserPass,
|
||||||
|
MethodTLS,
|
||||||
|
},
|
||||||
arg: arg,
|
arg: arg,
|
||||||
}
|
}
|
||||||
if arg.EncMeth == "tls" {
|
|
||||||
selector.methods = []uint8{MethodTLS, MethodTLSAuth}
|
|
||||||
}
|
|
||||||
c := gosocks5.ClientConn(conn, selector)
|
c := gosocks5.ClientConn(conn, selector)
|
||||||
if err := c.Handleshake(); err != nil {
|
if err := c.Handleshake(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
36
socks.go
36
socks.go
@ -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
|
||||||
goto out
|
break
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
if glog.V(LDEBUG) {
|
||||||
glog.Infoln(rep)
|
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,11 +264,10 @@ 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()
|
||||||
l.Close() // only accept one peer
|
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)
|
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 {
|
||||||
//log.Println(err)
|
//log.Println(err)
|
||||||
|
9
util.go
9
util.go
@ -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 err != nil {
|
|
||||||
if glog.V(LFATAL) {
|
if glog.V(LFATAL) {
|
||||||
glog.Errorln(err)
|
glog.Fatalln(err)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
args = append(args, arg)
|
args = append(args, arg)
|
||||||
|
Loading…
Reference in New Issue
Block a user