// * // // Unmount encrypted filesystem // public static BooleanResult UnmountEncryptedFS(string targetDrive) { using (Process process = new Process()) { // GET Dokan DIRECTORY string programDir = Toolbox.GetSoftwareDirectory(Config.Software.Dokan); if (programDir == null) { return(new BooleanResult() { Success = false, Message = "ERROR: Dokan inaccessible!" }); } // UNMOUNT ENCRYPTED FS ProcessStartInfo startInfo = new ProcessStartInfo(); try { //.\dokanctl.exe /u Z: startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.CreateNoWindow = true; startInfo.FileName = "cmd.exe"; startInfo.Arguments = "/C \"\"" + programDir + "dokanctl.exe\" /u \"" + targetDrive + ":\"\""; process.StartInfo = startInfo; process.Start(); process.WaitForExit(); // Ensure no errors were thrown (unmount status 0 = error, 1 = unmounted) if (process.ExitCode != 1) { return(new BooleanResult() { Success = false, Message = "ERROR: Error while unmounting! " + process.ExitCode }); } } catch (Exception err) { return(new BooleanResult() { Success = false, Message = "ERROR: Failed to unmount encrypted FS! " + err.Message }); } } // Invalidate EncFS instances that claim to be using this drive EncryptFS.InvalidateDrive(targetDrive); return(new BooleanResult() { Success = true }); }
private BooleanResult unmountCloud(string guid) { // Helper result object BooleanResult res = null; // Check to see if it is mounted // Dictionary <string, string> mounts = EncryptFS.GetAllMountedEncFS(); if (mounts == null) { return(new BooleanResult() { Success = false, Message = "ERROR: Cannot figure out which EncFS instances are mounted!" }); } if (!mounts.ContainsKey(guid)) { return(new BooleanResult() { Success = false, Message = "This encrypted folder does not appear to be mounted!" }); } // * // // Determine where this cloud is mounted to // string targetDrive = (string)Registry.GetValue(Config.CURR_USR_REG_DRIVE_ROOT + guid, "encDrive", null); if (string.IsNullOrEmpty(targetDrive)) { return(new BooleanResult() { Success = false, Message = "ERROR: Target drive not found! Is cloud mounted?" }); } // * // // Unmount encrypted drive res = EncryptFS.UnmountEncryptedFS(targetDrive); if (res == null || !res.Success) { return(res); } // * // return(new BooleanResult() { Success = true }); }
private BooleanResult mountCloud(string guid, Config.Clouds cloudSelected, string cloudPath) { // Get password from user // var promptPassword = new PromptPassword(); if (promptPassword.ShowDialog() != DialogResult.OK) { // Cancelled return(new BooleanResult() { Success = true }); } string password = promptPassword.CloudPassword; // * // // GET NEXT FREE DRIVE LETTER string targetDrive = Toolbox.GetNextFreeDriveLetter(); if (targetDrive == null) { return(new BooleanResult() { Success = false, Message = "ERROR: Cannot find a free drive letter!" }); } // * // // Helper result object BooleanResult res = null; // Check to see if it is already mounted // Dictionary <string, string> mounts = EncryptFS.GetAllMountedEncFS(); if (mounts == null) { return(new BooleanResult() { Success = false, Message = "ERROR: Cannot figure out which EncFS instances are mounted!" }); } if (mounts.ContainsKey(guid)) { return(new BooleanResult() { Success = false, Message = "This encrypted folder appears to already be mounted!" }); } // * // // Get and decrypt user's master key (using user password) // string masterKey = null; string encHeader = (string)Registry.GetValue(Config.CURR_USR_REG_DRIVE_ROOT + guid, "encHeader", null); if (string.IsNullOrEmpty(encHeader)) { return(new BooleanResult() { Success = false, Message = "ERROR: User's header information could not be found!" }); } masterKey = Toolbox.PasswordDecryptKey(encHeader, password); // Make sure we got a key back if (masterKey == null) { return(new BooleanResult() { Success = false, Message = "ERROR: Failed to decrypt master key!" }); } // * // // Mount their freshly-created encrypted drive res = EncryptFS.MountEncryptedFS(guid, targetDrive, masterKey, "Secure " + cloudSelected.ToString()); if (res == null || !res.Success) { return(res); } // * // return(new BooleanResult() { Success = true }); }
private BooleanResult encryptCloud(Config.Clouds cloudSelected, string cloudPath) { // Get new password from user // var promptPassword = new PromptNewPassword(); if (promptPassword.ShowDialog() != DialogResult.OK) { // Cancelled return(new BooleanResult() { Success = true }); } string password = promptPassword.CloudPassword; string passwordConf = promptPassword.CloudPasswordConfirm; // * // // Sanity checks // if (password.Length < Config.MIN_PASSWORD_LEN || !string.Equals(password, passwordConf)) { return(new BooleanResult() { Success = false, Message = "Passwords provided must match and be non-zero in length!" }); } // * // // GET NEXT FREE DRIVE LETTER string targetDrive = Toolbox.GetNextFreeDriveLetter(); if (targetDrive == null) { return(new BooleanResult() { Success = false, Message = "ERROR: Cannot find a free drive letter!" }); } // * // // Microsoft OneDrive will cause problems during migration if it is running, // so terminate it before we start if (cloudSelected == Config.Clouds.OneDrive) { // Ask user permission to close process first var confirmResult = MessageBox.Show("OneDrive process must be stopped before migration.", "Should I close it?", MessageBoxButtons.YesNo); if (confirmResult != DialogResult.Yes) { return(new BooleanResult() { Success = false, Message = "ERROR: Please close OneDrive application before migration." }); } // Try OneDrive first, then SkyDrive Process[] processes = Process.GetProcessesByName("OneDrive"); if (processes.Length == 0) { processes = Process.GetProcessesByName("SkyDrive"); } // If we found a OneDrive/SkyDrive process running, attempt to close it, or kill it otherwise if (processes.Length > 0) { processes[0].CloseMainWindow(); processes[0].WaitForExit(5000); if (!processes[0].HasExited) { processes[0].Kill(); processes[0].WaitForExit(5000); if (!processes[0].HasExited) { return(new BooleanResult() { Success = false, Message = "ERROR: Could not close OneDrive application!" }); } } } } else { // Tell user to turn of syncing for service var confirmResult = MessageBox.Show("Please remember to disable file syncronization for " + cloudSelected.ToString(), "Press OK when you're ready.", MessageBoxButtons.OKCancel); if (confirmResult != DialogResult.OK) { return(new BooleanResult() { Success = false, Message = "ERROR: Please disable file synchronization before migration." }); } } // * // // Disable while we calcualte stuff this.Cursor = Cursors.WaitCursor; g_tabContainer.Controls[1].Enabled = false; // Progress bar s_progress.Value = 0; s_progress.Visible = true; Application.DoEvents(); s_progress.ProgressBar.Refresh(); // Generate a new GUID to identify this FS string guid = Guid.NewGuid().ToString(); // Helper result object BooleanResult res = null; // Run work-heavy tasks in a separate thread CancellationTokenSource cts = new CancellationTokenSource(); CancellationToken cancelToken = cts.Token; var workerThread = Task.Factory.StartNew(() => { // Update UI this.Invoke((MethodInvoker) delegate { s_progress.Value = 25; l_statusLabel.Text = "Generating encryption key ..."; Application.DoEvents(); s_progress.ProgressBar.Refresh(); }); // Generate master key & protect with user password // string masterKey = Toolbox.GenerateKey(Config.MASTERKEY_PW_CHAR_COUNT); string encMasterKey = Toolbox.PasswordEncryptKey(masterKey, password); // Ensure we got good stuff back if (masterKey == null) { return(new BooleanResult() { Success = false, Message = "ERROR: Cannot generate master key!" }); } if (encMasterKey == null) { return(new BooleanResult() { Success = false, Message = "ERROR: Cannot encrypt master key!" }); } Registry.SetValue(Config.CURR_USR_REG_DRIVE_ROOT + guid, "encHeader", encMasterKey); // * // // Generate temporary location to hold enc data string tempFolderName = cloudPath + ".backup-" + Path.GetRandomFileName(); Directory.CreateDirectory(tempFolderName); // Update UI this.Invoke((MethodInvoker) delegate { s_progress.Value = 50; l_statusLabel.Text = "Creating EncFS drive"; Application.DoEvents(); s_progress.ProgressBar.Refresh(); }); // Create new EncFS res = EncryptFS.CreateEncryptedFS(guid, cloudPath, targetDrive, masterKey, "Secure " + cloudSelected.ToString(), true); if (res == null || !res.Success) { return(res); } // * // // Update UI this.Invoke((MethodInvoker) delegate { s_progress.Value = 75; l_statusLabel.Text = "Copying data from Cloud folder to encrypted drive"; Application.DoEvents(); s_progress.ProgressBar.Refresh(); }); // Copy cloud data over res = EncryptFS.MoveDataFromFolder(cloudPath, tempFolderName); if (res == null || !res.Success) { return(res); } res = EncryptFS.CopyDataFromFolder(tempFolderName, targetDrive + ":\\"); if (res == null || !res.Success) { return(res); } // * // return(new BooleanResult() { Success = true }); }, TaskCreationOptions.LongRunning); // When threaded tasks finish, check for errors and continue (if appropriate) workerThread.ContinueWith((antecedent) => { // Block until we get a result back from previous thread BooleanResult result = antecedent.Result; // Check if there was an error in previous thread if (result == null || !result.Success) { ReportEncryptCloudError(result); return; } // Re-enable everything // this.Cursor = Cursors.Default; g_tabContainer.Controls[1].Enabled = true; l_statusLabel.Text = "Successfully moved your cloud folder!"; s_progress.Value = 0; s_progress.Visible = false; Application.DoEvents(); // * // }, cancelToken, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.FromCurrentSynchronizationContext() ); return(new BooleanResult() { Success = true }); }
private void b_cloudAction_Click(object sender, EventArgs e) { // Determine which type of cloud service they want to perform action on Config.Clouds cloudSelected; if (rb_cloud_Google.Checked) { cloudSelected = Config.Clouds.GoogleDrive; } else if (rb_cloud_OneDrive.Checked) { cloudSelected = Config.Clouds.OneDrive; } else if (rb_cloud_Dropbox.Checked) { cloudSelected = Config.Clouds.Dropbox; } else { ReportEncryptCloudError(new BooleanResult() { Success = false, Message = "ERROR: Unsupported cloud type selected!" }); return; } // * // // Figure out where the cloud's folder is on this computer // string cloudPath = EncryptFS.GetCloudServicePath(cloudSelected); if (cloudPath == null) { ReportEncryptCloudError(new BooleanResult() { Success = false, Message = "ERROR: Cannot determine the location of your cloud service!" }); return; } // * // // Find guid of desired cloud folder // string guid = null; RegistryKey OurKey = Registry.CurrentUser; OurKey = OurKey.OpenSubKey(@"Software\Keenou\drives"); if (OurKey != null) { foreach (string Keyname in OurKey.GetSubKeyNames()) { RegistryKey key = OurKey.OpenSubKey(Keyname); if (key.GetValue("encContainerLoc") != null && key.GetValue("encContainerLoc").ToString() == cloudPath) { guid = Keyname.ToString(); } } } // * // // Helper result object BooleanResult res = null; // If there is no registered guid yet, then it's the first time (set up) // if (guid == null) { res = this.encryptCloud(cloudSelected, cloudPath); if (res == null || !res.Success) { ReportEncryptCloudError(res); return; } return; } // * // // Check to see if it is mounted // Dictionary <string, string> mounts = EncryptFS.GetAllMountedEncFS(); if (mounts == null) { ReportEncryptCloudError(new BooleanResult() { Success = false, Message = "ERROR: Cannot figure out which EncFS instances are mounted!" }); return; } if (mounts.ContainsKey(guid)) { // already mounted -- unmount res = this.unmountCloud(guid); if (res == null || !res.Success) { ReportEncryptCloudError(res); return; } return; } else { // not yet mounted -- mount res = this.mountCloud(guid, cloudSelected, cloudPath); if (res == null || !res.Success) { ReportEncryptCloudError(res); return; } return; } // * // // We should never make it to here }
// * // // Mount encrypted filesystem // public static BooleanResult MountEncryptedFS(string guid, string targetDrive, string masterKey, string label) { // Determine location of configuration file string configLoc = (string)Registry.GetValue(Config.CURR_USR_REG_DRIVE_ROOT + guid, "configLoc", string.Empty); if (string.IsNullOrEmpty(configLoc)) { return(new BooleanResult() { Success = false, Message = "ERROR: Invalid GUID given to mount!" }); } // Pull enc volume location from registry for this GUID string volumeLoc = (string)Registry.GetValue(Config.CURR_USR_REG_DRIVE_ROOT + guid, "encContainerLoc", string.Empty); if (string.IsNullOrEmpty(volumeLoc)) { return(new BooleanResult() { Success = false, Message = "ERROR: Invalid GUID given to mount!" }); } // Path cannot end with a slash due to CMD usage volumeLoc = volumeLoc.TrimEnd(new[] { '/', '\\' }); using (Process process = new Process()) { // GET EncFS DIRECTORY string programDir = Toolbox.GetSoftwareDirectory(Config.Software.EncFS); if (programDir == null) { return(new BooleanResult() { Success = false, Message = "ERROR: EncFS inaccessible!" }); } // GET Dokan DIRECTORY string dokanDir = Toolbox.GetSoftwareDirectory(Config.Software.Dokan); if (dokanDir == null) { return(new BooleanResult() { Success = false, Message = "ERROR: Dokan inaccessible!" }); } // MOUNT ENCRYPTED CONTAINER ProcessStartInfo startInfo = new ProcessStartInfo(); try { //.\encfs.exe "C:\Users\jetwhiz\Desktop\encfs4win\testing" "Z:" --stdinpass -o volname="Secure Dropbox" startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.CreateNoWindow = true; startInfo.RedirectStandardInput = true; startInfo.UseShellExecute = false; startInfo.FileName = "cmd.exe"; startInfo.EnvironmentVariables["ENCFS6_CONFIG"] = configLoc + Config.ENCFS_CONFIG_FILENAME; startInfo.Arguments = "/C \"\"" + programDir + "encfs.exe\" --require-macs --stdinpass -o volname=\"" + label + "\" \"" + volumeLoc + "\" \"" + targetDrive + ":\"\""; process.StartInfo = startInfo; process.Start(); // Send stdin inputs to program StreamWriter myStreamWriter = process.StandardInput; myStreamWriter.WriteLine(masterKey); // user's password myStreamWriter.Close(); // Give it a few seconds to finish // TODO: Figure out better way to determine when EncFS has finished process.WaitForExit(10000); // If it exited by itself, it was in error if (process.HasExited) { return(new BooleanResult() { Success = false, Message = "ERROR: Error while mounting encrypted FS! " + process.ExitCode }); } // Invalidate all other EncFS instances that still claim to be using this drive EncryptFS.InvalidateDrive(targetDrive); // Save where we mounted the encrypted volume Registry.SetValue(Config.CURR_USR_REG_DRIVE_ROOT + guid, "encDrive", targetDrive); // Process will block indefinitely (until unmount called), so just return //process.WaitForExit(); } catch (Exception err) { return(new BooleanResult() { Success = false, Message = "ERROR: Failed to mount encrypted FS! " + err.Message }); } } return(new BooleanResult() { Success = true }); }
// * // // Create new encrypted filesystem // public static BooleanResult CreateEncryptedFS(string guid, string volumeLoc, string targetDrive, string masterKey, string label, bool keepMounted = false) { // Path cannot end with a slash due to CMD usage volumeLoc = volumeLoc.TrimEnd(new[] { '/', '\\' }); // GET EncFS DIRECTORY string programDir = Toolbox.GetSoftwareDirectory(Config.Software.EncFS); if (programDir == null) { return(new BooleanResult() { Success = false, Message = "ERROR: EncFS inaccessible!" }); } // GET Dokan DIRECTORY string dokanDir = Toolbox.GetSoftwareDirectory(Config.Software.Dokan); if (dokanDir == null) { return(new BooleanResult() { Success = false, Message = "ERROR: Dokan inaccessible!" }); } // Determine Keenou config file location for this volume string configLoc = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + @"\Keenou\" + guid + @"\"; if (Directory.Exists(configLoc)) { // TODO: auto-recovery? return(new BooleanResult() { Success = false, Message = "ERROR: Possible GUID collision!" }); } // Create config file directory for this FS Directory.CreateDirectory(configLoc); // Save setting values to registry Registry.SetValue(Config.CURR_USR_REG_DRIVE_ROOT + guid, "encContainerLoc", volumeLoc); Registry.SetValue(Config.CURR_USR_REG_DRIVE_ROOT + guid, "configLoc", configLoc); using (Process process = new Process()) { // MOUNT ENCRYPTED CONTAINER ProcessStartInfo startInfo = new ProcessStartInfo(); try { //.\encfs.exe "C:\Users\jetwhiz\Desktop\encfs4win\testing" "Z:" --stdinpass -o volname="Secure Dropbox" startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.CreateNoWindow = true; startInfo.RedirectStandardInput = true; startInfo.UseShellExecute = false; startInfo.FileName = "cmd.exe"; startInfo.EnvironmentVariables["ENCFS6_CONFIG"] = configLoc + Config.ENCFS_CONFIG_FILENAME; startInfo.Arguments = "/C \"\"" + programDir + "encfs.exe\" --stdinpass -o volname=\"" + label + "\" \"" + volumeLoc + "\" \"" + targetDrive + ":\"\""; process.StartInfo = startInfo; process.Start(); // Send stdin inputs to program StreamWriter myStreamWriter = process.StandardInput; myStreamWriter.WriteLine("p"); // paranoia mode myStreamWriter.WriteLine(masterKey); // user's password myStreamWriter.Close(); // Give it a few seconds to finish // TODO: Figure out better way to determine when EncFS has finished process.WaitForExit(10000); // Unmount drive (forcing the closing of encfs process) if not already exited if (!process.HasExited) { // Auto-unmount unless they asked us not to if (!keepMounted) { BooleanResult res = EncryptFS.UnmountEncryptedFS(targetDrive); if (res == null || !res.Success) { return(res); } } else { // Invalidate all other EncFS instances that still claim to be using this drive EncryptFS.InvalidateDrive(targetDrive); // Save where we mounted the encrypted volume Registry.SetValue(Config.CURR_USR_REG_DRIVE_ROOT + guid, "encDrive", targetDrive); } } else { // If it exited by itself, it was in error return(new BooleanResult() { Success = false, Message = "ERROR: Error while creating encrypted FS! " + process.ExitCode }); } // Process will block indefinitely (until unmount called), so just return //process.WaitForExit(); } catch (Exception err) { return(new BooleanResult() { Success = false, Message = "ERROR: Failed to create encrypted FS! " + err.Message }); } } return(new BooleanResult() { Success = true }); }