From 533ceeaaf299c9396f82e11e16314afbc03407f8 Mon Sep 17 00:00:00 2001 From: gnattu Date: Tue, 4 Feb 2025 16:52:17 +0800 Subject: Fix subnet contains check We are still using `Subnet.Contains` a lot but that does not handle IPv4 mapped to IPv6 addresses at all. It was partially fixed by #12094 in local network checking, but it may not always happen on LAN. Also make all local network checking to use IsInLocalNetwork method instead of just performing `Subnet.Contains` which is not accurate. Filter out all link-local addresses for external interface matching. --- MediaBrowser.Common/Net/NetworkUtils.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'MediaBrowser.Common/Net') diff --git a/MediaBrowser.Common/Net/NetworkUtils.cs b/MediaBrowser.Common/Net/NetworkUtils.cs index 7380963520..e21fdeb3d4 100644 --- a/MediaBrowser.Common/Net/NetworkUtils.cs +++ b/MediaBrowser.Common/Net/NetworkUtils.cs @@ -326,4 +326,23 @@ public static partial class NetworkUtils return new IPAddress(BitConverter.GetBytes(broadCastIPAddress)); } + + /// + /// Check if a subnet contains an address. This method also handles IPv4 mapped to IPv6 addresses. + /// + /// The . + /// The . + /// Whether the supplied IP is in the supplied network. + public static bool SubNetContainsAddress(IPNetwork network, IPAddress address) + { + ArgumentNullException.ThrowIfNull(address); + ArgumentNullException.ThrowIfNull(network); + + if (address.IsIPv4MappedToIPv6) + { + address = address.MapToIPv4(); + } + + return network.Contains(address); + } } -- cgit v1.2.3 From 9aec576c763eeb6a2d1538175d397ab933227e5a Mon Sep 17 00:00:00 2001 From: gnattu Date: Wed, 5 Feb 2025 08:04:29 +0800 Subject: Typo Co-authored-by: Cody Robibero --- MediaBrowser.Common/Net/NetworkUtils.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Common/Net') diff --git a/MediaBrowser.Common/Net/NetworkUtils.cs b/MediaBrowser.Common/Net/NetworkUtils.cs index e21fdeb3d4..a498d6271b 100644 --- a/MediaBrowser.Common/Net/NetworkUtils.cs +++ b/MediaBrowser.Common/Net/NetworkUtils.cs @@ -333,7 +333,7 @@ public static partial class NetworkUtils /// The . /// The . /// Whether the supplied IP is in the supplied network. - public static bool SubNetContainsAddress(IPNetwork network, IPAddress address) + public static bool SubnetContainsAddress(IPNetwork network, IPAddress address) { ArgumentNullException.ThrowIfNull(address); ArgumentNullException.ThrowIfNull(network); -- cgit v1.2.3 From d18066f0f23f819efdef145a74ffb173df636b58 Mon Sep 17 00:00:00 2001 From: Niels van Velzen Date: Sat, 22 Feb 2025 10:27:42 +0100 Subject: Remove GetMacAddresses from NetworkManager --- MediaBrowser.Common/Net/INetworkManager.cs | 6 ------ src/Jellyfin.Networking/Manager/NetworkManager.cs | 23 ----------------------- 2 files changed, 29 deletions(-) (limited to 'MediaBrowser.Common/Net') diff --git a/MediaBrowser.Common/Net/INetworkManager.cs b/MediaBrowser.Common/Net/INetworkManager.cs index 78a391d36d..d838144ff6 100644 --- a/MediaBrowser.Common/Net/INetworkManager.cs +++ b/MediaBrowser.Common/Net/INetworkManager.cs @@ -94,12 +94,6 @@ namespace MediaBrowser.Common.Net /// IP address to use, or loopback address if all else fails. string GetBindAddress(string source, out int? port); - /// - /// Get a list of all the MAC addresses associated with active interfaces. - /// - /// List of MAC addresses. - IReadOnlyList GetMacAddresses(); - /// /// Returns true if the address is part of the user defined LAN. /// diff --git a/src/Jellyfin.Networking/Manager/NetworkManager.cs b/src/Jellyfin.Networking/Manager/NetworkManager.cs index dd01e9533b..2fbcbf79ce 100644 --- a/src/Jellyfin.Networking/Manager/NetworkManager.cs +++ b/src/Jellyfin.Networking/Manager/NetworkManager.cs @@ -49,11 +49,6 @@ public class NetworkManager : INetworkManager, IDisposable /// private bool _eventfire; - /// - /// List of all interface MAC addresses. - /// - private IReadOnlyList _macAddresses; - /// /// Dictionary containing interface addresses and their subnets. /// @@ -91,7 +86,6 @@ public class NetworkManager : INetworkManager, IDisposable _startupConfig = startupConfig; _initLock = new(); _interfaces = new List(); - _macAddresses = new List(); _publishedServerUrls = new List(); _networkEventLock = new(); _remoteAddressFilter = new List(); @@ -215,7 +209,6 @@ public class NetworkManager : INetworkManager, IDisposable /// /// Generate a list of all the interface ip addresses and submasks where that are in the active/unknown state. - /// Generate a list of all active mac addresses that aren't loopback addresses. /// private void InitializeInterfaces() { @@ -224,7 +217,6 @@ public class NetworkManager : INetworkManager, IDisposable _logger.LogDebug("Refreshing interfaces."); var interfaces = new List(); - var macAddresses = new List(); try { @@ -236,13 +228,6 @@ public class NetworkManager : INetworkManager, IDisposable try { var ipProperties = adapter.GetIPProperties(); - var mac = adapter.GetPhysicalAddress(); - - // Populate MAC list - if (adapter.NetworkInterfaceType != NetworkInterfaceType.Loopback && !PhysicalAddress.None.Equals(mac)) - { - macAddresses.Add(mac); - } // Populate interface list foreach (var info in ipProperties.UnicastAddresses) @@ -302,7 +287,6 @@ public class NetworkManager : INetworkManager, IDisposable _logger.LogDebug("Discovered {NumberOfInterfaces} interfaces.", interfaces.Count); _logger.LogDebug("Interfaces addresses: {Addresses}", interfaces.OrderByDescending(s => s.AddressFamily == AddressFamily.InterNetwork).Select(s => s.Address.ToString())); - _macAddresses = macAddresses; _interfaces = interfaces; } } @@ -711,13 +695,6 @@ public class NetworkManager : INetworkManager, IDisposable return true; } - /// - public IReadOnlyList GetMacAddresses() - { - // Populated in construction - so always has values. - return _macAddresses; - } - /// public IReadOnlyList GetLoopbacks() { -- cgit v1.2.3 From c152f610ce4acb36d940c032bdf624c269d37d6b Mon Sep 17 00:00:00 2001 From: Markus Prettner Date: Wed, 9 Apr 2025 03:21:57 +0200 Subject: Fix negated IP addresses without subnet mask not being parsed correctly (#13854) --- MediaBrowser.Common/Net/NetworkUtils.cs | 21 ++++++++++++++++----- .../Jellyfin.Networking.Tests/NetworkParseTests.cs | 5 ++++- 2 files changed, 20 insertions(+), 6 deletions(-) (limited to 'MediaBrowser.Common/Net') diff --git a/MediaBrowser.Common/Net/NetworkUtils.cs b/MediaBrowser.Common/Net/NetworkUtils.cs index a498d6271b..24ed47a81b 100644 --- a/MediaBrowser.Common/Net/NetworkUtils.cs +++ b/MediaBrowser.Common/Net/NetworkUtils.cs @@ -198,14 +198,25 @@ public static partial class NetworkUtils /// True if parsing was successful. public static bool TryParseToSubnet(ReadOnlySpan value, [NotNullWhen(true)] out IPNetwork? result, bool negated = false) { + // If multiple IP addresses are in a comma-separated string, the individual addresses may contain leading and/or trailing whitespace value = value.Trim(); + + bool isAddressNegated = false; + if (value.StartsWith('!')) + { + isAddressNegated = true; + value = value[1..]; // Remove leading '!' character + } + + if (isAddressNegated != negated) + { + result = null; + return false; + } + if (value.Contains('/')) { - if (negated && value.StartsWith("!") && IPNetwork.TryParse(value[1..], out result)) - { - return true; - } - else if (!negated && IPNetwork.TryParse(value, out result)) + if (IPNetwork.TryParse(value, out result)) { return true; } diff --git a/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs b/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs index 4144300da0..ef87e46a78 100644 --- a/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs +++ b/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs @@ -79,7 +79,10 @@ namespace Jellyfin.Networking.Tests [InlineData("[fe80::7add:12ff:febb:c67b%16]")] [InlineData("fd23:184f:2029:0:3139:7386:67d7:d517/56")] public static void TryParseValidIPStringsTrue(string address) - => Assert.True(NetworkUtils.TryParseToSubnet(address, out _)); + { + Assert.True(NetworkUtils.TryParseToSubnet(address, out _)); + Assert.True(NetworkUtils.TryParseToSubnet('!' + address, out _, true)); + } /// /// Checks invalid IP address formats. -- cgit v1.2.3 From 44b5de156886995fdcf881cbc1208505ad0e8b0e Mon Sep 17 00:00:00 2001 From: jade Date: Tue, 3 Jun 2025 14:22:30 -0700 Subject: Fix missing logging of connections by disallowed IPs (#14011) --- .../IpBasedAccessValidationMiddleware.cs | 20 +++++++-- Jellyfin.Api/Middleware/LanFilteringMiddleware.cs | 51 ---------------------- .../Extensions/ApiApplicationBuilderExtensions.cs | 10 ----- Jellyfin.Server/Startup.cs | 1 - .../Extensions/HttpContextExtensions.cs | 2 +- MediaBrowser.Common/Net/INetworkManager.cs | 4 +- .../Net/RemoteAccessPolicyResult.cs | 29 ++++++++++++ src/Jellyfin.Networking/Manager/NetworkManager.cs | 47 ++++++++++++-------- .../Jellyfin.Networking.Tests/NetworkParseTests.cs | 43 +++++++++++++----- 9 files changed, 109 insertions(+), 98 deletions(-) delete mode 100644 Jellyfin.Api/Middleware/LanFilteringMiddleware.cs create mode 100644 MediaBrowser.Common/Net/RemoteAccessPolicyResult.cs (limited to 'MediaBrowser.Common/Net') diff --git a/Jellyfin.Api/Middleware/IpBasedAccessValidationMiddleware.cs b/Jellyfin.Api/Middleware/IpBasedAccessValidationMiddleware.cs index 842a69dd98..a0ed6c8126 100644 --- a/Jellyfin.Api/Middleware/IpBasedAccessValidationMiddleware.cs +++ b/Jellyfin.Api/Middleware/IpBasedAccessValidationMiddleware.cs @@ -1,8 +1,10 @@ using System.Net; using System.Threading.Tasks; +using System.Web; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Net; using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Logging; namespace Jellyfin.Api.Middleware; @@ -12,14 +14,17 @@ namespace Jellyfin.Api.Middleware; public class IPBasedAccessValidationMiddleware { private readonly RequestDelegate _next; + private readonly ILogger _logger; /// /// Initializes a new instance of the class. /// /// The next delegate in the pipeline. - public IPBasedAccessValidationMiddleware(RequestDelegate next) + /// The logger to log to. + public IPBasedAccessValidationMiddleware(RequestDelegate next, ILogger logger) { _next = next; + _logger = logger; } /// @@ -32,16 +37,23 @@ public class IPBasedAccessValidationMiddleware { if (httpContext.IsLocal()) { - // Running locally. + // Accessing from the same machine as the server. await _next(httpContext).ConfigureAwait(false); return; } - var remoteIP = httpContext.Connection.RemoteIpAddress ?? IPAddress.Loopback; + var remoteIP = httpContext.GetNormalizedRemoteIP(); - if (!networkManager.HasRemoteAccess(remoteIP)) + var result = networkManager.ShouldAllowServerAccess(remoteIP); + if (result != RemoteAccessPolicyResult.Allow) { // No access from network, respond with 503 instead of 200. + _logger.LogWarning( + "Blocking request to {Path} by {RemoteIP} due to IP filtering rule, reason: {Reason}", + // url-encode to block log injection + HttpUtility.UrlEncode(httpContext.Request.Path), + remoteIP, + result); httpContext.Response.StatusCode = StatusCodes.Status503ServiceUnavailable; return; } diff --git a/Jellyfin.Api/Middleware/LanFilteringMiddleware.cs b/Jellyfin.Api/Middleware/LanFilteringMiddleware.cs deleted file mode 100644 index 35b0a1dd06..0000000000 --- a/Jellyfin.Api/Middleware/LanFilteringMiddleware.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System.Net; -using System.Threading.Tasks; -using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Configuration; -using Microsoft.AspNetCore.Http; - -namespace Jellyfin.Api.Middleware; - -/// -/// Validates the LAN host IP based on application configuration. -/// -public class LanFilteringMiddleware -{ - private readonly RequestDelegate _next; - - /// - /// Initializes a new instance of the class. - /// - /// The next delegate in the pipeline. - public LanFilteringMiddleware(RequestDelegate next) - { - _next = next; - } - - /// - /// Executes the middleware action. - /// - /// The current HTTP context. - /// The network manager. - /// The server configuration manager. - /// The async task. - public async Task Invoke(HttpContext httpContext, INetworkManager networkManager, IServerConfigurationManager serverConfigurationManager) - { - if (serverConfigurationManager.GetNetworkConfiguration().EnableRemoteAccess) - { - await _next(httpContext).ConfigureAwait(false); - return; - } - - var host = httpContext.GetNormalizedRemoteIP(); - if (!networkManager.IsInLocalNetwork(host)) - { - // No access from network, respond with 503 instead of 200. - httpContext.Response.StatusCode = StatusCodes.Status503ServiceUnavailable; - return; - } - - await _next(httpContext).ConfigureAwait(false); - } -} diff --git a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs index 6066893de3..a56baba33b 100644 --- a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs +++ b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs @@ -68,16 +68,6 @@ namespace Jellyfin.Server.Extensions return appBuilder.UseMiddleware(); } - /// - /// Adds LAN based access filtering to the application pipeline. - /// - /// The application builder. - /// The updated application builder. - public static IApplicationBuilder UseLanFiltering(this IApplicationBuilder appBuilder) - { - return appBuilder.UseMiddleware(); - } - /// /// Enables url decoding before binding to the application pipeline. /// diff --git a/Jellyfin.Server/Startup.cs b/Jellyfin.Server/Startup.cs index 688b169359..94ae54a359 100644 --- a/Jellyfin.Server/Startup.cs +++ b/Jellyfin.Server/Startup.cs @@ -208,7 +208,6 @@ namespace Jellyfin.Server mainApp.UseRouting(); mainApp.UseAuthorization(); - mainApp.UseLanFiltering(); mainApp.UseIPBasedAccessValidation(); mainApp.UseWebSocketHandler(); mainApp.UseServerStartupMessage(); diff --git a/MediaBrowser.Common/Extensions/HttpContextExtensions.cs b/MediaBrowser.Common/Extensions/HttpContextExtensions.cs index a1056b7c84..739a53c7ad 100644 --- a/MediaBrowser.Common/Extensions/HttpContextExtensions.cs +++ b/MediaBrowser.Common/Extensions/HttpContextExtensions.cs @@ -12,7 +12,7 @@ namespace MediaBrowser.Common.Extensions /// Checks the origin of the HTTP context. /// /// The incoming HTTP context. - /// true if the request is coming from LAN, false otherwise. + /// true if the request is coming from the same machine as is running the server, false otherwise. public static bool IsLocal(this HttpContext context) { return (context.Connection.LocalIpAddress is null diff --git a/MediaBrowser.Common/Net/INetworkManager.cs b/MediaBrowser.Common/Net/INetworkManager.cs index d838144ff6..bd785bcbc6 100644 --- a/MediaBrowser.Common/Net/INetworkManager.cs +++ b/MediaBrowser.Common/Net/INetworkManager.cs @@ -127,7 +127,7 @@ namespace MediaBrowser.Common.Net /// Checks if has access to the server. /// /// IP address of the client. - /// True if it has access, otherwise false. - bool HasRemoteAccess(IPAddress remoteIP); + /// The result of evaluating the access policy, Allow if it should be allowed. + RemoteAccessPolicyResult ShouldAllowServerAccess(IPAddress remoteIP); } } diff --git a/MediaBrowser.Common/Net/RemoteAccessPolicyResult.cs b/MediaBrowser.Common/Net/RemoteAccessPolicyResult.cs new file mode 100644 index 0000000000..193d37228f --- /dev/null +++ b/MediaBrowser.Common/Net/RemoteAccessPolicyResult.cs @@ -0,0 +1,29 @@ +using System; + +namespace MediaBrowser.Common.Net; + +/// +/// Result of . +/// +public enum RemoteAccessPolicyResult +{ + /// + /// The connection should be allowed. + /// + Allow, + + /// + /// The connection should be rejected since it is not from a local IP and remote access is disabled. + /// + RejectDueToRemoteAccessDisabled, + + /// + /// The connection should be rejected since it is from a blocklisted IP. + /// + RejectDueToIPBlocklist, + + /// + /// The connection should be rejected since it is from a remote IP that is not in the allowlist. + /// + RejectDueToNotAllowlistedRemoteIP, +} diff --git a/src/Jellyfin.Networking/Manager/NetworkManager.cs b/src/Jellyfin.Networking/Manager/NetworkManager.cs index 80a5741df9..126d9f15cf 100644 --- a/src/Jellyfin.Networking/Manager/NetworkManager.cs +++ b/src/Jellyfin.Networking/Manager/NetworkManager.cs @@ -690,33 +690,42 @@ public class NetworkManager : INetworkManager, IDisposable } /// - public bool HasRemoteAccess(IPAddress remoteIP) + public RemoteAccessPolicyResult ShouldAllowServerAccess(IPAddress remoteIP) { var config = _configurationManager.GetNetworkConfiguration(); - if (config.EnableRemoteAccess) + if (IsInLocalNetwork(remoteIP)) { - // Comma separated list of IP addresses or IP/netmask entries for networks that will be allowed to connect remotely. - // If left blank, all remote addresses will be allowed. - if (_remoteAddressFilter.Any() && !IsInLocalNetwork(remoteIP)) - { - // remoteAddressFilter is a whitelist or blacklist. - var matches = _remoteAddressFilter.Count(remoteNetwork => NetworkUtils.SubnetContainsAddress(remoteNetwork, remoteIP)); - if ((!config.IsRemoteIPFilterBlacklist && matches > 0) - || (config.IsRemoteIPFilterBlacklist && matches == 0)) - { - return true; - } - - return false; - } + return RemoteAccessPolicyResult.Allow; } - else if (!IsInLocalNetwork(remoteIP)) + + if (!config.EnableRemoteAccess) { // Remote not enabled. So everyone should be LAN. - return false; + return RemoteAccessPolicyResult.RejectDueToRemoteAccessDisabled; } - return true; + if (!_remoteAddressFilter.Any()) + { + // No filter on remote addresses, allow any of them. + return RemoteAccessPolicyResult.Allow; + } + + // Comma separated list of IP addresses or IP/netmask entries for networks that will be allowed to connect remotely. + // If left blank, all remote addresses will be allowed. + + // remoteAddressFilter is a whitelist or blacklist. + var anyMatches = _remoteAddressFilter.Any(remoteNetwork => NetworkUtils.SubnetContainsAddress(remoteNetwork, remoteIP)); + if (config.IsRemoteIPFilterBlacklist) + { + return anyMatches + ? RemoteAccessPolicyResult.RejectDueToIPBlocklist + : RemoteAccessPolicyResult.Allow; + } + + // Allow-list + return anyMatches + ? RemoteAccessPolicyResult.Allow + : RemoteAccessPolicyResult.RejectDueToNotAllowlistedRemoteIP; } /// diff --git a/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs b/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs index ef87e46a78..38208476f8 100644 --- a/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs +++ b/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs @@ -281,11 +281,11 @@ namespace Jellyfin.Networking.Tests } [Theory] - [InlineData("185.10.10.10,200.200.200.200", "79.2.3.4", true)] - [InlineData("185.10.10.10", "185.10.10.10", false)] - [InlineData("", "100.100.100.100", false)] + [InlineData("185.10.10.10,200.200.200.200", "79.2.3.4", RemoteAccessPolicyResult.RejectDueToNotAllowlistedRemoteIP)] + [InlineData("185.10.10.10", "185.10.10.10", RemoteAccessPolicyResult.Allow)] + [InlineData("", "100.100.100.100", RemoteAccessPolicyResult.Allow)] - public void HasRemoteAccess_GivenWhitelist_AllowsOnlyIPsInWhitelist(string addresses, string remoteIP, bool denied) + public void HasRemoteAccess_GivenWhitelist_AllowsOnlyIPsInWhitelist(string addresses, string remoteIP, RemoteAccessPolicyResult expectedResult) { // Comma separated list of IP addresses or IP/netmask entries for networks that will be allowed to connect remotely. // If left blank, all remote addresses will be allowed. @@ -299,15 +299,38 @@ namespace Jellyfin.Networking.Tests var startupConf = new Mock(); using var nm = new NetworkManager(NetworkParseTests.GetMockConfig(conf), startupConf.Object, new NullLogger()); - Assert.NotEqual(nm.HasRemoteAccess(IPAddress.Parse(remoteIP)), denied); + Assert.Equal(expectedResult, nm.ShouldAllowServerAccess(IPAddress.Parse(remoteIP))); } [Theory] - [InlineData("185.10.10.10", "79.2.3.4", false)] - [InlineData("185.10.10.10", "185.10.10.10", true)] - [InlineData("", "100.100.100.100", false)] + [InlineData("185.10.10.10,200.200.200.200", "79.2.3.4", RemoteAccessPolicyResult.RejectDueToRemoteAccessDisabled)] + [InlineData("185.10.10.10", "127.0.0.1", RemoteAccessPolicyResult.Allow)] + [InlineData("", "100.100.100.100", RemoteAccessPolicyResult.RejectDueToRemoteAccessDisabled)] - public void HasRemoteAccess_GivenBlacklist_BlacklistTheIPs(string addresses, string remoteIP, bool denied) + public void HasRemoteAccess_GivenRemoteAccessDisabled_IgnoresAllowlist(string addresses, string remoteIP, RemoteAccessPolicyResult expectedResult) + { + // Comma separated list of IP addresses or IP/netmask entries for networks that will be allowed to connect remotely. + // If left blank, all remote addresses will be allowed. + var conf = new NetworkConfiguration() + { + EnableIPv4 = true, + EnableRemoteAccess = false, + RemoteIPFilter = addresses.Split(','), + IsRemoteIPFilterBlacklist = false + }; + + var startupConf = new Mock(); + using var nm = new NetworkManager(NetworkParseTests.GetMockConfig(conf), startupConf.Object, new NullLogger()); + + Assert.Equal(expectedResult, nm.ShouldAllowServerAccess(IPAddress.Parse(remoteIP))); + } + + [Theory] + [InlineData("185.10.10.10", "79.2.3.4", RemoteAccessPolicyResult.Allow)] + [InlineData("185.10.10.10", "185.10.10.10", RemoteAccessPolicyResult.RejectDueToIPBlocklist)] + [InlineData("", "100.100.100.100", RemoteAccessPolicyResult.Allow)] + + public void HasRemoteAccess_GivenBlacklist_BlacklistTheIPs(string addresses, string remoteIP, RemoteAccessPolicyResult expectedResult) { // Comma separated list of IP addresses or IP/netmask entries for networks that will be allowed to connect remotely. // If left blank, all remote addresses will be allowed. @@ -321,7 +344,7 @@ namespace Jellyfin.Networking.Tests var startupConf = new Mock(); using var nm = new NetworkManager(NetworkParseTests.GetMockConfig(conf), startupConf.Object, new NullLogger()); - Assert.NotEqual(nm.HasRemoteAccess(IPAddress.Parse(remoteIP)), denied); + Assert.Equal(expectedResult, nm.ShouldAllowServerAccess(IPAddress.Parse(remoteIP))); } [Theory] -- cgit v1.2.3