public static (MessageServer messageServer, IEnumerable <MessageClient> clients) CreateClientsAndServer([CallerMemberName] string systemName = "", params string[] clientNames)
        {
            //TODO: Get server name from somewhere else
            MessageClientIdentity serverInfo = new MessageClientIdentity(systemName, "Server", ECDiffieHellmanCurve.P256);

            MessageClientIdentity[] clientsInfo    = new MessageClientIdentity[clientNames.Count()];
            MessageClient[]         messageClients = new MessageClient[clientNames.Count()];

            for (int i = 0; i < clientNames.Count(); i++)
            {
                clientsInfo[i] = new MessageClientIdentity(systemName, clientNames[i], ECDiffieHellmanCurve.P256);

                messageClients[i] = new MessageClientConfigurationBuilder()
                                    .Identity(clientsInfo[i])
                                    .TrustCoordinatorIdentity(serverInfo)
                                    .RabbitMQServerHostName(Properties.Resources.RabbitMQServerName)
                                    .RabbitMQCredentials(Properties.Resources.Username, Properties.Resources.Password)
                                    .QueuesAreDurable(false)
                                    .AutoDeleteQueuesOnClose(true)
                                    .CreateMessageClient();
            }

            var messageServer = new MessageServerConfigurationBuilder()
                                .Identity(serverInfo)
                                .AddClientInfoRange(clientsInfo)
                                .RabbitMQServerHostName(Properties.Resources.RabbitMQServerName)
                                .RabbitMQCredentials(Properties.Resources.Username, Properties.Resources.Password)
                                .QueuesAreDurable(false)
                                .AutoDeleteQueuesOnClose(true)
                                .CreateMessageServer();

            return(messageServer, messageClients);
        }
