diff options
author | vnugent <public@vaughnnugent.com> | 2023-10-18 21:51:34 -0400 |
---|---|---|
committer | vnugent <public@vaughnnugent.com> | 2023-10-18 21:51:34 -0400 |
commit | f44cdf8f2685c37e5a1d77018a5227942b578863 (patch) | |
tree | 70820eef3328c4269c46dcc4f129f1b798f56666 /lib | |
parent | 44a05ac3854d6cd0fa65d8ffc0f6efe7abfc87ad (diff) |
account and endpoint security updates
Diffstat (limited to 'lib')
14 files changed, 38 insertions, 118 deletions
diff --git a/lib/Hashing.Portable/src/RandomHash.cs b/lib/Hashing.Portable/src/RandomHash.cs index ebc8845..486b0c4 100644 --- a/lib/Hashing.Portable/src/RandomHash.cs +++ b/lib/Hashing.Portable/src/RandomHash.cs @@ -210,9 +210,10 @@ namespace VNLib.Hashing } /// <summary> - /// Fill the buffer with non-zero bytes + /// Fill the buffer with cryptographically secure non-zero bytes /// </summary> /// <param name="data">Buffer to fill</param> + [MethodImpl(MethodImplOptions.NoOptimization)] public static void GetRandomBytes(Span<byte> data) => RandomNumberGenerator.Fill(data); } }
\ No newline at end of file diff --git a/lib/Plugins.Essentials.ServiceStack/src/Construction/SsBuilderExtensions.cs b/lib/Plugins.Essentials.ServiceStack/src/Construction/SsBuilderExtensions.cs index 54b7ff2..abb1cc1 100644 --- a/lib/Plugins.Essentials.ServiceStack/src/Construction/SsBuilderExtensions.cs +++ b/lib/Plugins.Essentials.ServiceStack/src/Construction/SsBuilderExtensions.cs @@ -260,7 +260,7 @@ namespace VNLib.Plugins.Essentials.ServiceStack.Construction //Add all services plugin.OnPluginServiceEvent<ISessionProvider>(Instance.SetSessionProvider); plugin.OnPluginServiceEvent<IPageRouter>(Instance.SetPageRouter); - plugin.OnPluginServiceEvent<IAccountSecurityProvider>(p => Instance.SetAccountSecProvider(p)); + plugin.OnPluginServiceEvent<IAccountSecurityProvider>(Instance.SetAccountSecProvider); //Add all middleware to the chain plugin.OnPluginServiceEvent<IHttpMiddleware[]>(p => Array.ForEach(p, mw => Instance.MiddlewareChain.AddLast(mw))); diff --git a/lib/Plugins.Essentials/src/Accounts/AccountUtils.cs b/lib/Plugins.Essentials/src/Accounts/AccountUtils.cs index 259f52a..a5fb074 100644 --- a/lib/Plugins.Essentials/src/Accounts/AccountUtils.cs +++ b/lib/Plugins.Essentials/src/Accounts/AccountUtils.cs @@ -387,7 +387,7 @@ namespace VNLib.Plugins.Essentials.Accounts IClientAuthorization auth = GenerateAuthorization(entity, secInfo, user); //Set client token - response.Token = auth.SecurityToken.ClientToken; + response.Token = auth.GetClientAuthDataString(); } /// <summary> @@ -421,7 +421,7 @@ namespace VNLib.Plugins.Essentials.Accounts IClientAuthorization auth = prov.ReAuthorizeClient(entity); //Store the client token in response message - response.Token = auth.SecurityToken.ClientToken; + response.Token = auth.GetClientAuthDataString(); //Regen session id also entity.Session.RegenID(); diff --git a/lib/Plugins.Essentials/src/Accounts/ClientSecurityToken.cs b/lib/Plugins.Essentials/src/Accounts/ClientSecurityToken.cs deleted file mode 100644 index 0d81344..0000000 --- a/lib/Plugins.Essentials/src/Accounts/ClientSecurityToken.cs +++ /dev/null @@ -1,41 +0,0 @@ -/* -* Copyright (c) 2023 Vaughn Nugent -* -* Library: VNLib -* Package: VNLib.Plugins.Essentials -* File: ClientSecurityToken.cs -* -* ClientSecurityToken.cs is part of VNLib.Plugins.Essentials which is part -* of the larger VNLib collection of libraries and utilities. -* -* VNLib.Plugins.Essentials is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* VNLib.Plugins.Essentials is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see https://www.gnu.org/licenses/. -*/ - - -namespace VNLib.Plugins.Essentials.Accounts -{ - /// <summary> - /// A structure that contains the client/server information - /// for client/server authorization - /// </summary> - /// <param name="ClientToken"> - /// The public portion of the token to send to the client - /// </param> - /// <param name="ServerToken"> - /// The secret portion of the token that is to be - /// stored on the server (usually in the client's session) - /// </param> - public readonly record struct ClientSecurityToken(string ClientToken, string ServerToken) - { } -}
\ No newline at end of file diff --git a/lib/Plugins.Essentials/src/Accounts/IClientAuthorization.cs b/lib/Plugins.Essentials/src/Accounts/IClientAuthorization.cs index 73f97c0..608c639 100644 --- a/lib/Plugins.Essentials/src/Accounts/IClientAuthorization.cs +++ b/lib/Plugins.Essentials/src/Accounts/IClientAuthorization.cs @@ -31,13 +31,17 @@ namespace VNLib.Plugins.Essentials.Accounts public interface IClientAuthorization { /// <summary> - /// A security token that may be set as a cookie or used + /// Gets the client specific authorization data as a string, may be serialized + /// and will be sent to the client. /// </summary> - string? LoginSecurityString { get; } + /// <returns>A string representation of the client's authorization data</returns> + string GetClientAuthDataString(); /// <summary> - /// The clients security token information + /// Gets the client specific authorization data raw object and may be serialized + /// as needed. /// </summary> - ClientSecurityToken SecurityToken { get; } + /// <returns>The authorization object to send to the client</returns> + object GetClientAuthData(); } }
\ No newline at end of file diff --git a/lib/Plugins.Essentials/src/Endpoints/ProtectionSettings.cs b/lib/Plugins.Essentials/src/Endpoints/ProtectionSettings.cs index 4d09165..de77c0a 100644 --- a/lib/Plugins.Essentials/src/Endpoints/ProtectionSettings.cs +++ b/lib/Plugins.Essentials/src/Endpoints/ProtectionSettings.cs @@ -50,13 +50,6 @@ namespace VNLib.Plugins.Essentials.Endpoints public readonly bool DisableRefererMatch { get; init; } /// <summary> - /// Requires all connections to have pass an IsBrowser() check - /// (requires a valid user-agent header that contains Mozilla in - /// the string) - /// </summary> - public readonly bool DisableBrowsersOnly { get; init; } - - /// <summary> /// Disables response caching, by setting the cache control headers appropriatly. /// Default is disabled /// </summary> diff --git a/lib/Plugins.Essentials/src/Endpoints/ResourceEndpointBase.cs b/lib/Plugins.Essentials/src/Endpoints/ResourceEndpointBase.cs index 2177838..447d17b 100644 --- a/lib/Plugins.Essentials/src/Endpoints/ResourceEndpointBase.cs +++ b/lib/Plugins.Essentials/src/Endpoints/ResourceEndpointBase.cs @@ -150,12 +150,6 @@ namespace VNLib.Plugins.Essentials.Endpoints return false; } - //Enforce browser check - if (!EndpointProtectionSettings.DisableBrowsersOnly && !entity.Server.IsBrowser()) - { - return false; - } - //Enforce refer check if (!EndpointProtectionSettings.DisableRefererMatch && entity.Server.Referer != null && !entity.Server.RefererMatch()) { diff --git a/lib/Plugins.Essentials/src/EventProcessor.cs b/lib/Plugins.Essentials/src/EventProcessor.cs index f565707..f292068 100644 --- a/lib/Plugins.Essentials/src/EventProcessor.cs +++ b/lib/Plugins.Essentials/src/EventProcessor.cs @@ -255,7 +255,7 @@ namespace VNLib.Plugins.Essentials goto RespondAndExit; } } - } + } //If no virtual processor handled the ws request, deny it if (entity.Server.IsWebSocketRequest) @@ -548,20 +548,16 @@ namespace VNLib.Plugins.Essentials /// <param name="router">A reference to the current <see cref="IPageRouter"/> instance if cofigured</param> /// <param name="entity">The http entity to process</param> /// <returns>The results to return to the file processor, this method must return an argument</returns> - protected virtual async ValueTask<FileProcessArgs> RouteFileAsync(IPageRouter? router, HttpEntity entity) + protected virtual ValueTask<FileProcessArgs> RouteFileAsync(IPageRouter? router, HttpEntity entity) { if(router != null) { - //Get a file routine - FileProcessArgs routine = await router.RouteAsync(entity); - //Call post processor method - PostProcessEntity(entity, ref routine); - //Return the routine - return routine; + //Route file async from the router reference + return router.RouteAsync(entity); } else { - return FileProcessArgs.Continue; + return ValueTask.FromResult(FileProcessArgs.Continue); } } diff --git a/lib/Plugins.Essentials/src/Oauth/O2EndpointBase.cs b/lib/Plugins.Essentials/src/Oauth/O2EndpointBase.cs index 60004c7..eb3ff5b 100644 --- a/lib/Plugins.Essentials/src/Oauth/O2EndpointBase.cs +++ b/lib/Plugins.Essentials/src/Oauth/O2EndpointBase.cs @@ -43,10 +43,6 @@ namespace VNLib.Plugins.Essentials.Oauth /// </summary> public abstract class O2EndpointBase : ResourceEndpointBase { - //Disable browser only protection - ///<inheritdoc/> - protected override ProtectionSettings EndpointProtectionSettings { get; } = new() { DisableBrowsersOnly = true }; - ///<inheritdoc/> public override async ValueTask<VfReturnType> Process(HttpEntity entity) { diff --git a/lib/Plugins.Essentials/src/Sessions/ISessionExtensions.cs b/lib/Plugins.Essentials/src/Sessions/ISessionExtensions.cs index 81d6ad3..018c9a2 100644 --- a/lib/Plugins.Essentials/src/Sessions/ISessionExtensions.cs +++ b/lib/Plugins.Essentials/src/Sessions/ISessionExtensions.cs @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022 Vaughn Nugent +* Copyright (c) 2023 Vaughn Nugent * * Library: VNLib * Package: VNLib.Plugins.Essentials @@ -23,8 +23,8 @@ */ using System; -using System.Runtime.CompilerServices; using System.Security.Authentication; +using System.Runtime.CompilerServices; using VNLib.Net.Http; using VNLib.Utils; @@ -41,8 +41,7 @@ namespace VNLib.Plugins.Essentials.Sessions public const string REFER_ENTRY = "__.rfr"; public const string SECURE_ENTRY = "__.sec"; public const string CROSS_ORIGIN = "__.cor"; - public const string LOCAL_TIME_ENTRY = "__.lot"; - public const string LOGIN_TOKEN_ENTRY = "__.lte"; + public const string LOCAL_TIME_ENTRY = "__.lot"; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string GetUserAgent(this ISession session) => session[USER_AGENT_ENTRY]; @@ -61,10 +60,8 @@ namespace VNLib.Plugins.Essentials.Sessions public static void SetRefer(this ISession session, string refer) => session[REFER_ENTRY] = refer; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static SslProtocols GetSecurityProtocol(this ISession session) - { - return (SslProtocols)session.GetValueType<string, int>(SECURE_ENTRY); - } + public static SslProtocols GetSecurityProtocol(this ISession session) => (SslProtocols)session.GetValueType<string, int>(SECURE_ENTRY); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void SetSecurityProtocol(this ISession session, SslProtocols protocol) => session[SECURE_ENTRY] = VnEncoding.ToBase32String((int)protocol); @@ -72,11 +69,6 @@ namespace VNLib.Plugins.Essentials.Sessions public static bool IsCrossOrigin(this ISession session) => session[CROSS_ORIGIN] == bool.TrueString; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void IsCrossOrigin(this ISession session, bool crossOrign) => session[CROSS_ORIGIN] = crossOrign.ToString(); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string GetLoginToken(this ISession session) => session[LOGIN_TOKEN_ENTRY]; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SetLoginToken(this ISession session, string loginToken) => session[LOGIN_TOKEN_ENTRY] = loginToken; /// <summary> /// Initializes a "new" session with initial varaibles from the current connection diff --git a/lib/Plugins.Essentials/src/Sessions/SessionBase.cs b/lib/Plugins.Essentials/src/Sessions/SessionBase.cs index bf20b9d..47079a0 100644 --- a/lib/Plugins.Essentials/src/Sessions/SessionBase.cs +++ b/lib/Plugins.Essentials/src/Sessions/SessionBase.cs @@ -28,8 +28,6 @@ using System.Runtime.CompilerServices; using VNLib.Utils; -#nullable disable - namespace VNLib.Plugins.Essentials.Sessions { /// <summary> @@ -73,6 +71,8 @@ namespace VNLib.Plugins.Essentials.Sessions ///<inheritdoc/> public abstract DateTimeOffset Created { get; set; } +#nullable disable + ///<inheritdoc/> ///<exception cref="ObjectDisposedException"></exception> public string this[string index] @@ -80,13 +80,14 @@ namespace VNLib.Plugins.Essentials.Sessions get => IndexerGet(index); set => IndexerSet(index, value); } + ///<inheritdoc/> public virtual IPAddress UserIP { get { //try to parse the IP address, otherwise return null - _ = IPAddress.TryParse(this[IP_ADDRESS_ENTRY], out IPAddress ip); + _ = IPAddress.TryParse(this[IP_ADDRESS_ENTRY], out IPAddress? ip); return ip; } protected set @@ -138,6 +139,7 @@ namespace VNLib.Plugins.Essentials.Sessions [MethodImpl(MethodImplOptions.AggressiveInlining)] set => this[TOKEN_ENTRY] = value; } + ///<inheritdoc/> [MethodImpl(MethodImplOptions.AggressiveInlining)] public virtual void Invalidate(bool all = false) diff --git a/lib/Plugins.Essentials/src/Sessions/SessionInfo.cs b/lib/Plugins.Essentials/src/Sessions/SessionInfo.cs index 6c1141a..527792f 100644 --- a/lib/Plugins.Essentials/src/Sessions/SessionInfo.cs +++ b/lib/Plugins.Essentials/src/Sessions/SessionInfo.cs @@ -149,18 +149,7 @@ namespace VNLib.Plugins.Essentials.Sessions { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => UserSession.Created; - } - - /// <summary> - /// Gets or sets the session's login hash, if set to a non-empty/null value, will trigger an upgrade on close - /// </summary> - public readonly string LoginHash - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => UserSession.GetLoginToken(); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => UserSession.SetLoginToken(value); - } + } /// <summary> /// Gets or sets the session's login token, if set to a non-empty/null value, will trigger an upgrade on close diff --git a/lib/Utils/src/IO/VnMemoryStream.cs b/lib/Utils/src/IO/VnMemoryStream.cs index eed4ca2..d269134 100644 --- a/lib/Utils/src/IO/VnMemoryStream.cs +++ b/lib/Utils/src/IO/VnMemoryStream.cs @@ -332,7 +332,7 @@ namespace VNLib.Utils.IO _position++; //Return value - return ptr[0]; + return *ptr; } /* diff --git a/lib/Utils/src/Memory/Caching/ObjectRentalBase.cs b/lib/Utils/src/Memory/Caching/ObjectRentalBase.cs index ca07885..a68f8e7 100644 --- a/lib/Utils/src/Memory/Caching/ObjectRentalBase.cs +++ b/lib/Utils/src/Memory/Caching/ObjectRentalBase.cs @@ -129,14 +129,8 @@ namespace VNLib.Utils.Memory.Caching /// <param name="constructor">The constructor function invoked to create new instances of the <see cref="IReusable"/> type</param> /// <param name="quota">The maximum number of elements that will be cached</param> /// <returns></returns> - public static ObjectRental<T> CreateReusable<T>(Func<T> constructor, int quota = 0) where T : class, IReusable - { - //Rent/return callbacks - static void Rent(T item) => item.Prepare(); - static void Return(T item) => item.Release(); - - return Create(constructor, Rent, Return, quota); - } + public static ObjectRental<T> CreateReusable<T>(Func<T> constructor, int quota = 0) where T : class, IReusable + => Create(constructor, StaticOnReusablePrepare, StaticOnReusableRelease, quota); /// <summary> /// Creates a new <see cref="ThreadLocalObjectStorage{T}"/> instance with a parameterless constructor @@ -155,11 +149,11 @@ namespace VNLib.Utils.Memory.Caching /// <typeparam name="T">The <see cref="IReusable"/> type</typeparam> /// <param name="constructor">The constructor function invoked to create new instances of the <see cref="IReusable"/> type</param> /// <returns></returns> - public static ThreadLocalObjectStorage<T> CreateThreadLocalReusable<T>(Func<T> constructor) where T : class, IReusable - { - static void Rent(T item) => item.Prepare(); - static void Return(T item) => item.Release(); - return new ThreadLocalObjectStorage<T>(constructor, Rent, Return); - } + public static ThreadLocalObjectStorage<T> CreateThreadLocalReusable<T>(Func<T> constructor) where T : class, IReusable + => new(constructor, StaticOnReusablePrepare, StaticOnReusableRelease); + + private static void StaticOnReusablePrepare<T>(T item) where T: IReusable => item.Prepare(); + + private static void StaticOnReusableRelease<T>(T item) where T : IReusable => item.Release(); } } |