// * // // Return path to software installation chosen // public static string GetSoftwareDirectory(Config.Software type) { string testLoc = null; switch (type) { // Find VeraCrypt case Config.Software.VeraCrypt: // Prefer local installation over global one testLoc = Path.Combine(Config.KeenouProgramDirectory, @"VeraCrypt\"); if (Directory.Exists(testLoc)) { return testLoc; } // As backup, try using global installation testLoc = Path.Combine(Config.x86ProgramDirectory, @"VeraCrypt\"); if (Directory.Exists(testLoc)) { return testLoc; } break; // Find EncFS case Config.Software.EncFS: // Prefer local installation over global one testLoc = Path.Combine(Config.KeenouProgramDirectory, @"EncFS\"); if (Directory.Exists(testLoc)) { return testLoc; } // As backup, try using global installation testLoc = Path.Combine(Config.x86ProgramDirectory, @"EncFS\"); if (Directory.Exists(testLoc)) { return testLoc; } break; // Find Dokan case Config.Software.Dokan: // Use global installation testLoc = Path.Combine(Config.x86ProgramDirectory, @"Dokan\DokanLibrary\"); if (Directory.Exists(testLoc)) { return testLoc; } break; } return null; }
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 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 }; }
// * // // Get folder path for cloud service // public static string GetCloudServicePath(Config.Clouds type) { string folderPath = null; string configPath, configFilePath; switch (type) { case Config.Clouds.Dropbox: configPath = @"Dropbox\info.json"; // Find config file -- first try %APPDATA%, then %LOCALAPPDATA% configFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), configPath); if (!File.Exists(configFilePath)) { configFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), configPath); if (!File.Exists(configFilePath)) { return null; } } // Read and parse config file string personalPath = null; string businessPath = null; using (StreamReader r = new StreamReader(configFilePath)) { var serializer = new JavaScriptSerializer(); DropboxJSON accounts = serializer.Deserialize<DropboxJSON>(r.ReadToEnd()); if (accounts.personal != null) { personalPath = accounts.personal.path; } if (accounts.business != null) { businessPath = accounts.business.path; } // Only support personal folder for now folderPath = personalPath; } break; case Config.Clouds.GoogleDrive: configPath = @"Google\Drive\user_default\sync_config.db"; // Find config file -- first try Google\Drive\user_default\sync_config.db, then Google\Drive\sync_config.db configFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), configPath); if (!File.Exists(configFilePath)) { configPath = @"Google\Drive\sync_config.db"; configFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), configPath); if (!File.Exists(configFilePath)) { return null; } } using (SQLiteConnection con = new SQLiteConnection(@"Data Source=" + configFilePath + ";Version=3;New=False;Compress=True;")) { con.Open(); using (SQLiteCommand sqLitecmd = new SQLiteCommand(con)) { sqLitecmd.CommandText = "select * from data where entry_key='local_sync_root_path'"; using (SQLiteDataReader reader = sqLitecmd.ExecuteReader()) { reader.Read(); // data_value is in format "\\?\<path>" folderPath = reader["data_value"].ToString().Substring(4); } } } break; case Config.Clouds.OneDrive: // Find config file -- first try SkyDrive (old name), then OneDrive folderPath = (string)Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\SkyDrive", "UserFolder", null); if (folderPath == null) { folderPath = (string)Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\OneDrive", "UserFolder", null); } break; } return folderPath; }