Ejemplo n.º 2
0
        private void OpenKeyFile(string path)
        {
            var identity = MessageClientIdentity.ImportFromFile(path, () =>
            {
                //TODO: Need to popup up a password input box
                return("a");
            });

            propertyGrid.SelectedObject = identity;
        }
 public static MessageClient CreateClient(string clientName, MessageClientIdentity serverInfo, [CallerMemberName] string systemName = "")
 {
     return(new MessageClientConfigurationBuilder()
            .Identity(new MessageClientIdentity(systemName, clientName, ECDiffieHellmanCurve.P256))
            .TrustCoordinatorIdentity(serverInfo)
            .RabbitMQServerHostName(Properties.Resources.RabbitMQServerName)
            .RabbitMQCredentials(Properties.Resources.Username, Properties.Resources.Password)
            .QueuesAreDurable(false)
            .AutoDeleteQueuesOnClose(true)
            .CreateMessageClient());
 }
        public static (MessageServer messageServer, MessageClientIdentity serverInfo) CreateServer(string serverName, CngKey key, [CallerMemberName] string systemName = "", params MessageClientIdentity[] clientInfo)
        {
            //TODO: Get server name from somewhere else
            var serverInfo = new MessageClientIdentity(systemName, "Server", ECDiffieHellmanCurve.P256);

            return(new MessageServerConfigurationBuilder()
                   .Identity(serverInfo)
                   .AddClientInfoRange(clientInfo)
                   .RabbitMQServerHostName(Properties.Resources.RabbitMQServerName)
                   .RabbitMQCredentials(Properties.Resources.Username, Properties.Resources.Password)
                   .QueuesAreDurable(false)
                   .AutoDeleteQueuesOnClose(true)
                   .CreateMessageServer(), serverInfo);
        }
        public PushoverMessageClient(MessageClientIdentity identity, MessageClientIdentity serverIdentity, string rabbitMqServerHostName, string userName, string password, string pushoverAppApiKey, string pushoverUserKey, bool autoDeleteQueuesOnClose, bool queuesAreDurable, int heartbeatInterval, params MessageClientIdentity[] clientIdentities) :
            base(identity, serverIdentity, rabbitMqServerHostName, userName, password, autoDeleteQueuesOnClose, queuesAreDurable, heartbeatInterval, clientIdentities)
        {
            if (string.IsNullOrEmpty(pushoverAppApiKey))
            {
                throw new ArgumentException("A Pushover application API key must be supplied", nameof(pushoverAppApiKey));
            }

            if (string.IsNullOrEmpty(pushoverUserKey))
            {
                throw new ArgumentException("A Pushover user key must be supplied", nameof(pushoverUserKey));
            }

            pushoverClient       = new PushoverClient.Pushover(pushoverAppApiKey);
            this.pushoverUserKey = pushoverUserKey;

            this.MessageReceived += PushoverMessageClient_MessageReceived;
        }
        public void CreateAllEncryptedServerKeyFormats()
        {
            string path = Path.Combine(Path.GetTempPath(), "keyUtilTest");

            if (Directory.Exists(path))
            {
                Directory.Delete(path, true);
            }

            Directory.CreateDirectory(path);

            string systemName      = "aSystem";
            string baseKeyFilePath = Path.Combine(path, $"{systemName}-server");

            var proc = StartKeyUtil($"generate-server -s {systemName} --256 -j -l -u -d \"{path}\"", "pass1", "pass1");

            proc.StandardInput.WriteLine("pass1");
            proc.StandardInput.WriteLine("pass1");

            proc.WaitForExit();

            Assert.IsTrue(proc.ExitCode >= 0);

            Assert.IsTrue(File.Exists(baseKeyFilePath + ".priv"));
            Assert.IsTrue(File.Exists(baseKeyFilePath + ".privu"));
            Assert.IsTrue(File.Exists(baseKeyFilePath + ".privl"));
            Assert.IsTrue(File.Exists(baseKeyFilePath + ".pub"));

            var priv  = MessageClientIdentity.ImportFromFile(baseKeyFilePath + ".priv", "pass1");
            var privu = MessageClientIdentity.ImportFromFile(baseKeyFilePath + ".privu");
            var privl = MessageClientIdentity.ImportFromFile(baseKeyFilePath + ".privl");
            var pub   = MessageClientIdentity.ImportFromFile(baseKeyFilePath + ".pub");

            Assert.AreEqual(priv.IdentityHash, privu.IdentityHash);
            Assert.AreEqual(priv.IdentityHash, privl.IdentityHash);
            Assert.AreEqual(priv.IdentityHash, pub.IdentityHash);

            Directory.Delete(path, true);

            proc.Dispose();
        }
        public void IdentityInvalidUnitTest()
        {
            var clientIdent         = new MessageClientIdentity("system", "client", ECDiffieHellmanCurve.P256);
            var imposterClientIdent = new MessageClientIdentity("system", "client", ECDiffieHellmanCurve.P256);
            //TODO: WHere to get server name from?
            var serverIdent = new MessageClientIdentity("system", "Server", ECDiffieHellmanCurve.P256);

            var server = new MessageServerConfigurationBuilder()
                         .AddClientIdentity(clientIdent)
                         .AutoDeleteQueuesOnClose(true)
                         .QueuesAreDurable(false)
                         .Identity(serverIdent)
                         .CreateMessageServer();

            server.Connect(1000);

            var client = new MessageClientConfigurationBuilder()
                         .Identity(imposterClientIdent)
                         .TrustCoordinatorIdentity(serverIdent)
                         .QueuesAreDurable(false)
                         .AutoDeleteQueuesOnClose(true)
                         .CreateMessageClient();

            bool identityExceptionCaught = false;

            server.AsynchronousException += (sender, e) =>
            {
                if (e.Exception.GetType() == typeof(IdentityException))
                {
                    identityExceptionCaught = true;
                }
            };

            Pinknose.Utilities.CatchExceptionHelper.VerifyExceptionCaught <ConnectionException>(() => client.Connect(5000));
            Assert.IsTrue(identityExceptionCaught);

            // TODO:  Need the server to respond back to client saying the identity is invalid.
            Assert.IsTrue(false);
        }
