예제 #1
0
        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
            });
        }
예제 #2
0
파일: MainWindow.cs 프로젝트: CEMi4/Keenou
        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 };
        }