add tls
This commit is contained in:
parent
158125d41d
commit
c462a4df9d
18
cert.pem
Normal file
18
cert.pem
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIC5jCCAdCgAwIBAgIBADALBgkqhkiG9w0BAQUwEjEQMA4GA1UEChMHQWNtZSBD
|
||||||
|
bzAeFw0xNDAzMTcwNjIwNTFaFw0xNTAzMTcwNjIwNTFaMBIxEDAOBgNVBAoTB0Fj
|
||||||
|
bWUgQ28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDccNO1xmd4lWSf
|
||||||
|
d/0/QS3E93cYIWHw831i/IKxigdRD/XMZonLdEHywW6lOiXazaP8e6CqPGSmnl0x
|
||||||
|
5k/3dvGCMj2JCVxM6+z7NpL+AiwvXmvkj/TOciCgwqssCwYS2CiVwjfazRjx1ZUJ
|
||||||
|
VDC5qiyRsfktQ2fVHrpnJGVSRagmiQgwGWBilVG9B8QvRtpQKN/GQGq17oIQm8aK
|
||||||
|
kOdPt93g93ojMIg7YJpgDgOirvVz/hDn7YD4ryrtPos9CMafFkJprymKpRHyvz7P
|
||||||
|
8a3+OkuPjFjPnwOHQ5u1U3+8vC44vfb1ExWzDLoT8Xp8Gndx39k0f7MVOol3GnYu
|
||||||
|
MN/dvNUdAgMBAAGjSzBJMA4GA1UdDwEB/wQEAwIAoDATBgNVHSUEDDAKBggrBgEF
|
||||||
|
BQcDATAMBgNVHRMBAf8EAjAAMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDALBgkqhkiG
|
||||||
|
9w0BAQUDggEBAIG8CJqvTIgJnNOK+i5/IUc/3yF/mSCWuG8qP+Fmo2t6T0PVOtc0
|
||||||
|
8wiWH5iWtCAhjn0MRY9l/hIjWm6gUZGHCGuEgsOPpJDYGoNLjH9Xwokm4y3LFNRK
|
||||||
|
UBrrrDbKRNibApBHCapPf6gC5sXcjOwx7P2/kiHDgY7YH47jfcRhtAPNsM4gjsEO
|
||||||
|
RmwENY+hRUFHIRfQTyalqND+x6PWhRo3K6hpHs4DQEYPq4P2kFPqUqSBymH+Ny5/
|
||||||
|
BcQ3wdMNmC6Bm/oiL1QV0M+/InOsAgQk/EDd0kmoU1ZT2lYHQduGmP099bOlHNpS
|
||||||
|
uqO3vXF3q8SPPr/A9TqSs7BKkBQbe0+cdsA=
|
||||||
|
-----END CERTIFICATE-----
|
33
client.go
33
client.go
@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"crypto/tls"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/ginuerzh/gosocks5"
|
"github.com/ginuerzh/gosocks5"
|
||||||
@ -45,7 +46,7 @@ func handshake(conn net.Conn, methods ...uint8) (method uint8, err error) {
|
|||||||
nm = 1
|
nm = 1
|
||||||
}
|
}
|
||||||
b := make([]byte, 2+nm)
|
b := make([]byte, 2+nm)
|
||||||
b[0] = Ver5
|
b[0] = gosocks5.Ver5
|
||||||
b[1] = uint8(nm)
|
b[1] = uint8(nm)
|
||||||
copy(b[2:], methods)
|
copy(b[2:], methods)
|
||||||
|
|
||||||
@ -57,7 +58,7 @@ func handshake(conn net.Conn, methods ...uint8) (method uint8, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if b[0] != Ver5 {
|
if b[0] != gosocks5.Ver5 {
|
||||||
err = gosocks5.ErrBadVersion
|
err = gosocks5.ErrBadVersion
|
||||||
}
|
}
|
||||||
method = b[1]
|
method = b[1]
|
||||||
@ -74,17 +75,31 @@ func cliHandle(conn net.Conn) {
|
|||||||
}
|
}
|
||||||
defer sconn.Close()
|
defer sconn.Close()
|
||||||
|
|
||||||
method, err := handshake(sconn, MethodAES256, gosocks5.MethodNoAuth)
|
method := gosocks5.MethodNoAuth
|
||||||
if err != nil || method == gosocks5.MethodNoAcceptable {
|
for m, v := range Methods {
|
||||||
|
if Method == v {
|
||||||
|
method = m
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
method, err = handshake(sconn, method)
|
||||||
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if method == MethodAES256 {
|
|
||||||
cipher, _ := shadowsocks.NewCipher(Cipher, Password)
|
switch method {
|
||||||
|
case MethodTLS:
|
||||||
|
sconn = tls.Client(sconn, &tls.Config{InsecureSkipVerify: true})
|
||||||
|
case MethodAES128, MethodAES192, MethodAES256,
|
||||||
|
MethodDES, MethodBF, MethodCAST5, MethodRC4MD5, MethodRC4, MethodTable:
|
||||||
|
cipher, _ := shadowsocks.NewCipher(Methods[method], Password)
|
||||||
sconn = shadowsocks.NewConn(sconn, cipher)
|
sconn = shadowsocks.NewConn(sconn, cipher)
|
||||||
|
case gosocks5.MethodNoAcceptable:
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if Shadows {
|
if Shadows {
|
||||||
cipher, _ := shadowsocks.NewCipher(Cipher, Password)
|
cipher, _ := shadowsocks.NewCipher(SMethod, SPassword)
|
||||||
conn = shadowsocks.NewConn(conn, cipher)
|
conn = shadowsocks.NewConn(conn, cipher)
|
||||||
handleShadow(conn, sconn)
|
handleShadow(conn, sconn)
|
||||||
return
|
return
|
||||||
@ -157,7 +172,7 @@ func handleSocks5(conn net.Conn, sconn net.Conn) {
|
|||||||
uconn, err := net.ListenUDP("udp", nil)
|
uconn, err := net.ListenUDP("udp", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
gosocks5.NewReply(Failure, nil).Write(conn)
|
gosocks5.NewReply(gosocks5.Failure, nil).Write(conn)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer uconn.Close()
|
defer uconn.Close()
|
||||||
@ -166,7 +181,7 @@ func handleSocks5(conn net.Conn, sconn net.Conn) {
|
|||||||
addr.Host, _, _ = net.SplitHostPort(conn.LocalAddr().String())
|
addr.Host, _, _ = net.SplitHostPort(conn.LocalAddr().String())
|
||||||
//log.Println("udp:", addr)
|
//log.Println("udp:", addr)
|
||||||
|
|
||||||
rep = gosocks5.NewReply(Succeeded, addr)
|
rep = gosocks5.NewReply(gosocks5.Succeeded, addr)
|
||||||
if err := rep.Write(conn); err != nil {
|
if err := rep.Write(conn); err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return
|
return
|
||||||
|
27
key.pem
Normal file
27
key.pem
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEowIBAAKCAQEA3HDTtcZneJVkn3f9P0EtxPd3GCFh8PN9YvyCsYoHUQ/1zGaJ
|
||||||
|
y3RB8sFupTol2s2j/Hugqjxkpp5dMeZP93bxgjI9iQlcTOvs+zaS/gIsL15r5I/0
|
||||||
|
znIgoMKrLAsGEtgolcI32s0Y8dWVCVQwuaoskbH5LUNn1R66ZyRlUkWoJokIMBlg
|
||||||
|
YpVRvQfEL0baUCjfxkBqte6CEJvGipDnT7fd4Pd6IzCIO2CaYA4Doq71c/4Q5+2A
|
||||||
|
+K8q7T6LPQjGnxZCaa8piqUR8r8+z/Gt/jpLj4xYz58Dh0ObtVN/vLwuOL329RMV
|
||||||
|
swy6E/F6fBp3cd/ZNH+zFTqJdxp2LjDf3bzVHQIDAQABAoIBAHal26147nQ+pHwY
|
||||||
|
jxwers3XDCjWvup7g79lfcqlKi79UiUEA6KYHm7UogMYewt7p4nb2KwH+XycvDiB
|
||||||
|
aAUf5flXpTs+6IkWauUDiLZi4PlV7uiEexUq5FjirlL0U/6MjbudX4bK4WQ4uxDc
|
||||||
|
WaV07Kw2iJFOOHLDKT0en9JaX5jtJNc4ZnE9efFoQ5jfypPWtRw65G1rULEg6nvc
|
||||||
|
GDh+1ce+4foCkpLRC9c24xAwJONZG6x3UqrSS9qfAsb73nWRQrTfUcO3nhoN8VvL
|
||||||
|
kL9skn1+S06NyUN0KoEtyRBp+RcpXSsBWAo6qZmo/WqhB/gjzWrxVwn20+yJSm35
|
||||||
|
ZsMc6QECgYEA8GS+Mp9xfB2szWHz6YTOO1Uu4lHM1ccZMwS1G+dL0KO3uGAiPdvp
|
||||||
|
woVot6v6w88t7onXsLo5pgz7SYug0CpkF3K/MRd1Ar4lH7PK7IBQ6rFr9ppVxDbx
|
||||||
|
AEWRswUoPbKCr7W6HU8LbQHDavsDlEIwc6+DiwnL4BzlKjb7RpgQEz0CgYEA6sB5
|
||||||
|
uHvx3Y5FDcGk1n73leQSAcq14l3ZLNpjrs8msoREDil/j5WmuSN58/7PGMiMgHEi
|
||||||
|
1vLm3H796JmvGr9OBvspOjHyk07ui2/We/j9Hoxm1VWhyi8HkLNDj70HKalTTFMz
|
||||||
|
RHO4O+0xCva+h9mKZrRMVktXr2jjdFn/0MYIZ2ECgYAIIsC1IeRLWQ3CHbCNlKsO
|
||||||
|
IwHlMvOFwKk/qsceXKOaOhA7szU1dr3gkXdL0Aw6mEZrrkqYdpUA46uVf54/rU+Z
|
||||||
|
445I8QxKvXiwK/uQKX+TkdGflPWWIG3jnnch4ejMvb/ihnn4B/bRB6A/fKNQXzUY
|
||||||
|
lTYUfI5j1VaEKTwz1W2l2QKBgByFCcSp+jZqhGUpc3dDsZyaOr3Q/Mvlju7uEVI5
|
||||||
|
hIAHpaT60a6GBd1UPAqymEJwivFHzW3D0NxU6VAK68UaHMaoWNfjHY9b9YsnKS2i
|
||||||
|
kE3XzN56Ks+/avHfdYPO+UHMenw5V28nh+hv5pdoZrlmanQTz3pkaOC8o3WNQZEB
|
||||||
|
nh/BAoGBAMY5z2f1pmMhrvtPDSlEVjgjELbaInxFaxPLR4Pdyzn83gtIIU14+R8X
|
||||||
|
2LPs6PPwrNjWnIgrUSVXncIFL3pa45B+Mx1pYCpOAB1+nCZjIBQmpeo4Y0dwA/XH
|
||||||
|
85EthKPvoszm+OPbyI16OcePV5ocX7lupRYuAo0pek7bomhmHWHz
|
||||||
|
-----END RSA PRIVATE KEY-----
|
20
main.go
20
main.go
@ -10,17 +10,22 @@ import (
|
|||||||
var (
|
var (
|
||||||
Laddr, Saddr, Proxy string
|
Laddr, Saddr, Proxy string
|
||||||
Shadows bool
|
Shadows bool
|
||||||
Cipher, Password string
|
SMethod, SPassword string
|
||||||
|
Method, Password string
|
||||||
|
CertFile, KeyFile string
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
flag.StringVar(&Proxy, "P", "", "proxy for forward")
|
flag.StringVar(&Proxy, "P", "", "proxy for forward")
|
||||||
flag.StringVar(&Saddr, "S", "", "the server that connecting to")
|
flag.StringVar(&Saddr, "S", "", "the server that connecting to")
|
||||||
flag.StringVar(&Laddr, "L", ":8080", "listen address")
|
flag.StringVar(&Laddr, "L", ":8080", "listen address")
|
||||||
flag.StringVar(&Cipher, "cipher", "rc4-md5", "cipher method")
|
flag.StringVar(&Method, "m", "tls", "cipher method")
|
||||||
flag.StringVar(&Password, "password", "ginuerzh@gmail.com", "cipher password")
|
flag.StringVar(&Password, "p", "ginuerzh@gmail.com", "cipher password")
|
||||||
|
flag.StringVar(&CertFile, "cert", "cert.pem", "cert.pem file for tls")
|
||||||
|
flag.StringVar(&KeyFile, "key", "key.pem", "key.pem file for tls")
|
||||||
flag.BoolVar(&Shadows, "ss", false, "shadowsocks compatible")
|
flag.BoolVar(&Shadows, "ss", false, "shadowsocks compatible")
|
||||||
flag.BoolVar(&Debug, "d", false, "debug option")
|
flag.StringVar(&SMethod, "sm", "rc4-md5", "shadowsocks cipher method")
|
||||||
|
flag.StringVar(&SPassword, "sp", "ginuerzh@gmail.com", "shadowsocks cipher password")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||||
@ -30,9 +35,10 @@ func main() {
|
|||||||
//log.Fatal(gost.Run())
|
//log.Fatal(gost.Run())
|
||||||
if len(Saddr) == 0 {
|
if len(Saddr) == 0 {
|
||||||
srv := &gosocks5.Server{
|
srv := &gosocks5.Server{
|
||||||
Addr: Laddr,
|
Addr: Laddr,
|
||||||
SelectMethod: selectMethod,
|
SelectMethod: selectMethod,
|
||||||
Handle: srvHandle,
|
MethodSelected: methodSelected,
|
||||||
|
Handle: srvHandle,
|
||||||
}
|
}
|
||||||
log.Fatal(srv.ListenAndServe())
|
log.Fatal(srv.ListenAndServe())
|
||||||
return
|
return
|
||||||
|
43
server.go
43
server.go
@ -5,37 +5,46 @@ import (
|
|||||||
"github.com/shadowsocks/shadowsocks-go/shadowsocks"
|
"github.com/shadowsocks/shadowsocks-go/shadowsocks"
|
||||||
"net"
|
"net"
|
||||||
//"strconv"
|
//"strconv"
|
||||||
|
"crypto/tls"
|
||||||
"log"
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
MethodAES256 uint8 = 0x88
|
|
||||||
)
|
|
||||||
|
|
||||||
func selectMethod(methods ...uint8) uint8 {
|
func selectMethod(methods ...uint8) uint8 {
|
||||||
for _, method := range methods {
|
for _, method := range methods {
|
||||||
if method == MethodAES256 {
|
if _, ok := Methods[method]; ok {
|
||||||
return method
|
return method
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return gosocks5.MethodNoAuth
|
return gosocks5.MethodNoAuth
|
||||||
}
|
}
|
||||||
|
|
||||||
func srvHandle(conn net.Conn, method uint8) {
|
func methodSelected(method uint8, conn net.Conn) (net.Conn, error) {
|
||||||
defer conn.Close()
|
switch method {
|
||||||
|
case MethodTLS:
|
||||||
if method == gosocks5.MethodNoAcceptable {
|
cert, err := tls.LoadX509KeyPair(CertFile, KeyFile)
|
||||||
return
|
if err != nil {
|
||||||
}
|
log.Println(err)
|
||||||
|
return nil, err
|
||||||
if method == MethodAES256 {
|
}
|
||||||
cipher, _ := shadowsocks.NewCipher(Cipher, Password)
|
conn = tls.Server(conn, &tls.Config{Certificates: []tls.Certificate{cert}})
|
||||||
|
case MethodAES128, MethodAES192, MethodAES256,
|
||||||
|
MethodDES, MethodBF, MethodCAST5, MethodRC4MD5, MethodRC4, MethodTable:
|
||||||
|
cipher, err := shadowsocks.NewCipher(Methods[method], Password)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
conn = shadowsocks.NewConn(conn, cipher)
|
conn = shadowsocks.NewConn(conn, cipher)
|
||||||
|
case gosocks5.MethodNoAcceptable:
|
||||||
|
return nil, gosocks5.ErrBadMethod
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return conn, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func srvHandle(conn net.Conn) {
|
||||||
req, err := gosocks5.ReadRequest(conn)
|
req, err := gosocks5.ReadRequest(conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
//log.Println(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +105,7 @@ func srvHandle(conn net.Conn, method uint8) {
|
|||||||
uconn, err := net.ListenUDP("udp", nil)
|
uconn, err := net.ListenUDP("udp", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
gosocks5.NewReply(Failure, nil).Write(conn)
|
gosocks5.NewReply(gosocks5.Failure, nil).Write(conn)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer uconn.Close()
|
defer uconn.Close()
|
||||||
@ -104,7 +113,7 @@ func srvHandle(conn net.Conn, method uint8) {
|
|||||||
addr := ToSocksAddr(uconn.LocalAddr())
|
addr := ToSocksAddr(uconn.LocalAddr())
|
||||||
addr.Host, _, _ = net.SplitHostPort(conn.LocalAddr().String())
|
addr.Host, _, _ = net.SplitHostPort(conn.LocalAddr().String())
|
||||||
//log.Println("udp:", addr)
|
//log.Println("udp:", addr)
|
||||||
rep := gosocks5.NewReply(Succeeded, addr)
|
rep := gosocks5.NewReply(gosocks5.Succeeded, addr)
|
||||||
if err := rep.Write(conn); err != nil {
|
if err := rep.Write(conn); err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return
|
return
|
||||||
|
287
socks5.go
287
socks5.go
@ -1,287 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/binary"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
//"log"
|
|
||||||
"net"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
Ver5 = 5
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
MethodNoAuth uint8 = iota
|
|
||||||
MethodGSSAPI
|
|
||||||
MethodUserPass
|
|
||||||
// X'03' to X'7F' IANA ASSIGNED
|
|
||||||
// X'80' to X'FE' RESERVED FOR PRIVATE METHODS
|
|
||||||
MethodNoAcceptable = 0xFF
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
CmdConnect uint8 = 1
|
|
||||||
CmdBind = 2
|
|
||||||
CmdUdp = 3
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
AddrIPv4 uint8 = 1
|
|
||||||
AddrDomain = 3
|
|
||||||
AddrIPv6 = 4
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
Succeeded uint8 = iota
|
|
||||||
Failure
|
|
||||||
NotAllowed
|
|
||||||
NetUnreachable
|
|
||||||
HostUnreachable
|
|
||||||
ConnRefused
|
|
||||||
TTLExpired
|
|
||||||
CmdUnsupported
|
|
||||||
AddrUnsupported
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
ErrBadVersion = errors.New("Bad version")
|
|
||||||
ErrBadFormat = errors.New("Bad format")
|
|
||||||
ErrBadAddrType = errors.New("Bad address type")
|
|
||||||
ErrShortBuffer = errors.New("Short buffer")
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
+----+-----+-------+------+----------+----------+
|
|
||||||
|VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
|
|
||||||
+----+-----+-------+------+----------+----------+
|
|
||||||
| 1 | 1 | X'00' | 1 | Variable | 2 |
|
|
||||||
+----+-----+-------+------+----------+----------+
|
|
||||||
*/
|
|
||||||
type Cmd struct {
|
|
||||||
Cmd uint8
|
|
||||||
AddrType uint8
|
|
||||||
Addr string
|
|
||||||
Port uint16
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewCmd(cmd uint8, atype uint8, addr string, port uint16) *Cmd {
|
|
||||||
if len(addr) == 0 {
|
|
||||||
addr = "0.0.0.0"
|
|
||||||
}
|
|
||||||
return &Cmd{
|
|
||||||
Cmd: cmd,
|
|
||||||
AddrType: atype,
|
|
||||||
Addr: addr,
|
|
||||||
Port: port,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ReadCmd(r io.Reader) (*Cmd, error) {
|
|
||||||
b := make([]byte, 256)
|
|
||||||
n, err := r.Read(b)
|
|
||||||
//log.Println(b[:n])
|
|
||||||
if err != nil {
|
|
||||||
//log.Println(err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if n < 10 {
|
|
||||||
return nil, ErrBadFormat
|
|
||||||
}
|
|
||||||
if b[0] != Ver5 {
|
|
||||||
return nil, ErrBadVersion
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd := &Cmd{
|
|
||||||
Cmd: b[1],
|
|
||||||
AddrType: b[3],
|
|
||||||
}
|
|
||||||
|
|
||||||
pos := 4
|
|
||||||
|
|
||||||
switch cmd.AddrType {
|
|
||||||
case AddrIPv4:
|
|
||||||
if n != 10 {
|
|
||||||
return nil, ErrBadFormat
|
|
||||||
}
|
|
||||||
cmd.Addr = net.IP(b[pos : pos+net.IPv4len]).String()
|
|
||||||
pos += net.IPv4len
|
|
||||||
case AddrIPv6:
|
|
||||||
if n != 22 {
|
|
||||||
return nil, ErrBadFormat
|
|
||||||
}
|
|
||||||
cmd.Addr = net.IP(b[pos : pos+net.IPv6len]).String()
|
|
||||||
pos += net.IPv6len
|
|
||||||
case AddrDomain:
|
|
||||||
length := int(b[pos])
|
|
||||||
if n != 4+1+length+2 {
|
|
||||||
return nil, ErrBadFormat
|
|
||||||
}
|
|
||||||
|
|
||||||
pos++
|
|
||||||
cmd.Addr = string(b[pos : pos+length])
|
|
||||||
pos += length
|
|
||||||
default:
|
|
||||||
pos += 4
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Port = binary.BigEndian.Uint16(b[pos:])
|
|
||||||
|
|
||||||
return cmd, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cmd *Cmd) Write(w io.Writer) (err error) {
|
|
||||||
b := make([]byte, 256)
|
|
||||||
|
|
||||||
b[0] = Ver5
|
|
||||||
b[1] = cmd.Cmd
|
|
||||||
b[3] = cmd.AddrType
|
|
||||||
pos := 4
|
|
||||||
|
|
||||||
switch cmd.AddrType {
|
|
||||||
case AddrIPv4:
|
|
||||||
pos += copy(b[pos:], net.ParseIP(cmd.Addr).To4())
|
|
||||||
case AddrDomain:
|
|
||||||
b[pos] = byte(len(cmd.Addr))
|
|
||||||
pos++
|
|
||||||
pos += copy(b[pos:], []byte(cmd.Addr))
|
|
||||||
case AddrIPv6:
|
|
||||||
pos += copy(b[pos:], net.ParseIP(cmd.Addr).To16())
|
|
||||||
}
|
|
||||||
binary.BigEndian.PutUint16(b[pos:], cmd.Port)
|
|
||||||
pos += 2
|
|
||||||
|
|
||||||
_, err = w.Write(b[:pos])
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cmd *Cmd) String() string {
|
|
||||||
return fmt.Sprintf("5 %d 0 %d %s %d",
|
|
||||||
cmd.Cmd, cmd.AddrType, cmd.Addr, cmd.Port)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
+----+------+------+----------+----------+----------+
|
|
||||||
|RSV | FRAG | ATYP | DST.ADDR | DST.PORT | DATA |
|
|
||||||
+----+------+------+----------+----------+----------+
|
|
||||||
| 2 | 1 | 1 | Variable | 2 | Variable |
|
|
||||||
+----+------+------+----------+----------+----------+
|
|
||||||
*/
|
|
||||||
type UdpPayload struct {
|
|
||||||
Rsv uint16
|
|
||||||
Frag uint8
|
|
||||||
AddrType uint8
|
|
||||||
Addr string
|
|
||||||
Port uint16
|
|
||||||
Data []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewUdpPayload(rsv uint16, atype uint8, addr string, port uint16, data []byte) *UdpPayload {
|
|
||||||
if len(addr) == 0 {
|
|
||||||
addr = "0.0.0.0"
|
|
||||||
}
|
|
||||||
return &UdpPayload{
|
|
||||||
Rsv: rsv,
|
|
||||||
AddrType: atype,
|
|
||||||
Addr: addr,
|
|
||||||
Port: port,
|
|
||||||
Data: data,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ReadUdpPayload(r io.Reader) (*UdpPayload, error) {
|
|
||||||
buf := make([]byte, 65797)
|
|
||||||
n, err := io.ReadAtLeast(r, buf, 5)
|
|
||||||
//log.Println("r", buf[:n])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
up := &UdpPayload{
|
|
||||||
Rsv: binary.BigEndian.Uint16(buf[:2]),
|
|
||||||
Frag: buf[2],
|
|
||||||
AddrType: buf[3],
|
|
||||||
}
|
|
||||||
|
|
||||||
dataIndex := 0
|
|
||||||
switch up.AddrType {
|
|
||||||
case AddrIPv4:
|
|
||||||
dataIndex = 10
|
|
||||||
case AddrIPv6:
|
|
||||||
dataIndex = 22
|
|
||||||
case AddrDomain:
|
|
||||||
dataIndex = 7 + int(buf[4])
|
|
||||||
default:
|
|
||||||
return nil, ErrBadAddrType
|
|
||||||
}
|
|
||||||
|
|
||||||
dataLen := int(up.Rsv)
|
|
||||||
if n < dataIndex+dataLen {
|
|
||||||
if _, err := io.ReadFull(r, buf[n:dataIndex+dataLen]); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pos := 4
|
|
||||||
switch up.AddrType {
|
|
||||||
case AddrIPv4:
|
|
||||||
up.Addr = net.IP(buf[pos : pos+net.IPv4len]).String()
|
|
||||||
pos += net.IPv4len
|
|
||||||
case AddrIPv6:
|
|
||||||
up.Addr = net.IP(buf[pos : pos+net.IPv6len]).String()
|
|
||||||
pos += net.IPv6len
|
|
||||||
case AddrDomain:
|
|
||||||
length := int(buf[pos])
|
|
||||||
pos++
|
|
||||||
up.Addr = string(buf[pos : pos+length])
|
|
||||||
pos += length
|
|
||||||
}
|
|
||||||
|
|
||||||
up.Port = binary.BigEndian.Uint16(buf[pos:])
|
|
||||||
//log.Println(up.Addr, up.Port)
|
|
||||||
if dataLen > 0 {
|
|
||||||
up.Data = buf[dataIndex : dataIndex+dataLen]
|
|
||||||
} else {
|
|
||||||
up.Data = buf[dataIndex:n]
|
|
||||||
}
|
|
||||||
|
|
||||||
return up, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (up *UdpPayload) Write(w io.Writer) error {
|
|
||||||
buffer := &bytes.Buffer{}
|
|
||||||
|
|
||||||
b := make([]byte, 2)
|
|
||||||
|
|
||||||
binary.BigEndian.PutUint16(b, up.Rsv)
|
|
||||||
buffer.Write(b)
|
|
||||||
buffer.WriteByte(up.Frag)
|
|
||||||
buffer.WriteByte(up.AddrType)
|
|
||||||
|
|
||||||
switch up.AddrType {
|
|
||||||
case AddrIPv4:
|
|
||||||
buffer.Write(net.ParseIP(up.Addr).To4())
|
|
||||||
case AddrDomain:
|
|
||||||
buffer.WriteByte(uint8(len(up.Addr)))
|
|
||||||
buffer.Write([]byte(up.Addr))
|
|
||||||
case AddrIPv6:
|
|
||||||
buffer.Write(net.ParseIP(up.Addr).To16())
|
|
||||||
}
|
|
||||||
|
|
||||||
binary.BigEndian.PutUint16(b, up.Port)
|
|
||||||
buffer.Write(b)
|
|
||||||
buffer.Write(up.Data)
|
|
||||||
|
|
||||||
_, err := w.Write(buffer.Bytes())
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (up *UdpPayload) String() string {
|
|
||||||
return fmt.Sprintf("%d %d %d %s %d [%d]",
|
|
||||||
up.Rsv, up.Frag, up.AddrType, up.Addr, up.Port, len(up.Data))
|
|
||||||
}
|
|
28
util.go
28
util.go
@ -13,12 +13,38 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
MethodTLS uint8 = 0x80 + iota
|
||||||
|
MethodAES128
|
||||||
|
MethodAES192
|
||||||
|
MethodAES256
|
||||||
|
MethodDES
|
||||||
|
MethodBF
|
||||||
|
MethodCAST5
|
||||||
|
MethodRC4MD5
|
||||||
|
MethodRC4
|
||||||
|
MethodTable
|
||||||
|
)
|
||||||
|
|
||||||
|
var Methods = map[uint8]string{
|
||||||
|
MethodTLS: "tls", // 0x80
|
||||||
|
MethodAES128: "aes-128-cfb", // 0x81
|
||||||
|
MethodAES192: "aes-192-cfb", // 0x82
|
||||||
|
MethodAES256: "aes-256-cfb", // 0x83
|
||||||
|
MethodDES: "des-cfb", // 0x84
|
||||||
|
MethodBF: "bf-cfb", // 0x85
|
||||||
|
MethodCAST5: "cast5-cfb", // 0x86
|
||||||
|
MethodRC4MD5: "rc4-md5", // 8x87
|
||||||
|
MethodRC4: "rc4", // 0x88
|
||||||
|
MethodTable: "table", // 0x89
|
||||||
|
}
|
||||||
|
|
||||||
func ToSocksAddr(addr net.Addr) *gosocks5.Addr {
|
func ToSocksAddr(addr net.Addr) *gosocks5.Addr {
|
||||||
host, port, _ := net.SplitHostPort(addr.String())
|
host, port, _ := net.SplitHostPort(addr.String())
|
||||||
p, _ := strconv.Atoi(port)
|
p, _ := strconv.Atoi(port)
|
||||||
|
|
||||||
return &gosocks5.Addr{
|
return &gosocks5.Addr{
|
||||||
Type: AddrIPv4,
|
Type: gosocks5.AddrIPv4,
|
||||||
Host: host,
|
Host: host,
|
||||||
Port: uint16(p),
|
Port: uint16(p),
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user