From 58cbb73f0ff4c501d2afd25937afc169e1b3e520 Mon Sep 17 00:00:00 2001 From: Qian Wang Date: Mon, 12 Aug 2019 14:21:42 +0100 Subject: [PATCH] Refactor return value of decryption --- cmd/ck-server/ck-server.go | 42 +++++++++++++++++++------------------- internal/server/TLS.go | 6 +++--- internal/server/auth.go | 21 ++++++++++++++----- 3 files changed, 40 insertions(+), 29 deletions(-) diff --git a/cmd/ck-server/ck-server.go b/cmd/ck-server/ck-server.go index 1fafda4..e3f205b 100644 --- a/cmd/ck-server/ck-server.go +++ b/cmd/ck-server/ck-server.go @@ -52,14 +52,14 @@ func dispatchConnection(conn net.Conn, sta *server.State) { go util.Pipe(conn, webConn) } - UID, sessionID, proxyMethod, encryptionMethod, finishHandshake, err := server.PrepareConnection(data, sta, conn) + ci, finishHandshake, err := server.PrepareConnection(data, sta, conn) if err != nil { log.WithFields(log.Fields{ "remoteAddr": remoteAddr, - "UID": b64(UID), - "sessionId": sessionID, - "proxyMethod": proxyMethod, - "encryptionMethod": encryptionMethod, + "UID": b64(ci.UID), + "sessionId": ci.SessionId, + "proxyMethod": ci.ProxyMethod, + "encryptionMethod": ci.EncryptionMethod, }).Warn(err) goWeb() return @@ -67,7 +67,7 @@ func dispatchConnection(conn net.Conn, sta *server.State) { sessionKey := make([]byte, 32) rand.Read(sessionKey) - obfuscator, err := mux.GenerateObfs(encryptionMethod, sessionKey) + obfuscator, err := mux.GenerateObfs(ci.EncryptionMethod, sessionKey) if err != nil { log.Error(err) goWeb() @@ -77,7 +77,7 @@ func dispatchConnection(conn net.Conn, sta *server.State) { // adminUID can use the server as normal with unlimited QoS credits. The adminUID is not // added to the userinfo database. The distinction between going into the admin mode // and normal proxy mode is that sessionID needs == 0 for admin mode - if bytes.Equal(UID, sta.AdminUID) && sessionID == 0 { + if bytes.Equal(ci.UID, sta.AdminUID) && ci.SessionId == 0 { err = finishHandshake(sessionKey) if err != nil { log.Error(err) @@ -101,14 +101,14 @@ func dispatchConnection(conn net.Conn, sta *server.State) { } var user *server.ActiveUser - if sta.IsBypass(UID) { - user, err = sta.Panel.GetBypassUser(UID) + if sta.IsBypass(ci.UID) { + user, err = sta.Panel.GetBypassUser(ci.UID) } else { - user, err = sta.Panel.GetUser(UID) + user, err = sta.Panel.GetUser(ci.UID) } if err != nil { log.WithFields(log.Fields{ - "UID": b64(UID), + "UID": b64(ci.UID), "remoteAddr": remoteAddr, "error": err, }).Warn("+1 unauthorised UID") @@ -121,9 +121,9 @@ func dispatchConnection(conn net.Conn, sta *server.State) { Valve: nil, UnitRead: util.ReadTLS, } - sesh, existing, err := user.GetSession(sessionID, seshConfig) + sesh, existing, err := user.GetSession(ci.SessionId, seshConfig) if err != nil { - user.DeleteSession(sessionID, "") + user.DeleteSession(ci.SessionId, "") log.Error(err) return } @@ -147,8 +147,8 @@ func dispatchConnection(conn net.Conn, sta *server.State) { log.Trace("finished handshake") log.WithFields(log.Fields{ - "UID": b64(UID), - "sessionID": sessionID, + "UID": b64(ci.UID), + "sessionID": ci.SessionId, }).Info("New session") sesh.AddConnection(conn) @@ -157,20 +157,20 @@ func dispatchConnection(conn net.Conn, sta *server.State) { if err != nil { if err == mux.ErrBrokenSession { log.WithFields(log.Fields{ - "UID": b64(UID), - "sessionID": sessionID, + "UID": b64(ci.UID), + "sessionID": ci.SessionId, "reason": sesh.TerminalMsg(), }).Info("Session closed") - user.DeleteSession(sessionID, "") + user.DeleteSession(ci.SessionId, "") return } else { continue } } - localConn, err := net.Dial("tcp", sta.ProxyBook[proxyMethod]) + localConn, err := net.Dial("tcp", sta.ProxyBook[ci.ProxyMethod]) if err != nil { - log.Errorf("Failed to connect to %v: %v", proxyMethod, err) - user.DeleteSession(sessionID, "Failed to connect to proxy server") + log.Errorf("Failed to connect to %v: %v", ci.ProxyMethod, err) + user.DeleteSession(ci.SessionId, "Failed to connect to proxy server") continue } go util.Pipe(localConn, newStream) diff --git a/internal/server/TLS.go b/internal/server/TLS.go index 58af276..e46e842 100644 --- a/internal/server/TLS.go +++ b/internal/server/TLS.go @@ -218,7 +218,7 @@ var ErrBadClientHello = errors.New("non (or malformed) ClientHello") var ErrNotCloak = errors.New("TLS but non-Cloak ClientHello") var ErrBadProxyMethod = errors.New("invalid proxy method") -func PrepareConnection(firstPacket []byte, sta *State, conn net.Conn) (UID []byte, sessionID uint32, proxyMethod string, encryptionMethod byte, finisher func([]byte) error, err error) { +func PrepareConnection(firstPacket []byte, sta *State, conn net.Conn) (info *ClientInfo, finisher func([]byte) error, err error) { ch, err := parseClientHello(firstPacket) if err != nil { log.Debug(err) @@ -227,13 +227,13 @@ func PrepareConnection(firstPacket []byte, sta *State, conn net.Conn) (UID []byt } var sharedSecret []byte - UID, sessionID, proxyMethod, encryptionMethod, sharedSecret, err = TouchStone(ch, sta) + info, sharedSecret, err = TouchStone(ch, sta) if err != nil { log.Debug(err) err = ErrNotCloak return } - if _, ok := sta.ProxyBook[proxyMethod]; !ok { + if _, ok := sta.ProxyBook[info.ProxyMethod]; !ok { err = ErrBadProxyMethod return } diff --git a/internal/server/auth.go b/internal/server/auth.go index 9cf0e70..4d55175 100644 --- a/internal/server/auth.go +++ b/internal/server/auth.go @@ -10,12 +10,19 @@ import ( "time" ) +type ClientInfo struct { + UID []byte + SessionId uint32 + ProxyMethod string + EncryptionMethod byte +} + var ErrReplay = errors.New("duplicate random") var ErrInvalidPubKey = errors.New("public key has invalid format") var ErrCiphertextLength = errors.New("ciphertext has the wrong length") var ErrTimestampOutOfWindow = errors.New("timestamp is outside of the accepting window") -func TouchStone(ch *ClientHello, sta *State) (UID []byte, sessionID uint32, proxyMethod string, encryptionMethod byte, sharedSecret []byte, err error) { +func TouchStone(ch *ClientHello, sta *State) (info *ClientInfo, sharedSecret []byte, err error) { if sta.registerRandom(ch.random) { err = ErrReplay @@ -47,9 +54,13 @@ func TouchStone(ch *ClientHello, sta *State) (UID []byte, sessionID uint32, prox return } - UID = plaintext[0:16] - proxyMethod = string(bytes.Trim(plaintext[16:28], "\x00")) - encryptionMethod = plaintext[28] + info = &ClientInfo{ + UID: plaintext[0:16], + SessionId: 0, + ProxyMethod: string(bytes.Trim(plaintext[16:28], "\x00")), + EncryptionMethod: plaintext[28], + } + timestamp := int64(binary.BigEndian.Uint64(plaintext[29:37])) clientTime := time.Unix(timestamp, 0) serverTime := sta.Now() @@ -57,6 +68,6 @@ func TouchStone(ch *ClientHello, sta *State) (UID []byte, sessionID uint32, prox err = fmt.Errorf("%v: received timestamp %v", ErrTimestampOutOfWindow, timestamp) return } - sessionID = binary.BigEndian.Uint32(plaintext[37:41]) + info.SessionId = binary.BigEndian.Uint32(plaintext[37:41]) return }