namespace LmeLicenseManager; internal static class Program { [STAThread] private static void Main(string[] args) { if (args.Length == 3 && args[0].Equals("--issue-play-review", StringComparison.OrdinalIgnoreCase)) { if (!DateTimeOffset.TryParse( args[2], System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AssumeUniversal, out var expiresAt)) { throw new InvalidOperationException("Scadenza non valida. Usa il formato ISO 8601."); } var reviewRepository = new LicenseRepository(); reviewRepository.Initialize(); var license = reviewRepository.Issue( "Google", "Play Review", "livio.merola+play-review@gmail.com", expiresAt, "Accesso riutilizzabile per la revisione Google Play"); var outputPath = Path.GetFullPath(args[1]); File.WriteAllText(outputPath, license.Token, new System.Text.UTF8Encoding(false)); Console.WriteLine($"Licenza di revisione creata in: {outputPath}"); Console.WriteLine($"Scadenza UTC: {license.ExpiresAtUtc:O}"); return; } if (args.Length == 2 && args[0].Equals("--export-key", StringComparison.OrdinalIgnoreCase)) { var password = Environment.GetEnvironmentVariable("LME_LICENSE_BACKUP_PASSWORD"); if (string.IsNullOrWhiteSpace(password)) { throw new InvalidOperationException("Imposta LME_LICENSE_BACKUP_PASSWORD per esportare la chiave."); } var exportRepository = new LicenseRepository(); exportRepository.Initialize(); exportRepository.ExportSigningKeyBackup(Path.GetFullPath(args[1]), password); Console.WriteLine($"Backup chiave creato: {Path.GetFullPath(args[1])}"); return; } if (args.Contains("--self-test", StringComparer.OrdinalIgnoreCase)) { RunSelfTest(); return; } var repository = new LicenseRepository(); repository.Initialize(); if (args.Contains("--init", StringComparer.OrdinalIgnoreCase)) { return; } ApplicationConfiguration.Initialize(); Application.Run(new MainForm(repository)); } private static void RunSelfTest() { var testDirectory = Path.Combine(Path.GetTempPath(), $"LME-License-SelfTest-{Guid.NewGuid():N}"); var importedDirectory = Path.Combine(Path.GetTempPath(), $"LME-License-SelfTest-{Guid.NewGuid():N}"); var incompatibleDirectory = Path.Combine(Path.GetTempPath(), $"LME-License-SelfTest-{Guid.NewGuid():N}"); const string backupPassword = "LME-Test-Backup-Password-2026"; try { var repository = new LicenseRepository(testDirectory, allowKeyGeneration: true); repository.Initialize(); var license = repository.Issue( "Mario", "Rossi", "mario.rossi@example.test", DateTimeOffset.Now.AddDays(30), "Test automatico"); if (!repository.VerifyToken(license.Token)) { throw new InvalidOperationException("Il codice emesso non supera la verifica crittografica."); } var backupPath = Path.Combine(testDirectory, "signing-key.lmekey"); repository.ExportSigningKeyBackup(backupPath, backupPassword); var importedRepository = new LicenseRepository(importedDirectory, allowKeyGeneration: true); importedRepository.Initialize(); importedRepository.ImportSigningKeyBackup(backupPath, backupPassword); var portableLicense = importedRepository.Issue( "Giulia", "Bianchi", "giulia.bianchi@example.test", DateTimeOffset.Now.AddYears(1), "Test portabilita chiave"); if (!repository.VerifyToken(portableLicense.Token) || !importedRepository.VerifyToken(license.Token)) { throw new InvalidOperationException("La chiave importata non produce licenze compatibili."); } var incompatibleRepository = new LicenseRepository(incompatibleDirectory, allowKeyGeneration: true); incompatibleRepository.Initialize(); var strictRepository = new LicenseRepository(incompatibleDirectory); strictRepository.Initialize(); if (File.Exists(Path.Combine(incompatibleDirectory, "manual-license-private.dpapi")) || Directory.GetFiles(incompatibleDirectory, "manual-license-private-incompatible-*.dpapi").Length != 1) { throw new InvalidOperationException("La chiave incompatibile non e stata conservata correttamente."); } Console.WriteLine("Self-test licenze e portabilita chiave completato."); } finally { foreach (var directory in new[] { testDirectory, importedDirectory, incompatibleDirectory }) { var fullPath = Path.GetFullPath(directory); var tempRoot = Path.GetFullPath(Path.GetTempPath()); if (Directory.Exists(fullPath) && fullPath.StartsWith(tempRoot, StringComparison.OrdinalIgnoreCase) && Path.GetFileName(fullPath).StartsWith("LME-License-SelfTest-", StringComparison.Ordinal)) { Directory.Delete(fullPath, true); } } } } }