public static void Main(string[] args)
        {
            var currentPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            var certificate = new X509Certificate2(
                // ReSharper disable once AssignNullToNotNullAttribute
                Path.Combine(currentPath, "certificate.pfx"),
                "test",
                X509KeyStorageFlags.Exportable);

            Log.Logger = new LoggerConfiguration().MinimumLevel.Debug().WriteTo.File(
                Path.Combine(currentPath, @"log\NetCoreMQTTExampleJsonConfigHashedPasswords_.txt"),
                rollingInterval: RollingInterval.Day).CreateLogger();

            var config = ReadConfiguration(currentPath);

            var optionsBuilder = new MqttServerOptionsBuilder()
#if DEBUG
                                 .WithDefaultEndpoint().WithDefaultEndpointPort(1883)
#else
                                 .WithoutDefaultEndpoint()
#endif
                                 .WithEncryptedEndpoint().WithEncryptedEndpointPort(config.Port)
                                 .WithEncryptionCertificate(certificate.Export(X509ContentType.Pfx))
                                 .WithEncryptionSslProtocol(SslProtocols.Tls12).WithConnectionValidator(
                c =>
            {
                var currentUser = config.Users.FirstOrDefault(u => u.UserName == c.Username);

                if (currentUser == null)
                {
                    c.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
                    LogMessage(c, true);
                    return;
                }

                if (c.Username != currentUser.UserName)
                {
                    c.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
                    LogMessage(c, true);
                    return;
                }

                var hashingResult = Hasher.VerifyHashedPassword(currentUser, currentUser.Password, c.Password);

                if (hashingResult == PasswordVerificationResult.Failed)
                {
                    c.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
                    LogMessage(c, true);
                    return;
                }

                if (!currentUser.ValidateClientId)
                {
                    c.ReasonCode = MqttConnectReasonCode.Success;
                    c.SessionItems.Add(c.ClientId, currentUser);
                    LogMessage(c, false);
                    return;
                }

                if (string.IsNullOrWhiteSpace(currentUser.ClientIdPrefix))
                {
                    if (c.ClientId != currentUser.ClientId)
                    {
                        c.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
                        LogMessage(c, true);
                        return;
                    }

                    c.SessionItems.Add(currentUser.ClientId, currentUser);
                }
                else
                {
                    if (!ClientIdPrefixesUsed.Contains(currentUser.ClientIdPrefix))
                    {
                        ClientIdPrefixesUsed.Add(currentUser.ClientIdPrefix);
                    }

                    c.SessionItems.Add(currentUser.ClientIdPrefix, currentUser);
                }

                c.ReasonCode = MqttConnectReasonCode.Success;
                LogMessage(c, false);
            }).WithSubscriptionInterceptor(
                c =>
            {
                var clientIdPrefix = GetClientIdPrefix(c.ClientId);
                User currentUser;
                bool userFound;

                if (clientIdPrefix == null)
                {
                    userFound   = c.SessionItems.TryGetValue(c.ClientId, out var currentUserObject);
                    currentUser = currentUserObject as User;
                }
                else
                {
                    userFound   = c.SessionItems.TryGetValue(clientIdPrefix, out var currentUserObject);
                    currentUser = currentUserObject as User;
                }

                if (!userFound || currentUser == null)
                {
                    c.AcceptSubscription = false;
                    LogMessage(c, false);
                    return;
                }

                var topic = c.TopicFilter.Topic;

                if (currentUser.SubscriptionTopicLists.BlacklistTopics.Contains(topic))
                {
                    c.AcceptSubscription = false;
                    LogMessage(c, false);
                    return;
                }

                if (currentUser.SubscriptionTopicLists.WhitelistTopics.Contains(topic))
                {
                    c.AcceptSubscription = true;
                    LogMessage(c, true);
                    return;
                }

                // ReSharper disable once ForeachCanBeConvertedToQueryUsingAnotherGetEnumerator
                foreach (var forbiddenTopic in currentUser.SubscriptionTopicLists.BlacklistTopics)
                {
                    var doesTopicMatch = TopicChecker.Regex(forbiddenTopic, topic);
                    if (!doesTopicMatch)
                    {
                        continue;
                    }

                    c.AcceptSubscription = false;
                    LogMessage(c, false);
                    return;
                }

                // ReSharper disable once ForeachCanBeConvertedToQueryUsingAnotherGetEnumerator
                foreach (var allowedTopic in currentUser.SubscriptionTopicLists.WhitelistTopics)
                {
                    var doesTopicMatch = TopicChecker.Regex(allowedTopic, topic);
                    if (!doesTopicMatch)
                    {
                        continue;
                    }

                    c.AcceptSubscription = true;
                    LogMessage(c, true);
                    return;
                }

                c.AcceptSubscription = false;
                LogMessage(c, false);
            }).WithApplicationMessageInterceptor(
                c =>
            {
                var clientIdPrefix = GetClientIdPrefix(c.ClientId);
                User currentUser;
                bool userFound;

                if (clientIdPrefix == null)
                {
                    userFound   = c.SessionItems.TryGetValue(c.ClientId, out var currentUserObject);
                    currentUser = currentUserObject as User;
                }
                else
                {
                    userFound   = c.SessionItems.TryGetValue(clientIdPrefix, out var currentUserObject);
                    currentUser = currentUserObject as User;
                }

                if (!userFound || currentUser == null)
                {
                    c.AcceptPublish = false;
                    return;
                }

                var topic = c.ApplicationMessage.Topic;

                if (currentUser.ThrottleUser)
                {
                    var payload = c.ApplicationMessage?.Payload;

                    if (payload != null)
                    {
                        if (currentUser.MonthlyByteLimit != null)
                        {
                            if (IsUserThrottled(c.ClientId, payload.Length, currentUser.MonthlyByteLimit.Value))
                            {
                                c.AcceptPublish = false;
                                return;
                            }
                        }
                    }
                }

                if (currentUser.PublishTopicLists.BlacklistTopics.Contains(topic))
                {
                    c.AcceptPublish = false;
                    return;
                }

                if (currentUser.PublishTopicLists.WhitelistTopics.Contains(topic))
                {
                    c.AcceptPublish = true;
                    LogMessage(c);
                    return;
                }

                // ReSharper disable once ForeachCanBeConvertedToQueryUsingAnotherGetEnumerator
                foreach (var forbiddenTopic in currentUser.PublishTopicLists.BlacklistTopics)
                {
                    var doesTopicMatch = TopicChecker.Regex(forbiddenTopic, topic);
                    if (!doesTopicMatch)
                    {
                        continue;
                    }

                    c.AcceptPublish = false;
                    return;
                }

                // ReSharper disable once ForeachCanBeConvertedToQueryUsingAnotherGetEnumerator
                foreach (var allowedTopic in currentUser.PublishTopicLists.WhitelistTopics)
                {
                    var doesTopicMatch = TopicChecker.Regex(allowedTopic, topic);
                    if (!doesTopicMatch)
                    {
                        continue;
                    }

                    c.AcceptPublish = true;
                    LogMessage(c);
                    return;
                }

                c.AcceptPublish = false;
            });

            var mqttServer = new MqttFactory().CreateMqttServer();

            mqttServer.StartAsync(optionsBuilder.Build());
            Console.ReadLine();
        }