Ejemplo n.º 8
0
        static void Main(string[] args)
        {
            // Assuming first argument is the JSON Configuration file name
            JObject config = JObject.Parse(File.ReadAllText(args[0]));

            var serverIdentity = MessageClientIdentity.Import(config["ServerIdentity"].ToString(), "monkey123");

            var clientsJArray = (JArray)config["ClientIdentities"];
            List <MessageClientIdentity> clients = new List <MessageClientIdentity>();

            foreach (var item in clientsJArray)
            {
                clients.Add(MessageClientIdentity.Import(item.ToString()));
            }

            var server = new MessageServerConfigurationBuilder()
                         .RabbitMQCredentials(config["RabbitMQServer"]["UserName"].Value <string>(), config["RabbitMQServer"]["Password"].Value <string>())
                         .RabbitMQServerHostName(config["RabbitMQServer"]["HostName"].Value <string>())
                         .Identity(serverIdentity)
                         .AddClientInfoRange(clients)
                         .AutoDeleteQueuesOnClose(true)
                         .QueuesAreDurable(false)
                         .CreateMessageServer();
        }
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            string systemName = "";
            string clientName = "";

            byte[]     iv         = null;
            byte[]     salt       = null;
            Encryption encryption = Encryption.None;
            string     curveOid   = "";
            string     d          = null;
            string     qx         = "";
            string     qy         = "";
            string     hash       = "";

            while (reader.Read())
            {
                if (reader.TokenType == JsonToken.PropertyName)
                {
                    string propertyName = (string)reader.Value;

                    reader.Read();

                    switch (propertyName)
                    {
                    case nameof(MessageClientIdentity.SystemName):
                        systemName = (string)reader.Value;
                        break;

                    case nameof(MessageClientIdentity.Name):
                        clientName = (string)reader.Value;
                        break;

                    case "IV":
                        iv = Convert.FromBase64String((string)reader.Value);
                        break;

                    case "Salt":
                        salt = Convert.FromBase64String((string)reader.Value);
                        break;

                    case "Encryption":
                        encryption = (Encryption)Enum.Parse(typeof(Encryption), (string)reader.Value);
                        break;

                    case "CurveOid":
                        curveOid = (string)reader.Value;
                        break;

                    case "D":
                        d = (string)reader.Value;
                        break;

                    case "Q.Y":
                        qy = (string)reader.Value;
                        break;

                    case "Q.X":
                        qx = (string)reader.Value;
                        break;

                    case "Hash":
                        hash = (string)reader.Value;
                        break;
                    }
                }
            }

            byte[] privateKey = null;

            if (d != null)
            {
                privateKey = Decrypt(Convert.FromBase64String(d), encryption, iv, salt, _password);
            }

            ECParameters ecParameters = new ECParameters()
            {
                Curve = ECCurve.CreateFromOid(new Oid(curveOid)),
                D     = d == null ? null : privateKey,
                Q     = new ECPoint()
                {
                    X = Convert.FromBase64String(qx),
                    Y = Convert.FromBase64String(qy)
                }
            };

            ECDiffieHellman dh;

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                dh = new ECDiffieHellmanCng();
            }
            else
            {
#if (!NET48)
                dh = new ECDiffieHellmanOpenSsl();
#else
                throw new NotSupportedException("ECDiffieHellmanOpenSsl is not supported in .NET 4.8");
#endif
            }

            dh.ImportParameters(ecParameters);

            var ident = new MessageClientIdentity(systemName, clientName, dh, !string.IsNullOrEmpty(d));

            if (ident.IdentityHash != hash)
            {
                throw new NotImplementedException();
            }

            return(ident);
        }
