public async Task Handle(NewAgentCheckin agentCheckinMsg, string replyTo, string correlationId)
        {
            Console.WriteLine($"[i] Got AgentCheckin Message.");


            Transport transport = _taskRepository.GetTransport(agentCheckinMsg.TransportId);


            // Check in agent
            Agent agent = _taskRepository.GetAgent(agentCheckinMsg.AgentName);

            agent.TransportId = agentCheckinMsg.TransportId;
            agent.ExternalIp  = agentCheckinMsg.SourceIp;
            agent.LastCheckin = DateTime.UtcNow;

            if (!agent.Visible)
            {
                agent.Visible = true;
                AgentUpdated update = new AgentUpdated();
                update.Success = true;
                update.Agent   = agent;
                _eventBus.Publish(update);
            }
            _taskRepository.Update(agent.Id, agent);

            AgentCheckinAnnouncement agentCheckinAnnouncement = new AgentCheckinAnnouncement();

            agentCheckinAnnouncement.Id            = agent.Id;
            agentCheckinAnnouncement.SourceIp      = agentCheckinMsg.SourceIp;
            agentCheckinAnnouncement.TransportId   = agentCheckinMsg.TransportId;
            agentCheckinAnnouncement.TransportName = transport.Name;
            agentCheckinAnnouncement.Received      = agent.LastCheckin.Value;
            _eventBus.Publish(agentCheckinAnnouncement);

            // Decode and Decrypt AgentTaskResponse
            if (!String.IsNullOrEmpty(agentCheckinMsg.Message))
            {
                AgentCheckin agentCheckin = new AgentCheckin();
                agentCheckin.SourceIp    = agentCheckinMsg.SourceIp;
                agentCheckin.TransportId = agentCheckinMsg.TransportId;
                agentCheckin.HMAC        = agentCheckinMsg.HMAC;
                agentCheckin.IV          = agentCheckinMsg.IV;
                agentCheckin.Message     = agentCheckinMsg.Message;
                agentCheckin.AgentId     = agent.Id;
                agentCheckin.Agent       = agent;
                _taskRepository.Add(agentCheckin);

                // Decrypt Message from Agent
                string decryptedMessage = Crypto.Decrypt(agentCheckin);
                Console.WriteLine($"Got response {decryptedMessage}");
                if (!agent.Visible)
                {
                    agent.Visible = true;
                    _taskRepository.Update(agent.Id, agent);
                }
                // Process taskResults
                // TODO: Probably a better way to check if the message is blank.
                if ((decryptedMessage != "[]") || (!String.IsNullOrEmpty(decryptedMessage)))
                {
                    List <AgentTaskUpdate> taskUpdates = JsonConvert.DeserializeObject <List <AgentTaskUpdate> >(decryptedMessage);
                    foreach (AgentTaskUpdate taskUpdate in taskUpdates)
                    {
                        taskUpdate.AgentTask = _taskRepository.GetAgentTask(taskUpdate.TaskName);
                        taskUpdate.AgentId   = taskUpdate.AgentTask.AgentId;
                        taskUpdate.Received  = DateTime.UtcNow;

                        foreach (IOC ioc in taskUpdate.IOCs)
                        {
                            ioc.UserId            = taskUpdate.AgentTask.ConsoleMessage.UserId.Value;
                            ioc.AgentTaskUpdateId = taskUpdate.Id;
                        }
                        _taskRepository.Add(taskUpdate);

                        if (taskUpdate.AgentTask.Action == "LOAD" && taskUpdate.Success.Value)
                        {
                            AgentsModulesXref xref = new AgentsModulesXref();
                            xref.AgentId = taskUpdate.AgentId;
                            string languageName = taskUpdate.Agent.AgentType.Language.Name;
                            string moduleName   = taskUpdate.AgentTask.Command.Split(" ")[1];
                            if (moduleName.Contains("/"))
                            {
                                languageName = moduleName.Split("/")[0];
                                moduleName   = moduleName.Split("/")[1];
                            }

                            Module loadedModule = _taskRepository.GetModule(moduleName, languageName);
                            xref.ModuleId = loadedModule.Id;
                            _taskRepository.Add(xref);

                            List <Command> loadedCommands = _taskRepository.GetCommands(loadedModule.Id);
                            foreach (Command loadedCommand in loadedCommands)
                            {
                                loadedCommand.Parameters = _taskRepository.GetCommandParameters(loadedCommand.Id);
                            }
                            AgentCommandsUpdated agentCommandsUpdated = new AgentCommandsUpdated();
                            agentCommandsUpdated.Success  = true;
                            agentCommandsUpdated.AgentId  = xref.AgentId;
                            agentCommandsUpdated.Commands = loadedCommands;
                            _eventBus.Publish(agentCommandsUpdated);
                        }

                        if (taskUpdate.Type == "File" && !String.IsNullOrEmpty(taskUpdate.Content))
                        {
                            WebClient       wc = new WebClient();
                            FactionSettings factionSettings = Utility.GetConfiguration();
                            wc.Headers[HttpRequestHeader.ContentType] = "application/json";
                            string rsp = wc.UploadString($"{apiUrl}/login/",
                                                         $"{{\"Username\":\"{factionSettings.SYSTEM_USERNAME}\", \"Password\":\"{factionSettings.SYSTEM_PASSWORD}\"}}");
                            Dictionary <string, string> responseDict = JsonConvert.DeserializeObject <Dictionary <string, string> >(rsp);
                            wc.Dispose();

                            string apiKeyName = responseDict["AccessKeyId"];
                            string apiSecret  = responseDict["AccessSecret"];
                            string uploadUrl  = $"{apiUrl}/file/?token={apiKeyName}:{apiSecret}";

                            Dictionary <string, string> upload = new Dictionary <string, string>();
                            upload.Add("AgentName", taskUpdate.Agent.Name);
                            upload.Add("FileName", taskUpdate.ContentId);
                            upload.Add("FileContent", taskUpdate.Content);

                            WebClient uploadClient = new WebClient();
                            uploadClient.Headers[HttpRequestHeader.ContentType] = "application/json";
                            string content = JsonConvert.SerializeObject(upload);
                            Console.WriteLine(content);
                            string uploadResponse = uploadClient.UploadString(uploadUrl, content);
                        }

                        ConsoleMessage consoleMessage = new ConsoleMessage();
                        consoleMessage.Agent       = taskUpdate.Agent;
                        consoleMessage.Type        = "AgentTaskResult";
                        consoleMessage.AgentTask   = taskUpdate.AgentTask;
                        consoleMessage.AgentTaskId = taskUpdate.AgentTask.Id;
                        consoleMessage.Display     = taskUpdate.Message;
                        _taskRepository.Add(consoleMessage);

                        ConsoleMessageAnnouncement response = new ConsoleMessageAnnouncement();
                        response.Success        = true;
                        response.Username       = consoleMessage.Agent.Name;
                        response.ConsoleMessage = consoleMessage;
                        _eventBus.Publish(response);
                    }
                }
            }
        }
        public static ConsoleMessage ProcessHelpMessage(ConsoleMessage consoleMessage)
        {
            ConsoleMessage consoleResponse = new ConsoleMessage();

            consoleResponse.AgentId = consoleMessage.AgentId;
            consoleResponse.UserId  = 1;

            consoleResponse.Received = DateTime.UtcNow;
            consoleResponse.Type     = "HelpResponse";

            // Remove the leading "HELP ", if we can't do this lets assume its just "help"
            string recievedCommand = "";

            try
            {
                recievedCommand = consoleMessage.Content.Remove(0, 5);
            }
            catch
            {
                consoleResponse.Display = $"Faction Agent Help:\n\n* 'show commands' will return a list of available commands.\n* 'show modules' will show available modules\n* 'help <command>` will give you details about a command\n* 'help <command> /<paramater>' will give you details about a commands paramter";
                return(consoleResponse);
            }

            FactionCommand factionCommand = ProcessCommand(recievedCommand);

            if (factionCommand.Arguments.Count > 0)
            {
                string           ParameterName = factionCommand.Arguments.Keys.Last().ToString();
                CommandParameter parameter;
                try
                {
                    parameter = _taskRepository.GetCommandParameter(factionCommand.Command, ParameterName);
                    if (String.IsNullOrEmpty(parameter.Help))
                    {
                        consoleResponse.Display = $"No help available for parameter: {parameter.Name} under command {factionCommand.Command}";
                    }
                    else
                    {
                        consoleResponse.Display = $"Name: {parameter.Name}\nRequired: {parameter.Required}\nAccepted Values: {parameter.Values}\n\n## Help\n{parameter.Help}";
                    }
                }
                catch
                {
                    consoleResponse.Display = $"No parameter named {ParameterName} found for command {factionCommand.Command}";
                }
            }
            else
            {
                try
                {
                    Command command = _taskRepository.GetCommand(factionCommand.Command);
                    if (String.IsNullOrEmpty(command.Help))
                    {
                        consoleResponse.Display = $"No help available for command {command.Name}";
                    }
                    else
                    {
                        consoleResponse.Display  = $"Name: {command.Name}";
                        consoleResponse.Display += $"\nDescription: {command.Description}";
                        consoleResponse.Display += $"\nMitre ATT&CK Reference: {command.MitreReference}";
                        consoleResponse.Display += $"\nOpsecSafe: {command.OpsecSafe}";
                        consoleResponse.Display += $"\nLoaded: {AgentDetails.IsCommandAvailable(command)}";
                        consoleResponse.Display += $"\n\nHelp:\n{command.Help}\n";
                        List <CommandParameter> parameters = _taskRepository.GetCommandParameters(command.Id);
                        if (parameters.Count() > 0)
                        {
                            string parameterText = "\nParameters:";
                            foreach (CommandParameter param in parameters)
                            {
                                parameterText += $"\nName: {param.Name}";
                                parameterText += $"\nRequired: {param.Required.ToString()}";
                                if (param.Position.HasValue)
                                {
                                    parameterText += $"\nPosition: {param.Position.Value.ToString()}";
                                }
                                else
                                {
                                    parameterText += $"\nPosition: N/A";
                                }
                                parameterText += $"\nHelp: {param.Help}\n";
                            }
                            consoleResponse.Display += parameterText;
                        }
                        if (!String.IsNullOrEmpty(command.Artifacts))
                        {
                            consoleResponse.Display += "\n\nArtifacts:";
                            string[] artifacts = command.Artifacts.Split(",");
                            foreach (string artifact in artifacts)
                            {
                                consoleResponse.Display += $"\n* {artifact}";
                            }
                        }
                        consoleResponse.Display += "\n";
                    }
                }
                catch
                {
                    consoleResponse.Display = $"No command found named {recievedCommand}";
                }
            }
            return(consoleResponse);
        }