Beispiel #1
0
        private FileMapping(CryptExecutionContext ctx,
                            FileInfo src,
                            FileInfo dest,
                            XElement xml,
                            bool generatePwd)
        {
            this.CONTEXT     = ctx;
            this.DESTINATION = dest;
            this.SOURCE      = src;
            this.XML         = xml;

            if (generatePwd)
            {
                var rng = new RNGCryptoServiceProvider();

                this.PASSWORD = new byte[48];
                rng.GetBytes(this.PASSWORD);
            }

            this.SALT = ctx.Salt;

            switch (this.CONTEXT.Mode)
            {
            case RunningMode.Decrypt:
                this.TASK = new Task(this.TaskAction_Decrypt);
                break;

            case RunningMode.Encrypt:
                this.TASK = new Task(this.TaskAction_Encrypt);
                break;
            }
        }
Beispiel #2
0
 internal static Task CreateDecryptionTask(CryptExecutionContext ctx,
                                           XElement xml)
 {
     return(CreateDecryptionTask(ctx,
                                 ctx.Source, ctx.Destination,
                                 xml));
 }
Beispiel #3
0
 internal FileMapping(CryptExecutionContext ctx,
                      FileInfo src,
                      FileInfo dest)
     : this(ctx : ctx,
            src : src,
            dest : dest,
            xml : null,
            generatePwd : true)
 {
 }
Beispiel #4
0
 internal FileMapping(CryptExecutionContext ctx,
                      FileInfo src,
                      FileInfo dest,
                      XElement xml)
     : this(ctx : ctx,
            src : src,
            dest : dest,
            xml : xml,
            generatePwd : false)
 {
 }
Beispiel #5
0
        internal DirMapping(CryptExecutionContext ctx,
                            DirectoryInfo src,
                            DirectoryInfo dest,
                            XElement xml = null)
        {
            this.CONTEXT     = ctx.Clone();
            this.DESTINATION = dest;
            this.SOURCE      = src;
            this.XML         = xml;

            switch (this.CONTEXT.Mode)
            {
            case RunningMode.Decrypt:
                this.TASK = new Task(this.TaskAction_Decrypt);
                break;

            case RunningMode.Encrypt:
                this.TASK = new Task(this.TaskAction_Encrypt);
                break;
            }
        }
        internal static Task CreateEncryptionTask(CryptExecutionContext orgCtx,
                                                  DirectoryInfo src, DirectoryInfo dest)
        {
            var ctxClone = orgCtx.Clone();

            ctxClone.Source      = src;
            ctxClone.Destination = dest;

            return(new Task((state) =>
            {
                var ctx = (CryptExecutionContext)state;

                ctx.Destination.CreateDirectoryDeep();

                var metaFile = new FileInfo(Path.Combine(ctx.Destination.FullName,
                                                         AppGlobals.FILENAME_META));

                var metaXmlDoc = new XDocument(new XDeclaration("1.0", Encoding.UTF8.WebName, "yes"));
                metaXmlDoc.Add(new XElement("dir"));

                metaXmlDoc.Root.SetAttributeValue("name", ctx.Source.Name);

                // encrypt files
                FileMapping[] fileMappings;
                {
                    ulong index = 1;
                    fileMappings = ctx.Source
                                   .GetFiles()
                                   .Randomize(_RANDOM)
                                   .Select(file => new FileMapping(ctx,
                                                                   file,
                                                                   new FileInfo(Path.Combine(ctx.Destination.FullName,
                                                                                             string.Format("{0}.bin",
                                                                                                           index++)))))
                                   .ToArray();

                    foreach (var fm in fileMappings)
                    {
                        fm.TASK.Start();
                    }

                    TaskHelper.WaitAll(fileMappings.Select(m => m.TASK));
                }

                // handle sub directories
                DirMapping[] dirMappings;
                {
                    ulong index = 1;
                    dirMappings = ctx.Source
                                  .GetDirectories()
                                  .Randomize(_RANDOM)
                                  .Select(dir => new DirMapping(ctx,
                                                                dir,
                                                                new DirectoryInfo(Path.Combine(ctx.Destination.FullName,
                                                                                               (index++).ToString()))))
                                  .ToArray();

                    foreach (var dm in dirMappings)
                    {
                        dm.TASK.Start();
                    }

                    TaskHelper.WaitAll(dirMappings.Select(m => m.TASK));
                }

                if (dirMappings.Length > 0)
                {
                    var dirsElement = new XElement("dirs");
                    foreach (var dm in dirMappings.Randomize(_RANDOM))
                    {
                        var newDirElement = new XElement("dir");
                        newDirElement.SetAttributeValue("name", dm.SOURCE.Name);
                        newDirElement.SetAttributeValue("alias", dm.DESTINATION.Name);
                        newDirElement.SetAttributeValue("lastWrite", dm.SOURCE.LastWriteTimeUtc.Ticks);
                        newDirElement.SetAttributeValue("created", dm.SOURCE.CreationTimeUtc.Ticks);

                        dirsElement.Add(newDirElement);
                    }

                    metaXmlDoc.Root.Add(dirsElement);
                }

                if (fileMappings.Length > 0)
                {
                    var filesElement = new XElement("files");
                    foreach (var fm in fileMappings.Randomize(_RANDOM))
                    {
                        var newFileElement = new XElement("file");
                        newFileElement.SetAttributeValue("name", fm.SOURCE.Name);
                        newFileElement.SetAttributeValue("alias", fm.DESTINATION.Name);
                        newFileElement.SetAttributeValue("len", fm.SOURCE.Length);
                        newFileElement.SetAttributeValue("pwd", Convert.ToBase64String(fm.PASSWORD));
                        newFileElement.SetAttributeValue("lastWrite", fm.SOURCE.LastWriteTimeUtc.Ticks);
                        newFileElement.SetAttributeValue("created", fm.SOURCE.CreationTimeUtc.Ticks);

                        filesElement.Add(newFileElement);
                    }

                    metaXmlDoc.Root.Add(filesElement);
                }

                using (var srcStream = new MemoryStream())
                {
                    metaXmlDoc.Save(srcStream);
                    srcStream.Position = 0;

                    using (var destStream = new FileStream(metaFile.FullName,
                                                           FileMode.CreateNew,
                                                           FileAccess.ReadWrite))
                    {
                        EncryptionHelper.EncryptStream(srcStream, destStream,
                                                       ctx.Password, ctx.Salt);
                    }
                }

                FileSystemHelper.TrySetTimestampsUtc(metaFile,
                                                     ctx.StartTime);
            }, ctxClone));
        }
        // Internal Methods (3) 

        internal static Task CreateEncryptionTask(CryptExecutionContext ctx)
        {
            return(CreateEncryptionTask(ctx,
                                        ctx.Source, ctx.Destination));
        }