Ejemplo n.º 10
0
        public TConfigType AddClientIdentity(MessageClientIdentity clientIdentity)
        {
            _clientIdentities.Add(clientIdentity);

            return((TConfigType)(object)this);
        }
        private void createButton_Click(object sender, EventArgs e)
        {
            Success = false;

            if (!jsonFormatCheckBox.Checked &&
                !currentUserCheckBox.Checked &&
                !localMachineCheckBox.Checked)
            {
                ShowError("At least one private key format must be selected.");
                return;
            }

            if (jsonFormatCheckBox.Checked &&
                string.IsNullOrEmpty(passwordTextBox1.Text) &&
                string.IsNullOrEmpty(passwordTextBox2.Text))
            {
                if (MessageBox.Show("Saving the private key (JSON format) without encryption is dangerous.  Are you sure you want to save it unencrypted?  Click 'OK' if you want to continue saving the encrypted key.",
                                    "Empty Password",
                                    MessageBoxButtons.OKCancel,
                                    MessageBoxIcon.Exclamation) == DialogResult.Cancel)
                {
                    return;
                }
            }

            if (jsonFormatCheckBox.Checked &&
                passwordTextBox1.Text !=
                passwordTextBox2.Text)
            {
                ShowError("Passwords do not match.  Identity creation is canceled.");
                return;
            }

            if (string.IsNullOrEmpty(systemNameTextBox.Text) ||
                string.IsNullOrEmpty(clientNameTextBox.Text))
            {
                ShowError("System and Client names cannot be empty.");
                return;
            }

            folderBrowserDialog.SelectedPath = FolderPath;

            if (folderBrowserDialog.ShowDialog() == DialogResult.Cancel)
            {
                ShowCreationCanceledMessageBox();
                return;
            }

            FolderPath = folderBrowserDialog.SelectedPath;

            var curve = (ECDiffieHellmanCurve)curveComboBox.SelectedItem;

            var identity = new MessageClientIdentity(this.systemNameTextBox.Text, this.clientNameTextBox.Text, curve);

            string filePath = Path.Combine(FolderPath, this.systemNameTextBox.Text + "-" + this.clientNameTextBox.Text);

            File.WriteAllText(filePath + ".pub", identity.SerializePublicInfoToJson());

            if (jsonFormatCheckBox.Checked && this.passwordTextBox1.Text != "")
            {
                File.WriteAllText(filePath + ".priv", identity.SerializePrivateInfoToJson(Encryption.Password, this.passwordTextBox1.Text));
            }
            else if (jsonFormatCheckBox.Checked)
            {
                File.WriteAllText(filePath + ".priv", identity.SerializePrivateInfoToJson(Encryption.None));
            }

            if (currentUserCheckBox.Checked)
            {
                File.WriteAllText(filePath + ".privu", identity.SerializePrivateInfoToJson(Encryption.CurrentUser));
            }

            if (localMachineCheckBox.Checked)
            {
                File.WriteAllText(filePath + ".privl", identity.SerializePrivateInfoToJson(Encryption.LocalMachine));
            }

            MessageBox.Show("Client identity creation complete.", "Operation Complete", MessageBoxButtons.OK, MessageBoxIcon.Information);
            Success = true;
            this.Close();
        }
Ejemplo n.º 12
0
        private static void GenerateKey(GenerateClientOptions generateClientOptions, GenerateServerOptions generateServerOptions)
        {
            StringBuilder sb = new StringBuilder();

            MessageClientIdentity clientInfo          = null;
            GenerateOptionsBase   generateOptionsBase = generateClientOptions != null ? (GenerateOptionsBase)generateClientOptions : (GenerateOptionsBase)generateServerOptions;

            if (generateOptionsBase.Directory == null)
            {
                generateOptionsBase.Directory = Directory.GetCurrentDirectory();
            }
            else if (!Directory.Exists(generateOptionsBase.Directory))
            {
                Console.WriteLine($"{generateOptionsBase.Directory} is not a valid directory.");
                Environment.Exit(-1);
            }

            ECDiffieHellmanCurve curve = ECDiffieHellmanCurve.P256;

            if (generateOptionsBase.KeySize256)
            {
                curve = ECDiffieHellmanCurve.P256;
            }
            else if (generateOptionsBase.KeySize384)
            {
                curve = ECDiffieHellmanCurve.P384;
            }
            else if (generateOptionsBase.KeySize521)
            {
                curve = ECDiffieHellmanCurve.P521;
            }

            if (generateClientOptions != null)
            {
                clientInfo = new MessageClientIdentity(generateClientOptions.SystemName, generateClientOptions.ClientName, curve);
            }
            else if (generateServerOptions != null)
            {
                //TODO: Need to get server name from somehwere else.
                clientInfo = new MessageClientIdentity(generateServerOptions.SystemName, "Server", curve);
            }

            string path = Path.Combine(generateOptionsBase.Directory, clientInfo.SystemName + "-" + clientInfo.Name);

            string publicFile = path + ".pub";

            File.WriteAllText(publicFile, clientInfo.SerializePublicInfoToJson());

            sb.AppendLine("\nCreating Client Key");
            sb.AppendLine($"   Diffie-Hellman Elliptic Curve             {curve}");
            sb.AppendLine($"   System Name:                              {clientInfo.SystemName}");
            sb.AppendLine($"   Client Name:                              {clientInfo.Name}");
            sb.AppendLine($"   Identity Hash:                            {clientInfo.IdentityHash}");
            sb.AppendLine($"   Public Key File:                          {publicFile}");

            //Console.WriteLine($"   Private Key File:              {privateFile}");

            // Private Key saving

            if (generateOptionsBase.JsonPrivateKey)
            {
                string password    = "";
                bool   match       = false;
                string privateFile = path + ".priv";

                do
                {
                    do
                    {
                        Console.Write("Enter password: "******"Re-enter password: "******"Passwords do not match.");
                            match = false;
                        }
                        else
                        {
                            match = true;
                        }
                    } while (!match);

                    if (password == "")
                    {
                        Console.Write("You have entered a blank password.  Are you sure you want to save the private key without a password (not recommended!)? Type YES to continue without password: "******"YES")
                        {
                            Console.WriteLine();
                            File.WriteAllText(privateFile, clientInfo.SerializePrivateInfoToJson(Encryption.None));
                            sb.AppendLine($"   Unencrypted Private Key File:             {privateFile}");
                            break;
                        }
                    }
                    else
                    {
                        File.WriteAllText(privateFile, clientInfo.SerializePrivateInfoToJson(Encryption.Password, password));
                        sb.AppendLine($"   Password-Protected Private Key File:      {privateFile}");
                        break;
                    }
                } while (true);

                Console.WriteLine();
            }

            if (generateOptionsBase.LocalMachineEncryptedPrivateKey)
            {
                string privateFile = path + ".privl";

                File.WriteAllText(privateFile, clientInfo.SerializePrivateInfoToJson(Encryption.LocalMachine));
                sb.AppendLine($"   Current User-Encrypted Private Key File:  {privateFile}");
            }

            if (generateOptionsBase.CurrentUserEncryptedPrivateKey)
            {
                string privateFile = path + ".privu";

                File.WriteAllText(privateFile, clientInfo.SerializePrivateInfoToJson(Encryption.CurrentUser));
                sb.AppendLine($"   Local Machine-Encrypted Private Key File: {privateFile}");
            }

            Console.WriteLine(sb.ToString());

            // TEMP Test Code
            //var idu = MessageClientIdentity.ImportFromFile(path + ".privu");
            //var idl = MessageClientIdentity.ImportFromFile(path + ".privl");
            //var idj = MessageClientIdentity.ImportFromFile(path + ".priv", "duhh");
        }
 internal ClientAnnounceMessage(MessageClientIdentity clientIdentity) :
     base()
 {
     ClientIdentity = clientIdentity;
 }
