Example #1
0
        private void SyncLocal(PwDatabase pwDatabase, SafeVaultWebClient webClient, string databaseUuid, SafeVaultConf vaultConf)
        {
            SetStatusText("Check changes...");
            var value = GetRemoteLastModified(webClient, databaseUuid);

            if (value == null)
            {
                SetStatusText("Database not found on SafeVault. Nothing to sync");
                return;
            }
            var lastModified = value.Value;

            if (vaultConf.SyncRemoteLastModified == lastModified.ToString("u"))
            {
                SetStatusText("No changes");
                return;
            }

            SetStatusText("Downloading...");
            var dbData = Async.Invoke(() => DownloadFile(webClient, databaseUuid, vaultConf));

            SetStatusText("Sync...");
            SyncDatabase(pwDatabase, dbData, false);
            SetStatusText("Successfull Sync Local <= Remote");

            vaultConf.SyncRemoteLastModified = lastModified.ToString("u");
            vaultConf.Save();
            pwDatabase.Save(new NullStatusLogger());
        }
Example #2
0
        private static DateTime?GetRemoteLastModified(SafeVaultWebClient webClient, string databaseUuid)
        {
            try
            {
                return(Async.Invoke(() => webClient.DbxGetLastModified(databaseUuid)));
            }
            catch (HttpChannelException httpEx)
            {
                if (httpEx.StatusCode != (int)HttpStatusCode.NotFound)
                {
                    throw;
                }

                return(null);
            }
        }
Example #3
0
 private byte[] DownloadFile(SafeVaultWebClient webClient, string databaseUuid, SafeVaultConf vaultConf)
 {
     byte[] databaseData;
     try
     {
         databaseData = webClient.DbxDownload(databaseUuid,
                                              progress => { SetStatusText(string.Format("Download {0}%", progress)); });
     }
     catch (HttpChannelException httpEx)
     {
         if (httpEx.StatusCode == (int)HttpStatusCode.NotFound)
         {
             throw new SynchronizeException("Database not found on SafeVault. Please sync with SafeVault first.");
         }
         throw;
     }
     return(databaseData);
 }
Example #4
0
        private void SyncUpload(PwDatabase pwDatabase, SafeVaultWebClient webClient, string databaseUuid,
                                SafeVaultConf vaultConf)
        {
            var lastModified = GetLastModified(pwDatabase);
            var location     = _host.Database.IOConnectionInfo.Path;

            SetStatusText("Saving to SafeVault...");
            Async.Invoke(() =>
            {
                webClient.DbxUpload(
                    databaseUuid,
                    File.ReadAllBytes(location),
                    lastModified);
            });
            SetStatusText("Successfull Upload to SafeVault");
            vaultConf.SyncRemoteLastModified = lastModified.ToString("u");
            vaultConf.Save();
        }
Example #5
0
        private void SyncRemote(PwDatabase pwDatabase, SafeVaultWebClient webClient, string databaseUuid,
                                SafeVaultConf vaultConf)
        {
            SetStatusText("Check changes...");
            var localLastModified = GetLastModified(pwDatabase);
            var lastModified      = GetRemoteLastModified(webClient, databaseUuid);

            if (lastModified != null && lastModified == localLastModified)
            {
                SetStatusText("No changes.");
                return;
            }

            if (lastModified != null && lastModified.Value.ToString("u") != vaultConf.SyncRemoteLastModified)
            {
                SetStatusText("Downloading...");
                var dbData = Async.Invoke(() => DownloadFile(webClient, databaseUuid, vaultConf));
                if (dbData != null)
                {
                    SetStatusText("Sync...");
                    SyncDatabase(pwDatabase, dbData, true);
                    _host.MainWindow.Enabled = false;
                    localLastModified        = GetLastModified(pwDatabase);
                }
            }

            SetStatusText("Saving to SafeVault...");
            Async.Invoke(() =>
            {
                webClient.DbxUpload(
                    databaseUuid,
                    File.ReadAllBytes(pwDatabase.IOConnectionInfo.Path),
                    localLastModified);
            });
            SetStatusText("Successfull Sync Local <=> Remote");

            vaultConf.SyncRemoteLastModified = localLastModified.ToString("u");
            vaultConf.Save();
            pwDatabase.Save(new NullStatusLogger());
        }