Beispiel #8
0
        internal static Task CreateDecryptionTask(CryptExecutionContext orgCtx,
                                                  DirectoryInfo src, DirectoryInfo dest,
                                                  XElement xml)
        {
            var ctxClone = orgCtx.Clone();

            ctxClone.Source      = src;
            ctxClone.Destination = dest;

            return(new Task((state) =>
            {
                var ctx = (CryptExecutionContext)state;

                ctx.Destination.CreateDirectoryDeep();

                var metaFile = CollectionHelper.SingleOrDefault(ctx.Source.GetFiles(),
                                                                f => AppGlobals.FILENAME_META == f.Name.ToLower().Trim());
                if (metaFile != null)
                {
                    XDocument metaXmlDoc;
                    using (var srcStream = metaFile.OpenRead())
                    {
                        using (var temp = new MemoryStream())
                        {
                            DecryptionHelper.DecryptStream(srcStream, temp,
                                                           ctx.Password, ctx.Salt);

                            temp.Position = 0;
                            metaXmlDoc = XDocument.Load(temp);
                        }
                    }

                    // files
                    {
                        var fileMappings = metaXmlDoc.XPathSelectElements("//dir/files/file")
                                           .Select(fe =>
                        {
                            return new FileMapping(ctx: ctx,
                                                   src: new FileInfo(Path.Combine(ctx.Source.FullName,
                                                                                  fe.Attribute("alias").Value.Trim())),
                                                   dest: new FileInfo(Path.Combine(ctx.Destination.FullName,
                                                                                   fe.Attribute("name").Value.Trim())),
                                                   xml: fe);
                        }).ToArray();

                        foreach (var fm in fileMappings)
                        {
                            fm.TASK.Start();
                        }

                        TaskHelper.WaitAll(fileMappings.Select(fm => fm.TASK));
                    }

                    // directories
                    {
                        var dirMappings = metaXmlDoc.XPathSelectElements("//dir/dirs/dir")
                                          .Select(de =>
                        {
                            return new DirMapping(ctx: ctx,
                                                  src: new DirectoryInfo(Path.Combine(ctx.Source.FullName,
                                                                                      de.Attribute("alias").Value.Trim())),
                                                  dest: new DirectoryInfo(Path.Combine(ctx.Destination.FullName,
                                                                                       de.Attribute("name").Value.Trim())),
                                                  xml: de);
                        }).ToArray();

                        foreach (var dm in dirMappings)
                        {
                            dm.TASK.Start();
                        }

                        TaskHelper.WaitAll(dirMappings.Select(dm => dm.TASK));
                    }

                    if (xml != null)
                    {
                        FileSystemHelper.TrySetCreationTimeUtc(ctx.Destination,
                                                               new DateTimeOffset(ticks: long.Parse(xml.Attribute("created").Value.Trim()),
                                                                                  offset: TimeSpan.Zero));

                        FileSystemHelper.TrySetLastWriteTimeUtc(ctx.Destination,
                                                                new DateTimeOffset(ticks: long.Parse(xml.Attribute("lastWrite").Value.Trim()),
                                                                                   offset: TimeSpan.Zero));
                    }
                }
                else
                {
                    //TODO show warning
                }
            }, ctxClone));
        }
Beispiel #9
0
        // Internal Methods (4) 

        internal static Task CreateDecryptionTask(CryptExecutionContext ctx)
        {
            return(CreateDecryptionTask(ctx: ctx,
                                        xml: null));
        }