Skip to main content

[Obsolete] Azure package unpack and repack

Azure package

There are a lot of possible scenarios of Azure deployment. Most of them are based on package that we can define and create with Visual Studio.
If you need to change package use Visual studio to repack your project. To prepare specific web.config file, use different build configuration with transformation (web.config.release, web.config.debug etc.)
Only when it's not possible to use Visual Studio to repack Azure package, then it's possible to repack it the way described below.

Package repack

Azure package is a zip archive, that can be opened and changed with any zip archive tool. The structure of that archive is static and is followed by some rules (unfortunately it's not so easy to find information about correct structure and rules used to generate that package). 
Main content (web- or workerrole) of package placed in files with extension ".cssx", which is also a zip archived folder. That folder can be opened and changed, but that will make package invalid, because it's secured by hash value that is stored inside of the package. That means, that next action in repack is a recalculation of hash of changed files. To calculate hash used SHA256Managed algorithm, applied to file content stream:

var hashBytes = new SHA256Managed().ComputeHash(contentStream);
hash = BitConverter.ToString(hashBytes).Replace("-", "");
 
Calculated hash should be placed into ".csman" file in the root of the package. That file has a simple XML structure, so it's not a problem to find an appropriate place for calculated before hash.

 
var item = doc.SelectSingleNode($"//Item[@name='{contentEntry.Name}']");
item.Attributes["hash"].Value = hash;
Obviously that hash should be calculated after changes in the content file stream
using (var archiveStream = File.Open(archivePath, FileMode.Open))
using (var mainarchive = 
    new ZipArchive(archiveStream, ZipArchiveMode.Update))
{
    var contentEntry = mainarchive.Entries
        .Single(e => e.FullName.EndsWith(".cssx"));
    string hash;
    using(var contentStream = contentEntry.Open())
    using (var archive = 
        new ZipArchive(contentStream, ZipArchiveMode.Update))
    {
        var appEntry = archive.GetEntry("[Some entry]");
        // Some work here
    }
    using (var contentStream = contentEntry.Open())
    {
        var hashBytes = new SHA256Managed().ComputeHash(contentStream);
        hash = BitConverter.ToString(hashBytes).Replace("-", "");
    }
    var manifest = mainarchive.Entries
        .Single(entry => entry.FullName.EndsWith(".csman"));
    using (var manStream = manifest.Open())
    {
        var doc = new XmlDocument();
        doc.Load(manStream);
        var query = $"//Item[@name='{contentEntry.Name}']";
        var item = doc.SelectSingleNode(query);
        item.Attributes["hash"].Value = hash;
        manStream.SetLength(0);
        doc.Save(manStream);
    }
}
 This way is not trusted and changes in format or hash calculations are possible.

Comments

Popular posts from this blog

RetrieveMultiple Plugins MS CRM

Plugin for RetrieveMultiple message in MS Dynamics CRM RetrieveMultiple message is not the most popular message in CRM development, because not so much types of tasks are solved via plugin registered on this message. And it leads to situation, when this message is forgotten and not used.

System solutions in MS Dynamics CRM

In storage model description was described, how different types of solutions affect component storage in system. And only one system solution was mentioned: "Active solution", but it's not alone in CRM system. System solutions There are four standard solutions in any CRM organization