Beispiel #2
0
        public static void Main(string[] args)
        {
            var currentPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            var certificate = new X509Certificate2(
                Path.Combine(currentPath, "certificate.pfx"),
                "test",
                X509KeyStorageFlags.Exportable);

            var config = ReadConfiguration(currentPath);

            var optionsBuilder = new MqttServerOptionsBuilder()
                                 //// .WithDefaultEndpoint().WithDefaultEndpointPort(1883) // For testing purposes only
                                 .WithoutDefaultEndpoint()
                                 .WithEncryptedEndpoint().WithEncryptedEndpointPort(config.Port)
                                 .WithEncryptionCertificate(certificate.Export(X509ContentType.Pfx))
                                 .WithEncryptionSslProtocol(SslProtocols.Tls12).WithConnectionValidator(
                c =>
            {
                var currentUser = config.Users.FirstOrDefault(u => u.UserName == c.Username);

                if (currentUser == null)
                {
                    c.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
                    return;
                }

                if (c.Username != currentUser.UserName)
                {
                    c.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
                    return;
                }

                var hashingResult = Hasher.VerifyHashedPassword(currentUser.Password, c.Password);

                if (hashingResult == PasswordVerificationResult.Failed)
                {
                    c.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
                    return;
                }

                if (string.IsNullOrWhiteSpace(currentUser.ClientIdPrefix))
                {
                    if (c.ClientId != currentUser.ClientId)
                    {
                        c.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
                        return;
                    }

                    c.SessionItems.Add(currentUser.ClientId, currentUser);
                }
                else
                {
                    if (!ClientIdPrefixesUsed.Contains(currentUser.ClientIdPrefix))
                    {
                        ClientIdPrefixesUsed.Add(currentUser.ClientIdPrefix);
                    }

                    c.SessionItems.Add(currentUser.ClientIdPrefix, currentUser);
                }

                c.ReasonCode = MqttConnectReasonCode.Success;
            }).WithSubscriptionInterceptor(
                c =>
            {
                var clientIdPrefix = GetClientIdPrefix(c.ClientId);
                User currentUser;
                bool userFound;

                if (clientIdPrefix == null)
                {
                    userFound   = c.SessionItems.TryGetValue(c.ClientId, out var currentUserObject);
                    currentUser = currentUserObject as User;
                }
                else
                {
                    userFound   = c.SessionItems.TryGetValue(clientIdPrefix, out var currentUserObject);
                    currentUser = currentUserObject as User;
                }

                if (!userFound || currentUser == null)
                {
                    c.AcceptSubscription = false;
                    return;
                }

                var topic = c.TopicFilter.Topic;

                if (currentUser.SubscriptionTopicLists.BlacklistTopics.Contains(topic))
                {
                    c.AcceptSubscription = false;
                    return;
                }

                if (currentUser.SubscriptionTopicLists.WhitelistTopics.Contains(topic))
                {
                    c.AcceptSubscription = true;
                    return;
                }

                foreach (var forbiddenTopic in currentUser.SubscriptionTopicLists.BlacklistTopics)
                {
                    var doesTopicMatch = TopicChecker.Regex(forbiddenTopic, topic);
                    if (!doesTopicMatch)
                    {
                        continue;
                    }

                    c.AcceptSubscription = false;
                    return;
                }

                foreach (var allowedTopic in currentUser.SubscriptionTopicLists.WhitelistTopics)
                {
                    var doesTopicMatch = TopicChecker.Regex(allowedTopic, topic);
                    if (!doesTopicMatch)
                    {
                        continue;
                    }

                    c.AcceptSubscription = true;
                    return;
                }

                c.AcceptSubscription = false;
            }).WithApplicationMessageInterceptor(
                c =>
            {
                var clientIdPrefix = GetClientIdPrefix(c.ClientId);
                User currentUser;
                bool userFound;

                if (clientIdPrefix == null)
                {
                    userFound   = c.SessionItems.TryGetValue(c.ClientId, out var currentUserObject);
                    currentUser = currentUserObject as User;
                }
                else
                {
                    userFound   = c.SessionItems.TryGetValue(clientIdPrefix, out var currentUserObject);
                    currentUser = currentUserObject as User;
                }

                if (!userFound || currentUser == null)
                {
                    c.AcceptPublish = false;
                    return;
                }

                var topic = c.ApplicationMessage.Topic;

                if (currentUser.PublishTopicLists.BlacklistTopics.Contains(topic))
                {
                    c.AcceptPublish = false;
                    return;
                }

                if (currentUser.PublishTopicLists.WhitelistTopics.Contains(topic))
                {
                    c.AcceptPublish = true;
                    return;
                }

                foreach (var forbiddenTopic in currentUser.PublishTopicLists.BlacklistTopics)
                {
                    var doesTopicMatch = TopicChecker.Regex(forbiddenTopic, topic);
                    if (!doesTopicMatch)
                    {
                        continue;
                    }

                    c.AcceptPublish = false;
                    return;
                }

                foreach (var allowedTopic in currentUser.PublishTopicLists.WhitelistTopics)
                {
                    var doesTopicMatch = TopicChecker.Regex(allowedTopic, topic);
                    if (!doesTopicMatch)
                    {
                        continue;
                    }

                    c.AcceptPublish = true;
                    return;
                }

                c.AcceptPublish = false;
            });

            var mqttServer = new MqttFactory().CreateMqttServer();

            mqttServer.StartAsync(optionsBuilder.Build());
            Console.ReadLine();
        }