Example #6
0
        private void SyncDownload(PwDatabase pwDatabase, SafeVaultWebClient webClient, string databaseUuid,
                                  SafeVaultConf vaultConf)
        {
            var lastModified = GetRemoteLastModified(webClient, databaseUuid);

            if (lastModified != null)
            {
                SetStatusText("Downloading...");
                var dbData = Async.Invoke(() => DownloadFile(webClient, databaseUuid, vaultConf));

                ReplaceDatabase(pwDatabase, dbData);
                SetStatusText("Download Done.");
                vaultConf.ChangeDatabase(_host.Database);
                vaultConf.SyncRemoteLastModified = lastModified.Value.ToString("u");
                vaultConf.Save();
                pwDatabase.Save(new NullStatusLogger());
            }
            else
            {
                SetStatusText("Database not found. Nothing to sync");
            }
        }
Example #7
0
        private void SyncWithSafeVault(SyncCommand syncCommand)
        {
            PwDatabase pwDatabase = _host.Database;

            if (!pwDatabase.IsOpen)
            {
                ShowMessageBox("You first need to open a database.");
                return;
            }
            if (!pwDatabase.IOConnectionInfo.IsLocalFile())
            {
                ShowMessageBox("Only databases stored locally or on a network share are supported.\n" +
                               "Save your database locally or on a network share and try again.");
                return;
            }
            if (pwDatabase.Modified)
            {
                ShowMessageBox("Database has not saved changes. Save it first.");
                return;
            }

            SafeVaultConf vaultConf = new SafeVaultConf(pwDatabase);

            if (!IsSyncConfigured(vaultConf))
            {
                SetStatusText("Sync not Configured.");
                return;
            }

            _host.MainWindow.FileSaved  -= OnFileSaved;  // disable to not trigger when saving ourselves
            _host.MainWindow.FileOpened -= OnFileOpened; // disable to not trigger when opening ourselves
            _host.MainWindow.Enabled     = false;

            _lastStatus = "";

            try
            {
                var databaseUuid             = Path.GetFileNameWithoutExtension(pwDatabase.IOConnectionInfo.Path);
                SafeVaultWebClient webClient = new SafeVaultWebClient(vaultConf);

                if (syncCommand == SyncCommand.Download)
                {
                    try
                    {
                        SyncDownload(pwDatabase, webClient, databaseUuid, vaultConf);
                    }
                    catch (Exception ex)
                    {
                        ShowMessageBox(ex.Message);
                        SetStatusText("SyncDownload Failed");
                    }
                }
                if (syncCommand == SyncCommand.Upload)
                {
                    try
                    {
                        SyncUpload(pwDatabase, webClient, databaseUuid, vaultConf);
                    }
                    catch (Exception ex)
                    {
                        ShowMessageBox(ex.Message);
                        SetStatusText("SyncUpload Failed");
                    }
                }

                if (syncCommand == SyncCommand.SyncLocal)
                {
                    try
                    {
                        SyncLocal(pwDatabase, webClient, databaseUuid, vaultConf);
                    }
                    catch (Exception ex)
                    {
                        ShowMessageBox(ex.Message);
                        SetStatusText("SyncLocal Failed");
                    }
                }

                if (syncCommand == SyncCommand.SyncRemote)
                {
                    try
                    {
                        SyncRemote(pwDatabase, webClient, databaseUuid, vaultConf);
                    }
                    catch (Exception ex)
                    {
                        ShowMessageBox(ex.Message);
                        SetStatusText("SyncRemote Failed");
                    }
                }
            }
            catch (Exception ex)
            {
                ShowMessageBox(ex.Message);
                SetStatusText("Unknown Err: " + ex.Message);
            }

            _host.MainWindow.UpdateUI(false, null, true, null, true, null, false);
            _host.MainWindow.Enabled     = true;
            _host.MainWindow.FileSaved  += OnFileSaved;
            _host.MainWindow.FileOpened += OnFileOpened;
            if (_lastStatus != "")
            {
                SetStatusText(_lastStatus);
            }
        }
        private byte[] Create(KeyProviderQueryContext ctx)
        {
            var vaultConf = new SafeVaultConf(ctx.DatabaseIOInfo);

            var vaultConnectionForm = new VaultConnectionConfigForm();

            vaultConnectionForm.InitEx(vaultConf);

            if (UIUtil.ShowDialogAndDestroy(vaultConnectionForm) != DialogResult.OK)
            {
                return(null);
            }

            VaultKeyCreateForm createForm = new VaultKeyCreateForm();

            createForm.InitEx(vaultConf, ctx);
            if (UIUtil.ShowDialogAndDestroy(createForm) != DialogResult.OK)
            {
                return(null);
            }

            vaultConf.Type    = PROVIDER_TYPE;
            vaultConf.Version = PROVIDER_VERSION;

            var masterKey = Encoding.UTF8.GetBytes(vaultConf.DatabaseKeyA);

            var keyLen = (masterKey.Length > 254) ? masterKey.Length : 254;

            var keyA = new byte[keyLen + 2];

            Array.Copy(BitConverter.GetBytes((ushort)masterKey.Length), keyA, 2);
            Array.Copy(masterKey, 0, keyA, 2, masterKey.Length);

            var keyB = Random.Get(keyA.Length);

            for (int i = 0; i < keyB.Length; i++)
            {
                keyA[i] ^= keyB[i];
            }

            var salt = Random.Get(64);

            using (var aes = new Aes256Cipher())
            {
                aes.SetPassPhrase(salt);
                keyA = aes.Encrypt(keyA);
                keyB = aes.Encrypt(keyB);
            }

            using (var rsa = RsaCipher.LoadFromX509Store(vaultConf.ClientCertificateName))
            {
                salt = rsa.Encrypt(salt);
            }

            vaultConf.Salt         = Convert.ToBase64String(salt);
            vaultConf.DatabaseKeyA = Convert.ToBase64String(keyA);
            vaultConf.VaultKeyname = Guid.NewGuid().ToString();
            var databaseKeyB = Convert.ToBase64String(keyB);

            VaultKeyPromptForm promptForm = new VaultKeyPromptForm();

            promptForm.InitEx("Enter SafeVault Password", "Save KeyB to SafeVault", (oneTimePassword) => {
                string status = "";
                var query     = new SafeVaultWebClient(vaultConf);
                try
                {
                    status = Async.Invoke(() => query.SetDbxKey(vaultConf.VaultKeyname, databaseKeyB, oneTimePassword));
                    if (status == "OK")
                    {
                        return(true);
                    }

                    MessageService.ShowWarning(
                        query.Utc != null ? "DateTime: " + DateTime.Parse(query.Utc).ToLocalTime() : "",
                        status);
                }
                catch (CryptographicException ex)
                {
                    MessageService.ShowWarning(
                        query.Utc != null ? "DateTime: " + DateTime.Parse(query.Utc).ToLocalTime() : "",
                        ex.Message);
                }
                return(false);
            });

            if (UIUtil.ShowDialogAndDestroy(promptForm) != DialogResult.OK)
            {
                return(null);
            }

            try
            {
                vaultConf.Save();
            }
            catch (Exception e)
            {
                MessageService.ShowWarning(e.Message);
                return(null);
            }

            return(masterKey);
        }
        private byte[] OpenInternal(KeyProviderQueryContext ctx)
        {
            SafeVaultConf conf = new SafeVaultConf(ctx.DatabaseIOInfo);

            var required = new[] {
                conf.ClientCertificateName,
                conf.ServerUrl,
                conf.ServerCertificateName,
                conf.Salt,
                conf.Username,
                conf.VaultKeyname,
                conf.DatabaseKeyA
            };

            if (required.Any(string.IsNullOrEmpty))
            {
                throw new ConfigurationException("SafeVault not configured.");
            }

            byte[] salt = Convert.FromBase64String(conf.Salt);
            using (var rsa = RsaCipher.LoadFromX509Store(conf.ClientCertificateName))
            {
                salt = rsa.Decrypt(salt);
            }

            string             sKeyB      = string.Empty;
            VaultKeyPromptForm promptForm = new VaultKeyPromptForm();

            promptForm.InitEx("Enter SafeVault Password", "Open Database", (oneTimePassword) => {
                var query = new SafeVaultWebClient(conf);
                try
                {
                    sKeyB = query.GetDbxKey(conf.VaultKeyname, oneTimePassword);
                    return(true);
                }
                catch (SafeVaultException ex)
                {
                    MessageService.ShowWarning(
                        query.Utc != null ? "DateTime: " + DateTime.Parse(query.Utc).ToLocalTime() : "",
                        ex.Message
                        );
                }
                return(false);
            });

            if (UIUtil.ShowDialogAndDestroy(promptForm) != DialogResult.OK)
            {
                return(null);
            }

            byte[] keyA = Convert.FromBase64String(conf.DatabaseKeyA);
            byte[] keyB = Convert.FromBase64String(sKeyB);
            using (var aes = new Aes256Cipher())
            {
                aes.SetPassPhrase(salt);
                keyA = aes.Decrypt(keyA);
                keyB = aes.Decrypt(keyB);
            }

            if (keyA.Length != keyB.Length)
            {
                throw new SafevaultKeyProviderException("Incompatible KEYA and KEYB");
            }

            for (int i = 0; i < keyB.Length; i++)
            {
                keyA[i] ^= keyB[i];
            }
            int keyL = BitConverter.ToUInt16(keyA, 0);

            if (keyL > keyA.Length)
            {
                throw new SafevaultKeyProviderException("Invalid KEYB");
            }

            byte[] masterKey = new byte[keyL];
            Array.Copy(keyA, 2, masterKey, 0, masterKey.Length);

            return(masterKey);
        }