first version of KeeAutoExec functionality in Keepass2Android
This commit is contained in:
@@ -44,7 +44,7 @@ namespace keepass2android
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads the specified data as the currently open database, as unlocked.
|
/// Loads the specified data as the currently open database, as unlocked.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Database LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, CompositeKey compKey, ProgressDialogStatusLogger statusLogger, IDatabaseFormat databaseFormat);
|
Database LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, CompositeKey compKey, ProgressDialogStatusLogger statusLogger, IDatabaseFormat databaseFormat, bool makeCurrent);
|
||||||
|
|
||||||
|
|
||||||
HashSet<PwGroup> DirtyGroups { get; }
|
HashSet<PwGroup> DirtyGroups { get; }
|
||||||
@@ -64,12 +64,12 @@ namespace keepass2android
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tell the app that the file from ioc was opened with keyfile.
|
/// Tell the app that the file from ioc was opened with keyfile.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void StoreOpenedFileAsRecent(IOConnectionInfo ioc, string keyfile, string displayName = "");
|
void StoreOpenedFileAsRecent(IOConnectionInfo ioc, string keyfile, bool updateTimestamp, string displayName = "");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new database and returns it
|
/// Creates a new database and returns it
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Database CreateNewDatabase();
|
Database CreateNewDatabase(bool makeCurrent);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the user-displayable string identified by stringKey
|
/// Returns the user-displayable string identified by stringKey
|
||||||
|
|||||||
@@ -207,8 +207,7 @@ namespace keepass2android.Io
|
|||||||
|
|
||||||
public IOConnectionInfo GetParentPath(IOConnectionInfo ioc)
|
public IOConnectionInfo GetParentPath(IOConnectionInfo ioc)
|
||||||
{
|
{
|
||||||
//TODO: required for OTP Aux file retrieval
|
return IoUtil.GetParentPath(ioc);
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IOConnectionInfo GetFilePath(IOConnectionInfo folderPath, string filename)
|
public IOConnectionInfo GetFilePath(IOConnectionInfo folderPath, string filename)
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ namespace keepass2android
|
|||||||
private readonly String _name;
|
private readonly String _name;
|
||||||
private readonly int _iconId;
|
private readonly int _iconId;
|
||||||
private readonly PwUuid _groupCustomIconId;
|
private readonly PwUuid _groupCustomIconId;
|
||||||
internal PwGroup Group;
|
public PwGroup Group;
|
||||||
internal PwGroup Parent;
|
internal PwGroup Parent;
|
||||||
protected bool DontSave;
|
protected bool DontSave;
|
||||||
readonly Activity _ctx;
|
readonly Activity _ctx;
|
||||||
|
|||||||
@@ -32,15 +32,17 @@ namespace keepass2android
|
|||||||
private readonly Activity _ctx;
|
private readonly Activity _ctx;
|
||||||
private readonly IKp2aApp _app;
|
private readonly IKp2aApp _app;
|
||||||
private CompositeKey _key;
|
private CompositeKey _key;
|
||||||
|
private readonly bool _makeCurrent;
|
||||||
|
|
||||||
public CreateDb(IKp2aApp app, Activity ctx, IOConnectionInfo ioc, OnFinish finish, bool dontSave): base(ctx, finish) {
|
public CreateDb(IKp2aApp app, Activity ctx, IOConnectionInfo ioc, OnFinish finish, bool dontSave, bool makeCurrent): base(ctx, finish) {
|
||||||
_ctx = ctx;
|
_ctx = ctx;
|
||||||
_ioc = ioc;
|
_ioc = ioc;
|
||||||
_dontSave = dontSave;
|
_dontSave = dontSave;
|
||||||
_app = app;
|
_makeCurrent = makeCurrent;
|
||||||
|
_app = app;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreateDb(IKp2aApp app, Activity ctx, IOConnectionInfo ioc, OnFinish finish, bool dontSave, CompositeKey key)
|
public CreateDb(IKp2aApp app, Activity ctx, IOConnectionInfo ioc, OnFinish finish, bool dontSave, CompositeKey key, bool makeCurrent)
|
||||||
: base(ctx, finish)
|
: base(ctx, finish)
|
||||||
{
|
{
|
||||||
_ctx = ctx;
|
_ctx = ctx;
|
||||||
@@ -48,12 +50,13 @@ namespace keepass2android
|
|||||||
_dontSave = dontSave;
|
_dontSave = dontSave;
|
||||||
_app = app;
|
_app = app;
|
||||||
_key = key;
|
_key = key;
|
||||||
|
_makeCurrent = makeCurrent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void Run() {
|
public override void Run() {
|
||||||
StatusLogger.UpdateMessage(UiStringKey.progress_create);
|
StatusLogger.UpdateMessage(UiStringKey.progress_create);
|
||||||
Database db = _app.CreateNewDatabase();
|
Database db = _app.CreateNewDatabase(_makeCurrent);
|
||||||
|
|
||||||
db.KpDatabase = new KeePassLib.PwDatabase();
|
db.KpDatabase = new KeePassLib.PwDatabase();
|
||||||
|
|
||||||
|
|||||||
@@ -37,21 +37,25 @@ namespace keepass2android
|
|||||||
private readonly bool _rememberKeyfile;
|
private readonly bool _rememberKeyfile;
|
||||||
IDatabaseFormat _format;
|
IDatabaseFormat _format;
|
||||||
|
|
||||||
public LoadDb(Activity activity, IKp2aApp app, IOConnectionInfo ioc, Task<MemoryStream> databaseData, CompositeKey compositeKey, String keyfileOrProvider, OnFinish finish): base(activity, finish)
|
public LoadDb(Activity activity, IKp2aApp app, IOConnectionInfo ioc, Task<MemoryStream> databaseData, CompositeKey compositeKey, String keyfileOrProvider, OnFinish finish, bool updateLastUsageTimestamp, bool makeCurrent): base(activity, finish)
|
||||||
{
|
{
|
||||||
_app = app;
|
_app = app;
|
||||||
_ioc = ioc;
|
_ioc = ioc;
|
||||||
_databaseData = databaseData;
|
_databaseData = databaseData;
|
||||||
_compositeKey = compositeKey;
|
_compositeKey = compositeKey;
|
||||||
_keyfileOrProvider = keyfileOrProvider;
|
_keyfileOrProvider = keyfileOrProvider;
|
||||||
|
_updateLastUsageTimestamp = updateLastUsageTimestamp;
|
||||||
|
_makeCurrent = makeCurrent;
|
||||||
|
|
||||||
|
|
||||||
_rememberKeyfile = app.GetBooleanPreference(PreferenceKey.remember_keyfile);
|
_rememberKeyfile = app.GetBooleanPreference(PreferenceKey.remember_keyfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected bool success = false;
|
protected bool success = false;
|
||||||
|
private bool _updateLastUsageTimestamp;
|
||||||
public override void Run()
|
private readonly bool _makeCurrent;
|
||||||
|
|
||||||
|
public override void Run()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -144,13 +148,9 @@ namespace keepass2android
|
|||||||
//now let's go:
|
//now let's go:
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Database newDb = _app.LoadDatabase(_ioc, workingCopy, _compositeKey, StatusLogger, _format);
|
Database newDb = _app.LoadDatabase(_ioc, workingCopy, _compositeKey, StatusLogger, _format, _makeCurrent);
|
||||||
Kp2aLog.Log("LoadDB OK");
|
Kp2aLog.Log("LoadDB OK");
|
||||||
|
|
||||||
//make sure the stored access time for the actual file is more recent than that of its backup
|
|
||||||
Thread.Sleep(10);
|
|
||||||
SaveFileData(_ioc, _keyfileOrProvider);
|
|
||||||
|
|
||||||
Finish(true, _format.SuccessMessage);
|
Finish(true, _format.SuccessMessage);
|
||||||
return newDb;
|
return newDb;
|
||||||
}
|
}
|
||||||
@@ -182,7 +182,7 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
keyfileOrProvider = "";
|
keyfileOrProvider = "";
|
||||||
}
|
}
|
||||||
_app.StoreOpenedFileAsRecent(ioc, keyfileOrProvider);
|
_app.StoreOpenedFileAsRecent(ioc, keyfileOrProvider, _updateLastUsageTimestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -110,11 +110,19 @@ namespace keepass2android
|
|||||||
if (!KeeAutoExecExt.TryGetDatabaseIoc(autoExecItem, out ioc))
|
if (!KeeAutoExecExt.TryGetDatabaseIoc(autoExecItem, out ioc))
|
||||||
ioc = IOConnectionInfo.FromPath(entry.Strings.ReadSafe(PwDefs.UrlField));
|
ioc = IOConnectionInfo.FromPath(entry.Strings.ReadSafe(PwDefs.UrlField));
|
||||||
string path = ioc.Path;
|
string path = ioc.Path;
|
||||||
var filestorage = App.Kp2a.GetFileStorage(ioc);
|
try
|
||||||
if (filestorage != null)
|
|
||||||
{
|
{
|
||||||
path = filestorage.IocToPath(ioc);
|
var filestorage = App.Kp2a.GetFileStorage(ioc);
|
||||||
|
if (filestorage != null)
|
||||||
|
{
|
||||||
|
path = filestorage.IocToPath(ioc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
catch (NoFileStorageFoundException)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
entry.Strings.Set(strUiDatabaseFile, new ProtectedString(false, path));
|
entry.Strings.Set(strUiDatabaseFile, new ProtectedString(false, path));
|
||||||
entry.Strings.Set(strUiKeyFile,new ProtectedString(false,entry.Strings.ReadSafe(PwDefs.UserNameField)));
|
entry.Strings.Set(strUiKeyFile,new ProtectedString(false,entry.Strings.ReadSafe(PwDefs.UserNameField)));
|
||||||
|
|||||||
@@ -20,7 +20,10 @@ using Android.Widget;
|
|||||||
using keepass2android.database.edit;
|
using keepass2android.database.edit;
|
||||||
using KeePass.Util.Spr;
|
using KeePass.Util.Spr;
|
||||||
using KeePassLib;
|
using KeePassLib;
|
||||||
|
using KeePassLib.Keys;
|
||||||
using KeePassLib.Security;
|
using KeePassLib.Security;
|
||||||
|
using KeePassLib.Serialization;
|
||||||
|
using AlertDialog = Android.App.AlertDialog;
|
||||||
using Object = Java.Lang.Object;
|
using Object = Java.Lang.Object;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
@@ -92,6 +95,13 @@ namespace keepass2android
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
view.FindViewById<Button>(Resource.Id.child_db_open).Click += (sender, args) =>
|
||||||
|
{
|
||||||
|
View sending_view = (View)sender;
|
||||||
|
_context.OnOpen(_displayedChildDatabases[GetClickedPos(sending_view)]);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
view.FindViewById<Button>(Resource.Id.child_db_enable_a_copy_for_this_device).Click += (sender, args) =>
|
view.FindViewById<Button>(Resource.Id.child_db_enable_a_copy_for_this_device).Click += (sender, args) =>
|
||||||
{
|
{
|
||||||
View sending_view = (View)sender;
|
View sending_view = (View)sender;
|
||||||
@@ -144,6 +154,12 @@ namespace keepass2android
|
|||||||
view.FindViewById(Resource.Id.child_db_disable_on_this_device).Visibility = (deviceEnabled || !deviceEnabledExplict) && autoExecItem.Enabled ? ViewStates.Visible : ViewStates.Gone;
|
view.FindViewById(Resource.Id.child_db_disable_on_this_device).Visibility = (deviceEnabled || !deviceEnabledExplict) && autoExecItem.Enabled ? ViewStates.Visible : ViewStates.Gone;
|
||||||
view.FindViewById(Resource.Id.child_db_enable_a_copy_for_this_device_container).Visibility = !deviceEnabled && autoExecItem.Enabled ? ViewStates.Visible : ViewStates.Gone;
|
view.FindViewById(Resource.Id.child_db_enable_a_copy_for_this_device_container).Visibility = !deviceEnabled && autoExecItem.Enabled ? ViewStates.Visible : ViewStates.Gone;
|
||||||
view.FindViewById(Resource.Id.child_db_edit).Visibility = deviceEnabledExplict || !autoExecItem.Enabled ? ViewStates.Visible : ViewStates.Gone;
|
view.FindViewById(Resource.Id.child_db_edit).Visibility = deviceEnabledExplict || !autoExecItem.Enabled ? ViewStates.Visible : ViewStates.Gone;
|
||||||
|
IOConnectionInfo ioc;
|
||||||
|
if ((KeeAutoExecExt.TryGetDatabaseIoc(autoExecItem, out ioc)) && App.Kp2a.TryGetDatabase(ioc) == null)
|
||||||
|
{
|
||||||
|
view.FindViewById(Resource.Id.child_db_open).Visibility = ViewStates.Visible;
|
||||||
|
}
|
||||||
|
else view.FindViewById(Resource.Id.child_db_open).Visibility = ViewStates.Gone;
|
||||||
|
|
||||||
|
|
||||||
Database db = App.Kp2a.FindDatabaseForElement(pw);
|
Database db = App.Kp2a.FindDatabaseForElement(pw);
|
||||||
@@ -181,13 +197,21 @@ namespace keepass2android
|
|||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
{
|
{
|
||||||
_displayedChildDatabases = App.Kp2a.OpenDatabases.SelectMany(db => KeeAutoExecExt.GetAutoExecItems(db.KpDatabase)
|
|
||||||
|
_displayedChildDatabases = KeeAutoExecExt.GetAutoExecItems(App.Kp2a.CurrentDb.KpDatabase)
|
||||||
|
.Where(e => App.Kp2a.TryFindDatabaseForElement(e.Entry) != null) //Update() can be called while we're adding entries to the database. They may be part of the group but without saving complete
|
||||||
.OrderBy(e => SprEngine.Compile(e.Entry.Strings.ReadSafe(PwDefs.TitleField),new SprContext(e.Entry, App.Kp2a.FindDatabaseForElement(e.Entry).KpDatabase, SprCompileFlags.All)))
|
.OrderBy(e => SprEngine.Compile(e.Entry.Strings.ReadSafe(PwDefs.TitleField),new SprContext(e.Entry, App.Kp2a.FindDatabaseForElement(e.Entry).KpDatabase, SprCompileFlags.All)))
|
||||||
.ThenByDescending(e => e.Entry.LastModificationTime))
|
.ThenByDescending(e => e.Entry.LastModificationTime)
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnOpen(AutoExecItem item)
|
||||||
|
{
|
||||||
|
KeeAutoExecExt.AutoOpenEntry(this, item, true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private void OnEnableCopy(AutoExecItem item)
|
private void OnEnableCopy(AutoExecItem item)
|
||||||
{
|
{
|
||||||
//disable this device for the cloned entry
|
//disable this device for the cloned entry
|
||||||
@@ -219,7 +243,6 @@ namespace keepass2android
|
|||||||
|
|
||||||
private void OnEdit(AutoExecItem item)
|
private void OnEdit(AutoExecItem item)
|
||||||
{
|
{
|
||||||
App.Kp2a.CurrentDb = App.Kp2a.FindDatabaseForElement(item.Entry);
|
|
||||||
EntryEditActivity.Launch(this,item.Entry,new NullTask());
|
EntryEditActivity.Launch(this,item.Entry,new NullTask());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,6 +286,151 @@ namespace keepass2android
|
|||||||
listView.Adapter = _adapter;
|
listView.Adapter = _adapter;
|
||||||
|
|
||||||
SetSupportActionBar(FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.mytoolbar));
|
SetSupportActionBar(FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.mytoolbar));
|
||||||
|
|
||||||
|
FindViewById<Button>(Resource.Id.add_child_db_button).Click += (sender, args) =>
|
||||||
|
{
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
|
builder.SetTitle(Resource.String.add_child_db);
|
||||||
|
|
||||||
|
List<string> items = new List<string>();
|
||||||
|
Dictionary<int, Database> indexToDb = new Dictionary<int, Database>();
|
||||||
|
|
||||||
|
foreach (var db in App.Kp2a.OpenDatabases)
|
||||||
|
{
|
||||||
|
if (db != App.Kp2a.CurrentDb)
|
||||||
|
{
|
||||||
|
indexToDb[items.Count] = db;
|
||||||
|
items.Add(App.Kp2a.GetFileStorage(db.Ioc).GetDisplayName(db.Ioc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
indexToDb[items.Count] = null;
|
||||||
|
items.Add(GetString(Resource.String.open_other_db));
|
||||||
|
|
||||||
|
builder.SetItems(items.ToArray(), (o, eventArgs) =>
|
||||||
|
{
|
||||||
|
Database db;
|
||||||
|
if (!indexToDb.TryGetValue(eventArgs.Which, out db) || (db == null))
|
||||||
|
{
|
||||||
|
StartFileSelect();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddAutoOpenEntryForDatabase(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AlertDialog dialog = builder.Create();
|
||||||
|
dialog.Show();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void AddAutoOpenEntryForDatabase(Database db)
|
||||||
|
{
|
||||||
|
PwGroup autoOpenGroup = null;
|
||||||
|
var rootGroup = App.Kp2a.CurrentDb.KpDatabase.RootGroup;
|
||||||
|
foreach (PwGroup pgSub in rootGroup.Groups)
|
||||||
|
{
|
||||||
|
if (pgSub.Name == "AutoOpen")
|
||||||
|
{
|
||||||
|
autoOpenGroup = pgSub;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (autoOpenGroup == null)
|
||||||
|
{
|
||||||
|
AddGroup addGroupTask = AddGroup.GetInstance(this, App.Kp2a, "AutoOpen", 1, null, rootGroup, null, true);
|
||||||
|
addGroupTask.Run();
|
||||||
|
autoOpenGroup = addGroupTask.Group;
|
||||||
|
}
|
||||||
|
|
||||||
|
PwEntry newEntry = new PwEntry(true, true);
|
||||||
|
newEntry.Strings.Set(PwDefs.TitleField, new ProtectedString(false, App.Kp2a.GetFileStorage(db.Ioc).GetDisplayName(db.Ioc)));
|
||||||
|
newEntry.Strings.Set(PwDefs.UrlField, new ProtectedString(false, TryMakeRelativePath(App.Kp2a.CurrentDb, db.Ioc)));
|
||||||
|
var password = db.KpDatabase.MasterKey.GetUserKey<KcpPassword>();
|
||||||
|
newEntry.Strings.Set(PwDefs.PasswordField, password == null ? new ProtectedString(true, "") : password.Password);
|
||||||
|
|
||||||
|
var keyfile = db.KpDatabase.MasterKey.GetUserKey<KcpKeyFile>();
|
||||||
|
if ((keyfile != null) && (keyfile.Ioc != null))
|
||||||
|
{
|
||||||
|
newEntry.Strings.Set(PwDefs.UserNameField, new ProtectedString(false, TryMakeRelativePath(App.Kp2a.CurrentDb, keyfile.Ioc)));
|
||||||
|
}
|
||||||
|
|
||||||
|
newEntry.Strings.Set(KeeAutoExecExt._ifDevice,
|
||||||
|
new ProtectedString(false,
|
||||||
|
KeeAutoExecExt.BuildIfDevice(new Dictionary<string, bool>()
|
||||||
|
{
|
||||||
|
{KeeAutoExecExt.ThisDeviceId, true}
|
||||||
|
})));
|
||||||
|
|
||||||
|
var addTask = new AddEntry(this, App.Kp2a, newEntry, autoOpenGroup, new ActionOnFinish(this, (success, message, activity) => (activity as ConfigureChildDatabasesActivity)?.Update()));
|
||||||
|
|
||||||
|
ProgressTask pt = new ProgressTask(App.Kp2a, this, addTask);
|
||||||
|
pt.Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
private string TryMakeRelativePath(Database db, IOConnectionInfo ioc)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var fsDb = App.Kp2a.GetFileStorage(db.Ioc);
|
||||||
|
var dbParent = fsDb.GetParentPath(db.Ioc).Path + "/";
|
||||||
|
if (ioc.Path.StartsWith(dbParent))
|
||||||
|
{
|
||||||
|
return "{DB_DIR}{ENV_DIRSEP}" + ioc.Path.Substring(dbParent.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (NoFileStorageFoundException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return ioc.Path;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StartFileSelect(bool noForwardToPassword = false)
|
||||||
|
{
|
||||||
|
Intent intent = new Intent(this, typeof(FileSelectActivity));
|
||||||
|
intent.PutExtra(FileSelectActivity.NoForwardToPasswordActivity, noForwardToPassword);
|
||||||
|
intent.PutExtra("MakeCurrent", false);
|
||||||
|
StartActivityForResult(intent, ReqCodeOpenNewDb);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
|
||||||
|
{
|
||||||
|
base.OnActivityResult(requestCode, resultCode, data);
|
||||||
|
|
||||||
|
if (requestCode == ReqCodeOpenNewDb)
|
||||||
|
{
|
||||||
|
switch ((int)resultCode)
|
||||||
|
{
|
||||||
|
case (int)Result.Ok:
|
||||||
|
|
||||||
|
string iocString = data?.GetStringExtra("ioc");
|
||||||
|
IOConnectionInfo ioc = IOConnectionInfo.UnserializeFromString(iocString);
|
||||||
|
var db = App.Kp2a.TryGetDatabase(ioc);
|
||||||
|
if (db != null)
|
||||||
|
AddAutoOpenEntryForDatabase(db);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case PasswordActivity.ResultSelectOtherFile:
|
||||||
|
StartFileSelect(true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public const int ReqCodeOpenNewDb = 1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -128,7 +128,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
FindViewById(Resource.Id.btn_create).Click += (sender, evt) =>
|
FindViewById(Resource.Id.btn_create).Click += (sender, evt) =>
|
||||||
{
|
{
|
||||||
CreateDatabase();
|
CreateDatabase(Intent.GetBooleanExtra("MakeCurrent",true));
|
||||||
};
|
};
|
||||||
|
|
||||||
ImageButton btnTogglePassword = (ImageButton)FindViewById(Resource.Id.toggle_password);
|
ImageButton btnTogglePassword = (ImageButton)FindViewById(Resource.Id.toggle_password);
|
||||||
@@ -164,7 +164,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateDatabase()
|
private void CreateDatabase(bool makeCurrent)
|
||||||
{
|
{
|
||||||
var keyfileCheckbox = FindViewById<CheckBox>(Resource.Id.use_keyfile);
|
var keyfileCheckbox = FindViewById<CheckBox>(Resource.Id.use_keyfile);
|
||||||
string password;
|
string password;
|
||||||
@@ -204,7 +204,7 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the new database
|
// Create the new database
|
||||||
CreateDb create = new CreateDb(App.Kp2a, this, _ioc, new LaunchGroupActivity(_ioc, this), false, newKey);
|
CreateDb create = new CreateDb(App.Kp2a, this, _ioc, new LaunchGroupActivity(_ioc, this), false, newKey, makeCurrent);
|
||||||
ProgressTask createTask = new ProgressTask(
|
ProgressTask createTask = new ProgressTask(
|
||||||
App.Kp2a,
|
App.Kp2a,
|
||||||
this, create);
|
this, create);
|
||||||
@@ -416,9 +416,7 @@ namespace keepass2android
|
|||||||
// Add to recent files
|
// Add to recent files
|
||||||
FileDbHelper dbHelper = App.Kp2a.FileDbHelper;
|
FileDbHelper dbHelper = App.Kp2a.FileDbHelper;
|
||||||
|
|
||||||
|
dbHelper.CreateFile(_ioc, Filename, true);
|
||||||
//TODO: getFilename always returns "" -> bug?
|
|
||||||
dbHelper.CreateFile(_ioc, Filename);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Intent data = new Intent();
|
Intent data = new Intent();
|
||||||
@@ -446,7 +444,7 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override bool OnOptionsItemSelected(IMenuItem item)
|
public override bool OnOptionsItemSelected(IMenuItem item)
|
||||||
{
|
{
|
||||||
switch (item.ItemId)
|
switch (item.ItemId)
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Provider;
|
using Android.Provider;
|
||||||
using Android.Webkit;
|
using Android.Webkit;
|
||||||
|
using Android.Widget;
|
||||||
using Java.Nio.FileNio;
|
using Java.Nio.FileNio;
|
||||||
using KeePass.DataExchange;
|
using KeePass.DataExchange;
|
||||||
using KeePass.Util.Spr;
|
using KeePass.Util.Spr;
|
||||||
@@ -260,36 +262,20 @@ namespace keepass2android
|
|||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnFileOpen(PwDatabase db)
|
public static bool AutoOpenEntry(Activity activity, AutoExecItem item, bool bManual)
|
||||||
{
|
|
||||||
List<AutoExecItem> l = GetAutoExecItems(db);
|
|
||||||
foreach (AutoExecItem a in l)
|
|
||||||
{
|
|
||||||
if (!a.Enabled) continue;
|
|
||||||
|
|
||||||
try { AutoOpenEntryPriv(a, false); }
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
MessageService.ShowWarning(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AutoOpenEntryPriv(AutoExecItem a, bool bManual)
|
|
||||||
{
|
{
|
||||||
string str;
|
string str;
|
||||||
PwEntry pe = a.Entry;
|
PwEntry pe = item.Entry;
|
||||||
SprContext ctxNoEsc = new SprContext(pe, a.Database, SprCompileFlags.All);
|
SprContext ctxNoEsc = new SprContext(pe, item.Database, SprCompileFlags.All);
|
||||||
IOConnectionInfo ioc;
|
IOConnectionInfo ioc;
|
||||||
if (!TryGetDatabaseIoc(a, out ioc)) return;
|
if (!TryGetDatabaseIoc(item, out ioc)) return false;
|
||||||
|
|
||||||
var ob = GetBoolEx(pe, "SkipIfNotExists", ctxNoEsc);
|
var ob = GetBoolEx(pe, "SkipIfNotExists", ctxNoEsc);
|
||||||
if (!ob.HasValue) // Backw. compat.
|
if (!ob.HasValue) // Backw. compat.
|
||||||
ob = GetBoolEx(pe, "Skip if not exists", ctxNoEsc);
|
ob = GetBoolEx(pe, "Skip if not exists", ctxNoEsc);
|
||||||
if (ob.HasValue && ob.Value)
|
if (ob.HasValue && ob.Value)
|
||||||
{
|
{
|
||||||
//TODO adjust to KP2A
|
if (!CheckFileExsts(ioc)) return false;
|
||||||
if (!IOConnection.FileExists(ioc)) return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CompositeKey ck = new CompositeKey();
|
CompositeKey ck = new CompositeKey();
|
||||||
@@ -303,8 +289,8 @@ namespace keepass2android
|
|||||||
IOConnectionInfo iocKey = IOConnectionInfo.FromPath(strAbs);
|
IOConnectionInfo iocKey = IOConnectionInfo.FromPath(strAbs);
|
||||||
if (iocKey.IsLocalFile() && !UrlUtil.IsAbsolutePath(strAbs))
|
if (iocKey.IsLocalFile() && !UrlUtil.IsAbsolutePath(strAbs))
|
||||||
{
|
{
|
||||||
//TODO
|
//local relative paths not supported on Android
|
||||||
/* strAbs = UrlUtil.MakeAbsolutePath(WinUtil.GetExecutable(), strAbs);*/
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -312,16 +298,14 @@ namespace keepass2android
|
|||||||
if (ob.HasValue && ob.Value)
|
if (ob.HasValue && ob.Value)
|
||||||
{
|
{
|
||||||
IOConnectionInfo iocKeyAbs = IOConnectionInfo.FromPath(strAbs);
|
IOConnectionInfo iocKeyAbs = IOConnectionInfo.FromPath(strAbs);
|
||||||
//TODO adjust to KP2A
|
if (!CheckFileExsts(iocKeyAbs)) return false;
|
||||||
if (!IOConnection.FileExists(iocKeyAbs)) return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try { ck.AddUserKey(new KcpKeyFile(strAbs)); }
|
try { ck.AddUserKey(new KcpKeyFile(strAbs)); }
|
||||||
catch (InvalidOperationException)
|
catch (InvalidOperationException)
|
||||||
{
|
{
|
||||||
//TODO
|
Toast.MakeText(Application.Context,Resource.String.error_adding_keyfile,ToastLength.Long).Show();
|
||||||
throw new Exception("TODO");
|
return false;
|
||||||
//throw new Exception(strAbs + MessageService.NewParagraph + KPRes.KeyFileError);
|
|
||||||
}
|
}
|
||||||
catch (Exception) { throw; }
|
catch (Exception) { throw; }
|
||||||
}
|
}
|
||||||
@@ -333,46 +317,32 @@ namespace keepass2android
|
|||||||
StrUtil.DataToDataUri(pBin.ReadData(), null))));
|
StrUtil.DataToDataUri(pBin.ReadData(), null))));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetString(pe, "KeyProvider", ctxNoEsc, true, out str))
|
|
||||||
{
|
|
||||||
/*TODO KeyProvider kp = m_host.KeyProviderPool.Get(str);
|
|
||||||
if (kp == null)
|
|
||||||
throw new Exception(@"Unknown key provider: '" + str + @"'!");
|
|
||||||
|
|
||||||
KeyProviderQueryContext ctxKP = new KeyProviderQueryContext(
|
|
||||||
ioc, false, false);
|
|
||||||
|
|
||||||
bool bPerformHash = !kp.DirectKey;
|
|
||||||
byte[] pbProvKey = kp.GetKey(ctxKP);
|
|
||||||
if ((pbProvKey != null) && (pbProvKey.Length != 0))
|
|
||||||
{
|
|
||||||
ck.AddUserKey(new KcpCustomKey(str, pbProvKey, bPerformHash));
|
|
||||||
MemUtil.ZeroByteArray(pbProvKey);
|
|
||||||
}
|
|
||||||
else return; // Provider has shown error message*/
|
|
||||||
throw new Exception("KeyProvider not supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
ob = GetBoolEx(pe, "UserAccount", ctxNoEsc);
|
|
||||||
if (ob.HasValue && ob.Value)
|
|
||||||
ck.AddUserKey(new KcpUserAccount());
|
|
||||||
|
|
||||||
if (ck.UserKeyCount == 0) return;
|
|
||||||
|
|
||||||
GetString(pe, "Focus", ctxNoEsc, true, out str);
|
GetString(pe, "Focus", ctxNoEsc, true, out str);
|
||||||
bool bRestoreFocus = str.Equals("Restore", StrUtil.CaseIgnoreCmp);
|
bool bRestoreFocus = str.Equals("Restore", StrUtil.CaseIgnoreCmp);
|
||||||
/*TODO
|
|
||||||
* PwDatabase pdPrev = m_host.MainWindow.ActiveDatabase;
|
|
||||||
|
|
||||||
m_host.MainWindow.OpenDatabase(ioc, ck, true);
|
PasswordActivity.Launch(activity,ioc,ck,new ActivityLaunchModeSimple(), !
|
||||||
|
bRestoreFocus);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (bRestoreFocus && (pdPrev != null) && !bManual)
|
private static bool CheckFileExsts(IOConnectionInfo ioc)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
PwDocument docPrev = m_host.MainWindow.DocumentManager.FindDocument(
|
var fileStorage = App.Kp2a.GetFileStorage(ioc);
|
||||||
pdPrev);
|
using (var stream = fileStorage.OpenFileForRead(ioc))
|
||||||
if (docPrev != null) m_host.MainWindow.MakeDocumentActive(docPrev);
|
{
|
||||||
else { Debug.Assert(false); }
|
}
|
||||||
}*/
|
}
|
||||||
|
catch (NoFileStorageFoundException e)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool TryGetDatabaseIoc(AutoExecItem a, out IOConnectionInfo ioc)
|
public static bool TryGetDatabaseIoc(AutoExecItem a, out IOConnectionInfo ioc)
|
||||||
|
|||||||
@@ -160,18 +160,19 @@ namespace keepass2android
|
|||||||
static CompositeKey compositeKeyForImmediateLoad = null;
|
static CompositeKey compositeKeyForImmediateLoad = null;
|
||||||
|
|
||||||
|
|
||||||
public static void Launch(Activity act, IOConnectionInfo ioc, CompositeKey compositeKey, ActivityLaunchMode launchMode)
|
public static void Launch(Activity act, IOConnectionInfo ioc, CompositeKey compositeKey, ActivityLaunchMode launchMode, bool makeCurrent)
|
||||||
{
|
{
|
||||||
compositeKeyForImmediateLoad = compositeKey;
|
compositeKeyForImmediateLoad = compositeKey;
|
||||||
Launch(act, ioc, launchMode);
|
Launch(act, ioc, launchMode, makeCurrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void Launch(Activity act, IOConnectionInfo ioc, ActivityLaunchMode launchMode)
|
public static void Launch(Activity act, IOConnectionInfo ioc, ActivityLaunchMode launchMode, bool makeCurrent)
|
||||||
{
|
{
|
||||||
Intent i = new Intent(act, typeof(PasswordActivity));
|
Intent i = new Intent(act, typeof(PasswordActivity));
|
||||||
Util.PutIoConnectionToIntent(ioc, i);
|
Util.PutIoConnectionToIntent(ioc, i);
|
||||||
|
i.PutExtra("MakeCurrent", makeCurrent);
|
||||||
|
|
||||||
launchMode.Launch(act, i);
|
launchMode.Launch(act, i);
|
||||||
}
|
}
|
||||||
@@ -1385,8 +1386,8 @@ namespace keepass2android
|
|||||||
OnFinish onFinish = new AfterLoad(handler, this, _ioConnection);
|
OnFinish onFinish = new AfterLoad(handler, this, _ioConnection);
|
||||||
LoadDb task = (KeyProviderTypes.Contains(KeyProviders.Otp))
|
LoadDb task = (KeyProviderTypes.Contains(KeyProviders.Otp))
|
||||||
? new SaveOtpAuxFileAndLoadDb(App.Kp2a, _ioConnection, _loadDbFileTask, compositeKey, GetKeyProviderString(),
|
? new SaveOtpAuxFileAndLoadDb(App.Kp2a, _ioConnection, _loadDbFileTask, compositeKey, GetKeyProviderString(),
|
||||||
onFinish, this)
|
onFinish, this, true, Intent.GetBooleanExtra("MakeCurrent", true))
|
||||||
: new LoadDb(this, App.Kp2a, _ioConnection, _loadDbFileTask, compositeKey, GetKeyProviderString(), onFinish);
|
: new LoadDb(this, App.Kp2a, _ioConnection, _loadDbFileTask, compositeKey, GetKeyProviderString(), onFinish,true, Intent.GetBooleanExtra("MakeCurrent",true));
|
||||||
_loadDbFileTask = null; // prevent accidental re-use
|
_loadDbFileTask = null; // prevent accidental re-use
|
||||||
|
|
||||||
new ProgressTask(App.Kp2a, this, task).Run();
|
new ProgressTask(App.Kp2a, this, task).Run();
|
||||||
@@ -1734,7 +1735,7 @@ namespace keepass2android
|
|||||||
OnFinish onFinish = new AfterLoad(handler, this, _ioConnection);
|
OnFinish onFinish = new AfterLoad(handler, this, _ioConnection);
|
||||||
_performingLoad = true;
|
_performingLoad = true;
|
||||||
LoadDb task = new LoadDb(this, App.Kp2a, _ioConnection, _loadDbFileTask, compositeKeyForImmediateLoad, GetKeyProviderString(),
|
LoadDb task = new LoadDb(this, App.Kp2a, _ioConnection, _loadDbFileTask, compositeKeyForImmediateLoad, GetKeyProviderString(),
|
||||||
onFinish);
|
onFinish, false, Intent.GetBooleanExtra("MakeCurrent",false));
|
||||||
_loadDbFileTask = null; // prevent accidental re-use
|
_loadDbFileTask = null; // prevent accidental re-use
|
||||||
new ProgressTask(App.Kp2a, this, task).Run();
|
new ProgressTask(App.Kp2a, this, task).Run();
|
||||||
compositeKeyForImmediateLoad = null; //don't reuse or keep in memory
|
compositeKeyForImmediateLoad = null; //don't reuse or keep in memory
|
||||||
@@ -2053,7 +2054,7 @@ namespace keepass2android
|
|||||||
private readonly PasswordActivity _act;
|
private readonly PasswordActivity _act;
|
||||||
|
|
||||||
|
|
||||||
public SaveOtpAuxFileAndLoadDb(IKp2aApp app, IOConnectionInfo ioc, Task<MemoryStream> databaseData, CompositeKey compositeKey, string keyfileOrProvider, OnFinish finish, PasswordActivity act) : base(act, app, ioc, databaseData, compositeKey, keyfileOrProvider, finish)
|
public SaveOtpAuxFileAndLoadDb(IKp2aApp app, IOConnectionInfo ioc, Task<MemoryStream> databaseData, CompositeKey compositeKey, string keyfileOrProvider, OnFinish finish, PasswordActivity act, bool updateLastUsageTimestamp, bool makeCurrent) : base(act, app, ioc, databaseData, compositeKey, keyfileOrProvider, finish,updateLastUsageTimestamp,makeCurrent)
|
||||||
{
|
{
|
||||||
_act = act;
|
_act = act;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,6 +80,11 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/edit"/>
|
android:text="@string/edit"/>
|
||||||
|
<Button
|
||||||
|
android:id="@+id/child_db_open"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/menu_open"/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/child_db_enable_a_copy_for_this_device_container"
|
android:id="@+id/child_db_enable_a_copy_for_this_device_container"
|
||||||
|
|||||||
@@ -1,7 +1,39 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
<ListView
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
android:layout_width="fill_parent"
|
||||||
android:id="@android:id/list"
|
android:background="?activityBackgroundColor"
|
||||||
android:layout_width="fill_parent"
|
android:layout_height="fill_parent">
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:padding="8dp" />
|
<RelativeLayout
|
||||||
|
|
||||||
|
android:id="@+id/bottom_bar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:baselineAligned="false">
|
||||||
|
<Button
|
||||||
|
android:id="@+id/add_child_db_button"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:text="@string/add_child_db"
|
||||||
|
android:drawableLeft="@drawable/ic_plus"
|
||||||
|
style="@style/BottomBarButton" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<ListView
|
||||||
|
android:id="@android:id/list"
|
||||||
|
android:padding="8dp"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_above="@id/bottom_bar"
|
||||||
|
android:layout_marginBottom="12dip"
|
||||||
|
android:layout_marginLeft="12dip"
|
||||||
|
android:layout_marginRight="12dip"
|
||||||
|
android:layout_marginTop="12dip"
|
||||||
|
android:layout_alignParentTop="true" />
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -744,6 +744,7 @@
|
|||||||
<string name="child_db_enable_on_this_device">Enable on this device</string>
|
<string name="child_db_enable_on_this_device">Enable on this device</string>
|
||||||
<string name="child_db_disable_on_this_device">Disable on this device</string>
|
<string name="child_db_disable_on_this_device">Disable on this device</string>
|
||||||
<string name="child_db_enable_a_copy_for_this_device">Copy for this device</string>
|
<string name="child_db_enable_a_copy_for_this_device">Copy for this device</string>
|
||||||
|
<string name="add_child_db">Add child database...</string>
|
||||||
<string name="EnableCopyForThisDevice_Info">This will create and enable a copy of the child database settings. These copied settings can then be adjusted specifically for this device.</string>
|
<string name="EnableCopyForThisDevice_Info">This will create and enable a copy of the child database settings. These copied settings can then be adjusted specifically for this device.</string>
|
||||||
|
|
||||||
<string name="Visible_title">Visible</string>
|
<string name="Visible_title">Visible</string>
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
private void OnOpenOther()
|
private void OnOpenOther()
|
||||||
{
|
{
|
||||||
StartFileSelect(true);
|
StartFileSelect(true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnItemSelected(Database selectedDatabase)
|
private void OnItemSelected(Database selectedDatabase)
|
||||||
@@ -267,7 +267,7 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
if (App.Kp2a.OpenDatabases.Any() == false)
|
if (App.Kp2a.OpenDatabases.Any() == false)
|
||||||
{
|
{
|
||||||
StartFileSelect();
|
StartFileSelect(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,6 +281,13 @@ namespace keepass2android
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//see if there are any AutoOpen items to open
|
||||||
|
|
||||||
|
foreach (var db in App.Kp2a.OpenDatabases)
|
||||||
|
{
|
||||||
|
if (OpenAutoExecEntries(db)) return;
|
||||||
|
}
|
||||||
|
|
||||||
//database(s) unlocked
|
//database(s) unlocked
|
||||||
if (App.Kp2a.OpenDatabases.Count() == 1)
|
if (App.Kp2a.OpenDatabases.Count() == 1)
|
||||||
{
|
{
|
||||||
@@ -293,28 +300,55 @@ namespace keepass2android
|
|||||||
_adapter.Update();
|
_adapter.Update();
|
||||||
_adapter.NotifyDataSetChanged();
|
_adapter.NotifyDataSetChanged();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
base.OnResume();
|
base.OnResume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool OpenAutoExecEntries(Database db)
|
||||||
|
{
|
||||||
|
string thisDevice = KeeAutoExecExt.ThisDeviceId;
|
||||||
|
foreach (var autoOpenItem in KeeAutoExecExt.GetAutoExecItems(db.KpDatabase))
|
||||||
|
{
|
||||||
|
if (!autoOpenItem.Enabled)
|
||||||
|
continue;
|
||||||
|
if (!KeeAutoExecExt.IsDeviceEnabled(autoOpenItem, thisDevice, out _))
|
||||||
|
continue;
|
||||||
|
IOConnectionInfo dbIoc;
|
||||||
|
if (KeeAutoExecExt.TryGetDatabaseIoc(autoOpenItem, out dbIoc) &&
|
||||||
|
App.Kp2a.TryGetDatabase(dbIoc) == null &&
|
||||||
|
App.Kp2a.AttemptedToOpenBefore(dbIoc) == false
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (KeeAutoExecExt.AutoOpenEntry(this, autoOpenItem, false))
|
||||||
|
{
|
||||||
|
LaunchingOther = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnPause()
|
protected override void OnPause()
|
||||||
{
|
{
|
||||||
LaunchingOther = false;
|
LaunchingOther = false;
|
||||||
base.OnPause();
|
base.OnPause();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StartFileSelect(bool noForwardToPassword = false)
|
private void StartFileSelect(bool makeCurrent, bool noForwardToPassword = false)
|
||||||
{
|
{
|
||||||
Intent intent = new Intent(this, typeof(FileSelectActivity));
|
Intent intent = new Intent(this, typeof(FileSelectActivity));
|
||||||
AppTask.ToIntent(intent);
|
AppTask.ToIntent(intent);
|
||||||
intent.PutExtra(FileSelectActivity.NoForwardToPasswordActivity, noForwardToPassword);
|
intent.PutExtra(FileSelectActivity.NoForwardToPasswordActivity, noForwardToPassword);
|
||||||
|
intent.PutExtra("MakeCurrent", makeCurrent);
|
||||||
LaunchingOther = true;
|
LaunchingOther = true;
|
||||||
StartActivityForResult(intent, ReqCodeOpenNewDb);
|
StartActivityForResult(intent, ReqCodeOpenNewDb);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal AppTask AppTask;
|
internal AppTask AppTask;
|
||||||
private bool _loadAnotherDatabase;
|
|
||||||
private OpenDatabaseAdapter _adapter;
|
private OpenDatabaseAdapter _adapter;
|
||||||
private MyBroadcastReceiver _intentReceiver;
|
private MyBroadcastReceiver _intentReceiver;
|
||||||
|
|
||||||
@@ -350,6 +384,7 @@ namespace keepass2android
|
|||||||
IOConnectionInfo ioc = IOConnectionInfo.UnserializeFromString(iocString);
|
IOConnectionInfo ioc = IOConnectionInfo.UnserializeFromString(iocString);
|
||||||
if (App.Kp2a.TrySelectCurrentDb(ioc))
|
if (App.Kp2a.TrySelectCurrentDb(ioc))
|
||||||
{
|
{
|
||||||
|
if (OpenAutoExecEntries(App.Kp2a.CurrentDb)) return;
|
||||||
LaunchingOther = true;
|
LaunchingOther = true;
|
||||||
AppTask.CanActivateSearchViewOnStart = true;
|
AppTask.CanActivateSearchViewOnStart = true;
|
||||||
AppTask.LaunchFirstGroupActivity(this);
|
AppTask.LaunchFirstGroupActivity(this);
|
||||||
@@ -358,7 +393,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case PasswordActivity.ResultSelectOtherFile:
|
case PasswordActivity.ResultSelectOtherFile:
|
||||||
StartFileSelect(true);
|
StartFileSelect(true, true);
|
||||||
break;
|
break;
|
||||||
case (int)Result.Canceled:
|
case (int)Result.Canceled:
|
||||||
if (App.Kp2a.OpenDatabases.Any() == false)
|
if (App.Kp2a.OpenDatabases.Any() == false)
|
||||||
@@ -410,7 +445,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case KeePass.ExitLoadAnotherDb:
|
case KeePass.ExitLoadAnotherDb:
|
||||||
StartFileSelect(true);
|
StartFileSelect(true, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -419,7 +454,7 @@ namespace keepass2android
|
|||||||
private void LaunchPasswordActivityForReload(IOConnectionInfo ioc, CompositeKey compositeKey)
|
private void LaunchPasswordActivityForReload(IOConnectionInfo ioc, CompositeKey compositeKey)
|
||||||
{
|
{
|
||||||
LaunchingOther = true;
|
LaunchingOther = true;
|
||||||
PasswordActivity.Launch(this, ioc, compositeKey, new ActivityLaunchModeRequestCode(ReqCodeOpenNewDb));
|
PasswordActivity.Launch(this, ioc, compositeKey, new ActivityLaunchModeRequestCode(ReqCodeOpenNewDb), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool LaunchingOther { get; set; }
|
public bool LaunchingOther { get; set; }
|
||||||
|
|||||||
@@ -129,6 +129,7 @@ namespace keepass2android
|
|||||||
BroadcastDatabaseAction(Application.Context, Strings.ActionCloseDatabase);
|
BroadcastDatabaseAction(Application.Context, Strings.ActionCloseDatabase);
|
||||||
|
|
||||||
// Couldn't quick-lock, so unload database(s) instead
|
// Couldn't quick-lock, so unload database(s) instead
|
||||||
|
_openAttempts.Clear();
|
||||||
_openDatabases.Clear();
|
_openDatabases.Clear();
|
||||||
_currentDatabase = null;
|
_currentDatabase = null;
|
||||||
LastOpenedEntry = null;
|
LastOpenedEntry = null;
|
||||||
@@ -164,7 +165,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Database LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, CompositeKey compositeKey, ProgressDialogStatusLogger statusLogger, IDatabaseFormat databaseFormat)
|
public Database LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, CompositeKey compositeKey, ProgressDialogStatusLogger statusLogger, IDatabaseFormat databaseFormat, bool makeCurrent)
|
||||||
{
|
{
|
||||||
var prefs = PreferenceManager.GetDefaultSharedPreferences(Application.Context);
|
var prefs = PreferenceManager.GetDefaultSharedPreferences(Application.Context);
|
||||||
var createBackup = prefs.GetBoolean(Application.Context.GetString(Resource.String.CreateBackups_key), true)
|
var createBackup = prefs.GetBoolean(Application.Context.GetString(Resource.String.CreateBackups_key), true)
|
||||||
@@ -190,12 +191,14 @@ namespace keepass2android
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_openAttempts.Add(ioConnectionInfo);
|
||||||
var newDb = new Database(new DrawableFactory(), this);
|
var newDb = new Database(new DrawableFactory(), this);
|
||||||
newDb.LoadData(this, ioConnectionInfo, memoryStream, compositeKey, statusLogger, databaseFormat);
|
newDb.LoadData(this, ioConnectionInfo, memoryStream, compositeKey, statusLogger, databaseFormat);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
_currentDatabase = newDb;
|
if ((_currentDatabase == null) || makeCurrent)
|
||||||
|
_currentDatabase = newDb;
|
||||||
_openDatabases.Add(newDb);
|
_openDatabases.Add(newDb);
|
||||||
|
|
||||||
|
|
||||||
@@ -228,8 +231,8 @@ namespace keepass2android
|
|||||||
Java.Lang.Object baseIocDisplayName = baseDisplayName;
|
Java.Lang.Object baseIocDisplayName = baseDisplayName;
|
||||||
|
|
||||||
string keyfile = App.Kp2a.FileDbHelper.GetKeyFileForFile(ioConnectionInfo.Path);
|
string keyfile = App.Kp2a.FileDbHelper.GetKeyFileForFile(ioConnectionInfo.Path);
|
||||||
App.Kp2a.StoreOpenedFileAsRecent(targetIoc, keyfile, Application.Context.
|
App.Kp2a.StoreOpenedFileAsRecent(targetIoc, keyfile, false, Application.Context.
|
||||||
GetString(Resource.String.LocalBackupOf, new Java.Lang.Object[]{baseIocDisplayName}));
|
GetString(Resource.String.LocalBackupOf, new Java.Lang.Object[]{baseIocDisplayName}));
|
||||||
|
|
||||||
prefs.Edit()
|
prefs.Edit()
|
||||||
.PutBoolean(IoUtil.GetIocPrefKey(ioConnectionInfo, "has_local_backup"), true)
|
.PutBoolean(IoUtil.GetIocPrefKey(ioConnectionInfo, "has_local_backup"), true)
|
||||||
@@ -341,6 +344,7 @@ namespace keepass2android
|
|||||||
public FileDbHelper FileDbHelper;
|
public FileDbHelper FileDbHelper;
|
||||||
private List<IFileStorage> _fileStorages;
|
private List<IFileStorage> _fileStorages;
|
||||||
|
|
||||||
|
private readonly List<IOConnectionInfo> _openAttempts = new List<IOConnectionInfo>(); //stores which files have been attempted to open. Used to avoid that we repeatedly try to load files which failed to load.
|
||||||
private readonly List<Database> _openDatabases = new List<Database>();
|
private readonly List<Database> _openDatabases = new List<Database>();
|
||||||
private Database _currentDatabase;
|
private Database _currentDatabase;
|
||||||
|
|
||||||
@@ -352,6 +356,16 @@ namespace keepass2android
|
|||||||
public readonly HashSet<PwGroup> dirty = new HashSet<PwGroup>(new PwGroupEqualityFromIdComparer());
|
public readonly HashSet<PwGroup> dirty = new HashSet<PwGroup>(new PwGroupEqualityFromIdComparer());
|
||||||
public HashSet<PwGroup> DirtyGroups { get { return dirty; } }
|
public HashSet<PwGroup> DirtyGroups { get { return dirty; } }
|
||||||
|
|
||||||
|
public bool AttemptedToOpenBefore(IOConnectionInfo ioc)
|
||||||
|
{
|
||||||
|
foreach (var attemptedIoc in _openAttempts)
|
||||||
|
{
|
||||||
|
if (attemptedIoc.IsSameFileAs(ioc))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void MarkAllGroupsAsDirty()
|
public void MarkAllGroupsAsDirty()
|
||||||
{
|
{
|
||||||
@@ -456,9 +470,9 @@ namespace keepass2android
|
|||||||
dialog.Show();
|
dialog.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StoreOpenedFileAsRecent(IOConnectionInfo ioc, string keyfile, string displayName = "")
|
public void StoreOpenedFileAsRecent(IOConnectionInfo ioc, string keyfile, bool updateTimestamp, string displayName = "")
|
||||||
{
|
{
|
||||||
FileDbHelper.CreateFile(ioc, keyfile, displayName);
|
FileDbHelper.CreateFile(ioc, keyfile, updateTimestamp, displayName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetResourceString(UiStringKey key)
|
public string GetResourceString(UiStringKey key)
|
||||||
@@ -841,11 +855,13 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Database CreateNewDatabase()
|
public Database CreateNewDatabase(bool makeCurrent)
|
||||||
{
|
{
|
||||||
_currentDatabase = new Database(new DrawableFactory(), this);
|
Database newDatabase = new Database(new DrawableFactory(), this);
|
||||||
_openDatabases.Add(_currentDatabase);
|
if ((_currentDatabase == null) || makeCurrent)
|
||||||
return _currentDatabase;
|
_currentDatabase = newDatabase;
|
||||||
|
_openDatabases.Add(newDatabase);
|
||||||
|
return newDatabase;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ShowToast(string message)
|
internal void ShowToast(string message)
|
||||||
@@ -989,14 +1005,22 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Database GetDatabase(IOConnectionInfo dbIoc)
|
public Database TryGetDatabase(IOConnectionInfo dbIoc)
|
||||||
{
|
{
|
||||||
foreach (Database db in OpenDatabases)
|
foreach (Database db in OpenDatabases)
|
||||||
{
|
{
|
||||||
if (db.Ioc.IsSameFileAs(dbIoc))
|
if (db.Ioc.IsSameFileAs(dbIoc))
|
||||||
return db;
|
return db;
|
||||||
}
|
}
|
||||||
throw new Exception("Database not found for dbIoc!");
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Database GetDatabase(IOConnectionInfo dbIoc)
|
||||||
|
{
|
||||||
|
Database result = TryGetDatabase(dbIoc);
|
||||||
|
if (result == null)
|
||||||
|
throw new Exception("Database not found for dbIoc!");
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Database GetDatabase(string databaseId)
|
public Database GetDatabase(string databaseId)
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ namespace keepass2android
|
|||||||
private const String FileTable = "files";
|
private const String FileTable = "files";
|
||||||
private const int DatabaseVersion = 2;
|
private const int DatabaseVersion = 2;
|
||||||
|
|
||||||
private const int MaxFiles = 15;
|
private const int MaxFiles = 1000;
|
||||||
|
|
||||||
public const String KeyFileId = "_id";
|
public const String KeyFileId = "_id";
|
||||||
public const String KeyFileFilename = "fileName";
|
public const String KeyFileFilename = "fileName";
|
||||||
@@ -101,7 +101,7 @@ namespace keepass2android
|
|||||||
mDb.Close();
|
mDb.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long CreateFile(IOConnectionInfo ioc, string keyFile, string displayName = "") {
|
public long CreateFile(IOConnectionInfo ioc, string keyFile, bool updateLastUsageTimestamp, string displayName = "") {
|
||||||
|
|
||||||
// Check to see if this filename is already used
|
// Check to see if this filename is already used
|
||||||
ICursor cursor;
|
ICursor cursor;
|
||||||
@@ -128,7 +128,8 @@ namespace keepass2android
|
|||||||
|
|
||||||
var vals = new ContentValues();
|
var vals = new ContentValues();
|
||||||
vals.Put(KeyFileKeyfile, keyFile);
|
vals.Put(KeyFileKeyfile, keyFile);
|
||||||
vals.Put(KeyFileUpdated, Java.Lang.JavaSystem.CurrentTimeMillis());
|
if (updateLastUsageTimestamp)
|
||||||
|
vals.Put(KeyFileUpdated, Java.Lang.JavaSystem.CurrentTimeMillis());
|
||||||
|
|
||||||
vals.Put(KeyFileUsername, iocToStore.UserName);
|
vals.Put(KeyFileUsername, iocToStore.UserName);
|
||||||
vals.Put(KeyFilePassword, iocToStore.Password);
|
vals.Put(KeyFilePassword, iocToStore.Password);
|
||||||
@@ -145,7 +146,7 @@ namespace keepass2android
|
|||||||
vals.Put(KeyFileUsername, iocToStore.UserName);
|
vals.Put(KeyFileUsername, iocToStore.UserName);
|
||||||
vals.Put(KeyFilePassword, iocToStore.Password);
|
vals.Put(KeyFilePassword, iocToStore.Password);
|
||||||
vals.Put(KeyFileCredsavemode, (int)iocToStore.CredSaveMode);
|
vals.Put(KeyFileCredsavemode, (int)iocToStore.CredSaveMode);
|
||||||
vals.Put(KeyFileUpdated, Java.Lang.JavaSystem.CurrentTimeMillis());
|
vals.Put(KeyFileUpdated, updateLastUsageTimestamp ? Java.Lang.JavaSystem.CurrentTimeMillis(): 0);
|
||||||
vals.Put(KeyFileDisplayname, displayName);
|
vals.Put(KeyFileDisplayname, displayName);
|
||||||
|
|
||||||
result = mDb.Insert(FileTable, null, vals);
|
result = mDb.Insert(FileTable, null, vals);
|
||||||
|
|||||||
@@ -301,7 +301,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
private void EditFileEntry(string filename, IOConnectionInfo newConnectionInfo)
|
private void EditFileEntry(string filename, IOConnectionInfo newConnectionInfo)
|
||||||
{
|
{
|
||||||
_dbHelper.CreateFile(newConnectionInfo, _dbHelper.GetKeyFileForFile(filename));
|
_dbHelper.CreateFile(newConnectionInfo, _dbHelper.GetKeyFileForFile(filename), false);
|
||||||
_dbHelper.DeleteFile(filename);
|
_dbHelper.DeleteFile(filename);
|
||||||
|
|
||||||
LaunchPasswordActivityForIoc(newConnectionInfo);
|
LaunchPasswordActivityForIoc(newConnectionInfo);
|
||||||
@@ -342,7 +342,7 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
PasswordActivity.Launch(this, ioc, new ActivityLaunchModeForward());
|
PasswordActivity.Launch(this, ioc, new ActivityLaunchModeForward(), Intent.GetBooleanExtra("MakeCurrent",true));
|
||||||
Finish();
|
Finish();
|
||||||
} catch (Java.IO.FileNotFoundException)
|
} catch (Java.IO.FileNotFoundException)
|
||||||
{
|
{
|
||||||
@@ -355,7 +355,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
private void AfterQueryCredentials(IOConnectionInfo ioc)
|
private void AfterQueryCredentials(IOConnectionInfo ioc)
|
||||||
{
|
{
|
||||||
PasswordActivity.Launch(this, ioc, new ActivityLaunchModeForward());
|
PasswordActivity.Launch(this, ioc, new ActivityLaunchModeForward(), Intent.GetBooleanExtra("MakeCurrent", true));
|
||||||
Finish();
|
Finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -437,14 +437,19 @@ namespace keepass2android
|
|||||||
//if no database is loaded: load the most recent database
|
//if no database is loaded: load the most recent database
|
||||||
if ( (Intent.GetBooleanExtra(NoForwardToPasswordActivity, false)==false) && _dbHelper.HasRecentFiles() && !App.Kp2a.OpenDatabases.Any())
|
if ( (Intent.GetBooleanExtra(NoForwardToPasswordActivity, false)==false) && _dbHelper.HasRecentFiles() && !App.Kp2a.OpenDatabases.Any())
|
||||||
{
|
{
|
||||||
ICursor filesCursor = _dbHelper.FetchAllFiles();
|
var fileStorage = new LocalFileStorage(App.Kp2a);
|
||||||
StartManagingCursor(filesCursor);
|
ICursor filesCursor = _dbHelper.FetchAllFiles();
|
||||||
filesCursor.MoveToFirst();
|
filesCursor = new FilteredCursor(filesCursor, cursor => !fileStorage.IsLocalBackup(IOConnectionInfo.FromPath(cursor.GetString(1))));
|
||||||
IOConnectionInfo ioc = _dbHelper.CursorToIoc(filesCursor);
|
StartManagingCursor(filesCursor);
|
||||||
if (App.Kp2a.GetFileStorage(ioc).RequiresSetup(ioc) == false)
|
if (filesCursor.Count > 0)
|
||||||
{
|
{
|
||||||
LaunchPasswordActivityForIoc(ioc);
|
filesCursor.MoveToFirst();
|
||||||
}
|
IOConnectionInfo ioc = _dbHelper.CursorToIoc(filesCursor);
|
||||||
|
if (App.Kp2a.GetFileStorage(ioc).RequiresSetup(ioc) == false)
|
||||||
|
{
|
||||||
|
LaunchPasswordActivityForIoc(ioc);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -876,7 +876,7 @@ namespace keepass2android
|
|||||||
var newIoc = IoUtil.ImportFileToInternalDirectory(sourceIoc, Activity, App.Kp2a);
|
var newIoc = IoUtil.ImportFileToInternalDirectory(sourceIoc, Activity, App.Kp2a);
|
||||||
((KcpKeyFile)masterKey.GetUserKey(typeof(KcpKeyFile))).ResetIoc(newIoc);
|
((KcpKeyFile)masterKey.GetUserKey(typeof(KcpKeyFile))).ResetIoc(newIoc);
|
||||||
var keyfileString = IOConnectionInfo.SerializeToString(newIoc);
|
var keyfileString = IOConnectionInfo.SerializeToString(newIoc);
|
||||||
App.Kp2a.StoreOpenedFileAsRecent(App.Kp2a.CurrentDb.Ioc, keyfileString);
|
App.Kp2a.StoreOpenedFileAsRecent(App.Kp2a.CurrentDb.Ioc, keyfileString, false);
|
||||||
return () =>
|
return () =>
|
||||||
{
|
{
|
||||||
UpdateImportKeyfilePref();
|
UpdateImportKeyfilePref();
|
||||||
@@ -952,7 +952,7 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
var key = App.Kp2a.CurrentDb.KpDatabase.MasterKey;
|
var key = App.Kp2a.CurrentDb.KpDatabase.MasterKey;
|
||||||
App.Kp2a.CloseDatabase(App.Kp2a.CurrentDb);
|
App.Kp2a.CloseDatabase(App.Kp2a.CurrentDb);
|
||||||
PasswordActivity.Launch(Activity, newIoc, key, new ActivityLaunchModeSimple());
|
PasswordActivity.Launch(Activity, newIoc, key, new ActivityLaunchModeSimple(), false);
|
||||||
|
|
||||||
});
|
});
|
||||||
builder.Show();
|
builder.Show();
|
||||||
|
|||||||
Reference in New Issue
Block a user