Full removal of Lop's phone home code.
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
<Project Sdk="Dalamud.NET.Sdk/13.0.0">
|
<Project Sdk="Dalamud.NET.Sdk/13.0.0">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<AssemblyName>Snowcloak</AssemblyName>
|
<AssemblyName>Snowcloak</AssemblyName>
|
||||||
<Version>0.1.6.1</Version>
|
<Version>0.1.6.2</Version>
|
||||||
<PackageProjectUrl>https://github.com/Eauldane/SnowcloakClient/</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/Eauldane/SnowcloakClient/</PackageProjectUrl>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
@@ -12,14 +12,6 @@ namespace MareSynchronos.Services;
|
|||||||
|
|
||||||
public sealed class RemoteConfigurationService
|
public sealed class RemoteConfigurationService
|
||||||
{
|
{
|
||||||
// private readonly static Dictionary<string, string> ConfigPublicKeys = new(StringComparer.Ordinal)
|
|
||||||
// {
|
|
||||||
// { "", "" },
|
|
||||||
// };
|
|
||||||
|
|
||||||
private readonly static string[] ConfigSources = [
|
|
||||||
"https://snowcloak-sync.com/config.json",
|
|
||||||
];
|
|
||||||
|
|
||||||
private readonly ILogger<RemoteConfigurationService> _logger;
|
private readonly ILogger<RemoteConfigurationService> _logger;
|
||||||
private readonly RemoteConfigCacheService _configService;
|
private readonly RemoteConfigCacheService _configService;
|
||||||
@@ -31,170 +23,20 @@ public sealed class RemoteConfigurationService
|
|||||||
_configService = configService;
|
_configService = configService;
|
||||||
_initTask = Task.Run(DownloadConfig);
|
_initTask = Task.Run(DownloadConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<JsonObject> GetConfigAsync(string sectionName)
|
|
||||||
{
|
|
||||||
await _initTask.ConfigureAwait(false);
|
|
||||||
if (!_configService.Current.Configuration.TryGetPropertyValue(sectionName, out var section))
|
|
||||||
section = null;
|
|
||||||
return (section as JsonObject) ?? new();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<T?> GetConfigAsync<T>(string sectionName)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var json = await GetConfigAsync(sectionName).ConfigureAwait(false);
|
|
||||||
return JsonSerializer.Deserialize<T>(json);
|
|
||||||
}
|
|
||||||
catch (JsonException ex)
|
|
||||||
{
|
|
||||||
_logger.LogWarning(ex, "Invalid JSON in remote config: {sectionName}", sectionName);
|
|
||||||
return default;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task DownloadConfig()
|
private async Task DownloadConfig()
|
||||||
{
|
{
|
||||||
string? jsonResponse = null;
|
// Removed Lop's remote config code. Function exists purely to keep things clean.
|
||||||
|
LoadConfig();
|
||||||
foreach (var remoteUrl in ConfigSources)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_logger.LogDebug("Fetching {url}", remoteUrl);
|
|
||||||
|
|
||||||
using var httpClient = new HttpClient(
|
|
||||||
new HttpClientHandler
|
|
||||||
{
|
|
||||||
AllowAutoRedirect = true,
|
|
||||||
MaxAutomaticRedirections = 5
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
httpClient.Timeout = TimeSpan.FromSeconds(6);
|
|
||||||
|
|
||||||
var ver = Assembly.GetExecutingAssembly().GetName().Version;
|
|
||||||
httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("MareSynchronos", ver!.Major + "." + ver!.Minor + "." + ver!.Build));
|
|
||||||
|
|
||||||
var request = new HttpRequestMessage(HttpMethod.Get, remoteUrl);
|
|
||||||
|
|
||||||
if (remoteUrl.Equals(_configService.Current.Origin, StringComparison.Ordinal))
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(_configService.Current.ETag))
|
|
||||||
request.Headers.IfNoneMatch.Add(new EntityTagHeaderValue(_configService.Current.ETag));
|
|
||||||
|
|
||||||
if (_configService.Current.LastModified != null)
|
|
||||||
request.Headers.IfModifiedSince = _configService.Current.LastModified;
|
|
||||||
}
|
|
||||||
|
|
||||||
var response = await httpClient.SendAsync(request).ConfigureAwait(false);
|
|
||||||
|
|
||||||
if (response.StatusCode == HttpStatusCode.NotModified)
|
|
||||||
{
|
|
||||||
_logger.LogDebug("Using cached remote configuration from {url}", remoteUrl);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
response.EnsureSuccessStatusCode();
|
|
||||||
|
|
||||||
var contentType = response.Content.Headers.ContentType?.MediaType;
|
|
||||||
|
|
||||||
if (contentType == null || !contentType.Equals("application/json", StringComparison.Ordinal))
|
|
||||||
{
|
|
||||||
_logger.LogWarning("HTTP request for remote config failed: wrong MIME type");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
_logger.LogInformation("Downloaded new configuration from {url}", remoteUrl);
|
|
||||||
|
|
||||||
_configService.Current.Origin = remoteUrl;
|
|
||||||
_configService.Current.ETag = response.Headers.ETag?.ToString() ?? string.Empty;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (response.Content.Headers.Contains("Last-Modified"))
|
|
||||||
{
|
|
||||||
var lastModified = response.Content.Headers.GetValues("Last-Modified").First();
|
|
||||||
_configService.Current.LastModified = DateTimeOffset.Parse(lastModified, System.Globalization.CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
_configService.Current.LastModified = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
jsonResponse = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogWarning(ex, "HTTP request for remote config failed");
|
|
||||||
|
|
||||||
if (remoteUrl.Equals(_configService.Current.Origin, StringComparison.Ordinal))
|
|
||||||
{
|
|
||||||
_configService.Current.ETag = string.Empty;
|
|
||||||
_configService.Current.LastModified = null;
|
|
||||||
_configService.Save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (jsonResponse == null)
|
|
||||||
{
|
|
||||||
_logger.LogWarning("Could not download remote config");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var jsonDoc = JsonNode.Parse(jsonResponse) as JsonObject;
|
|
||||||
|
|
||||||
if (jsonDoc == null)
|
|
||||||
{
|
|
||||||
_logger.LogWarning("Downloaded remote config is not a JSON object");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadConfig(jsonDoc);
|
|
||||||
}
|
|
||||||
catch (JsonException ex)
|
|
||||||
{
|
|
||||||
_logger.LogWarning(ex, "Invalid JSON in remote config response");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool VerifySignature(string message, ulong ts, string signature, string pubKey)
|
private void LoadConfig()
|
||||||
{
|
|
||||||
byte[] msg = [.. BitConverter.GetBytes(ts), .. Encoding.UTF8.GetBytes(message)];
|
|
||||||
byte[] sig = Convert.FromBase64String(signature);
|
|
||||||
byte[] pub = Convert.FromBase64String(pubKey);
|
|
||||||
return Ed25519.Verify(sig, msg, pub);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LoadConfig(JsonObject jsonDoc)
|
|
||||||
{
|
{
|
||||||
ulong ts = 1755859494;
|
ulong ts = 1755859494;
|
||||||
|
|
||||||
//if (ts <= _configService.Current.Timestamp)
|
|
||||||
//{
|
|
||||||
// _logger.LogDebug("Remote configuration is not newer than cached config");
|
|
||||||
// return;
|
|
||||||
//}
|
|
||||||
|
|
||||||
var signatures = jsonDoc["sig"]!.AsObject();
|
|
||||||
var configString = "{\"mainServer\":{\"api_url\":\"wss://hub.snowcloak-sync.com/\",\"hub_url\":\"wss://hub.snowcloak-sync.com/mare\"},\"repoChange\":{\"current_repo\":\"https://hub.snowcloak-sync.com/repo.json\",\"valid_repos\":[\"https://hub.snowcloak-sync.com/repo.json\"]},\"noSnap\":{\"listOfPlugins\":[\"Snapper\",\"Snappy\",\"Meddle.Plugin\"]}}";
|
var configString = "{\"mainServer\":{\"api_url\":\"wss://hub.snowcloak-sync.com/\",\"hub_url\":\"wss://hub.snowcloak-sync.com/mare\"},\"repoChange\":{\"current_repo\":\"https://hub.snowcloak-sync.com/repo.json\",\"valid_repos\":[\"https://hub.snowcloak-sync.com/repo.json\"]},\"noSnap\":{\"listOfPlugins\":[\"Snapper\",\"Snappy\",\"Meddle.Plugin\"]}}";
|
||||||
// var configString = jsonDoc["config"]!.GetValue<string>();
|
|
||||||
// bool verified = signatures.Any(sig =>
|
|
||||||
// ConfigPublicKeys.TryGetValue(sig.Key, out var pubKey) &&
|
|
||||||
// VerifySignature(configString, ts, sig.Value!.GetValue<string>(), pubKey));
|
|
||||||
|
|
||||||
//bool verified = true;
|
|
||||||
// if (!verified)
|
|
||||||
// {
|
|
||||||
// _logger.LogWarning("Could not verify signature for downloaded remote config");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
_configService.Current.Configuration = JsonNode.Parse(configString)!.AsObject();
|
_configService.Current.Configuration = JsonNode.Parse(configString)!.AsObject();
|
||||||
_configService.Current.Timestamp = ts;
|
_configService.Current.Timestamp = ts;
|
||||||
|
Reference in New Issue
Block a user