public bool CheckHandshake(Context context)
 {
     if(context.ReceivedByteCount > 8)
     {
         ClientHandshake handshake = new ClientHandshake(context.Header);
         // See if our header had the required information
         if (handshake.IsValid())
         {
             // Optionally check Origin and Location if they're set.
             if (Origin != string.Empty)
                 if (handshake.Origin != "http://" + Origin)
                     return false;
             if (Location != string.Empty)
                 if (handshake.Host != Location + ":" + context.Server.Port.ToString())
                     return false;
             // Generate response handshake for the client
             ServerHandshake serverShake = GenerateResponseHandshake(handshake, context);
             serverShake.SubProtocol = handshake.SubProtocol;
             // Send the response handshake
             SendServerHandshake(serverShake, context);
             return true;
         }
     }
     return false;
 }
Esempio n. 2
0
 public static bool CheckHandshake(Context AContext)
 {
     if(AContext.ReceivedByteCount > 8)
     {
         ClientHandshake AHandshake = new ClientHandshake(new ArraySegment<byte>(AContext.Buffer, AContext.ReceivedByteCount-8, 8), AContext.Header);
         // See if our header had the required information
         if (AHandshake.IsValid())
         {
             // Optionally check Origin and Location if they're set.
             if (Origin != string.Empty)
                 if (AHandshake.Origin != "http://" + Origin)
                     return false;
             if (Location != string.Empty)
                 if (AHandshake.Host != Location + ":" + AContext.Server.Port.ToString())
                     return false;
             // Generate response handshake for the client
             ServerHandshake ServerShake = GenerateResponseHandshake(AHandshake);
             // Send the response handshake
             SendServerHandshake(ServerShake, AContext);
             return true;
         }
     }
     return false;
 }
        private static string GenerateAccept(string key, Context context)
        {
            string rawAnswer = key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";

            // Create a hash of the rawAnswer and return it
            SHA1 hasher = SHA1.Create();
            return Convert.ToBase64String(hasher.ComputeHash(context.UserContext.Encoding.GetBytes(rawAnswer)));
        }
 /// <summary>
 /// Fires when a client connects.
 /// </summary>
 /// <param name="AConnection">The TCP Connection.</param>
 protected override void OnRunClient(TcpClient connection)
 {
     using (Context context = new Context())
     {
         context.Server = this;
         context.Connection = connection;
         context.UserContext.ClientAddress = context.Connection.Client.RemoteEndPoint;
         context.UserContext.SetOnConnect(DefaultOnConnect);
         context.UserContext.SetOnDisconnect(DefaultOnDisconnect);
         context.UserContext.SetOnSend(DefaultOnSend);
         context.UserContext.SetOnReceive(DefaultOnReceive);
         context.BufferSize = _defaultBufferSize;
         context.UserContext.OnConnect();
         try
         {
             while (context.Connection.Connected)
             {
                 if (context.ReceiveReady.Wait(TimeOut))
                 {
                     context.Connection.Client.BeginReceive(context.Buffer, 0, context.Buffer.Length, SocketFlags.None, DoReceive, context);
                 }
                 else
                 {
                     break;
                 }
             }
         }
         catch (Exception e) { Log.Debug("Client Forcefully Disconnected", e); }
     }
 }
