예제 #1
0
        /// <summary>
        /// Shuffles the passes in the input array, effectively randomizing the
        /// order or rewrites.
        /// </summary>
        /// <param name="passes">The input set of passes.</param>
        /// <returns>The shuffled set of passes.</returns>
        protected static ErasureMethodPass[] ShufflePasses(ErasureMethodPass[] passes)
        {
            //Make a copy.
            ErasureMethodPass[] result = new ErasureMethodPass[passes.Length];
            passes.CopyTo(result, 0);

            //Randomize.
            IPrng rand = Host.Instance.Prngs.ActivePrng;

            for (int i = 0; i < result.Length; ++i)
            {
                int val = rand.Next(result.Length - 1);
                ErasureMethodPass tmpPass = result[val];
                result[val] = result[i];
                result[i]   = tmpPass;
            }

            return(result);
        }
예제 #2
0
        /// <summary>
        /// Gets a random file from within the provided directory.
        /// </summary>
        /// <param name="info">The directory to get a random file name from.</param>
        /// <returns>A string containing the full path to the file.</returns>
        public static string GetRandomFile(DirectoryInfo info)
        {
            //First retrieve the list of files and folders in the provided directory.
            FileSystemInfo[] entries = null;
            try
            {
                entries = info.GetFileSystemInfos();
            }
            catch (DirectoryNotFoundException)
            {
                return(string.Empty);
            }
            if (entries.Length == 0)
            {
                return(string.Empty);
            }

            //Find a random entry.
            IPrng  prng   = Host.Instance.Prngs.ActivePrng;
            string result = string.Empty;

            while (result.Length == 0)
            {
                int index = prng.Next(entries.Length - 1);
                if (entries[index] is DirectoryInfo)
                {
                    result = GetRandomFile((DirectoryInfo)entries[index]);
                }
                else
                {
                    result = ((FileInfo)entries[index]).FullName;
                }
            }

            return(result);
        }
예제 #3
0
        /// <summary>
        /// Writes a file for plausible deniability over the current stream.
        /// </summary>
        /// <param name="stream">The stream to write the data to.</param>
        private void DeleteFileWithPlausibleDeniability(FileInfo info)
        {
            ObfuscateFileSystemInfoName(info);

            //Get the template file to copy
            FileInfo shadowFileInfo;

            {
                string        shadowFile = null;
                List <string> entries    = new List <string>(
                    Host.Instance.Settings.PlausibleDeniabilityFiles);
                IPrng prng = Host.Instance.Prngs.ActivePrng;
                do
                {
                    if (entries.Count == 0)
                    {
                        throw new FatalException(S._("Plausible deniability was selected, " +
                                                     "but no decoy files were found. The current file has been only " +
                                                     "replaced with random data."));
                    }

                    //Get an item from the list of files, and then check that the item exists.
                    int index = prng.Next(entries.Count - 1);
                    shadowFile = entries[index];
                    if (File.Exists(shadowFile) || Directory.Exists(shadowFile))
                    {
                        if ((File.GetAttributes(shadowFile) & FileAttributes.Directory) != 0)
                        {
                            DirectoryInfo dir   = new DirectoryInfo(shadowFile);
                            FileInfo[]    files = dir.GetFiles("*", SearchOption.AllDirectories);
                            entries.Capacity += files.Length;
                            foreach (FileInfo f in files)
                            {
                                entries.Add(f.FullName);
                            }
                            shadowFile = null;
                        }
                        else
                        {
                            shadowFile = entries[index];
                        }
                    }
                    else
                    {
                        shadowFile = null;
                    }

                    entries.RemoveAt(index);
                }while (string.IsNullOrEmpty(shadowFile));
                shadowFileInfo = new FileInfo(shadowFile);
            }

            //Copy the contents of the shadow.
            using (Stream stream = info.OpenWrite())
            {
                //Dump the copy (the first 4MB, or less, depending on the file size and size of
                //the original file)
                long amountToCopy = Math.Min(4 * 1024 * 1024, shadowFileInfo.Length);
                using (FileStream shadowFileStream = shadowFileInfo.Open(
                           FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    while (stream.Position < amountToCopy)
                    {
                        byte[] buf       = new byte[524288];
                        int    bytesRead = shadowFileStream.Read(buf, 0, buf.Length);

                        //Stop bothering if the input stream is at the end
                        if (bytesRead == 0)
                        {
                            break;
                        }

                        //Dump the read contents onto the file to be deleted
                        stream.Write(buf, 0,
                                     (int)Math.Min(bytesRead, amountToCopy - stream.Position));
                    }
                }

                //Make the file to be deleted have the same length as the file
                //which is being used as a decoy. The end of the file might contain
                //noise, which should make the decoy more convincing.
                stream.SetLength(shadowFileInfo.Length);
            }

            //Make the file to be deleted look like the shadow.
            info.MoveTo(Path.Combine(info.DirectoryName, shadowFileInfo.Name));
            if (shadowFileInfo.IsCompressed())
            {
                info.Compress();
            }
            info.SetAccessControl(shadowFileInfo.GetAccessControl());
            info.Attributes = shadowFileInfo.Attributes;
            info.CopyTimes(shadowFileInfo);

            //Just delete the file.
            info.Delete();
        }