Standardize use of IsLocal and RemoteIp

This commit is contained in:
cvium 2020-09-10 14:16:41 +02:00
parent 78cab77f81
commit 7576824cee
12 changed files with 45 additions and 61 deletions

View File

@ -28,7 +28,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
var authorization = _authContext.GetAuthorizationInfo(requestContext); var authorization = _authContext.GetAuthorizationInfo(requestContext);
var user = authorization.User; var user = authorization.User;
return _sessionManager.LogSessionActivity(authorization.Client, authorization.Version, authorization.DeviceId, authorization.Device, requestContext.Request.RemoteIp(), user); return _sessionManager.LogSessionActivity(authorization.Client, authorization.Version, authorization.DeviceId, authorization.Device, requestContext.GetNormalizedRemoteIp(), user);
} }
public SessionInfo GetSession(object requestContext) public SessionInfo GetSession(object requestContext)

View File

@ -1,6 +1,7 @@
using System.Security.Claims; using System.Security.Claims;
using Jellyfin.Api.Helpers; using Jellyfin.Api.Helpers;
using Jellyfin.Data.Enums; using Jellyfin.Data.Enums;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net; using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
@ -69,7 +70,7 @@ namespace Jellyfin.Api.Auth
return false; return false;
} }
var ip = RequestHelpers.NormalizeIp(_httpContextAccessor.HttpContext.Connection.RemoteIpAddress).ToString(); var ip = _httpContextAccessor.HttpContext.GetNormalizedRemoteIp();
var isInLocalNetwork = _networkManager.IsInLocalNetwork(ip); var isInLocalNetwork = _networkManager.IsInLocalNetwork(ip);
// User cannot access remotely and user is remote // User cannot access remotely and user is remote
if (!user.HasPermission(PermissionKind.EnableRemoteAccess) && !isInLocalNetwork) if (!user.HasPermission(PermissionKind.EnableRemoteAccess) && !isInLocalNetwork)

View File

@ -8,6 +8,7 @@ using Jellyfin.Api.Constants;
using Jellyfin.Api.Helpers; using Jellyfin.Api.Helpers;
using Jellyfin.Api.Models.MediaInfoDtos; using Jellyfin.Api.Models.MediaInfoDtos;
using Jellyfin.Api.Models.VideoDtos; using Jellyfin.Api.Models.VideoDtos;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Net;
@ -164,7 +165,7 @@ namespace Jellyfin.Api.Controllers
enableTranscoding, enableTranscoding,
allowVideoStreamCopy, allowVideoStreamCopy,
allowAudioStreamCopy, allowAudioStreamCopy,
Request.HttpContext.Connection.RemoteIpAddress.ToString()); Request.HttpContext.GetNormalizedRemoteIp());
} }
_mediaInfoHelper.SortMediaSources(info, maxStreamingBitrate); _mediaInfoHelper.SortMediaSources(info, maxStreamingBitrate);

View File

@ -7,6 +7,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Jellyfin.Api.Constants; using Jellyfin.Api.Constants;
using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net; using MediaBrowser.Common.Net;
using MediaBrowser.Controller; using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Configuration;
@ -176,8 +177,8 @@ namespace Jellyfin.Api.Controllers
{ {
return new EndPointInfo return new EndPointInfo
{ {
IsLocal = Request.HttpContext.Connection.LocalIpAddress.Equals(Request.HttpContext.Connection.RemoteIpAddress), IsLocal = HttpContext.IsLocal(),
IsInNetwork = _network.IsInLocalNetwork(Request.HttpContext.Connection.RemoteIpAddress.ToString()) IsInNetwork = _network.IsInLocalNetwork(HttpContext.GetNormalizedRemoteIp())
}; };
} }

View File

@ -7,6 +7,7 @@ using System.Threading.Tasks;
using Jellyfin.Api.Constants; using Jellyfin.Api.Constants;
using Jellyfin.Api.Helpers; using Jellyfin.Api.Helpers;
using Jellyfin.Api.Models.StreamingDtos; using Jellyfin.Api.Models.StreamingDtos;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.MediaEncoding;
@ -158,7 +159,7 @@ namespace Jellyfin.Api.Controllers
true, true,
true, true,
true, true,
Request.HttpContext.Connection.RemoteIpAddress.ToString()); Request.HttpContext.GetNormalizedRemoteIp());
} }
_mediaInfoHelper.SortMediaSources(info, maxStreamingBitrate); _mediaInfoHelper.SortMediaSources(info, maxStreamingBitrate);

