Code/Endpoints/NetworkStorageRuntimeSecurityConfigLoad.cs
using System;
using System.Text.Json;
using System.Threading.Tasks;
namespace Sandbox;
public static partial class NetworkStorage
{
private static async Task<bool> LoadRuntimeSecurityConfigAsync( string reason, bool forceRefresh )
{
var url = $"{ApiRoot}/security-config/{Uri.EscapeDataString( ProjectId )}";
if ( forceRefresh )
url += "?refresh=1";
try
{
var raw = await Http.RequestStringAsync( url, "GET", null, null );
if ( !TryParseRuntimeSecurityConfig( raw, out var loaded, out var error ) )
return UseSyncedSecurityConfig( reason, error );
var previousMode = _runtimeSecurityConfig?.ModeText ?? "none";
_runtimeSecurityConfig = loaded with
{
Loaded = true,
Source = forceRefresh ? "backend-refresh" : "backend",
LoadedAt = DateTimeOffset.UtcNow,
LastRefreshReason = reason ?? "",
SyncedEnableAuthSessions = EnableAuthSessions,
SyncedEnableEncryptedRequests = EnableEncryptedRequests
};
EnableAuthSessions = loaded.EnableAuthSessions;
EnableEncryptedRequests = loaded.EnableEncryptedRequests;
Log.Info( $"[NetworkStorage] security config loaded reason={reason} {previousMode}->{_runtimeSecurityConfig.ModeText} version={loaded.ConfigVersion} ttl={loaded.TtlSeconds}s" );
return true;
}
catch ( Exception ex )
{
return UseSyncedSecurityConfig( reason, ex.Message );
}
}
private static bool TryParseRuntimeSecurityConfig( string raw, out RuntimeSecurityConfigSnapshot snapshot, out string error )
{
snapshot = null;
error = "";
if ( string.IsNullOrWhiteSpace( raw ) )
{
error = "empty response";
return false;
}
try
{
using var doc = JsonDocument.Parse( raw );
var root = doc.RootElement;
if ( root.TryGetProperty( "ok", out var ok ) && ok.ValueKind == JsonValueKind.False )
{
error = "backend returned ok=false";
return false;
}
var config = root.TryGetProperty( "config", out var configProp ) ? configProp : root;
var projectId = ReadString( config, "projectId" );
if ( !string.Equals( projectId, ProjectId, StringComparison.Ordinal ) )
{
error = $"project mismatch {projectId}";
return false;
}
if ( !NetworkStorageSecuritySignature.VerifySecurityConfigSignature( config, out var verificationMode ) )
{
error = "invalid signature";
return false;
}
if ( string.Equals( verificationMode, "config-version-fallback", StringComparison.OrdinalIgnoreCase ) )
Log.Warning( "[NetworkStorage] security config RSA verification failed; accepted HTTPS config with config-version integrity fallback" );
var settings = config.TryGetProperty( "settings", out var settingsProp ) ? settingsProp : default;
ApplyAnalyticsRuntimeConfig( settings );
snapshot = new RuntimeSecurityConfigSnapshot
{
ProjectId = projectId,
ConfigVersion = ReadString( config, "configVersion" ),
GeneratedAt = ReadDateTimeOffset( config, "generatedAt" ),
TtlSeconds = ReadInt( config, "ttlSeconds", 60 ),
EnableAuthSessions = ReadBool( settings, "enableAuthSessions", EnableAuthSessions ),
EnableEncryptedRequests = ReadBool( settings, "enableEncryptedRequests", EnableEncryptedRequests ),
EnablePlayerAnalytics = EnablePlayerAnalytics,
SignaturePresent = true
};
return true;
}
catch ( Exception ex )
{
error = ex.Message;
return false;
}
}
private static bool UseSyncedSecurityConfig( string reason, string error )
{
var isEndpointMissing = (error ?? "").Contains( "404", StringComparison.OrdinalIgnoreCase )
|| (error ?? "").Contains( "Not Found", StringComparison.OrdinalIgnoreCase );
_runtimeSecurityConfig = RuntimeSecurityConfigSnapshot.FromSyncedSettings() with
{
Loaded = true,
Source = isEndpointMissing ? "backend-missing-fallback" : "synced-fallback",
LoadedAt = DateTimeOffset.UtcNow,
TtlSeconds = isEndpointMissing ? 10 : 60,
LastRefreshReason = reason ?? "",
LastMismatchCode = error ?? ""
};
if ( isEndpointMissing )
{
if ( !_securityConfigUnavailableLogged )
Log.Info( $"[NetworkStorage] security config endpoint unavailable; using synced config authSessions={EnableAuthSessions} encryptedRequests={EnableEncryptedRequests}" );
}
else
{
Log.Warning( $"[NetworkStorage] security config unavailable reason={reason} error={error}; using synced config authSessions={EnableAuthSessions} encryptedRequests={EnableEncryptedRequests}" );
}
_securityConfigUnavailableLogged = true;
return false;
}
}