Пример #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="handshakeData"></param>
        /// <returns></returns>
        protected override bool ResponseHandshake(TNSocket socket, HandshakeData handshakeData)
        {
            string secKey1;
            string secKey2;

            byte[] secKey3;
            if (handshakeData.ParamItems.TryGet(HandshakeHeadKeys.SecKey1, out secKey1) &&
                handshakeData.ParamItems.TryGet(HandshakeHeadKeys.SecKey2, out secKey2) &&
                handshakeData.ParamItems.TryGet(HandshakeHeadKeys.SecKey3, out secKey3))
            {
                //The minimum version support
                StringBuilder response = new StringBuilder();
                response.AppendLine(HandshakeHeadKeys.RespHead_00);
                response.AppendLine(HandshakeHeadKeys.RespUpgrade00);
                response.AppendLine(HandshakeHeadKeys.RespConnection);
                string origin;
                if (handshakeData.ParamItems.TryGet(HandshakeHeadKeys.Origin, out origin))
                {
                    response.AppendLine(string.Format(HandshakeHeadKeys.RespOriginLine, origin));
                }
                response.AppendLine(string.Format(HandshakeHeadKeys.SecLocation, handshakeData.UriSchema, handshakeData.Host, handshakeData.UrlPath));
                if (!string.IsNullOrEmpty(handshakeData.Protocol))
                {
                    response.AppendLine(string.Format(HandshakeHeadKeys.RespProtocol, handshakeData.Protocol));
                }
                response.AppendLine();
                Handler.SendMessage(socket, response.ToString(), Encoding, result => { });
                //Encrypt message
                byte[] securityKey = GetResponseSecurityKey(secKey1, secKey2, secKey3);
                Handler.SendMessage(socket, securityKey, result => { });

                return(true);
            }
            return(false);
        }
        private string GenreateKey(HandshakeData handshakeData)
        {
            string key;

            if (handshakeData.ParamItems.TryGet(HandshakeHeadKeys.SecKey, out key))
            {
                return(GenreateKey(key));
            }
            return(string.Empty);
        }
Пример #3
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="handshakeData"></param>
 /// <returns></returns>
 protected override bool CheckSignKey(HandshakeData handshakeData)
 {
     byte[] secAccept;
     byte[] signKey;
     if (handshakeData.ParamItems.TryGet(HandshakeHeadKeys.SecAccept, out secAccept) &&
         handshakeData.ParamItems.TryGet(HandshakeHeadKeys.SecSignKey, out signKey))
     {
         return(secAccept.IndexOf(signKey) != -1);
     }
     return(false);
 }
        /// <summary>
        ///
        /// </summary>
        /// <param name="handshakeData"></param>
        /// <returns></returns>
        protected override bool CheckSignKey(HandshakeData handshakeData)
        {
            if (handshakeData.WebSocketVersion < _version)
            {
                return(base.CheckSignKey(handshakeData));
            }
            string signKey;
            string accecpKey;

            if (handshakeData.ParamItems.TryGet(HandshakeHeadKeys.SecAccept, out accecpKey) &&
                handshakeData.ParamItems.TryGet(HandshakeHeadKeys.SecSignKey, out signKey))
            {
                return(string.Equals(signKey, accecpKey));
            }
            return(false);
        }
