/// <summary> /// Initiates an syncronous check for updates /// </summary> /// <param name="force">A value indicating if the duration and user-enabled check should be bypassed</param> public void CheckForUpdates(bool force) { try { if (m_config == null) { System.Xml.Serialization.XmlSerializer src = new System.Xml.Serialization.XmlSerializer(typeof(Config)); using (System.IO.FileStream fs = new System.IO.FileStream(m_configFile, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read)) m_config = (Config)src.Deserialize(fs); } //This throws an exception if somethings broken m_config.CheckValid(); if (!m_config.Enabled && !force) return; if (m_lastCheck == null) { string file = m_config.ApplicationName + ".xml"; foreach (char c in System.IO.Path.GetInvalidFileNameChars()) file = file.Replace(c, '-'); file = System.IO.Path.Combine(System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FreshKeeper"), file); if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(file))) System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(file)); if (System.IO.File.Exists(file)) { System.Xml.Serialization.XmlSerializer srl = new System.Xml.Serialization.XmlSerializer(typeof(LastCheck)); using (System.IO.FileStream fs = new System.IO.FileStream(m_configFile, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read)) m_lastCheck = (LastCheck)srl.Deserialize(fs); } else m_lastCheck = new LastCheck(); } if (Duplicati.Library.Core.Timeparser.ParseTimeInterval(m_config.CheckInterval, m_lastCheck.Time) > DateTime.Now) return; Random r = new Random(); string url = m_config.Urls[r.Next(0, m_config.Urls.Length)]; System.Net.WebClient wc = new System.Net.WebClient(); System.Xml.XmlDocument doc = new System.Xml.XmlDocument(); doc.PreserveWhitespace = true; //Make sure we don't alter the document using (System.IO.MemoryStream ms = new System.IO.MemoryStream(wc.DownloadData(url))) doc.Load(ms); string hash = doc["UpdateList"].Attributes["SignedHash"].Value; doc["UpdateList"].Attributes["SignedHash"].Value = ""; System.Security.Cryptography.RSACryptoServiceProvider rsa = new System.Security.Cryptography.RSACryptoServiceProvider(); rsa.FromXmlString(m_config.PublicKey); UpdateList lst = null; using(System.IO.MemoryStream ms = new System.IO.MemoryStream()) { doc.Save(ms); if (!rsa.VerifyData(ms.ToArray(), System.Security.Cryptography.CryptoConfig.MapNameToOID("SHA1"), Convert.FromBase64String(hash))) throw new Exception("Failed to verify signature"); ms.Position = 0; System.Xml.Serialization.XmlSerializer sr = new System.Xml.Serialization.XmlSerializer(typeof(UpdateList)); lst = (UpdateList)sr.Deserialize(ms); lst.SignedHash = hash; } if (lst == null || lst.Updates == null || lst.Updates.Length == 0) return; Update newest = lst.Updates[0]; foreach(Update u in lst.Updates) if (u.Version > newest.Version && (!u.BugfixUpdate || (u.BugfixUpdate && m_config.NotifyOnRevisionChange))) newest = u; if (newest.Version > m_config.LocalVersion) if (Updateavailable != null) Updateavailable(this, newest); } catch (Exception ex) { RaiseErrorEvent(ex); return; } }
/// <summary> /// Initiates an syncronous check for updates /// </summary> /// <param name="force">A value indicating if the duration and user-enabled check should be bypassed</param> public void CheckForUpdates(bool force) { try { if (m_config == null) { System.Xml.Serialization.XmlSerializer src = new System.Xml.Serialization.XmlSerializer(typeof(Config)); using (System.IO.FileStream fs = new System.IO.FileStream(m_configFile, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read)) m_config = (Config)src.Deserialize(fs); } //This throws an exception if somethings broken m_config.CheckValid(); if (!m_config.Enabled && !force) { return; } if (m_lastCheck == null) { string file = m_config.ApplicationName + ".xml"; foreach (char c in System.IO.Path.GetInvalidFileNameChars()) { file = file.Replace(c, '-'); } file = System.IO.Path.Combine(System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FreshKeeper"), file); if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(file))) { System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(file)); } if (System.IO.File.Exists(file)) { System.Xml.Serialization.XmlSerializer srl = new System.Xml.Serialization.XmlSerializer(typeof(LastCheck)); using (System.IO.FileStream fs = new System.IO.FileStream(m_configFile, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read)) m_lastCheck = (LastCheck)srl.Deserialize(fs); } else { m_lastCheck = new LastCheck(); } } if (Duplicati.Library.Core.Timeparser.ParseTimeInterval(m_config.CheckInterval, m_lastCheck.Time) > DateTime.Now) { return; } Random r = new Random(); string url = m_config.Urls[r.Next(0, m_config.Urls.Length)]; System.Net.WebClient wc = new System.Net.WebClient(); System.Xml.XmlDocument doc = new System.Xml.XmlDocument(); doc.PreserveWhitespace = true; //Make sure we don't alter the document using (System.IO.MemoryStream ms = new System.IO.MemoryStream(wc.DownloadData(url))) doc.Load(ms); string hash = doc["UpdateList"].Attributes["SignedHash"].Value; doc["UpdateList"].Attributes["SignedHash"].Value = ""; System.Security.Cryptography.RSACryptoServiceProvider rsa = new System.Security.Cryptography.RSACryptoServiceProvider(); rsa.FromXmlString(m_config.PublicKey); UpdateList lst = null; using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) { doc.Save(ms); if (!rsa.VerifyData(ms.ToArray(), System.Security.Cryptography.CryptoConfig.MapNameToOID("SHA1"), Convert.FromBase64String(hash))) { throw new Exception("Failed to verify signature"); } ms.Position = 0; System.Xml.Serialization.XmlSerializer sr = new System.Xml.Serialization.XmlSerializer(typeof(UpdateList)); lst = (UpdateList)sr.Deserialize(ms); lst.SignedHash = hash; } if (lst == null || lst.Updates == null || lst.Updates.Length == 0) { return; } Update newest = lst.Updates[0]; foreach (Update u in lst.Updates) { if (u.Version > newest.Version && (!u.BugfixUpdate || (u.BugfixUpdate && m_config.NotifyOnRevisionChange))) { newest = u; } } if (newest.Version > m_config.LocalVersion) { if (Updateavailable != null) { Updateavailable(this, newest); } } } catch (Exception ex) { RaiseErrorEvent(ex); return; } }