Ejemplo n.º 14
0
        public TConfigType TrustCoordinatorIdentity(MessageClientIdentity trustCoordinatorIdentity)
        {
            _trustCoordinatorIdentity = trustCoordinatorIdentity;

            return((TConfigType)(object)this);
        }
Ejemplo n.º 15
0
#pragma warning restore CA1051 // Do not declare visible instance fields

        #endregion Fields

        #region Methods

        public TConfigType Identity(MessageClientIdentity identity)
        {
            _thisIdentity = identity;

            return((TConfigType)(object)this);
        }
    //internal TServerQueue LogQueue { get; private set; }

    #region Constructors

    protected MessageClientBase(MessageClientIdentity clientInfo, string rabbitMqServerHostName, string userName, string password, bool autoDeleteQueuesOnClose, bool queuesAreDurable) :
        base(clientInfo, rabbitMqServerHostName, userName, password, autoDeleteQueuesOnClose, queuesAreDurable)
    {
    }
Ejemplo n.º 17
0
 public PublicKeyUpdate(MessageClientIdentity clientInfo) : base()
 {
     ClientInfo = clientInfo;
 }
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            if (value is null)
            {
                throw new ArgumentNullException(nameof(value));
            }

            MessageClientIdentity clientIdent = (MessageClientIdentity)value;

            JObject jObject = new JObject();

            jObject.Add(nameof(MessageClientIdentity.SystemName), clientIdent.SystemName);
            jObject.Add(nameof(MessageClientIdentity.Name), clientIdent.Name);

            ECParameters parms = clientIdent.ECDiffieHellman.ExportParameters(_savePrivateKey);

            if (!parms.Curve.IsNamed)
            {
                throw new NotImplementedException();
            }

            jObject.Add("CurveOid", parms.Curve.Oid.Value);

            if (parms.D != null && _savePrivateKey)
            {
                byte[] privateKey = parms.D;

                if (_encryptionType == Encryption.Password)
                {
                    using var random = RNGCryptoServiceProvider.Create();
                    byte[] salt = new byte[SaltSize];
                    random.GetBytes(salt);

                    using Rfc2898DeriveBytes deriveBytes = new Rfc2898DeriveBytes(_password, salt, KeyDerivationIterations, HashAlgorithmName.SHA512);
                    Aes aes;
                    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                    {
                        aes = new AesCng();
                    }
                    else
                    {
                        aes = new AesManaged();
                    }
                    aes.Key = deriveBytes.GetBytes(aes.KeySize / 8);

                    jObject.Add("Salt", salt);
                    jObject.Add("IV", aes.IV);

                    using var encryptor = aes.CreateEncryptor();
                    privateKey          = encryptor.TransformFinalBlock(privateKey, 0, privateKey.Length);

                    aes.Dispose();
                }
                else if (_encryptionType == Encryption.LocalMachine)
                {
                    privateKey = ProtectedData.Protect(privateKey, null, DataProtectionScope.LocalMachine);
                }
                else if (_encryptionType == Encryption.CurrentUser)
                {
                    privateKey = ProtectedData.Protect(privateKey, null, DataProtectionScope.CurrentUser);
                }

                jObject.Add("Encryption", _encryptionType.ToString());

                jObject.Add("D", privateKey);
            }

            jObject.Add("Q.X", parms.Q.X);
            jObject.Add("Q.Y", parms.Q.Y);

            jObject.Add("Hash", clientIdent.IdentityHash);
            jObject.WriteTo(writer);
        }
