Esempio n. 1
0
        /// <summary>
        /// This is used internally to remove a WebSocket connection from the authenticated clients (if present).
        /// </summary>
        /// <param name="conn">The connection to remove.</param>
        private void RemoveWith(IWebSocketConnection conn)
        {
            BlackTeaConnection client = null;

            lock (Clients)
            {
                foreach (var blackTeaConnection in Clients.ToList())
                {
                    if (blackTeaConnection.Connection.Equals(conn))
                    {
                        client = blackTeaConnection;
                        break;
                    }
                }
            }

            if (client != null)
            {
                //very unlikely that the collection has changed
                lock (Clients) if (Clients.Contains(client))
                    {
                        Clients.Remove(client);
                    }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// A client has connected to the websocket server.
        /// </summary>
        /// <param name="conn">The client to process.</param>
        private void OnOpen(IWebSocketConnection conn)
        {
            if (QEDector.IsAttacking(IPAddress.Parse((ReadOnlySpan <char>)conn.ConnectionInfo.ClientIpAddress)))
            {
                lock (AttackerAddresses)
                {
                    if (!AttackerAddresses.Contains(conn.ConnectionInfo.ClientIpAddress))
                    {
                        Push(
                            $"Under denial of service attack from: {conn.ConnectionInfo.ClientIpAddress}! The address has been booted from accessing the Web API server, for 5 minutes. Please take action!",
                            "-HIGHEST PRIORITY/CRITICAL-", Structures.MessageFlag.ConsoleLogMessage);
                        AttackerAddresses.Add(conn.ConnectionInfo.ClientIpAddress);
                    }
                }

                return;
            }
            conn.OnMessage = message =>
            {
                //we will handle AUTH and commands here.
                try
                {
                    BlackTeaConnection connection;
                    if (!ContainsWith(conn))
                    {
                        var cryptoResult = QEData.TryDecrypt(message);
                        if (cryptoResult != null)
                        {
                            connection = new BlackTeaConnection(conn, cryptoResult.Password);
                        }
                        else
                        {
                            var reject = new Structures.BaseMessage
                            {
                                Name = "reject",
                                Date = GetTime(),
                                Type = Structures.MessageFlag.LoginApiRejected
                            };
                            conn.Send(JsonSerializer.Serialize(reject));
                            Master.LogManager.LogDashboard(IPAddress.Parse(conn.ConnectionInfo.ClientIpAddress), "[CRITICAL WARN] Failed log-in attempt.");
                            conn.Close();
                            //we log the issue.
                            Logger.LogWarning($"Failed log-in attempt : {conn.ConnectionInfo.ClientIpAddress}.");
                            return;
                        }
                    }
                    else
                    {
                        connection = GetWith(conn);
                    }

                    var json = QEData.Decrypt(message, connection.Key);
                    if (json == null)
                    {
                        return;
                    }
                    var msg = JsonSerializer.Deserialize <Structures.BaseMessage>(json);
                    if (msg != null)
                    {
                        if (msg.Type.Equals(Structures.MessageFlag.LoginApiRequest))
                        {
                            //the client has entered an invalid key.
                            lock (ApiKeys) if (!ApiKeys.Contains(msg.Text))
                                {
                                    msg.Name = "reject";
                                    msg.Date = GetTime();
                                    msg.Type = Structures.MessageFlag.LoginApiRejected;
                                    conn.Send(JsonSerializer.Serialize(msg));
                                    Master.LogManager.LogDashboard(IPAddress.Parse(conn.ConnectionInfo.ClientIpAddress), "[CRITICAL WARN] Failed log-in attempt.");
                                    conn.Close();
                                    //we log the issue.
                                    Logger.LogWarning($"Failed log-in attempt : {conn.ConnectionInfo.ClientIpAddress} - key : {msg.Text}");
                                    return;
                                }
                            lock (Clients)
                            {
                                Clients.Add(connection);
                                Logger.LogWarning($"ImpostorHQ : New web admin client : {conn.ConnectionInfo.ClientIpAddress}");
                                msg.Text = "You have successfully connected to ImpostorHQ!";
                                msg.Type = Structures.MessageFlag.LoginApiAccepted;
                                msg.Name = "welcome";
                                msg.Date = GetTime();
                                conn.Send(JsonSerializer.Serialize(msg));
                                conn.OnClose += () =>
                                {
                                    //we handle the client disconnecting.
                                    RemoveWith(conn);
                                };
                            }
                        }
                        else if (msg.Type.Equals(Structures.MessageFlag.ConsoleCommand))
                        {
                            if (!ContainsWith(conn))
                            {
                                //we are being attacked.
                                //the client is sending commands without being logged in.
                                conn.Close();
                                RemoveWith(conn);
                                Logger.LogWarning($"Break-in attempt from : {conn.ConnectionInfo.ClientIpAddress}");
                                return;
                            }
                            MessageReceived(msg, conn);
                        }
                        else
                        {
                            //invalid API call.
                            //probably not a client.
                            conn.Close();
                        }
                    }
                }
                catch (Exception ex)
                {
                    //not JSON.
                    Console.WriteLine($"Fatal error occured : {ex}");
                    return;
                }
            };
        }