/// <summary> /// Tests the sync logic with custom <see cref="AppList"/>s. /// </summary> /// <param name="resetMode">The <see cref="SyncResetMode"/> to pass to <see cref="SyncIntegrationManager.Sync"/>.</param> /// <param name="appListLocal">The current local <see cref="AppList"/>.</param> /// <param name="appListLast">The state of the <see cref="AppList"/> after the last successful sync.</param> /// <param name="appListServer">The current server-side <see cref="AppList"/>.</param> private void TestSync(SyncResetMode resetMode, AppList appListLocal, AppList appListLast, AppList appListServer) { appListLocal.SaveXml(_appListPath); if (appListLast != null) { appListLast.SaveXml(_appListPath + SyncIntegrationManager.AppListLastSyncSuffix); } using (var stream = File.Create(_appListPath + ".zip")) appListServer.SaveXmlZip(stream); using (var appListServerFile = File.OpenRead(_appListPath + ".zip")) using (var syncServer = new MicroServer("app-list", appListServerFile)) { using (var integrationManager = new SyncIntegrationManager(_appListPath, new SyncServer { Uri = syncServer.ServerUri }, interfaceId => new Feed(), new SilentTaskHandler())) integrationManager.Sync(resetMode); appListServer = AppList.LoadXmlZip(syncServer.FileContent); } appListLocal = XmlStorage.LoadXml <AppList>(_appListPath); appListLast = XmlStorage.LoadXml <AppList>(_appListPath + SyncIntegrationManager.AppListLastSyncSuffix); Assert.AreEqual(appListLocal, appListServer, "Server and local data should be equal after sync"); Assert.AreEqual(appListLocal, appListLast, "Last sync snapshot and local data should be equal after sync"); }
public static void LoadCurrent() { try { string settingsPath = Locations.GetSaveConfigPath(GeneralSettings.AppName, true, "Settings.xml"); if (File.Exists(settingsPath)) { Current = XmlStorage.LoadXml <Settings>(settingsPath); Log.Info("Loaded settings from " + settingsPath); return; } } #region Error handling catch (IOException ex) { Log.Warn("Failed to load settings: " + ex.Message + "\nReverting to defaults"); } catch (UnauthorizedAccessException ex) { Log.Warn("Insufficient rights to load settings: " + ex.Message + "\nReverting to defaults"); } catch (InvalidDataException ex) { Log.Warn("Settings file damaged: " + ex.Message + "\nReverting to defaults"); } #endregion Log.Info("Loaded default settings"); Current = new Settings(); }
/// <summary> /// Detects attacks such as feed substitution or replay attacks. /// </summary> /// <param name="data">The content of the feed file as a byte array.</param> /// <param name="uri">The URI the feed originally came from.</param> /// <param name="signature">The first trusted signature for the feed.</param> /// <exception cref="ReplayAttackException">A replay attack was detected.</exception> /// <exception cref="UriFormatException"><see cref="Feed.Uri"/> is missing or does not match <paramref name="uri"/>.</exception> private void DetectAttacks(byte[] data, FeedUri uri, ValidSignature signature) { // Detect feed substitution var feed = XmlStorage.LoadXml <Feed>(new MemoryStream(data)); if (feed.Uri == null) { throw new UriFormatException(string.Format(Resources.FeedUriMissing, uri)); } if (feed.Uri != uri) { throw new UriFormatException(string.Format(Resources.FeedUriMismatch, feed.Uri, uri)); } // Detect replay attacks try { var oldSignature = _feedCache.GetSignatures(uri).OfType <ValidSignature>().FirstOrDefault(); if (oldSignature != null && signature.Timestamp < oldSignature.Timestamp) { throw new ReplayAttackException(uri, oldSignature.Timestamp, signature.Timestamp); } } catch (KeyNotFoundException) { // No existing feed to be replaced } }
/// <summary> /// Tests the sync logic with custom <see cref="AppList"/>s. /// </summary> /// <param name="resetMode">The <see cref="SyncResetMode"/> to pass to <see cref="SyncIntegrationManager.Sync"/>.</param> /// <param name="appListLocal">The current local <see cref="AppList"/>.</param> /// <param name="appListLast">The state of the <see cref="AppList"/> after the last successful sync.</param> /// <param name="appListServer">The current server-side <see cref="AppList"/>.</param> private static void TestSync(SyncResetMode resetMode, AppList appListLocal, AppList?appListLast, AppList appListServer) { string appListLocalPath = AppList.GetDefaultPath(); appListLocal.SaveXml(appListLocalPath); appListLast?.SaveXml(appListLocalPath + SyncIntegrationManager.AppListLastSyncSuffix); using var appListServerPath = new TemporaryFile("0install-test-applist"); { using (var stream = File.Create(appListServerPath)) appListServer.SaveXmlZip(stream, CryptoKey); using (var appListServerFile = File.OpenRead(appListServerPath)) { using var syncServer = new MicroServer("app-list", appListServerFile); var config = new Config { SyncServer = new(syncServer.ServerUri), SyncServerUsername = "******", SyncServerPassword = "******", SyncCryptoKey = CryptoKey }; using (var integrationManager = new SyncIntegrationManager(config, _ => new Feed(), new SilentTaskHandler())) integrationManager.Sync(resetMode); appListServer = AppList.LoadXmlZip(syncServer.FileContent, CryptoKey); } } appListLocal = XmlStorage.LoadXml <AppList>(appListLocalPath); appListLast = XmlStorage.LoadXml <AppList>(appListLocalPath + SyncIntegrationManager.AppListLastSyncSuffix); appListServer.Should().Be(appListLocal, because: "Server and local data should be equal after sync"); appListLast.Should().Be(appListLocal, because: "Last sync snapshot and local data should be equal after sync"); }
private AppList LoadAppListSafe() { try { return(XmlStorage.LoadXml <AppList>(AppList.GetDefaultPath(_machineWide))); } #region Error handling catch (FileNotFoundException) { return(new AppList()); } catch (IOException ex) { Log.Warn(Resources.UnableToLoadAppList); Log.Warn(ex); return(new AppList()); } catch (UnauthorizedAccessException ex) { Log.Warn(Resources.UnableToLoadAppList); Log.Warn(ex); return(new AppList()); } catch (InvalidDataException ex) { Log.Warn(Resources.UnableToLoadAppList); Log.Warn(ex); return(new AppList()); } #endregion }
/// <inheritdoc/> public void Add(FeedUri feedUri, byte[] data) { #region Sanity checks if (feedUri == null) { throw new ArgumentNullException("feedUri"); } if (data == null) { throw new ArgumentNullException("data"); } #endregion // Add to underlying cache _backingCache.Add(feedUri, data); // Add to memory cache (replacing existing old versions) var feed = XmlStorage.LoadXml <Feed>(new MemoryStream(data)); feed.Normalize(feedUri); string key = feedUri.Escape(); lock (_feedDictionary) { _feedDictionary.Remove(key); _feedDictionary.Add(key, feed); } }
public static AppList LoadXmlZip([NotNull] Stream stream, [CanBeNull] string password = null) { #region Sanity checks if (stream == null) { throw new ArgumentNullException("stream"); } #endregion using (var zipFile = new ZipFile(stream) { IsStreamOwner = false, Password = password }) { var zipEntry = zipFile.Cast <ZipEntry>().First(x => StringUtils.EqualsIgnoreCase(x.Name, "data.xml")); try { return(XmlStorage.LoadXml <AppList>(zipFile.GetInputStream(zipEntry))); } catch (InvalidOperationException) { throw new InvalidDataException(Resources.SyncServerDataDamaged); } } }
/// <summary> /// Creates a new sync manager for a custom <see cref="AppList"/> file. Used for testing. /// </summary> /// <param name="appListPath">The storage location of the <see cref="AppList"/> file.</param> /// <param name="server">Access information for the sync server.</param> /// <param name="feedRetriever">Callback method used to retrieve additional <see cref="Feed"/>s on demand.</param> /// <param name="handler">A callback object used when the the user is to be informed about the progress of long-running operations such as downloads.</param> /// <param name="machineWide">Apply operations machine-wide instead of just for the current user.</param> /// <exception cref="IOException">A problem occurs while accessing the <see cref="AppList"/> file.</exception> /// <exception cref="UnauthorizedAccessException">Read or write access to the <see cref="AppList"/> file is not permitted or if another desktop integration class is currently active.</exception> /// <exception cref="InvalidDataException">A problem occurs while deserializing the XML data.</exception> public SyncIntegrationManager([NotNull] string appListPath, SyncServer server, [NotNull] Converter <FeedUri, Feed> feedRetriever, [NotNull] ITaskHandler handler, bool machineWide = false) : base(appListPath, handler, machineWide) { #region Sanity checks if (server.Uri == null) { throw new ArgumentNullException("server"); } if (feedRetriever == null) { throw new ArgumentNullException("feedRetriever"); } #endregion _server = server; _feedRetriever = feedRetriever; if (File.Exists(AppListPath + AppListLastSyncSuffix)) { _appListLastSync = XmlStorage.LoadXml <AppList>(AppListPath + AppListLastSyncSuffix); } else { _appListLastSync = new AppList(); _appListLastSync.SaveXml(AppListPath + AppListLastSyncSuffix); } }
/// <summary> /// Creates a new integration manager using a custom <see cref="DesktopIntegration.AppList"/>. Do not use directly except for testing purposes! /// </summary> /// <param name="appListPath">The storage location of the <see cref="AppList"/> file.</param> /// <param name="handler">A callback object used when the the user is to be informed about the progress of long-running operations such as downloads.</param> /// <param name="machineWide">Apply operations machine-wide instead of just for the current user.</param> /// <exception cref="IOException">A problem occurs while accessing the <see cref="AppList"/> file.</exception> /// <exception cref="UnauthorizedAccessException">Read or write access to the <see cref="AppList"/> file is not permitted.</exception> /// <exception cref="InvalidDataException">A problem occurs while deserializing the XML data.</exception> public IntegrationManager([NotNull] string appListPath, [NotNull] ITaskHandler handler, bool machineWide = false) : base(handler) { #region Sanity checks if (appListPath == null) { throw new ArgumentNullException("appListPath"); } if (handler == null) { throw new ArgumentNullException("handler"); } #endregion MachineWide = machineWide; AppListPath = appListPath; if (File.Exists(AppListPath)) { Log.Debug("Loading AppList from: " + AppListPath); AppList = XmlStorage.LoadXml <AppList>(AppListPath); } else { Log.Debug("Creating new AppList: " + AppListPath); AppList = new AppList(); AppList.SaveXml(AppListPath); } }
public static AppList LoadSafe(bool machineWide = false) { try { return(XmlStorage.LoadXml <AppList>(GetDefaultPath(machineWide))); } #region Error handling catch (FileNotFoundException) { return(new AppList()); } catch (IOException ex) { Log.Warn(ex); return(new AppList()); } catch (UnauthorizedAccessException ex) { Log.Warn(ex); return(new AppList()); } catch (InvalidDataException ex) { Log.Warn(ex); return(new AppList()); } #endregion }
public void GetInstalledPackages([CanBeNull] string name) { var appList = XmlStorage.LoadXml <AppList>(AppList.GetDefaultPath(MachineWide)); foreach (var entry in appList.Search(name)) { Yield(entry.EffectiveRequirements); } }
/// <summary> /// Import a feed from a local file, as if it had been downloaded from the network. /// </summary> /// <param name="path">The local path of the feed file to import.</param> /// <exception cref="InvalidDataException">The feed specifies no <see cref="Feed.Uri"/>.</exception> private void ImportFile([NotNull] string path) { var feed = XmlStorage.LoadXml <Feed>(path); if (feed.Uri == null) { throw new InvalidDataException(Resources.ImportNoSource); } FeedManager.ImportFeed(path, feed.Uri, mirrorUrl: new FeedUri(path)); }
public static SignedCatalog Load([NotNull] string path) { #region Sanity checks if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } #endregion return(new SignedCatalog(XmlStorage.LoadXml <Catalog>(path), FeedUtils.GetKey(path, OpenPgpFactory.CreateDefault()))); }
/// <summary> /// Trys to parse <see cref="Store.Model.Requirements.InterfaceUri"/> as a pre-computed <see cref="Store.Model.Selection.Selections"/> document. /// </summary> /// <seealso cref="SelectionsDocument"/> private void TryParseSelectionsDocument() { try { // Try to parse as selections document Selections = XmlStorage.LoadXml <Selections>(Requirements.InterfaceUri.LocalPath); Requirements.InterfaceUri = Selections.InterfaceUri; SelectionsDocument = true; } catch (InvalidDataException) { // If that fails assume it is an interface } }
public static TrustDB Load() { string path = Locations.GetSaveConfigPath("0install.net", true, "injector", "trustdb.xml"); if (!File.Exists(path)) { return(new TrustDB()); } Log.Debug("Loading trust database from: " + path); return(XmlStorage.LoadXml <TrustDB>(path)); }
/// <summary> /// Loads a <see cref="Catalog"/> from an XML file and identifies the signature (if any). /// </summary> /// <param name="path">The file to load from.</param> /// <returns>The loaded <see cref="SignedCatalog"/>.</returns> /// <exception cref="IOException">A problem occurred while reading the file.</exception> /// <exception cref="UnauthorizedAccessException">Read access to the file is not permitted.</exception> /// <exception cref="InvalidDataException">A problem occurred while deserializing the XML data.</exception> public static SignedCatalog Load(string path) { #region Sanity checks if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException(nameof(path)); } #endregion var openPgp = OpenPgp.Signing(); return(new SignedCatalog(XmlStorage.LoadXml <Catalog>(path), FeedUtils.GetKey(path, openPgp), openPgp)); }
public void TestNormalizeHash() { var feed = CreateTestFeed(); using var tempFile = new TemporaryFile("0install-unit-tests"); feed.SaveXml(tempFile); var feedReload = XmlStorage.LoadXml <Feed>(tempFile); feed.Normalize(new FeedUri(tempFile)); feedReload.Normalize(new FeedUri(tempFile)); feedReload.GetHashCode().Should().Be(feed.GetHashCode()); }
public Catalog?GetCached() { try { using (new MutexLock(CacheMutexName)) return(XmlStorage.LoadXml <Catalog>(_cacheFilePath)); } catch (FileNotFoundException) { return(null); } }
/// <summary> /// Loads the <see cref="TrustDB"/> from a file. /// </summary> /// <param name="path">The file to load from.</param> /// <returns>The loaded <see cref="TrustDB"/>.</returns> /// <exception cref="IOException">A problem occured while reading the file.</exception> /// <exception cref="UnauthorizedAccessException">Read access to the file is not permitted.</exception> /// <exception cref="InvalidDataException">A problem occured while deserializing the XML data.</exception> public static TrustDB Load(string path) { #region Sanity checks if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException(nameof(path)); } #endregion Log.Debug("Loading trust database from: " + path); var trustDB = XmlStorage.LoadXml <TrustDB>(path); trustDB._filePath = path; return(trustDB); }
private static void CheckFeed(byte[] data, FeedUri feedUri) { // Detect feed substitution var feed = XmlStorage.LoadXml <Feed>(new MemoryStream(data)); if (feed.Uri == null) { throw new InvalidDataException(string.Format(Resources.FeedUriMissing, feedUri)); } if (feed.Uri != feedUri) { throw new InvalidDataException(string.Format(Resources.FeedUriMismatch, feed.Uri, feedUri)); } }
/// <inheritdoc/> public Feed GetFeed(FeedUri feedUri) { #region Sanity checks if (feedUri == null) { throw new ArgumentNullException(nameof(feedUri)); } #endregion string path = GetPath(feedUri); Log.Debug("Loading feed " + feedUri.ToStringRfc() + " from disk cache: " + path); return(XmlStorage.LoadXml <Feed>(path)); }
private Catalog DownloadCatalog([NotNull] FeedUri source) { if (source.IsFile) { return(XmlStorage.LoadXml <Catalog>(source.LocalPath)); } Log.Info("Downloading catalog: " + source.ToStringRfc()); byte[] data; using (var webClient = new WebClientTimeout()) data = webClient.DownloadData(source); _trustManager.CheckTrust(data, source); return(XmlStorage.LoadXml <Catalog>(new MemoryStream(data))); }
/// <summary> /// Creates a new sync manager. Performs Mutex-based locking! /// </summary> /// <param name="config">Configuration for communicating with a sync server.</param> /// <param name="feedRetriever">Callback method used to retrieve additional <see cref="Feed"/>s on demand.</param> /// <param name="handler">A callback object used when the the user is to be informed about the progress of long-running operations such as downloads.</param> /// <param name="machineWide">Apply operations machine-wide instead of just for the current user.</param> /// <exception cref="IOException">A problem occurred while accessing the <see cref="AppList"/> file.</exception> /// <exception cref="UnauthorizedAccessException">Read or write access to the <see cref="AppList"/> file is not permitted or another desktop integration class is currently active.</exception> /// <exception cref="InvalidDataException">A problem occurred while deserializing the XML data.</exception> public SyncIntegrationManager(Config config, Converter<FeedUri, Feed> feedRetriever, ITaskHandler handler, bool machineWide = false) : base(config, handler, machineWide) { if (!config.IsSyncConfigured) throw new InvalidDataException(Resources.PleaseConfigSync); _syncServer = config.SyncServer.EnsureTrailingSlash(); _feedRetriever = feedRetriever ?? throw new ArgumentNullException(nameof(feedRetriever)); if (File.Exists(AppListPath + AppListLastSyncSuffix)) _appListLastSync = XmlStorage.LoadXml<AppList>(AppListPath + AppListLastSyncSuffix); else { _appListLastSync = new AppList(); _appListLastSync.SaveXml(AppListPath + AppListLastSyncSuffix); } }
public void TestFile() { TestData testData1 = new TestData { Data = "Hello" }, testData2; using (var tempFile = new TemporaryFile("unit-tests")) { // Write and read file testData1.SaveXml(tempFile); testData2 = XmlStorage.LoadXml <TestData>(tempFile); } // Ensure data stayed the same testData2.Data.Should().Be(testData1.Data); }
public void TestSaveLoad() { Feed feed1 = CreateTestFeed(), feed2; using (var tempFile = new TemporaryFile("0install-unit-tests")) { // Write and read file feed1.SaveXml(tempFile); feed2 = XmlStorage.LoadXml <Feed>(tempFile); } // Ensure data stayed the same feed2.Should().Be(feed1, because: "Serialized objects should be equal."); feed2.GetHashCode().Should().Be(feed1.GetHashCode(), because: "Serialized objects' hashes should be equal."); feed2.Should().NotBeSameAs(feed1, because: "Serialized objects should not return the same reference."); }
public void TestFileRelative() { TestData testData1 = new TestData { Data = "Hello" }, testData2; using (new TemporaryWorkingDirectory("unit-tests")) { // Write and read file testData1.SaveXml("file.xml"); testData2 = XmlStorage.LoadXml <TestData>("file.xml"); } // Ensure data stayed the same testData2.Data.Should().Be(testData1.Data); }
[Fact] // Ensures that the class is correctly serialized and deserialized. public void TestSaveLoad() { CapabilityList capabilityList1 = CreateTestCapabilityList(), capabilityList2; using (var tempFile = new TemporaryFile("0install-test-capabilities")) { // Write and read file capabilityList1.SaveXml(tempFile); capabilityList2 = XmlStorage.LoadXml <CapabilityList>(tempFile); } // Ensure data stayed the same capabilityList2.Should().Be(capabilityList1, because: "Serialized objects should be equal."); capabilityList2.GetHashCode().Should().Be(capabilityList1.GetHashCode(), because: "Serialized objects' hashes should be equal."); capabilityList2.Should().NotBeSameAs(capabilityList1, because: "Serialized objects should not return the same reference."); }
public void TestSaveLoad() { Selections selections1 = CreateTestSelections(), selections2; using (var tempFile = new TemporaryFile("0install-unit-tests")) { // Write and read file selections1.SaveXml(tempFile); selections2 = XmlStorage.LoadXml <Selections>(tempFile); } // Ensure data stayed the same selections2.Should().Be(selections1, because: "Serialized objects should be equal."); selections2.GetHashCode().Should().Be(selections1.GetHashCode(), because: "Serialized objects' hashes should be equal."); selections2.Should().NotBeSameAs(selections1, because: "Serialized objects should not return the same reference."); }
public void TestSaveLoad() { FeedPreferences preferences1 = CreateTestFeedPreferences(), preferences2; Assert.That(preferences1, Is.XmlSerializable); using (var tempFile = new TemporaryFile("0install-unit-tests")) { // Write and read file preferences1.SaveXml(tempFile); preferences2 = XmlStorage.LoadXml<FeedPreferences>(tempFile); } // Ensure data stayed the same preferences2.Should().Be(preferences1, because: "Serialized objects should be equal."); preferences2.GetHashCode().Should().Be(preferences1.GetHashCode(), because: "Serialized objects' hashes should be equal."); preferences2.Should().NotBeSameAs(preferences1, because: "Serialized objects should not return the same reference."); }
/// <inheritdoc/> public void ImportFeed(string path) { #region Sanity checks if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException(nameof(path)); } #endregion var feed = XmlStorage.LoadXml <Feed>(path); if (feed.Uri == null) { throw new InvalidDataException(Resources.ImportNoSource); } ImportFeed(File.ReadAllBytes(path), feed.Uri, path); }