View File

@ -7,6 +7,7 @@ using Jellyfin.Api.Constants;
using Jellyfin.Api.Helpers; using Jellyfin.Api.Helpers;
using Jellyfin.Api.Models.UserDtos; using Jellyfin.Api.Models.UserDtos;
using Jellyfin.Data.Enums; using Jellyfin.Data.Enums;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net; using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Authentication; using MediaBrowser.Controller.Authentication;
using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Configuration;
@ -117,7 +118,7 @@ namespace Jellyfin.Api.Controllers
return NotFound("User not found"); return NotFound("User not found");
} }
var result = _userManager.GetUserDto(user, HttpContext.Connection.RemoteIpAddress.ToString()); var result = _userManager.GetUserDto(user, HttpContext.GetNormalizedRemoteIp());
return result; return result;
} }
@ -203,7 +204,7 @@ namespace Jellyfin.Api.Controllers
DeviceName = auth.Device, DeviceName = auth.Device,
Password = request.Pw, Password = request.Pw,
PasswordSha1 = request.Password, PasswordSha1 = request.Password,
RemoteEndPoint = HttpContext.Connection.RemoteIpAddress.ToString(), RemoteEndPoint = HttpContext.GetNormalizedRemoteIp(),
Username = request.Username Username = request.Username
}).ConfigureAwait(false); }).ConfigureAwait(false);
@ -212,7 +213,7 @@ namespace Jellyfin.Api.Controllers
catch (SecurityException e) catch (SecurityException e)
{ {
// rethrow adding IP address to message // rethrow adding IP address to message
throw new SecurityException($"[{HttpContext.Connection.RemoteIpAddress}] {e.Message}", e); throw new SecurityException($"[{HttpContext.GetNormalizedRemoteIp()}] {e.Message}", e);
} }
} }
@ -246,7 +247,7 @@ namespace Jellyfin.Api.Controllers
catch (SecurityException e) catch (SecurityException e)
{ {
// rethrow adding IP address to message // rethrow adding IP address to message
throw new SecurityException($"[{HttpContext.Connection.RemoteIpAddress}] {e.Message}", e); throw new SecurityException($"[{HttpContext.GetNormalizedRemoteIp()}] {e.Message}", e);
} }
} }
@ -290,7 +291,7 @@ namespace Jellyfin.Api.Controllers
user.Username, user.Username,
request.CurrentPw, request.CurrentPw,
request.CurrentPw, request.CurrentPw,
HttpContext.Connection.RemoteIpAddress.ToString(), HttpContext.GetNormalizedRemoteIp(),
false).ConfigureAwait(false); false).ConfigureAwait(false);
if (success == null) if (success == null)
@ -496,7 +497,7 @@ namespace Jellyfin.Api.Controllers
await _userManager.ChangePassword(newUser, request.Password).ConfigureAwait(false); await _userManager.ChangePassword(newUser, request.Password).ConfigureAwait(false);
} }
var result = _userManager.GetUserDto(newUser, HttpContext.Connection.RemoteIpAddress.ToString()); var result = _userManager.GetUserDto(newUser, HttpContext.GetNormalizedRemoteIp());
return result; return result;
} }
@ -511,8 +512,8 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<ForgotPasswordResult>> ForgotPassword([FromBody] string? enteredUsername) public async Task<ActionResult<ForgotPasswordResult>> ForgotPassword([FromBody] string? enteredUsername)
{ {
var isLocal = HttpContext.Connection.RemoteIpAddress.Equals(HttpContext.Connection.LocalIpAddress) var isLocal = HttpContext.IsLocal()
|| _networkManager.IsInLocalNetwork(HttpContext.Connection.RemoteIpAddress.ToString()); || _networkManager.IsInLocalNetwork(HttpContext.GetNormalizedRemoteIp());
var result = await _userManager.StartForgotPasswordProcess(enteredUsername, isLocal).ConfigureAwait(false); var result = await _userManager.StartForgotPasswordProcess(enteredUsername, isLocal).ConfigureAwait(false);
@ -559,7 +560,7 @@ namespace Jellyfin.Api.Controllers
if (filterByNetwork) if (filterByNetwork)
{ {
if (!_networkManager.IsInLocalNetwork(HttpContext.Connection.RemoteIpAddress.ToString())) if (!_networkManager.IsInLocalNetwork(HttpContext.GetNormalizedRemoteIp()))
{ {
users = users.Where(i => i.HasPermission(PermissionKind.EnableRemoteAccess)); users = users.Where(i => i.HasPermission(PermissionKind.EnableRemoteAccess));
} }
@ -567,7 +568,7 @@ namespace Jellyfin.Api.Controllers
var result = users var result = users
.OrderBy(u => u.Username) .OrderBy(u => u.Username)
.Select(i => _userManager.GetUserDto(i, HttpContext.Connection.RemoteIpAddress.ToString())); .Select(i => _userManager.GetUserDto(i, HttpContext.GetNormalizedRemoteIp()));
return result; return result;
} }

View File

@ -8,6 +8,7 @@ using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Jellyfin.Api.Models.StreamingDtos; using Jellyfin.Api.Models.StreamingDtos;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net; using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Devices;
@ -198,12 +199,12 @@ namespace Jellyfin.Api.Helpers
if (!string.IsNullOrWhiteSpace(subtitleGroup)) if (!string.IsNullOrWhiteSpace(subtitleGroup))
{ {
AddSubtitles(state, subtitleStreams, builder, _httpContextAccessor.HttpContext.Request.HttpContext.User); AddSubtitles(state, subtitleStreams, builder, _httpContextAccessor.HttpContext.User);
} }
AppendPlaylist(builder, state, playlistUrl, totalBitrate, subtitleGroup); AppendPlaylist(builder, state, playlistUrl, totalBitrate, subtitleGroup);
if (EnableAdaptiveBitrateStreaming(state, isLiveStream, enableAdaptiveBitrateStreaming, _httpContextAccessor.HttpContext.Request.HttpContext.Connection.RemoteIpAddress)) if (EnableAdaptiveBitrateStreaming(state, isLiveStream, enableAdaptiveBitrateStreaming, _httpContextAccessor.HttpContext.GetNormalizedRemoteIp()))
{ {
var requestedVideoBitrate = state.VideoRequest == null ? 0 : state.VideoRequest.VideoBitRate ?? 0; var requestedVideoBitrate = state.VideoRequest == null ? 0 : state.VideoRequest.VideoBitRate ?? 0;
@ -334,11 +335,10 @@ namespace Jellyfin.Api.Helpers
} }
} }
private bool EnableAdaptiveBitrateStreaming(StreamState state, bool isLiveStream, bool enableAdaptiveBitrateStreaming, IPAddress ipAddress) private bool EnableAdaptiveBitrateStreaming(StreamState state, bool isLiveStream, bool enableAdaptiveBitrateStreaming, string ipAddress)
{ {
// Within the local network this will likely do more harm than good. // Within the local network this will likely do more harm than good.
var ip = RequestHelpers.NormalizeIp(ipAddress).ToString(); if (_networkManager.IsInLocalNetwork(ipAddress))
if (_networkManager.IsInLocalNetwork(ip))
{ {
return false; return false;
} }

View File

@ -6,6 +6,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Jellyfin.Data.Entities; using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums; using Jellyfin.Data.Enums;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net; using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Devices;
@ -498,7 +499,7 @@ namespace Jellyfin.Api.Helpers
true, true,
true, true,
true, true,
httpRequest.HttpContext.Connection.RemoteIpAddress.ToString()); httpRequest.HttpContext.GetNormalizedRemoteIp());
} }
else else
{ {

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using Jellyfin.Data.Enums; using Jellyfin.Data.Enums;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Session; using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Querying; using MediaBrowser.Model.Querying;
@ -119,7 +120,7 @@ namespace Jellyfin.Api.Helpers
authorization.Version, authorization.Version,
authorization.DeviceId, authorization.DeviceId,
authorization.Device, authorization.Device,
request.HttpContext.Connection.RemoteIpAddress.ToString(), request.HttpContext.GetNormalizedRemoteIp(),
user); user);
if (session == null) if (session == null)

