aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar vnugent <public@vaughnnugent.com>2023-10-18 21:51:34 -0400
committerLibravatar vnugent <public@vaughnnugent.com>2023-10-18 21:51:34 -0400
commitf44cdf8f2685c37e5a1d77018a5227942b578863 (patch)
tree70820eef3328c4269c46dcc4f129f1b798f56666
parent44a05ac3854d6cd0fa65d8ffc0f6efe7abfc87ad (diff)
account and endpoint security updates
-rw-r--r--lib/Hashing.Portable/src/RandomHash.cs3
-rw-r--r--lib/Plugins.Essentials.ServiceStack/src/Construction/SsBuilderExtensions.cs2
-rw-r--r--lib/Plugins.Essentials/src/Accounts/AccountUtils.cs4
-rw-r--r--lib/Plugins.Essentials/src/Accounts/ClientSecurityToken.cs41
-rw-r--r--lib/Plugins.Essentials/src/Accounts/IClientAuthorization.cs12
-rw-r--r--lib/Plugins.Essentials/src/Endpoints/ProtectionSettings.cs7
-rw-r--r--lib/Plugins.Essentials/src/Endpoints/ResourceEndpointBase.cs6
-rw-r--r--lib/Plugins.Essentials/src/EventProcessor.cs14
-rw-r--r--lib/Plugins.Essentials/src/Oauth/O2EndpointBase.cs4
-rw-r--r--lib/Plugins.Essentials/src/Sessions/ISessionExtensions.cs18
-rw-r--r--lib/Plugins.Essentials/src/Sessions/SessionBase.cs8
-rw-r--r--lib/Plugins.Essentials/src/Sessions/SessionInfo.cs13
-rw-r--r--lib/Utils/src/IO/VnMemoryStream.cs2
-rw-r--r--lib/Utils/src/Memory/Caching/ObjectRentalBase.cs22
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();
}
}