/// <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); }
/// <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); }
/// <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(); }