diff --git a/cmd/gost/vendor/github.com/ginuerzh/gost/conn.go b/cmd/gost/vendor/github.com/ginuerzh/gost/conn.go index f44fcc1..a46a285 100644 --- a/cmd/gost/vendor/github.com/ginuerzh/gost/conn.go +++ b/cmd/gost/vendor/github.com/ginuerzh/gost/conn.go @@ -2,18 +2,18 @@ package gost import ( "bufio" - "bytes" "crypto/tls" "encoding/base64" "errors" "github.com/ginuerzh/gosocks5" "github.com/golang/glog" - "github.com/shadowsocks/shadowsocks-go/shadowsocks" + ss "github.com/shadowsocks/shadowsocks-go/shadowsocks" "net" "net/http" "net/http/httputil" "net/url" "strconv" + "strings" "sync" "time" ) @@ -115,15 +115,7 @@ func (c *ProxyConn) handshake() error { } c.conn = conn case "ss": // shadowsocks - if len(c.Node.Users) > 0 { - method := c.Node.Users[0].Username() - password, _ := c.Node.Users[0].Password() - cipher, err := shadowsocks.NewCipher(method, password) - if err != nil { - return err - } - c.conn = &shadowConn{conn: shadowsocks.NewConn(c.conn, cipher)} - } + // nothing to do case "http", "http2": fallthrough default: @@ -138,26 +130,31 @@ func (c *ProxyConn) handshake() error { func (c *ProxyConn) Connect(addr string) error { switch c.Node.Protocol { case "ss": // shadowsocks - host, port, err := net.SplitHostPort(addr) + rawaddr, err := ss.RawAddr(addr) if err != nil { return err } - p, _ := strconv.Atoi(port) - req := gosocks5.NewRequest(gosocks5.CmdConnect, &gosocks5.Addr{ - Type: gosocks5.AddrDomain, - Host: host, - Port: uint16(p), - }) - buf := bytes.Buffer{} - if err := req.Write(&buf); err != nil { - return err + + var method, password string + if len(c.Node.Users) > 0 { + method = c.Node.Users[0].Username() + password, _ = c.Node.Users[0].Password() } - b := buf.Bytes() - if _, err := c.Write(b[3:]); err != nil { + if c.Node.getBool("ota") && !strings.HasSuffix(method, "-auth") { + method += "-auth" + } + + cipher, err := ss.NewCipher(method, password) + if err != nil { return err } - glog.V(LDEBUG).Infoln("[ss]", req) + ssc, err := ss.DialWithRawAddrConn(rawaddr, c.conn, cipher) + if err != nil { + return err + } + c.conn = &shadowConn{conn: ssc} + return nil case "socks", "socks5": host, port, err := net.SplitHostPort(addr) if err != nil { diff --git a/cmd/gost/vendor/github.com/ginuerzh/gost/server.go b/cmd/gost/vendor/github.com/ginuerzh/gost/server.go index 955dd2f..74b3861 100644 --- a/cmd/gost/vendor/github.com/ginuerzh/gost/server.go +++ b/cmd/gost/vendor/github.com/ginuerzh/gost/server.go @@ -10,6 +10,7 @@ import ( "net" "net/http" "strconv" + "strings" ) type ProxyServer struct { @@ -18,6 +19,7 @@ type ProxyServer struct { TLSConfig *tls.Config selector *serverSelector cipher *ss.Cipher + ota bool } func NewProxyServer(node ProxyNode, chain *ProxyChain, config *tls.Config) *ProxyServer { @@ -29,10 +31,20 @@ func NewProxyServer(node ProxyNode, chain *ProxyChain, config *tls.Config) *Prox } var cipher *ss.Cipher - if node.Protocol == "ss" && node.Users != nil { + var ota bool + if node.Protocol == "ss" { var err error - method := node.Users[0].Username() - password, _ := node.Users[0].Password() + var method, password string + + if len(node.Users) > 0 { + method = node.Users[0].Username() + password, _ = node.Users[0].Password() + } + ota = node.getBool("ota") + if strings.HasSuffix(method, "-auth") { + ota = true + method = strings.TrimSuffix(method, "-auth") + } cipher, err = ss.NewCipher(method, password) if err != nil { glog.Fatal(err) @@ -54,6 +66,7 @@ func NewProxyServer(node ProxyNode, chain *ProxyChain, config *tls.Config) *Prox tlsConfig: config, }, cipher: cipher, + ota: ota, } } @@ -134,7 +147,7 @@ func (s *ProxyServer) handleConn(conn net.Conn) { switch s.Node.Protocol { case "ss": // shadowsocks server := NewShadowServer(ss.NewConn(conn, s.cipher.Copy()), s) - server.OTA = s.Node.getBool("ota") + server.OTA = s.ota server.Serve() return case "http": diff --git a/cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/conn.go b/cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/conn.go index 1a79f1d..525bfa2 100644 --- a/cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/conn.go +++ b/cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/conn.go @@ -82,6 +82,29 @@ func DialWithRawAddr(rawaddr []byte, server string, cipher *Cipher) (c *Conn, er return } +// add by yang for gost ota +// see https://groups.google.com/forum/#!topic/go-gost/GYBtHmLKR0o +func DialWithRawAddrConn(rawaddr []byte, conn net.Conn, cipher *Cipher) (c *Conn, err error) { + c = NewConn(conn, cipher) + if cipher.ota { + if c.enc == nil { + if _, err = c.initEncrypt(); err != nil { + return + } + } + // since we have initEncrypt, we must send iv manually + conn.Write(cipher.iv) + rawaddr[0] |= OneTimeAuthMask + rawaddr = otaConnectAuth(cipher.iv, cipher.key, rawaddr) + } + + if _, err = c.write(rawaddr); err != nil { + c.Close() + return nil, err + } + return +} + // addr should be in the form of host:port func Dial(addr, server string, cipher *Cipher) (c *Conn, err error) { ra, err := RawAddr(addr) diff --git a/cmd/gost/vendor/vendor.json b/cmd/gost/vendor/vendor.json index 1a173ed..3505c2d 100644 --- a/cmd/gost/vendor/vendor.json +++ b/cmd/gost/vendor/vendor.json @@ -15,10 +15,10 @@ "revisionTime": "2016-09-03T01:06:34Z" }, { - "checksumSHA1": "QooLgOqsl0ivXxYygSepzSRAtjQ=", + "checksumSHA1": "t4O2pqbz2JHm0t6OGz7e7L28IRM=", "path": "github.com/ginuerzh/gost", - "revision": "15a5d74b563e644a471fa42aab0a2876da6b1bb0", - "revisionTime": "2017-01-09T03:39:18Z" + "revision": "148d114c7366e1d15e807fe2e472f635fb6ed557", + "revisionTime": "2017-01-14T05:41:49Z" }, { "checksumSHA1": "URsJa4y/sUUw/STmbeYx9EKqaYE=", @@ -153,7 +153,7 @@ "revisionTime": "2016-10-02T05:25:12Z" }, { - "checksumSHA1": "VrDrpS/tpn8nfuFCY51U4eH/Jg0=", + "checksumSHA1": "o0WHRL8mNIhfsoWlzhdJ8du6+C8=", "path": "github.com/shadowsocks/shadowsocks-go/shadowsocks", "revision": "5c9897ecdf623f385ccb8c2c78e32c5256961b41", "revisionTime": "2016-06-15T15:25:08Z"