Ejemplo n.º 19
0
        private static void Main(string[] args)
        {
            // Get secrets
            var devEnvironmentVariable = Environment.GetEnvironmentVariable("NETCORE_ENVIRONMENT");
            var isDevelopment          = string.IsNullOrEmpty(devEnvironmentVariable) || devEnvironmentVariable.ToLower() == "development";

            string secretsPath = Path.Combine(
                Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
                @"Microsoft\UserSecrets\9a735c2c-ec7a-4c5a-936e-7210fc978f5d",
                "secrets.json");

            var secrets = JsonConvert.DeserializeObject <UserSecrets>(File.ReadAllText(secretsPath));

            // Do everything else

            int val = 0;

            string systemName         = "aSystem";
            string rabbitMQServerName = "garage";
            string userName           = "******";
            string password           = "******";

            var duhh1 = AesCng.Create();


            CngProvider provider = new CngProvider("dumdum");


            var random = new Random();

            UInt32 key = random.NextUInt32();
            UInt32 iv  = random.NextUInt32();

            (var cipherText, var signature) = SimpleCBC.Encode("Hi", key, iv, 2);

            var sig = BitConverter.GetBytes(signature);

            var duhh    = System.Text.Encoding.UTF8.GetString(cipherText);
            var message = SimpleCBC.Decode(cipherText, key, iv, 2);


            var errorTag = new MessageTagValue("Severity", "Error");
            var infoTag  = new MessageTagValue("Severity", "Info");
            var debugTag = new MessageTagValue("Severity", "Debug");

            using var serverPublicInfo  = MessageClientIdentity.ImportFromFile(@"Keys\system-server.pub");
            using var serverPrivateInfo = MessageClientIdentity.ImportFromFile(@"Keys\system-server.priv", "abc");

            using var coordinatorPublicInfo  = MessageClientIdentity.ImportFromFile(@"Keys\system-coordinator.pub");
            using var coordinatorPrivateInfo = MessageClientIdentity.ImportFromFile(@"Keys\system-coordinator.priv", "monkey123");

            using var client1PublicInfo  = MessageClientIdentity.ImportFromFile(@"Keys\system-client1.pub");
            using var client1PrivateInfo = MessageClientIdentity.ImportFromFile(@"Keys\system-client1.priv", "abc");

            using var client2PublicInfo  = MessageClientIdentity.ImportFromFile(@"Keys\system-client2.pub");
            using var client2PrivateInfo = MessageClientIdentity.ImportFromFile(@"Keys\system-client2.priv", "abc");

            using var client3PublicInfo  = MessageClientIdentity.ImportFromFile(@"Keys\system-client3.pub");
            using var client3PrivateInfo = MessageClientIdentity.ImportFromFile(@"Keys\system-client3.priv", "abc");

            //using var pushoverPublicInfo = MessageClientIdentity.ImportFromFile(@"Keys\system-pushoverClient.pub");
            //using var pushoverPrivateInfo = MessageClientIdentity.ImportFromFile(@"Keys\system-pushoverClient.priv", "abc");


            Console.WriteLine(serverPublicInfo.IdentityHash);
            Console.WriteLine(client1PublicInfo.IdentityHash);
            Console.WriteLine(client2PublicInfo.IdentityHash);
            Console.WriteLine(client3PublicInfo.IdentityHash);



            var xbeeModule        = new XBeeNetworkGatewayModule("COM8", new SerialPortParameters(115200, 8, StopBits.One, Parity.None, Handshake.None));
            var coordinatorModule = new TrustCoordinatorModule(TimeSpan.FromMinutes(1));

            var server = new MessageClientConfigurationBuilder()
                         .RabbitMQCredentials(userName, password)
                         .RabbitMQServerHostName(rabbitMQServerName)
                         .Identity(coordinatorPrivateInfo)
                         .AddClientIdentity(client1PublicInfo)
                         .AddClientIdentity(client2PublicInfo)
                         .AddClientIdentity(client3PublicInfo)
                         //.AddClientIdentity(pushoverPublicInfo)
                         .AutoDeleteQueuesOnClose(true)
                         .QueuesAreDurable(false)
                         .AddModule(coordinatorModule)
                         .AddModule(xbeeModule)
                         .CreateMessageClient();


#if false
            var server = new MessageServerConfigurationBuilder()
                         .RabbitMQCredentials(userName, password)
                         .RabbitMQServerHostName(rabbitMQServerName)
                         .Identity(serverPrivateInfo)
                         .AddClientIdentity(client1PublicInfo)
                         .AddClientIdentity(client2PublicInfo)
                         .AddClientIdentity(client3PublicInfo)
                         //.AddClientIdentity(pushoverPublicInfo)
                         .AutoDeleteQueuesOnClose(true)
                         .QueuesAreDurable(false)
                         .CreateMessageServer();
#endif

            server.MessageReceived += (sender, e) =>
            {
                e.Response = MessageResponse.Ack;

                if (e.MessageEnevelope.Message.GetType() == typeof(XBeeFromXBeeMessage))
                {
                    var tempMessage = (XBeeFromXBeeMessage)e.MessageEnevelope.Message;

                    Log.Verbose($"{tempMessage.XBeeSourceAddress}: {tempMessage.RawData}");
                }
            };

            server.AsynchronousException += Client_AsynchronousException;

            System.Timers.Timer sendTimer = new System.Timers.Timer(1000)
            {
                AutoReset = true
            };

            sendTimer.Elapsed += (sender, e) =>
            {
                IntMessage message = new IntMessage(val);

                string tag = val % 2 == 0 ? "even" : "odd";

                server.WriteToSubscriptionQueues(message, true, new MessageTagValue("duhh", tag), errorTag, infoTag);
                val++;

                //server.BroacastToAllClients(message);
            };

            Log.Logger = new LoggerConfiguration()
                         .MinimumLevel.Verbose()
                         //.WriteTo.DistributedWorkersSink(server)
                         .WriteTo.Console()
                         .CreateLogger();

            //Log.Verbose($"Server public string: {serverInfo.PublicKey.PublicKeyToString()}");

            server.Connect(TimeSpan.FromSeconds(20));
            sendTimer.Start();

            //Thread.Sleep(30000);

            var odd   = new MessageTagValue("duhh", "odd");
            var even  = new MessageTagValue("duhh", "even");
            var never = new MessageTagValue("duhh", "never");

#if false
            var pushoverModule = new PushoverModule(secrets.PushoverAppApiKey, secrets.PushoverUserKey);
            pushoverModule.AddTransform <IntMessage>(t =>
            {
                if (t.Payload % 10 == 0)
                {
                    return(null); // (t.Payload.ToString());
                }

                return(null);
            });
#endif



            // TODO: Not all configuration options return the right configuration builder type
#if false
            var pushoverClient = new PushoverMessageClientConfigurationBuilder()
                                 .PushoverAppApiKey(secrets.PushoverAppApiKey)
                                 .PushoverUserKey(secrets.PushoverUserKey)
                                 .RabbitMQCredentials(userName, password)
                                 .RabbitMQServerHostName(rabbitMQServerName)
                                 .ServerIdentity(serverPublicInfo)
                                 .Identity(pushoverPrivateInfo)
                                 .AutoDeleteQueuesOnClose(true)
                                 .QueuesAreDurable(false)
                                 .CreateMessageClient();


            pushoverClient.AddTransform <IntMessage>(t =>
            {
                if (t.Payload % 10 == 0)
                {
                    return(null); // (t.Payload.ToString());
                }

                return(null);
            });

            pushoverClient.AsynchronousException += Client_AsynchronousException;
            pushoverClient.Connect(20000);
#endif

            AzureIoTModule iotModule = new AzureIoTModule(secrets.AzureIoTHubConnectionString);
            iotModule.ForwardMessageToIoTHubTransform = (me) =>
            {
                return(null);

                if (me.Message.GetType() == typeof(XBeeFromXBeeMessage))
                {
                    var xBeeMessage = (XBeeFromXBeeMessage)me.Message;

                    var iotMessage = new Microsoft.Azure.Devices.Client.Message();

                    var tempData = xBeeMessage.GetJObject()["Data"];

                    iotMessage.Properties.Add("Refrigerator Temperature", tempData[0]["Refrigerator"].ToString());
                    iotMessage.Properties.Add("Freezer Temperature", tempData[1]["Freezer"].ToString());

                    return(iotMessage);
                }

                return(null);
            };

            MessageClient client1 = new MessageClientConfigurationBuilder()
                                    .RabbitMQCredentials(userName, password)
                                    .RabbitMQServerHostName(rabbitMQServerName)
                                    .TrustCoordinatorIdentity(coordinatorPublicInfo)
                                    .Identity(client1PrivateInfo)
                                    .AutoDeleteQueuesOnClose(true)
                                    .QueuesAreDurable(false)
                                    //.AddModule(pushoverModule)
                                    .AddModule(iotModule)
                                    .CreateMessageClient();

            xbeeModule.OpenXBee();

            client1.AsynchronousException += Client_AsynchronousException;

            client1.MessageReceived += (sender, e) =>
            {
                e.Response = MessageResponse.Ack;

                if (e.MessageEnevelope.Message.GetType() == typeof(IntMessage))
                {
                    Console.WriteLine($"Client 1: Message Payload: {((IntMessage)e.MessageEnevelope.Message).Value}.");
                }
            };
            client1.Connect(TimeSpan.FromSeconds(10), odd, new XBeeReceivedDataTag());
            client1.BeginFullWorkConsume(true);

            MessageClient client2 = new MessageClientConfigurationBuilder()
                                    .RabbitMQCredentials(userName, password)
                                    .RabbitMQServerHostName(rabbitMQServerName)
                                    .TrustCoordinatorIdentity(coordinatorPublicInfo)
                                    .Identity(client2PrivateInfo)
                                    .AutoDeleteQueuesOnClose(true)
                                    .QueuesAreDurable(false)
                                    .CreateMessageClient();

            client2.AsynchronousException += Client_AsynchronousException;

            client2.MessageReceived += (sender, e) =>
            {
                e.Response = MessageResponse.Ack;
                if (e.MessageEnevelope.Message.GetType() == typeof(IntMessage))
                {
                    Console.WriteLine($"Client 2: Message Payload: {((IntMessage)e.MessageEnevelope.Message).Value}.");
                }
                else if (e.MessageEnevelope.Message.GetType() == typeof(XBeeFromXBeeMessage))
                {
                    var tempMessage = (XBeeFromXBeeMessage)e.MessageEnevelope.Message;

                    Console.WriteLine($"Client 2 XBee ({tempMessage.XBeeSourceAddress}): {tempMessage.RawData}");
                }
            };
            client2.Connect(TimeSpan.FromSeconds(10), even, new XBeeReceivedDataTag());
            //client2.BeginFullWorkConsume(true);

#if false
            MessageClient client3 = new MessageClientConfiguration()
                                    .RabbitMQCredentials(userName, password)
                                    .RabbitMQServer(rabbitMQServerName)
                                    .ServerInfo(serverInfo)
                                    .ClientInfo(client3Info)
                                    .AutoDeleteQueuesOnClose(true)
                                    .QueuesAreDurable(false)
                                    .CreateMessageClient();
            client3.MessageReceived += (sender, e) =>
            {
                e.Response = MessageResponse.Ack;
                Console.WriteLine($"Client 3: Message Payload: {((IntMessage)e.MessageEnevelope.Message).Payload}.");
            };

            client3.BeginFullWorkConsume(true);
#endif

            //
            //client3.Connect(TimeSpan.FromSeconds(10));


            var serialPort = new XBeeRemoteSerialPort(xbeeModule, new SerializableXBeeAddress(new XBee64BitAddress("0013A20041AE9E32")));

            Log.Information("Dumdum");

            Console.ReadKey();
        }