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
                                 .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;
                }

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

                if (string.IsNullOrWhiteSpace(currentUser.ClientIdPrefix))
                {
                    if (c.ClientId != currentUser.ClientId)
                    {
                        c.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
                        return;
                    }
                    else
                    {
                        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   = null;
                bool userFound;

                if (clientIdPrefix == null)
                {
                    userFound   = c.SessionItems.TryGetValue(c.ClientId, out object currentUserObject);
                    currentUser = currentUserObject as User;
                }
                else
                {
                    userFound   = c.SessionItems.TryGetValue(clientIdPrefix, out object 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)
                    {
                        c.AcceptSubscription = false;
                        return;
                    }
                }

                foreach (var allowedTopic in currentUser.SubscriptionTopicLists.WhitelistTopics)
                {
                    var doesTopicMatch = TopicChecker.Regex(allowedTopic, topic);
                    if (doesTopicMatch)
                    {
                        c.AcceptSubscription = true;
                        return;
                    }
                }

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

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

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

                var topic = c.ApplicationMessage.Topic;

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

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

                foreach (var forbiddenTopic in currentUser.SubscriptionTopicLists.BlacklistTopics)
                {
                    var doesTopicMatch = TopicChecker.Regex(forbiddenTopic, topic);
                    if (doesTopicMatch)
                    {
                        c.AcceptPublish = false;
                        return;
                    }
                }

                foreach (var allowedTopic in currentUser.SubscriptionTopicLists.WhitelistTopics)
                {
                    var doesTopicMatch = TopicChecker.Regex(allowedTopic, topic);
                    if (doesTopicMatch)
                    {
                        c.AcceptPublish = true;
                        return;
                    }
                }

                c.AcceptPublish = false;
            });

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

            mqttServer.StartAsync(optionsBuilder.Build());
            Console.ReadLine();
        }
Пример #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);

            Log.Logger = new LoggerConfiguration()
                         .MinimumLevel.Debug()
                         .WriteTo.File(Path.Combine(currentPath,
                                                    @"log\NetCoreMQTTExampleJsonConfig_.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;
                }

                if (c.Password != currentUser.Password)
                {
                    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.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();
        }