예제 #1
0
        /// <summary>
        /// Create a signed package
        /// </summary>
        private static AppletPackage CreateSignedPackage(AppletManifest mfst, ConsoleParameters parameters)
        {
            try
            {
                if (String.IsNullOrEmpty(parameters.SignPassword))
                {
                    using (var frmKey = new frmKeyPassword(parameters.SignKey))
                        if (frmKey.ShowDialog() == DialogResult.OK)
                        {
                            parameters.SignPassword = frmKey.Password;
                        }
                }
                else if (File.Exists(parameters.SignPassword))
                {
                    parameters.SignPassword = File.ReadAllText(parameters.SignPassword);
                }

                X509Certificate2 signCert = new X509Certificate2(parameters.SignKey, parameters.SignPassword);

                mfst.Info.PublicKeyToken = signCert.Thumbprint;
                var retVal = mfst.CreatePackage(parameters.Compression);
                retVal.Meta.Hash           = SHA256.Create().ComputeHash(retVal.Manifest);
                retVal.Meta.PublicKeyToken = signCert.Thumbprint;

                if (parameters.EmbedCertificate)
                {
                    retVal.PublicKey = signCert.Export(X509ContentType.Cert);
                }

                if (!signCert.HasPrivateKey)
                {
                    throw new SecurityException($"Provided key {parameters.SignKey} has no private key");
                }
                RSACryptoServiceProvider rsa = signCert.PrivateKey as RSACryptoServiceProvider;
                retVal.Meta.Signature = rsa.SignData(retVal.Manifest, CryptoConfig.MapNameToOID("SHA1"));
                return(retVal);
            }
            catch (Exception e)
            {
                Console.WriteLine("Error signing package: {0}", e);
                return(null);
            }
        }
예제 #2
0
        /// <summary>
        /// Create a signed package
        /// </summary>
        public AppletPackage CreateSignedPackage(AppletManifest mfst)
        {
            try
            {
                X509Certificate2 signCert = this.GetSigningCert();

                if (!signCert.HasPrivateKey)
                {
                    throw new InvalidOperationException($"You do not have the private key for certificiate {signCert.Subject}");
                }

                mfst.Info.TimeStamp      = DateTime.Now; // timestamp
                mfst.Info.PublicKeyToken = signCert.Thumbprint;
                var retVal = mfst.CreatePackage();

                retVal.Meta.Hash           = SHA256.Create().ComputeHash(retVal.Manifest);
                retVal.Meta.PublicKeyToken = signCert.Thumbprint;

                if (this.m_parms.EmbedCertificate)
                {
                    retVal.PublicKey = signCert.Export(X509ContentType.Cert);
                }

                if (!signCert.HasPrivateKey)
                {
                    throw new SecurityException($"Provided key {this.m_parms.SignKeyFile} has no private key");
                }
                RSACryptoServiceProvider rsa = signCert.PrivateKey as RSACryptoServiceProvider;
                retVal.Meta.Signature = rsa.SignData(retVal.Manifest, CryptoConfig.MapNameToOID("SHA1"));
                return(retVal);
            }
            catch (Exception e)
            {
                Emit.Message("ERROR", "Error signing package: {0}", e);
                return(null);
            }
        }
