Ejemplo n.º 1
0
 private void ConnectionDataCallback(SecureTCPServer server, uint clientIndex, int numberOfBytesReceived)
 {
     try
     {
         byte[] data             = server.GetIncomingDataBufferForSpecificClient(clientIndex);
         string dataASCIIEncoded = Encoding.ASCII.GetString(data, 0, data.Length);
         //TODO: Cambiare la regex e renderla sicura
         if (new Regex("^GET").IsMatch(dataASCIIEncoded))
         {
             CrestronLogger.WriteToLog("WS_SERVER - PERFORMING HANDSHAKE", 1);
             PerformHandShake(clientIndex, dataASCIIEncoded);
             if (server.ClientConnected(clientIndex))
             {
                 oldDecodedFrame.Add(clientIndex, new List <byte>());
                 server.ReceiveDataAsync(clientIndex, ReceiveCallback);
             }
         }
         else
         {
             RejectConnection(clientIndex);
         }
     }
     catch (Exception)
     {
         CrestronLogger.WriteToLog("WS_SERVER - ConnectionCallback - connection error ", 8);
         RejectConnection(clientIndex);
     }
 }
Ejemplo n.º 2
0
 public void Disconnect(string args)
 {
     try
     {
         if (server == null)
         {
             CrestronConsole.PrintLine("Server is already disconnected");
             return;
         }
         if (args == "")
         { // When no arguments are provided, disconnect from all clients and destroy the server
             server.DisconnectAll();
             CrestronConsole.PrintLine("Server has disconnected from all clients and is no longer listening on port " + server.PortNumber);
             server = null;
         }
         else
         { // Disconnect from the client specified by the user
             uint clientIndex = uint.Parse(args);
             if (server.ClientConnected(clientIndex))
             {
                 server.Disconnect(clientIndex);
                 CrestronConsole.PrintLine("Server has disconnected from " + clientIndex);
             }
             else
             {
                 CrestronConsole.PrintLine("Client #" + clientIndex + " does not exist currently");
             }
         }
     }
     catch (Exception e)
     {
         PrintAndLog("Error in Disconnect: " + e.Message);
     }
 }
Ejemplo n.º 3
0
 /// <summary>
 /// Secure TCP Client Connected to Secure Server Callback
 /// </summary>
 /// <param name="mySecureTCPServer"></param>
 /// <param name="clientIndex"></param>
 void SecureConnectCallback(SecureTCPServer mySecureTCPServer, uint clientIndex)
 {
     if (mySecureTCPServer.ClientConnected(clientIndex))
     {
         if (SharedKeyRequired)
         {
             byte[] b = Encoding.GetEncoding(28591).GetBytes(SharedKey + "\n");
             mySecureTCPServer.SendDataAsync(clientIndex, b, b.Length, SecureSendDataAsyncCallback);
             Debug.Console(2, "Sent Shared Key to client at {0}", mySecureTCPServer.GetAddressServerAcceptedConnectionFromForSpecificClient(clientIndex));
         }
         if (HeartbeatRequired)
         {
             CTimer HeartbeatTimer = new CTimer(HeartbeatTimer_CallbackFunction, clientIndex, HeartbeatRequiredIntervalMs);
             HeartbeatTimerDictionary.Add(clientIndex, HeartbeatTimer);
         }
         mySecureTCPServer.ReceiveDataAsync(clientIndex, SecureReceivedDataAsyncCallback);
         if (mySecureTCPServer.State != ServerState.SERVER_LISTENING && MaxClients > 1 && !ServerStopped)
         {
             mySecureTCPServer.WaitForConnectionAsync(IPAddress.Any, SecureConnectCallback);
         }
     }
 }
        /// <summary>
        /// Disconnect All Clients
        /// </summary>
        public void DisconnectAllClientsForShutdown()
        {
            Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Disconnecting All Clients");
            if (SecureServer != null)
            {
                SecureServer.SocketStatusChange -= SecureServer_SocketStatusChange;
                foreach (var index in ConnectedClientsIndexes.ToList()) // copy it here so that it iterates properly
                {
                    var i = index;
                    if (!SecureServer.ClientConnected(index))
                    {
                        continue;
                    }
                    try
                    {
                        SecureServer.Disconnect(i);
                        Debug.Console(2, this, Debug.ErrorLogLevel.Notice, "Disconnected client index: {0}", i);
                    }
                    catch (Exception ex)
                    {
                        Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Error Disconnecting client index: {0}. Error: {1}", i, ex);
                    }
                }
                Debug.Console(2, this, Debug.ErrorLogLevel.Notice, "Server Status: {0}", SecureServer.ServerSocketStatus);
            }

            Debug.Console(2, this, Debug.ErrorLogLevel.Notice, "Disconnected All Clients");
            ConnectedClientsIndexes.Clear();

            if (!ProgramIsStopping)
            {
                OnConnectionChange();
                OnServerStateChange(SecureServer.State); //State shows both listening and connected
            }

            // var o = new { };
        }
