Example #1
0
        /// <summary>
        /// Downloads all new files and replaces old files in directory.
        /// </summary>
        /// <param name="info">Update information generated by <c>FetchUpdateInfoAsync</c></param>
        /// <returns>True on success, false on failure.</returns>
        /// <exception cref="KangarupException">On a file checksum error.</exception>
        public async Task <bool> UpdateNewFilesAsync(UpdateInfo info)
        {
            if (UpdateUri == null)
            {
                throw new ArgumentNullException("UpdateUri cannot be null");
            }

            var httpClient = new HttpClient();
            var tempPath   = Path.GetTempPath();
            var tempFolder = Directory.CreateDirectory(Path.Combine(tempPath, TempFolderName));

            foreach (var infoFile in info.Files)
            {
                var downloadStream = await httpClient.GetStreamAsync(UpdateUri.Append(infoFile.RelativeUrl)).ConfigureAwait(false);

                var fileToReplace = Path.GetFileName(infoFile.RelativeUrl);

                try
                {
                    // download file
                    var tmpFile = Path.GetTempFileName();
                    using (var fileStream = File.Create(tmpFile))
                    {
                        await downloadStream.CopyToAsync(fileStream).ConfigureAwait(false);
                    }

                    // verify file
                    var sha256 = SHA256.Create();
                    using (var inputStream = File.OpenRead(tmpFile))
                    {
                        var hash    = sha256.ComputeHash(inputStream);
                        var hashHex = BitConverter.ToString(hash).Replace("-", string.Empty);
                        if (infoFile.Checksum != hashHex)
                        {
                            // checksum wrong
                            throw new KangarupException($"Checksum mismatch of file '{fileToReplace}'.");
                        }
                    }

                    // place file
                    File.Move(fileToReplace, Path.Combine(tempFolder.FullName, $"{fileToReplace}"));
                    File.Move(tmpFile, fileToReplace);
                }
                catch (IOException e)
                {
                    Logger?.Error($"Unable to update file '{fileToReplace}': {e.Message}", e);
                    return(false);
                }

                //File.Delete($"{fileToReplace}.old"); // TODO not possible on running application
            }

            return(true);
        }
Example #2
0
        public override void Insert(T instance, ResponseHandler callback)
        {
            string serializedObj = Serializer.Serialize <T>(instance);

            MimePart mimePart = new MimePart(MimePart.ApplicationXml, serializedObj);

            httpClient.Post(CreateUri, DefaultRetryCount, mimePart, (postResult) =>
            {
                List <T> responseInstance = null;
                string error = null;
                try
                {
                    using (HttpResult httpResult = postResult.AsyncState as HttpResult)
                    {
                        // Check server response
                        if (CheckServerResult(httpResult, ref error))
                        {
                            string responseObj = httpResult.Response;
                            if (!string.IsNullOrEmpty(responseObj))
                            {
                                RestResponse response = Serializer.Deserialize <R>(responseObj) as RestResponse;
                                responseInstance      = response.ToList <T>();
                                error = response.Error;
                            }
                            else
                            {
                                error = "Empty response for: " + UpdateUri.ToString();
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    error = "Unable to upload data to the cloud. " + e.Message;
                }
                finally
                {
                    if (!String.IsNullOrEmpty(error))
                    {
                        DebugLog.Error(error);
                    }

                    if (callback != null)
                    {
                        callback(new Response(responseInstance, error));
                    }
                }
            });
        }
Example #3
0
        public void Write(Stream stream)
        {
            EnsureState();

            XmlDocument doc  = new XmlDocument();
            XmlElement  root = doc.CreateElement("package");

            PackageItem.AddAttribute(root, "id", Id);
            PackageItem.AddAttribute(root, "name", Name);
            if (Condition != null)
            {
                PackageItem.AddAttribute(root, "condition", Condition.ToString());
            }
            PackageItem.AddAttribute(root, "version", Version.ToString());
            PackageItem.AddAttribute(root, "attribution", Attribution);
            if (Website != null)
            {
                PackageItem.AddAttribute(root, "website", Website.ToString());
            }
            if (UpdateUri != null)
            {
                PackageItem.AddAttribute(root, "updateUri", UpdateUri.ToString());
            }
            if (FeedbackUri != null)
            {
                PackageItem.AddAttribute(root, "feedbackUri", FeedbackUri.ToString());
            }

            doc.AppendChild(root);

            RootGroup.Write(root);

            XmlWriterSettings settings = new XmlWriterSettings();

            settings.ConformanceLevel = ConformanceLevel.Document;
            settings.Encoding         = Encoding.UTF8;
            settings.Indent           = true;
            settings.IndentChars      = "\t";

            XmlWriter wtr = XmlWriter.Create(stream, settings);

            doc.WriteTo(wtr);

            wtr.Flush();
        }
Example #4
0
        /// <summary>
        /// Retrieves latest update information from server and verifies cryptographic signature.
        /// </summary>
        /// <exception cref="KangarupException">Cryptographic signature does not match update manifest</exception>
        /// <exception cref="ArgumentNullException">UpdateUri is null</exception>
        /// <returns>Latest update information.</returns>
        public async Task <UpdateInfo> FetchUpdateInfoAsync()
        {
            if (UpdateUri == null)
            {
                throw new ArgumentNullException("UpdateUri cannot be null");
            }

            if (_rsa == null)
            {
                LoadCertificate();
            }

            // download update manifest
            var httpClient = new HttpClient();

            try
            {
                var rawUpdateInfo =
                    await httpClient.GetByteArrayAsync(
                        UpdateUri.Append("update.yml"));

                // download update manifest signature
                var signature = await httpClient.GetByteArrayAsync(UpdateUri.Append("update.sig"));

                // verify manifest
                if (!_rsa.VerifyData(rawUpdateInfo, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1))
                {
                    throw new KangarupException("Update manifest signature is wrong.");
                }

                // construct UpdateInfo object from data
                var deserializer = new Deserializer();
                return(deserializer.Deserialize <UpdateInfo>(Encoding.UTF8.GetString(rawUpdateInfo)));
            }
            catch (HttpRequestException e)
            {
                Logger?.Error("Unable to contact update server.", e);
                return(null);
            }
        }