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 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 }; }