Ejemplo n.º 5
0
        /// <summary>
        /// The callback for receiving data from the secure server client.
        /// </summary>
        /// <param name="server">The server the callback is executed on.</param>
        /// <param name="clientIndex">The index of the client data is received from.</param>
        /// <param name="count">The number of bytes of data received.</param>
        private void SecureReceiveDataCallback(SecureTCPServer server, uint clientIndex, int count)
        {
            if (count <= 0)
            {
                if (server.ClientConnected(clientIndex))
                {
                    server.ReceiveDataAsync(clientIndex, SecureReceiveDataCallback);
                }

                return;
            }

            var dataBuffer = server.GetIncomingDataBufferForSpecificClient(clientIndex);
            var data       = Encoding.UTF8.GetString(dataBuffer, 0, count);

            if (Regex.IsMatch(data, "^GET", RegexOptions.IgnoreCase))
            {
                var key = Regex.Match(data, "Sec-WebSocket-Key: (.*)").Groups[1].Value.Trim();
                key = key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
                byte[] keySha1 = Crestron.SimplSharp.Cryptography.SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(key));
                string sha64   = Convert.ToBase64String(keySha1);

                var responseMessage = "HTTP/1.1 101 Switching Protocols\r\n" +
                                      "Connection: Upgrade\r\n" +
                                      "Upgrade: websocket\r\n" +
                                      "Sec-WebSocket-Accept: " + sha64 + "\r\n\r\n";

                this.Send(responseMessage, clientIndex, false);
            }
            else
            {
                CrestronConsole.PrintLine("Received '{0}' bytes.", count);
                bool  fin        = (dataBuffer[0] & 128) != 0;
                bool  mask       = (dataBuffer[1] & 128) != 0;
                int   opcode     = dataBuffer[0] & 15;
                ulong dataLength = (ulong)(dataBuffer[1] - 128);
                ulong offset     = 2;

                if (opcode == 0x0)
                {
                    CrestronConsole.PrintLine("Received continuation frame opcode.");
                }
                else if (opcode == 0x1)
                {
                    CrestronConsole.PrintLine("Received text frame opcode.");
                }
                else if (opcode == 0x2)
                {
                    CrestronConsole.PrintLine("Received binary frame opcode.");
                }
                else if (opcode >= 0x3 && opcode <= 0x7)
                {
                    CrestronConsole.PrintLine("Received reserved non-control opcode.");
                }
                else if (opcode == 0x8)
                {
                    this.Send(new byte[]
                    {
                        BitConverter.GetBytes(0x88)[0],
                        BitConverter.GetBytes(0x00)[0]
                    }, clientIndex, false);
                    server.Disconnect(clientIndex);
                    CrestronConsole.PrintLine("Received disconnect OpCode. Disconnected.");
                    return;
                }
                else if (opcode == 0x9)
                {
                    this.Send(new byte[]
                    {
                        BitConverter.GetBytes(0x8A)[0],
                        BitConverter.GetBytes(0x00)[0]
                    }, clientIndex, false);
                    CrestronConsole.PrintLine("Received Ping and sent a Pong.");

                    if (server.ClientConnected(clientIndex))
                    {
                        server.ReceiveDataAsync(clientIndex, SecureReceiveDataCallback);
                    }

                    return;
                }
                else if (opcode == 0xA)
                {
                    CrestronConsole.PrintLine("Received Pong.");
                    if (server.ClientConnected(clientIndex))
                    {
                        server.ReceiveDataAsync(clientIndex, SecureReceiveDataCallback);
                    }

                    return;
                }
                else if (opcode >= 0xB && opcode <= 0xF)
                {
                    CrestronConsole.PrintLine("Received reserved control frame opcode.");
                }

                if (dataLength == 126)
                {
                    CrestronConsole.PrintLine("Data length is 126.");
                    dataLength = BitConverter.ToUInt16(new byte[] { dataBuffer[3], dataBuffer[2] }, 0);
                    offset     = 4;
                }
                else if (dataLength == 127)
                {
                    CrestronConsole.PrintLine("Data length is 127.");
                    dataLength = BitConverter.ToUInt64(new byte[] { dataBuffer[9], dataBuffer[8], dataBuffer[7], dataBuffer[6], dataBuffer[5], dataBuffer[4], dataBuffer[3], dataBuffer[2] }, 0);
                    offset     = 10;
                }

                if (dataLength == 0)
                {
                    CrestronConsole.PrintLine("Data length was zero.");
                    this.Send(string.Format("{0}>", InitialParametersClass.ControllerPromptName), clientIndex, true);
                }
                else if (mask)
                {
                    byte[] de = new byte[dataLength];
                    byte[] mk = new byte[4] {
                        dataBuffer[offset], dataBuffer[offset + 1], dataBuffer[offset + 2], dataBuffer[offset + 3]
                    };
                    offset += 4;

                    for (ulong i = 0; i < dataLength; i++)
                    {
                        de[i] = (byte)(dataBuffer[offset + i] ^ mk[i % 4]);
                    }

                    var text = Encoding.UTF8.GetString(de, 0, de.Length);
                    var dr   = DataReceived;
                    if (dr != null)
                    {
                        dr.Invoke(text, clientIndex);
                    }
                }
                else
                {
                    CrestronConsole.PrintLine("Data length was '{0}', but mask bit not set. Invalid message received.", dataLength);
                    var dbg = string.Empty;
                    for (var i = 0; i < count; i++)
                    {
                        dbg += string.Format("[{0}]", Convert.ToString(dataBuffer[i], 16));
                    }

                    Debug.WriteDebugLine(this, dbg);
                }
            }

            if (server.ClientConnected(clientIndex))
            {
                server.ReceiveDataAsync(clientIndex, SecureReceiveDataCallback);
            }
        }
        /// <summary>
        /// Secure TCP Client Connected to Secure Server Callback
        /// </summary>
        /// <param name="mySecureTCPServer"></param>
        /// <param name="clientIndex"></param>
        void SecureConnectCallback(SecureTCPServer server, uint clientIndex)
        {
            try
            {
                Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "ConnectCallback: IPAddress: {0}. Index: {1}. Status: {2}",
                              server.GetAddressServerAcceptedConnectionFromForSpecificClient(clientIndex),
                              clientIndex, server.GetServerSocketStatusForSpecificClient(clientIndex));
                if (clientIndex != 0)
                {
                    if (server.ClientConnected(clientIndex))
                    {
                        if (!ConnectedClientsIndexes.Contains(clientIndex))
                        {
                            ConnectedClientsIndexes.Add(clientIndex);
                        }
                        if (SharedKeyRequired)
                        {
                            if (!WaitingForSharedKey.Contains(clientIndex))
                            {
                                WaitingForSharedKey.Add(clientIndex);
                            }
                            byte[] b = Encoding.GetEncoding(28591).GetBytes("SharedKey:");
                            server.SendDataAsync(clientIndex, b, b.Length, (x, y, z) => { });
                            Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Sent Shared Key Request to client at {0}", server.GetAddressServerAcceptedConnectionFromForSpecificClient(clientIndex));
                        }
                        else
                        {
                            OnServerClientReadyForCommunications(clientIndex);
                        }
                        if (HeartbeatRequired)
                        {
                            if (!HeartbeatTimerDictionary.ContainsKey(clientIndex))
                            {
                                HeartbeatTimerDictionary.Add(clientIndex, new CTimer(HeartbeatTimer_CallbackFunction, clientIndex, HeartbeatRequiredIntervalMs));
                            }
                        }

                        server.ReceiveDataAsync(clientIndex, SecureReceivedDataAsyncCallback);
                    }
                }
                else
                {
                    Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Client attempt faulty.");
                }
            }
            catch (Exception ex)
            {
                Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Error in Socket Status Connect Callback. Error: {0}", ex);
            }

            // Rearm the listner
            SocketErrorCodes status = server.WaitForConnectionAsync(IPAddress.Any, SecureConnectCallback);

            if (status != SocketErrorCodes.SOCKET_OPERATION_PENDING)
            {
                Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Socket status connect callback status {0}", status);
                if (status == SocketErrorCodes.SOCKET_CONNECTION_IN_PROGRESS)
                {
                    // There is an issue where on a failed negotiation we need to stop and start the server. This should still leave connected clients intact.
                    server.Stop();
                    Listen();
                }
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Secure TCP Client Connected to Secure Server Callback
        /// </summary>
        /// <param name="mySecureTCPServer"></param>
        /// <param name="clientIndex"></param>
        void SecureConnectCallback(SecureTCPServer server, uint clientIndex)
        {
            try
            {
                Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "ConnectCallback: IPAddress: {0}. Index: {1}. Status: {2}",
                              server.GetAddressServerAcceptedConnectionFromForSpecificClient(clientIndex),
                              clientIndex, server.GetServerSocketStatusForSpecificClient(clientIndex));
                if (clientIndex != 0)
                {
                    if (server.ClientConnected(clientIndex))
                    {
                        if (!ConnectedClientsIndexes.Contains(clientIndex))
                        {
                            ConnectedClientsIndexes.Add(clientIndex);
                        }
                        if (SharedKeyRequired)
                        {
                            if (!WaitingForSharedKey.Contains(clientIndex))
                            {
                                WaitingForSharedKey.Add(clientIndex);
                            }
                            byte[] b = Encoding.GetEncoding(28591).GetBytes("SharedKey:");
                            server.SendDataAsync(clientIndex, b, b.Length, (x, y, z) => { });
                            Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Sent Shared Key Request to client at {0}", server.GetAddressServerAcceptedConnectionFromForSpecificClient(clientIndex));
                        }
                        else
                        {
                            OnServerClientReadyForCommunications(clientIndex);
                        }
                        if (HeartbeatRequired)
                        {
                            if (!HeartbeatTimerDictionary.ContainsKey(clientIndex))
                            {
                                HeartbeatTimerDictionary.Add(clientIndex, new CTimer(HeartbeatTimer_CallbackFunction, clientIndex, HeartbeatRequiredIntervalMs));
                            }
                        }

                        server.ReceiveDataAsync(clientIndex, SecureReceivedDataAsyncCallback);
                    }
                }
                else
                {
                    Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Client attempt faulty.");
                    if (!ServerStopped)
                    {
                        server.WaitForConnectionAsync(IPAddress.Any, SecureConnectCallback);
                        return;
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Error in Socket Status Connect Callback. Error: {0}", ex);
            }
            //Debug.Console(1, this, Debug.ErrorLogLevel, "((((((Server State bitfield={0}; maxclient={1}; ServerStopped={2}))))))",
            //    server.State,
            //    MaxClients,
            //    ServerStopped);
            if ((server.State & ServerState.SERVER_LISTENING) != ServerState.SERVER_LISTENING && MaxClients > 1 && !ServerStopped)
            {
                Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Waiting for next connection");
                server.WaitForConnectionAsync(IPAddress.Any, SecureConnectCallback);
            }
        }