예제 #3
0
        /// <summary>
        /// Compile
        /// </summary>
        static int Compile(ConsoleParameters parameters)
        {
            int retVal = 0;

            // First is there a Manifest.xml?
            if (!Path.IsPathRooted(parameters.Source))
            {
                parameters.Source = Path.Combine(Environment.CurrentDirectory, parameters.Source);
            }

            // Applet collection
            AppletCollection ac  = new AppletCollection();
            XmlSerializer    xsz = new XmlSerializer(typeof(AppletManifest));
            XmlSerializer    xpz = new XmlSerializer(typeof(AppletPackage));

            if (parameters.References != null)
            {
                foreach (var itm in parameters.References)
                {
                    if (File.Exists(itm))
                    {
                        using (var fs = File.OpenRead(itm))
                        {
                            if (Path.GetExtension(itm) == ".pak")
                            {
                                using (var gzs = new GZipStream(fs, CompressionMode.Decompress))
                                {
                                    var pack = xpz.Deserialize(gzs) as AppletPackage;
                                    var mfst = pack.Unpack();
                                    mfst.Initialize();
                                    ac.Add(mfst);
                                    Console.WriteLine("Added reference to {0}; v={1}", mfst.Info.Id, mfst.Info.Version);
                                }
                            }
                            else
                            {
                                var mfst = xsz.Deserialize(fs) as AppletManifest;
                                mfst.Initialize();
                                ac.Add(mfst);
                                Console.WriteLine("Added reference to {0}; v={1}", mfst.Info.Id, mfst.Info.Version);
                            }
                        }
                    }
                }
            }

            Console.WriteLine("Processing {0}...", parameters.Source);
            String manifestFile = Path.Combine(parameters.Source, "manifest.xml");

            if (!File.Exists(manifestFile))
            {
                Console.WriteLine("Directory must have manifest.xml");
            }
            else
            {
                Console.WriteLine("\t Reading Manifest...", parameters.Source);

                using (var fs = File.OpenRead(manifestFile))
                {
                    AppletManifest mfst = xsz.Deserialize(fs) as AppletManifest;
                    mfst.Assets.AddRange(ProcessDirectory(parameters.Source, parameters.Source, parameters));
                    foreach (var i in mfst.Assets)
                    {
                        i.Name = i.Name.Substring(1);
                    }

                    if (mfst.Info.Version.Contains("*"))
                    {
                        mfst.Info.Version = mfst.Info.Version.Replace("*", (((DateTime.Now.Subtract(new DateTime(DateTime.Now.Year, 1, 1)).Ticks >> 24) % 10000)).ToString("0000"));
                    }

                    if (!Directory.Exists(Path.GetDirectoryName(parameters.Output)) && !String.IsNullOrEmpty(Path.GetDirectoryName(parameters.Output)))
                    {
                        Directory.CreateDirectory(Path.GetDirectoryName(parameters.Output));
                    }

                    AppletPackage pkg = null;

                    // Is there a signature?
                    if (!String.IsNullOrEmpty(parameters.SignKey))
                    {
                        pkg = CreateSignedPackage(mfst, parameters);
                        if (pkg == null)
                        {
                            return(-102);
                        }
                    }
                    else
                    {
                        Console.WriteLine("WARNING:>>> THIS PACKAGE IS NOT SIGNED - MOST OPEN IZ TOOLS WILL NOT LOAD IT");
                        mfst.Info.PublicKeyToken = null;
                        pkg = mfst.CreatePackage(parameters.Compression);
                        //pkg.Meta.PublicKeyToken = null;
                    }
                    pkg.Meta.Hash = SHA256.Create().ComputeHash(pkg.Manifest);

                    using (var ofs = File.Create(Path.ChangeExtension(parameters.Output ?? "out.pak", ".pak")))
                    {
                        pkg.Save(ofs);
                    }
                    // Render the build directory

                    if (!String.IsNullOrEmpty(parameters.Deploy))
                    {
                        var bindir = Path.Combine(Path.GetDirectoryName(parameters.Output), "bin");

                        if (String.IsNullOrEmpty(parameters.Deploy))
                        {
                            if (Directory.Exists(bindir) && parameters.Clean)
                            {
                                Directory.Delete(bindir, true);
                            }
                            bindir = Path.Combine(bindir, mfst.Info.Id);
                            Directory.CreateDirectory(bindir);
                        }
                        else
                        {
                            bindir = parameters.Deploy;
                        }

                        mfst.Initialize();
                        ac.Add(mfst);

                        foreach (var lang in mfst.Strings)
                        {
                            string wd = Path.Combine(bindir, lang.Language);
                            if (String.IsNullOrEmpty(parameters.Lang))
                            {
                                Directory.CreateDirectory(wd);
                            }
                            else if (parameters.Lang == lang.Language)
                            {
                                wd = bindir;
                            }
                            else
                            {
                                continue;
                            }

                            foreach (var m in ac)
                            {
                                foreach (var itm in m.Assets)
                                {
                                    try
                                    {
                                        String fn = Path.Combine(wd, m.Info.Id, itm.Name.Replace("/", "\\"));
                                        Console.WriteLine("\tRendering {0}...", fn);
                                        if (!Directory.Exists(Path.GetDirectoryName(fn)))
                                        {
                                            Directory.CreateDirectory(Path.GetDirectoryName(fn));
                                        }
                                        File.WriteAllBytes(fn, ac.RenderAssetContent(itm, lang.Language));
                                    }
                                    catch (Exception e)
                                    {
                                        Console.WriteLine("E: {0}: {1} {2}", itm, e.GetType().Name, e);
                                        retVal = -1000;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(retVal);
        }
예제 #4
0
        /// <summary>
        /// Compose multiple PAK files into a solution
        /// </summary>
        public int Compose()
        {
            try
            {
                AppletManifest mfst = null;
                using (FileStream fs = File.OpenRead(this.m_parms.Source))
                    mfst = AppletManifest.Load(fs);

                var slnPak = mfst.CreatePackage();

                AppletSolution sln = new AppletSolution();
                sln.Meta      = slnPak.Meta;
                sln.PublicKey = slnPak.PublicKey;
                sln.Manifest  = slnPak.Manifest;

                if (sln.Meta.Uuid == Guid.Empty)
                {
                    Emit.Message("WARN", "The package does not carry a UUID! You should add a UUID to your solution manifest");
                }
                sln.Include = new List <AppletPackage>();

                foreach (var pfile in sln.Meta.Dependencies.ToArray())
                {
                    AppletPackage pkg = null;
                    if (!String.IsNullOrEmpty(pfile.Version)) // specific version
                    {
                        pkg = PackageRepositoryUtil.GetFromAny(pfile.Id, new Version(pfile.Version));
                    }
                    else if (!String.IsNullOrEmpty(m_parms.Version))
                    {
                        pkg = PackageRepositoryUtil.GetFromAny(pfile.Id, new Version(m_parms.Version))
                              ?? PackageRepositoryUtil.GetFromAny(pfile.Id, null);
                    }
                    else
                    {
                        pkg = PackageRepositoryUtil.GetFromAny(pfile.Id, null);
                    }

                    if (pkg == null)
                    {
                        throw new KeyNotFoundException($"Package {pfile.Id} ({pfile.Version ?? m_parms.Version ?? "latest"}) not found");
                    }
                    else
                    {
                        Emit.Message("INFO", "Including {0} version {1}..", pkg.Meta.Id, pkg.Meta.Version);
                        sln.Meta.Dependencies.RemoveAll(o => o.Id == pkg.Meta.Id);

                        if (this.m_parms.Sign && pkg.Meta.Signature == null)
                        {
                            Emit.Message("WARN", "Package {0} is not signed, but you're signing your package. We'll sign it using your key", pkg.Meta.Id);
                            pkg = new Signer(this.m_parms).CreateSignedPackage(pkg.Unpack());
                        }
                        sln.Include.Add(pkg);
                    }
                }

                // Emit i18n file?
                if (!String.IsNullOrEmpty(this.m_parms.InternationalizationFile))
                {
                    Emit.Message("INFO", $"Writing string manifest to {this.m_parms.InternationalizationFile}");
                    using (var fs = File.Create(this.m_parms.InternationalizationFile))
                        using (var tw = new StreamWriter(fs, System.Text.Encoding.UTF8))
                        {
                            // tx translations
                            var mfsts         = sln.Include.Select(o => o.Unpack()).ToList();
                            var appletStrings = mfsts.SelectMany(o => o.Strings).ToArray();
                            var stringKeys    = appletStrings.SelectMany(o => o.String).Select(o => o.Key).Distinct();
                            var langs         = appletStrings.Select(o => o.Language).Distinct().ToArray();
                            tw.Write("key,");
                            tw.WriteLine(String.Join(",", langs));

                            foreach (var str in stringKeys)
                            {
                                tw.Write($"{str},");
                                foreach (var lang in langs)
                                {
                                    tw.Write($"\"{appletStrings.Where(o => o.Language == lang).SelectMany(s => s.String).FirstOrDefault(o => o.Key == str)?.Value}\",");
                                }
                                tw.WriteLine();
                            }
                        }
                }

                sln.Meta.Hash = SHA256.Create().ComputeHash(sln.Include.SelectMany(o => o.Manifest).ToArray());
                // Sign the signature package
                if (this.m_parms.Sign)
                {
                    new Signer(this.m_parms).CreateSignedSolution(sln);
                }

                // Now save
                using (FileStream fs = File.Create(this.m_parms.Output ?? Path.ChangeExtension(sln.Meta.Id, ".sln.pak")))
                    sln.Save(fs);

                return(0);
            }
            catch (System.Exception e)
            {
                Emit.Message("ERROR", e.Message);
                //Console.Error.WriteLine("Cannot compose solution {0}: {1}", this.m_parms.Source, e);
                return(-1);
            }
        }
예제 #5
0
        /// <summary>
        /// Compile
        /// </summary>
        public int Compile()
        {
            int retVal = 0;

            // First is there a Manifest.xml?
            if (!Path.IsPathRooted(this.m_parms.Source))
            {
                this.m_parms.Source = Path.Combine(Environment.CurrentDirectory, this.m_parms.Source);
            }


            Console.WriteLine("Processing {0}...", this.m_parms.Source);

            String manifestFile = this.m_parms.Source;

            if (!File.Exists(manifestFile) && Directory.Exists(manifestFile))
            {
                manifestFile = Path.Combine(this.m_parms.Source, "manifest.xml");
            }

            if (!File.Exists(manifestFile))
            {
                throw new InvalidOperationException($"Directory {this.m_parms.Source} must have manifest.xml");
            }
            else
            {
                Console.WriteLine("\t Reading Manifest...", manifestFile);

                using (var fs = File.OpenRead(manifestFile))
                {
                    AppletManifest mfst = AppletManifest.Load(fs);
                    mfst.Assets.AddRange(this.ProcessDirectory(Path.GetDirectoryName(manifestFile), Path.GetDirectoryName(manifestFile)));
                    foreach (var i in mfst.Assets)
                    {
                        if (i.Name.StartsWith("/"))
                        {
                            i.Name = i.Name.Substring(1);
                        }
                    }

                    if (!string.IsNullOrEmpty(this.m_parms.Version))
                    {
                        mfst.Info.Version = this.m_parms.Version;
                    }
                    mfst.Info.Version = PakManTool.ApplyVersion(mfst.Info.Version);

                    if (!Directory.Exists(Path.GetDirectoryName(this.m_parms.Output)) && !String.IsNullOrEmpty(Path.GetDirectoryName(this.m_parms.Output)))
                    {
                        Directory.CreateDirectory(Path.GetDirectoryName(this.m_parms.Output));
                    }

                    AppletPackage pkg = null;

                    // Is there a signature?
                    if (this.m_parms.Sign)
                    {
                        pkg = new Signer(this.m_parms).CreateSignedPackage(mfst);
                        if (pkg == null)
                        {
                            return(-102);
                        }
                    }
                    else
                    {
                        Emit.Message("WARN", "THIS PACKAGE IS NOT SIGNED - MOST OPEN IZ TOOLS WILL NOT LOAD IT");
                        mfst.Info.PublicKeyToken = null;
                        pkg = mfst.CreatePackage();
                        //pkg.Meta.PublicKeyToken = null;
                    }
                    pkg.Meta.Hash = SHA256.Create().ComputeHash(pkg.Manifest);

                    var outFile = this.m_parms.Output ?? mfst.Info.Id + ".pak";
                    using (var ofs = File.Create(outFile))
                        pkg.Save(ofs);

                    if (this.m_parms.Install)
                    {
                        Emit.Message("INFO", "INSTALLING PACKAGE {0}", pkg.Meta.Id);
                        PackageRepositoryUtil.InstallCache(pkg);
                    }
                    if (this.m_parms.Publish)
                    {
                        try
                        {
                            Emit.Message("INFO", "PUBLISHING PACKAGE TO {0}", this.m_parms.PublishServer);
                            PackageRepositoryUtil.Publish(this.m_parms.PublishServer, pkg);
                        }
                        catch (Exception e)
                        {
                            Emit.Message("ERROR", "ERROR PUBLISHING PACKAGE - {0}", e.Message);
                        }
                    }
                }
            }

            return(retVal);
        }