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(); }
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(); }