Esempio n. 5
0
        /// <summary>
        /// Runs the client.
        /// Sets up the UserContext.
        /// Executes in it's own thread.
        /// Utilizes a semaphore(ReceiveReady) to limit the number of receive events active for this client to 1 at a time.
        /// </summary>
        /// <param name="AResult">The A result.</param>
        private void RunClient(IAsyncResult AResult)
        {
            TcpClient AConnection = null;
            try
            {
                if (Listener != null)
                    AConnection = Listener.EndAcceptTcpClient(AResult);
            }
            catch (Exception) { Log.Error("[WS_SERVER]: Connection to client failed."); }

            ConnectReady.Release();
            if(AConnection != null)
            {
                ClientLock.Wait();
                _Clients++;
                ClientLock.Release();

                using (Context AContext = new Context())
                //each client has its own context
                {
                    AContext.Server = this;
                    AContext.Connection = AConnection;
                    AContext.UserContext.ClientAddress = AContext.Connection.Client.RemoteEndPoint;
                    AContext.UserContext.SetOnConnect(DefaultOnConnect);
                    AContext.UserContext.SetOnDisconnect(DefaultOnDisconnect);
                    AContext.UserContext.SetOnSend(DefaultOnSend);
                    AContext.UserContext.SetOnReceive(DefaultOnReceive);
                    AContext.BufferSize = DefaultBufferSize;
                    AContext.UserContext.OnConnect();
                    try
                    {
                        // message listener, per client
                        while (AContext.Connection.Connected)
                        {
                            if (AContext.ReceiveReady.Wait(TimeOut))
                            {
                                AContext.Connection.Client.BeginReceive(AContext.Buffer, 0, AContext.Buffer.Length, SocketFlags.None, new AsyncCallback(DoReceive), AContext);
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                    catch {
                        Log.Info("[WS_SERVER]: Client disconnected 1.");
                    }
                }

                ClientLock.Wait();
                _Clients--;
                ClientLock.Release();
            }
        }
 /// <summary>
 /// Attempts to authenticates the specified user context.
 /// If authentication fails it kills the connection.
 /// </summary>
 /// <param name="AContext">The user context.</param>
 private void Authenticate(Context AContext)
 {
     if (AContext.Handler.Authentication.CheckHandshake(AContext))
     {
         AContext.UserContext.Protocol = AContext.Header.Protocol;
         AContext.UserContext.RequestPath = AContext.Header.RequestPath;
         AContext.Header = null;
         AContext.IsSetup = true;
     }
     else
     {
         AContext.Dispose();
     }
 }
 /// <summary>
 /// Handles the request.
 /// </summary>
 /// <param name="AContext">The user context.</param>
 public override void HandleRequest(Context AContext)
 {
     if (AContext.IsSetup)
     {
         AContext.UserContext.DataFrame.Append(AContext.Buffer);
         if (AContext.UserContext.DataFrame.State == DataFrame.DataState.Complete)
         {
             switch (AContext.UserContext.DataFrame.Length)
             {
                 case 1:
                     //Process Command
                     string ACommand = AContext.UserContext.DataFrame.ToString();
                     if (ACommand == AContext.Server.PingCommand)
                     {
                         SendPingResponse(AContext);
                         AContext.Pings++;
                     }
                     else
                     {
                         AContext.Pings = 0;
                         AContext.UserContext.OnReceive();
                     }
                     if ((AContext.Pings >= AContext.Server.MaxPingsInSequence) && (AContext.Server.MaxPingsInSequence != 0))
                     {
                         AContext.Dispose();
                     }
                     break;
                 default:
                     AContext.Pings = 0;
                     AContext.UserContext.OnReceive();
                     break;
             }
         }
         else if (AContext.UserContext.DataFrame.State == DataFrame.DataState.Closed)
         {
             AContext.UserContext.Send(new byte[0], true);
         }
     }
     else
     {
         Authenticate(AContext);
     }
 }
 private static ServerHandshake GenerateResponseHandshake(ClientHandshake AHandshake, Context AContext)
 {
     ServerHandshake AResponseHandshake = new ServerHandshake();
     AResponseHandshake.Accept = GenerateAccept(AHandshake.Key, AContext);
     return AResponseHandshake;
 }
Esempio n. 9
0
        /// <summary>
        /// Runs the client.
        /// Sets up the UserContext.
        /// Executes in it's own thread.
        /// Utilizes a semaphore(ReceiveReady) to limit the number of receive events active for this client to 1 at a time.
        /// </summary>
        /// <param name="AResult">The A result.</param>
        private void RunClient(IAsyncResult AResult)
        {
            TcpClient AConnection = null;
            try
            {
                if (Listener != null)
                    AConnection = Listener.EndAcceptTcpClient(AResult);
            }
            catch (Exception e) { Log.Debug("Connect Failed", e); }

            ConnectReady.Release();
            if(AConnection != null)
            {
                ClientLock.Wait();
                _Clients++;
                ClientLock.Release();

                using (Context AContext = new Context())
                {
                    AContext.Server = this;
                    AContext.Connection = AConnection;
                    AContext.UserContext.ClientAddress = AContext.Connection.Client.RemoteEndPoint;
                    AContext.UserContext.SetOnConnect(DefaultOnConnect);
                    AContext.UserContext.SetOnDisconnect(DefaultOnDisconnect);
                    AContext.UserContext.SetOnSend(DefaultOnSend);
                    AContext.UserContext.SetOnReceive(DefaultOnReceive);
                    AContext.BufferSize = DefaultBufferSize;
                    AContext.UserContext.OnConnect();
                    try
                    {
                        while (AContext.Connection.Connected)
                        {
                            if (AContext.ReceiveReady.Wait(TimeOut))
                            {
                                AContext.Connection.Client.BeginReceive(AContext.Buffer, 0, AContext.Buffer.Length, SocketFlags.None, DoReceive, AContext);
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                    catch (Exception e) { Log.Debug("Client Forcefully Disconnected", e); }
                }

                ClientLock.Wait();
                _Clients--;
                ClientLock.Release();
            }
        }
 /// <summary>
 /// Processes the header.
 /// </summary>
 /// <param name="context">The user context.</param>
 public void ProcessHeader(Context context)
 {
     string data = context.UserContext.Encoding.GetString(context.Buffer, 0, context.ReceivedByteCount);
     //Check first to see if this is a flash socket XML request.
     if (data == "<policy-file-request/>\0")
     {
         try
         {
             //if it is, we access the Access Policy Server instance to send the appropriate response.
             context.Server.AccessPolicyServer.SendResponse(context.Connection);
         }
         catch { }
         context.Dispose();
     }
     else//If it isn't, process http/websocket header as normal.
     {
         context.Header = new Header(data);
         switch (context.Header.Protocol)
         {
             case Protocol.WebSocketHybi00:
                 context.Handler = Alchemy.Server.Handlers.WebSocket.hybi00.WebSocketHandler.Instance;
                 context.UserContext.DataFrame = new Alchemy.Server.Handlers.WebSocket.hybi00.DataFrame();
                 break;
             case Protocol.WebSocketHybi10:
                 context.Handler = Alchemy.Server.Handlers.WebSocket.hybi10.WebSocketHandler.Instance;
                 context.UserContext.DataFrame = new Alchemy.Server.Handlers.WebSocket.hybi10.DataFrame();
                 break;
             case Protocol.FlashSocket:
                 context.Handler = Alchemy.Server.Handlers.WebSocket.hybi00.WebSocketHandler.Instance;
                 context.UserContext.DataFrame = new Alchemy.Server.Handlers.WebSocket.hybi00.DataFrame();
                 break;
             default:
                 context.Header.Protocol = Protocol.None;
                 break;
         }
         if (context.Header.Protocol != Protocol.None)
         {
             context.Handler.HandleRequest(context);
         }
         else
         {
             context.UserContext.Send(Response.NotImplemented, true);
         }
     }
 }
 /// <summary>
 /// Sends the ping response.
 /// </summary>
 /// <param name="context">The user context.</param>
 private static void SendPingResponse(Context context)
 {
     context.UserContext.Send(context.Server.PongCommand);
 }
 /// <summary>
 /// Attempts to authenticates the specified user context.
 /// If authentication fails it kills the connection.
 /// </summary>
 /// <param name="context">The user context.</param>
 private static void Authenticate(Context context)
 {
     if (context.Handler.Authentication.CheckHandshake(context))
     {
         context.UserContext.Protocol = context.Header.Protocol;
         context.UserContext.RequestPath = context.Header.RequestPath;
         context.Header = null;
         context.IsSetup = true;
     }
     else
     {
         context.Dispose();
     }
 }
Esempio n. 13
0
 /// <summary>
 /// Initializes a new instance of the <see cref="UserContext"/> class.
 /// </summary>
 /// <param name="AContext">The user context.</param>
 public UserContext(Context AContext)
 {
     this.Context = AContext;
 }
 private static ServerHandshake GenerateResponseHandshake(ClientHandshake handshake, Context context)
 {
     ServerHandshake responseHandshake = new ServerHandshake();
     responseHandshake.Accept = GenerateAccept(handshake.Key, context);
     return responseHandshake;
 }
 /// <summary>
 /// Sends the specified data.
 /// </summary>
 /// <param name="data">The data.</param>
 /// <param name="context">The user context.</param>
 /// <param name="close">if set to <c>true</c> [close].</param>
 public override void Send(byte[] data, Context context, bool close = false)
 {
     byte[] wrappedData = context.UserContext.DataFrame.Wrap(data);
         AsyncCallback callback = EndSend;
         if (close)
             callback = EndSendAndClose;
         context.SendReady.Wait();
         try
         {
             context.Connection.Client.BeginSend(wrappedData, 0, wrappedData.Length, SocketFlags.None, callback, context);
         }
         catch
         {
             context.SendReady.Release();
         }
 }
 private static void SendServerHandshake(ServerHandshake handshake, Context context)
 {
     // generate a byte array representation of the handshake including the answer to the challenge
     string temp = handshake.ToString();
     byte[] handshakeBytes = context.UserContext.Encoding.GetBytes(temp);
     context.UserContext.SendRaw(handshakeBytes);
 }
Esempio n. 17
0
 /// <summary>
 /// Handles the initial request.
 /// Attempts to process the header that should have been sent.
 /// Otherwise, through magic and wizardry, the client gets disconnected.
 /// </summary>
 /// <param name="AContext">The user context.</param>
 public override void HandleRequest(Context AContext)
 {
     if (AContext.IsSetup)
     {
         AContext.Dispose();
     }
     else
     {
         ProcessHeader(AContext);
     }
 }
Esempio n. 18
0
        private static void SendServerHandshake(ServerHandshake AHandshake, Context AContext)
        {
            // generate a byte array representation of the handshake including the answer to the challenge
            byte[] HandshakeBytes = AContext.UserContext.Encoding.GetBytes(AHandshake.ToString());
            Array.Copy(AHandshake.AnswerBytes, 0, HandshakeBytes, HandshakeBytes.Length-16, 16);

            AContext.UserContext.SendRaw(HandshakeBytes);
        }
Esempio n. 19
0
        /// <summary>
        /// Processes the header.
        /// </summary>
        /// <param name="AContext">The user context.</param>
        public void ProcessHeader(Context AContext)
        {
            string Data = AContext.UserContext.Encoding.GetString(AContext.Buffer, 0, AContext.ReceivedByteCount);

            AContext.Header = new Header(Data);
            switch (AContext.Header.Protocol)
            {
                case Protocol.WebSocket:
                    AContext.Handler = WebSocketHandler.Instance;
                    break;
                default:
                    AContext.Header.Protocol = Protocol.None;
                    break;
            }
            if (AContext.Header.Protocol != Protocol.None)
            {
                AContext.Handler.HandleRequest(AContext);
            }
            else
            {
                AContext.UserContext.Send(Response.NotImplemented, true);
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="UserContext"/> class.
 /// </summary>
 /// <param name="context">The user context.</param>
 public UserContext(Context AContext)
 {
     this.Context = AContext;
     this.Header = this.Context.Header;
 }
Esempio n. 21
0
 public abstract void HandleRequest(Context Request);
 /// <summary>
 /// Sends the specified data.
 /// </summary>
 /// <param name="Data">The data.</param>
 /// <param name="AContext">The user context.</param>
 /// <param name="Close">if set to <c>true</c> [close].</param>
 public override void Send(byte[] Data, Context AContext, bool Close = false)
 {
     byte[] WrappedData = AContext.UserContext.DataFrame.Wrap(Data);
         AsyncCallback ACallback = EndSend;
         if (Close)
             ACallback = EndSendAndClose;
         AContext.SendReady.Wait();
         try
         {
             AContext.Connection.Client.BeginSend(WrappedData, 0, WrappedData.Length, SocketFlags.None, ACallback, AContext);
         }
         catch
         {
             AContext.SendReady.Release();
         }
 }
Esempio n. 23
0
 public abstract void Send(byte[] Data, Context AContext, bool Close = false);
 /// <summary>
 /// Sends the ping response.
 /// </summary>
 /// <param name="AContext">The user context.</param>
 private void SendPingResponse(Context AContext)
 {
     AContext.UserContext.Send(AContext.Server.PongCommand);
 }
Esempio n. 25
0
        /// <summary>
        /// Sends the specified data.
        /// </summary>
        /// <param name="Data">The data.</param>
        /// <param name="AContext">The user context.</param>
        /// <param name="Close">if set to <c>true</c> [close].</param>
        public override void Send(byte[] Data, Context AContext, bool Close = false)
        {
            byte[] WrappedData = DataFrame.Wrap(Data);
                AsyncCallback ACallback = EndSend;
                if (Close)
                    ACallback = EndSendAndClose;
                //AContext.SendReady.Wait();
                try
                {
                    AContext.SendReady.Wait();
                    if (AContext.Connection != null)
                    {
                        AContext.Connection.Client.BeginSend(WrappedData, 0, WrappedData.Length, SocketFlags.None, ACallback, AContext);
                    }
                }
                catch
                {
                    //Console.WriteLine("[WebSocketHandler]: Exception sending");
                    //AContext.SendReady.Release();
                }

                AContext.SendReady.Release();
        }