background thread full/incremental sync operations. pool sqlconnection. sqlconnection to FullMutex mode for multithread environment. try/catch decryption errors.

This commit is contained in:
Kyle Spearrin 2016-07-06 22:33:50 -04:00
parent 0be15d7a34
commit 29c7a0ccf0
4 changed files with 104 additions and 71 deletions

View file

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

View file

@ -57,35 +57,7 @@ namespace Bit.App
MessagingCenter.Subscribe<Application, bool>(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<Application, bool>(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

View file

@ -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)

View file

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