diff --git a/src/Android/Services/SqlService.cs b/src/Android/Services/SqlService.cs index d7f31c516..d826a3994 100644 --- a/src/Android/Services/SqlService.cs +++ b/src/Android/Services/SqlService.cs @@ -1,22 +1,29 @@ using System; using System.IO; using Bit.App.Abstractions; +using SQLite; namespace Bit.Android.Services { public class SqlService : ISqlService { - public SQLite.SQLiteConnection GetConnection() + private SQLiteConnection _connection; + + public SQLiteConnection GetConnection() { + if(_connection != null) + { + return _connection; + } + var sqliteFilename = "bitwarden.db3"; var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); // Documents folder var path = Path.Combine(documentsPath, sqliteFilename); - Console.WriteLine(path); - var conn = new SQLite.SQLiteConnection(path); - // Return the database connection - return conn; + _connection = new SQLiteConnection(path, + SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create | SQLiteOpenFlags.FullMutex | SQLiteOpenFlags.SharedCache); + return _connection; } } } diff --git a/src/App/App.cs b/src/App/App.cs index b6c98924b..744f85e4d 100644 --- a/src/App/App.cs +++ b/src/App/App.cs @@ -57,35 +57,7 @@ namespace Bit.App MessagingCenter.Subscribe(Current, "Resumed", async (sender, args) => { await CheckLockAsync(args); - if(_connectivity.IsConnected) - { - var attempt = 0; - do - { - try - { - await _syncService.IncrementalSyncAsync(); - break; - } - catch(WebException) - { - Debug.WriteLine("Failed to sync."); - if(attempt >= 1) - { - await _userDialogs.AlertAsync("Unable to automatically sync."); - } - else - { - await Task.Delay(1000); - } - attempt++; - } - } while(attempt <= 1); - } - else - { - Debug.WriteLine("Not connected."); - } + await Task.Run(() => IncrementalSyncAsync()).ConfigureAwait(false); }); MessagingCenter.Subscribe(Current, "Lock", async (sender, args) => @@ -99,30 +71,7 @@ namespace Bit.App // Handle when your app starts await CheckLockAsync(false); _databaseService.CreateTables(); - if(_connectivity.IsConnected) - { - var attempt = 0; - do - { - try - { - await _syncService.FullSyncAsync(); - break; - } - catch(WebException) - { - if(attempt >= 1) - { - await _userDialogs.AlertAsync("Unable to automatically sync. Manual sync required."); - } - else - { - await Task.Delay(1000); - } - attempt++; - } - } while(attempt <= 1); - } + await Task.Run(() => FullSyncAsync()).ConfigureAwait(false); Debug.WriteLine("OnStart"); } @@ -155,6 +104,68 @@ namespace Bit.App } } + private async Task IncrementalSyncAsync() + { + if(_connectivity.IsConnected) + { + var attempt = 0; + do + { + try + { + await _syncService.IncrementalSyncAsync(); + break; + } + catch(WebException) + { + Debug.WriteLine("Failed to incremental sync."); + if(attempt >= 1) + { + break; + } + else + { + await Task.Delay(1000); + } + attempt++; + } + } while(attempt <= 1); + } + else + { + Debug.WriteLine("Not connected."); + } + } + + private async Task FullSyncAsync() + { + if(_connectivity.IsConnected) + { + var attempt = 0; + do + { + try + { + await _syncService.FullSyncAsync(); + break; + } + catch(WebException) + { + Debug.WriteLine("Failed to full sync."); + if(attempt >= 1) + { + break; + } + else + { + await Task.Delay(1000); + } + attempt++; + } + } while(attempt <= 1); + } + } + private async Task CheckLockAsync(bool forceLock) { // Only lock if they are logged in diff --git a/src/App/Services/CryptoService.cs b/src/App/Services/CryptoService.cs index 6c50e22b7..b9207811e 100644 --- a/src/App/Services/CryptoService.cs +++ b/src/App/Services/CryptoService.cs @@ -1,7 +1,9 @@ using System; +using System.Diagnostics; using System.Text; using Bit.App.Abstractions; using Bit.App.Models; +using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Digests; using Org.BouncyCastle.Crypto.Engines; using Org.BouncyCastle.Crypto.Generators; @@ -113,14 +115,20 @@ namespace Bit.App.Services throw new ArgumentNullException(nameof(encyptedValue)); } - var keyParamWithIV = new ParametersWithIV(_keyParameter, encyptedValue.InitializationVectorBytes, 0, InitializationVectorSize); - - _cipher.Init(false, keyParamWithIV); - byte[] comparisonBytes = new byte[_cipher.GetOutputSize(encyptedValue.CipherTextBytes.Length)]; - var length = _cipher.ProcessBytes(encyptedValue.CipherTextBytes, comparisonBytes, 0); - _cipher.DoFinal(comparisonBytes, length); - - return Encoding.UTF8.GetString(comparisonBytes, 0, comparisonBytes.Length).TrimEnd('\0'); + try + { + var keyParamWithIV = new ParametersWithIV(_keyParameter, encyptedValue.InitializationVectorBytes, 0, InitializationVectorSize); + _cipher.Init(false, keyParamWithIV); + byte[] comparisonBytes = new byte[_cipher.GetOutputSize(encyptedValue.CipherTextBytes.Length)]; + var length = _cipher.ProcessBytes(encyptedValue.CipherTextBytes, comparisonBytes, 0); + _cipher.DoFinal(comparisonBytes, length); + return Encoding.UTF8.GetString(comparisonBytes, 0, comparisonBytes.Length).TrimEnd('\0'); + } + catch(Exception e) + { + Debug.WriteLine("Could not decrypt '{0}'. {1}", encyptedValue, e.Message); + return "[error: cannot decrypt]"; + } } public byte[] MakeKeyFromPassword(string password, string salt) diff --git a/src/iOS.Core/Services/SqlService.cs b/src/iOS.Core/Services/SqlService.cs index 1b1c79775..570e834f9 100644 --- a/src/iOS.Core/Services/SqlService.cs +++ b/src/iOS.Core/Services/SqlService.cs @@ -2,24 +2,31 @@ using System.IO; using Bit.App.Abstractions; using Foundation; +using SQLite; namespace Bit.iOS.Core.Services { public class SqlService : ISqlService { - public SQLite.SQLiteConnection GetConnection() + private SQLiteConnection _connection; + + public SQLiteConnection GetConnection() { + if(_connection != null) + { + return _connection; + } + var sqliteFilename = "bitwarden.db3"; var fileManager = new NSFileManager(); var appGroupContainer = fileManager.GetContainerUrl("group.com.8bit.bitwarden"); var libraryPath = Path.Combine(appGroupContainer.Path, "Library"); // Library folder var path = Path.Combine(libraryPath, sqliteFilename); - Console.WriteLine(path); - var conn = new SQLite.SQLiteConnection(path); - // Return the database connection - return conn; + _connection = new SQLiteConnection(path, + SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create | SQLiteOpenFlags.FullMutex | SQLiteOpenFlags.SharedCache); + return _connection; } } }