Пример #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="handshake"></param>
        /// <param name="cookieStr"></param>
        /// <returns></returns>
        protected void ParseCookies(HandshakeData handshake, string cookieStr)
        {
            if (handshake == null)
            {
                return;
            }
            if (handshake.Cookies == null)
            {
                handshake.Cookies = new Dictionary <string, string>();
            }
            var array = cookieStr.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);

            foreach (var item in array)
            {
                var kvs = item.Split('=');
                if (kvs.Length == 2 && !string.IsNullOrEmpty(kvs[0]))
                {
                    handshake.Cookies[Uri.UnescapeDataString(kvs[0])] = Uri.UnescapeDataString(kvs[1].Trim());
                }
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="handshakeData"></param>
        /// <returns></returns>
        protected override bool ResponseHandshake(TNSocket socket, HandshakeData handshakeData)
        {
            if (handshakeData.WebSocketVersion < _version)
            {
                return(base.ResponseHandshake(socket, handshakeData));
            }

            string        secKeyAccept = GenreateKey(handshakeData);
            StringBuilder response     = new StringBuilder();

            response.AppendLine(HandshakeHeadKeys.RespHead_10);
            response.AppendLine(HandshakeHeadKeys.RespUpgrade);
            response.AppendLine(HandshakeHeadKeys.RespConnection);
            response.AppendLine(string.Format(HandshakeHeadKeys.RespAccept, secKeyAccept));

            if (!string.IsNullOrEmpty(handshakeData.Protocol))
            {
                response.AppendLine(string.Format(HandshakeHeadKeys.RespProtocol, handshakeData.Protocol));
            }
            response.AppendLine();
            Handler.SendMessage(socket, response.ToString(), Encoding, result => { });
            return(true);
        }
Пример #7
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="handshakeData"></param>
 /// <returns></returns>
 protected abstract bool CheckSignKey(HandshakeData handshakeData);
Пример #8
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="socket"></param>
 /// <param name="handshakeData"></param>
 protected abstract bool ResponseHandshake(TNSocket socket, HandshakeData handshakeData);
Пример #9
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="message"></param>
        /// <param name="handshakeData"></param>
        /// <param name="error"></param>
        /// <returns></returns>
        protected virtual bool TryParseHandshake(string message, HandshakeData handshakeData, out string error)
        {
            using (var reader = new StringReader(message))
            {
                error = string.Empty;
                string headData   = reader.ReadLine() ?? "";
                var    headParams = headData.Split(' ');
                if (headParams.Length < 3 ||
                    (headParams[0] != HandshakeHeadKeys.Method && headParams[0] != HandshakeHeadKeys.HttpVersion))
                {
                    return(false);
                }
                bool isResponse = headParams[0] == HandshakeHeadKeys.HttpVersion;
                if (!isResponse)
                {
                    if (Handler.IsSecurity)
                    {
                        handshakeData.UriSchema = "wss";
                    }
                    handshakeData.Method      = headParams[0];
                    handshakeData.UrlPath     = headParams[1];
                    handshakeData.HttpVersion = headParams[2];
                }

                string paramStr;
                while (!string.IsNullOrEmpty(paramStr = reader.ReadLine()))
                {
                    //ex: Upgrade: WebSocket
                    var paramArr = paramStr.Split(':');
                    if (paramArr.Length < 2)
                    {
                        continue;
                    }
                    string key = paramArr[0].Trim();
                    //value includ spance char
                    string value = string.Join("", paramArr, 1, paramArr.Length - 1);
                    if (value.Length > 1)
                    {
                        value = value.Substring(1);                   //pre char is spance
                    }
                    if (string.IsNullOrEmpty(key))
                    {
                        continue;
                    }
                    if (string.Equals(HandshakeHeadKeys.Host, key))
                    {
                        handshakeData.Host = value;
                        continue;
                    }
                    if (string.Equals(HandshakeHeadKeys.SecVersion, key))
                    {
                        handshakeData.WebSocketVersion = value.ToInt();
                        continue;
                    }
                    if (string.Equals(HandshakeHeadKeys.SecProtocol, key))
                    {
                        handshakeData.Protocol = GetFirstProtocol(value);
                        continue;
                    }
                    if (string.Equals(HandshakeHeadKeys.Cookie, key))
                    {
                        ParseCookies(handshakeData, value);
                        continue;
                    }
                    handshakeData.ParamItems[key] = value;
                }

                if (handshakeData.ParamItems.ContainsKey(HandshakeHeadKeys.Upgrade) &&
                    handshakeData.ParamItems.ContainsKey(HandshakeHeadKeys.Connection))
                {
                    return(true);
                }
                error = "not support websocket ";
            }

            return(false);
        }
Пример #10
0
        /// <summary>
        /// Receive handshake
        /// </summary>
        /// <param name="ioEventArgs"></param>
        /// <param name="dataToken"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        internal HandshakeResult Receive(SocketAsyncEventArgs ioEventArgs, DataToken dataToken, byte[] data)
        {
            if (dataToken.byteArrayForHandshake == null)
            {
                dataToken.byteArrayForHandshake = new List <byte>(data);
            }
            else
            {
                dataToken.byteArrayForHandshake.AddRange(data);
            }
            var buffer     = dataToken.byteArrayForHandshake.ToArray();
            int headLength = MathUtils.IndexOf(buffer, HandshakeEndBytes);

            if (headLength < 0)
            {
                //data not complate, wait receive
                return(HandshakeResult.Wait);
            }
            headLength += HandshakeEndBytes.Length;
            byte[] headBytes = new byte[headLength];
            Buffer.BlockCopy(buffer, 0, headBytes, 0, headBytes.Length);

            string        message       = Encoding.GetString(headBytes);
            HandshakeData handshakeData = dataToken.Socket.Handshake;
            string        error;

            if (TryParseHandshake(message, handshakeData, out error))
            {
                if (handshakeData.ParamItems.ContainsKey(HandshakeHeadKeys.SecKey1) &&
                    handshakeData.ParamItems.ContainsKey(HandshakeHeadKeys.SecKey2))
                {
                    int remainBytesNum = buffer.Length - headLength;
                    if (!handshakeData.IsClient && remainBytesNum == 8)
                    {
                        byte[] secKey3Bytes = new byte[remainBytesNum];
                        Buffer.BlockCopy(buffer, headBytes.Length, secKey3Bytes, 0, secKey3Bytes.Length);
                        handshakeData.ParamItems[HandshakeHeadKeys.SecKey3] = secKey3Bytes;
                    }
                    else if (handshakeData.IsClient && remainBytesNum == 16)
                    {
                        byte[] secKey3Bytes = new byte[remainBytesNum];
                        Buffer.BlockCopy(buffer, headBytes.Length, secKey3Bytes, 0, secKey3Bytes.Length);
                        handshakeData.ParamItems[HandshakeHeadKeys.SecAccept] = secKey3Bytes;
                    }
                    else
                    {
                        //data not complate, wait receive
                        return(HandshakeResult.Wait);
                    }
                }
                if (!handshakeData.IsClient)
                {
                    bool result = ResponseHandshake(dataToken.Socket, handshakeData);
                    if (!result)
                    {
                        TraceLog.ReleaseWriteDebug("Client {0} handshake fail, message:\r\n{2}", dataToken.Socket.RemoteEndPoint, message);
                        return(HandshakeResult.Close);
                    }
                    dataToken.byteArrayForHandshake       = null;
                    dataToken.Socket.Handshake.Handshaked = true;
                    return(HandshakeResult.Success);
                }
                if (CheckSignKey(handshakeData))
                {
                    dataToken.byteArrayForHandshake       = null;
                    dataToken.Socket.Handshake.Handshaked = true;
                    return(HandshakeResult.Success);
                }
                return(HandshakeResult.Close);
            }
            TraceLog.WriteWarn("Client {0} handshake {1}error, detail\r\n{2}", dataToken.Socket.RemoteEndPoint, error, message);
            return(HandshakeResult.Close);
        }