Permissions, RateControl and Auditing

This commit is contained in:
2026-07-16 14:01:08 +03:00
parent 3a1b95dbc5
commit ba64a0c95a
62 changed files with 6095 additions and 2366 deletions
+57 -8
View File
@@ -1053,13 +1053,38 @@ public partial class EpConnection : NetworkConnection, IStore
// check if the request through Websockets
if (_initialPacket)
{
var available = ends - offset;
var matchesGetPrefix = available > 0 && msg[offset] == 'G' &&
(available < 2 || msg[offset + 1] == 'E') &&
(available < 3 || msg[offset + 2] == 'T');
if (matchesGetPrefix && available < 3)
{
data.HoldFor(msg, offset, available, 3);
return ends;
}
_initialPacket = false;
if (msg.Length > 3 && Encoding.Default.GetString(msg, 0, 3) == "GET")
if (available >= 3 &&
msg[offset] == 'G' && msg[offset + 1] == 'E' && msg[offset + 2] == 'T')
{
// Parse with http packet
var req = new HttpRequestPacket();
var pSize = req.Parse(msg, 0, (uint)msg.Length);
long pSize;
try
{
pSize = req.Parse(msg, offset, ends);
}
catch (Exception exception) when (
exception is InvalidDataException ||
exception is ParserLimitException ||
exception is ArgumentException)
{
Global.Log(exception);
pSize = 0;
}
if (pSize > 0)
{
// check for WS upgrade
@@ -1090,10 +1115,24 @@ public partial class EpConnection : NetworkConnection, IStore
//@TODO: kill the connection
}
}
else if (pSize < 0)
{
_initialPacket = true;
var requiredLength = (ulong)available + (ulong)(-pSize);
if (requiredLength > uint.MaxValue)
throw new ParserLimitException("HTTP upgrade request is too large.");
data.HoldFor(msg, offset, available, (uint)requiredLength);
return ends;
}
else
{
// packet incomplete
return (uint)pSize;
var res = new HttpResponsePacket
{
Number = HttpResponseCode.BadRequest
};
res.Compose(HttpComposeOption.AllCalculateLength);
Send(res.Data);
}
// switching completed
@@ -1130,7 +1169,9 @@ public partial class EpConnection : NetworkConnection, IStore
if (_authPacket.Tdu != null)
{
remoteHeaders = Codec.ParseIndexedType<SessionHeaders>(_authPacket.Tdu.Value, null);
remoteHeaders = Codec.ParseIndexedType<SessionHeaders>(
_authPacket.Tdu.Value,
_serverWarehouse);
remoteAuthData = remoteHeaders.AuthenticationData;
remoteHeaders.AuthenticationData = null;
}
@@ -1162,7 +1203,17 @@ public partial class EpConnection : NetworkConnection, IStore
return offset;
}
if (_session.RemoteHeaders.AuthenticationProtocol == null)
var authenticationProtocol = _session.RemoteHeaders.AuthenticationProtocol;
var allowedAuthenticationProviders =
Server?.AllowedAuthenticationProviders ?? Array.Empty<string>();
var provider = !string.IsNullOrWhiteSpace(authenticationProtocol)
&& allowedAuthenticationProviders.Contains(
authenticationProtocol,
StringComparer.Ordinal)
? _serverWarehouse?.TryGetAuthenticationProvider(authenticationProtocol)
: null;
if (provider == null)
{
SendAuthHeaders(EpAuthPacketMethod.NotSupported, localHeaders);
_invalidCredentials = true;
@@ -1170,8 +1221,6 @@ public partial class EpConnection : NetworkConnection, IStore
return offset;
}
var provider = _serverWarehouse.GetAuthenticationProvider(_session.RemoteHeaders.AuthenticationProtocol);
var handler = provider.CreateAuthenticationHandler(new AuthenticationContext()
{
Direction = AuthenticationDirection.Responder,
@@ -56,6 +56,20 @@ partial class EpConnection
internal bool IsRateControlBlocked => Volatile.Read(ref _rateControlBlocked) != 0;
IEnumerable<IResourceManager> ResolveTypeDefManagers(TypeDef typeDef)
{
var definedType = typeDef switch
{
LocalTypeDef localTypeDef => localTypeDef.DefinedType,
RemoteTypeDef remoteTypeDef => remoteTypeDef.ProxyType,
_ => null
};
return definedType == null
? Array.Empty<IResourceManager>()
: Instance.Warehouse.ResolveResourceManagers(definedType, null);
}
bool TryApplyManagers(
MemberDef member,
IResource? resource,
@@ -1359,7 +1373,7 @@ partial class EpConnection
var classNames = (string[])value;
var typeDefs = new List<LocalTypeDef>();
var typeDefs = new List<TypeDef>();
foreach (var className in classNames)
{
@@ -1372,7 +1386,7 @@ partial class EpConnection
if (typeDefs.Count > 0)
{
var managers = typeDefs
.SelectMany(typeDef => Instance.Warehouse.ResolveResourceManagers(typeDef.DefinedType, null));
.SelectMany(ResolveTypeDefManagers);
if (!TryApplyManagers(
null,
@@ -1405,7 +1419,7 @@ partial class EpConnection
if (t != null)
{
var managers = Instance.Warehouse.ResolveResourceManagers(t.DefinedType, null);
var managers = ResolveTypeDefManagers(t);
if (!TryApplyManagers(
null,
null,
@@ -1670,7 +1684,6 @@ partial class EpConnection
ErrorType.Management,
ExceptionCode.InvokeDenied,
out var managerDelay,
managers: Instance.Warehouse.ResolveResourceManagers(typeDef.DefinedType, null),
supportsDelay: true))
return;
+7 -8
View File
@@ -56,8 +56,13 @@ public class EpServer : NetworkServer<EpConnection>, IResource
set;
}
//[Attribute]
public string[] AllowedAuthenticationProviders { get; set; }
/// <summary>
/// Authentication provider protocol names that incoming connections may negotiate.
/// Providers must also be registered with the server Warehouse. An empty list denies
/// authenticated negotiation; anonymous access remains controlled separately by
/// <see cref="AllowUnauthorizedAccess"/>.
/// </summary>
public string[] AllowedAuthenticationProviders { get; set; } = Array.Empty<string>();
/// <summary>
/// Encryption provider protocol names that incoming connections may negotiate.
@@ -124,12 +129,6 @@ public class EpServer : NetworkServer<EpConnection>, IResource
| ExceptionLevel.Message
| ExceptionLevel.Trace;
public void RegisterAuthenticationHandler<T>(string[] domains, AuthenticationMode[] modes) where T : class, IAuthenticationHandler
{
}
public Instance Instance
{