View File

@ -32,13 +32,13 @@ namespace Jellyfin.Server.Middleware
/// <returns>The async task.</returns> /// <returns>The async task.</returns>
public async Task Invoke(HttpContext httpContext, INetworkManager networkManager, IServerConfigurationManager serverConfigurationManager) public async Task Invoke(HttpContext httpContext, INetworkManager networkManager, IServerConfigurationManager serverConfigurationManager)
{ {
if (httpContext.Request.IsLocal()) if (httpContext.IsLocal())
{ {
await _next(httpContext).ConfigureAwait(false); await _next(httpContext).ConfigureAwait(false);
return; return;
} }
var remoteIp = httpContext.Request.RemoteIp(); var remoteIp = httpContext.GetNormalizedRemoteIp();
if (serverConfigurationManager.Configuration.EnableRemoteAccess) if (serverConfigurationManager.Configuration.EnableRemoteAccess)
{ {

View File

@ -1,6 +1,7 @@
using System.Diagnostics; using System.Diagnostics;
using System.Globalization; using System.Globalization;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Configuration;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions; using Microsoft.AspNetCore.Http.Extensions;
@ -69,7 +70,7 @@ namespace Jellyfin.Server.Middleware
_logger.LogWarning( _logger.LogWarning(
"Slow HTTP Response from {url} to {remoteIp} in {elapsed:g} with Status Code {statusCode}", "Slow HTTP Response from {url} to {remoteIp} in {elapsed:g} with Status Code {statusCode}",
context.Request.GetDisplayUrl(), context.Request.GetDisplayUrl(),
context.Connection.RemoteIpAddress, context.GetNormalizedRemoteIp(),
watch.Elapsed, watch.Elapsed,
context.Response.StatusCode); context.Response.StatusCode);
} }

View File

@ -1,5 +1,3 @@
using System.Net;
using MediaBrowser.Common.Net;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
namespace MediaBrowser.Common.Extensions namespace MediaBrowser.Common.Extensions
@ -10,54 +8,32 @@ namespace MediaBrowser.Common.Extensions
public static class HttpContextExtensions public static class HttpContextExtensions
{ {
/// <summary> /// <summary>
/// Checks the origin of the HTTP request. /// Checks the origin of the HTTP context.
/// </summary> /// </summary>
/// <param name="request">The incoming HTTP request.</param> /// <param name="context">The incoming HTTP context.</param>
/// <returns><c>true</c> if the request is coming from LAN, <c>false</c> otherwise.</returns> /// <returns><c>true</c> if the request is coming from LAN, <c>false</c> otherwise.</returns>
public static bool IsLocal(this HttpRequest request) public static bool IsLocal(this HttpContext context)
{ {
return (request.HttpContext.Connection.LocalIpAddress == null return (context.Connection.LocalIpAddress == null
&& request.HttpContext.Connection.RemoteIpAddress == null) && context.Connection.RemoteIpAddress == null)
|| request.HttpContext.Connection.LocalIpAddress.Equals(request.HttpContext.Connection.RemoteIpAddress); || context.Connection.LocalIpAddress.Equals(context.Connection.RemoteIpAddress);
} }
/// <summary> /// <summary>
/// Extracts the remote IP address of the caller of the HTTP request. /// Extracts the remote IP address of the caller of the HTTP context.
/// </summary> /// </summary>
/// <param name="request">The HTTP request.</param> /// <param name="context">The HTTP context.</param>
/// <returns>The remote caller IP address.</returns> /// <returns>The remote caller IP address.</returns>
public static string RemoteIp(this HttpRequest request) public static string GetNormalizedRemoteIp(this HttpContext context)
{ {
var cachedRemoteIp = request.HttpContext.Items["RemoteIp"]?.ToString(); var ip = context.Connection.RemoteIpAddress;
if (!string.IsNullOrEmpty(cachedRemoteIp))
{
return cachedRemoteIp;
}
IPAddress ip;
// "Real" remote ip might be in X-Forwarded-For of X-Real-Ip
// (if the server is behind a reverse proxy for example)
if (!IPAddress.TryParse(request.Headers[CustomHeaderNames.XForwardedFor].ToString(), out ip))
{
if (!IPAddress.TryParse(request.Headers[CustomHeaderNames.XRealIP].ToString(), out ip))
{
ip = request.HttpContext.Connection.RemoteIpAddress;
// Default to the loopback address if no RemoteIpAddress is specified (i.e. during integration tests)
ip ??= IPAddress.Loopback;
}
}
if (ip.IsIPv4MappedToIPv6) if (ip.IsIPv4MappedToIPv6)
{ {
ip = ip.MapToIPv4(); ip = ip.MapToIPv4();
} }
var normalizedIp = ip.ToString(); return ip.ToString();
request.HttpContext.Items["RemoteIp"] = normalizedIp;
return normalizedIp;
} }
} }
} }