Splitted keepass2android project into

- keepass2android: UI stuff only
 - Kp2aBusinessLogic: Password-Database related algorithms (even though tied to android, no UI required here)

Removed dependencies of logic layer to static Application, Resource class or other UI stuff
Added MonoDroidUnitTesting (not yet used, will be used for testing logic layer)
This commit is contained in:
Philipp Crocoll
2013-06-14 06:14:50 +02:00
parent 9d8e10b236
commit 26575c4ba4
102 changed files with 5623 additions and 1184 deletions

View File

@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Content.Res;
using KeePassLib;
using Android.Graphics.Drawables;
namespace keepass2android
{
public interface IDrawableFactory
{
void assignDrawableTo (ImageView iv, Resources res, PwDatabase db, PwIcon icon, PwUuid customIconId);
Drawable getIconDrawable(Resources res, PwDatabase db, PwIcon icon, PwUuid customIconId);
void Clear();
}
}

View File

@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using KeePassLib.Serialization;
namespace keepass2android
{
public interface IKp2aApp
{
void SetShutdown();
Database GetDb();
void StoreOpenedFileAsRecent(IOConnectionInfo ioc, string keyfile);
Database CreateNewDatabase();
string GetResourceString(UiStringKey stringKey);
bool GetBooleanPreference(PreferenceKey key);
void AskYesNoCancel(UiStringKey titleKey, UiStringKey messageKey,
EventHandler<DialogClickEventArgs> yesHandler,
EventHandler<DialogClickEventArgs> noHandler,
EventHandler<DialogClickEventArgs> cancelHandler,
Context ctx);
}
}

View File

@@ -0,0 +1,71 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
namespace keepass2android
{
[Serializable]
public class KeyFileException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="T:KeyFileException"/> class
/// </summary>
public KeyFileException ()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="T:KeyFileException"/> class
/// </summary>
/// <param name="message">A <see cref="T:System.String"/> that describes the exception. </param>
public KeyFileException (string message) : base (message)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="T:KeyFileException"/> class
/// </summary>
/// <param name="message">A <see cref="T:System.String"/> that describes the exception. </param>
/// <param name="inner">The exception that is the cause of the current exception. </param>
public KeyFileException (string message, Exception inner) : base (message, inner)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="T:KeyFileException"/> class
/// </summary>
/// <param name="context">The contextual information about the source or destination.</param>
/// <param name="info">The object that holds the serialized object data.</param>
protected KeyFileException (System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base (info, context)
{
}
}
}

View File

@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}</ProjectGuid>
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>keepass2android</RootNamespace>
<AssemblyName>Kp2aBusinessLogic</AssemblyName>
<FileAlignment>512</FileAlignment>
<AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Mono.Android" />
<Reference Include="mscorlib" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="PreferenceKey.cs" />
<Compile Include="UiStringKey.cs" />
<Compile Include="database\Database.cs" />
<Compile Include="database\edit\ActionOnFinish.cs" />
<Compile Include="database\edit\AddEntry.cs" />
<Compile Include="database\edit\AddGroup.cs" />
<Compile Include="database\edit\CreateDB.cs" />
<Compile Include="database\edit\DeleteEntry.cs" />
<Compile Include="database\edit\DeleteGroup.cs" />
<Compile Include="database\edit\DeleteRunnable.cs" />
<Compile Include="database\edit\FileOnFinish.cs" />
<Compile Include="database\edit\LoadDB.cs" />
<Compile Include="database\edit\OnFinish.cs" />
<Compile Include="database\edit\RunnableOnFinish.cs" />
<Compile Include="database\edit\SaveDB.cs" />
<Compile Include="database\edit\SetPassword.cs" />
<Compile Include="database\edit\UpdateEntry.cs" />
<Compile Include="IKp2aApp.cs" />
<Compile Include="IDrawableFactory.cs" />
<Compile Include="KeyFileException.cs" />
<Compile Include="ProgressTask.cs" />
<Compile Include="PwGroupEqualityFromIdComparer.cs" />
<Compile Include="PwUuidEqualityComparer.cs" />
<Compile Include="Resources\Resource.Designer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SearchDbHelper.cs" />
<Compile Include="UpdateStatus.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\KeePassLib2Android\KeePassLib2Android.csproj">
<Project>{545b4a6b-8bba-4fbe-92fc-4ac060122a54}</Project>
<Name>KeePassLib2Android</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
namespace keepass2android
{
public enum PreferenceKey
{
remember_keyfile,
UseFileTransactions
}
}

View File

@@ -0,0 +1,88 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Java.Lang;
namespace keepass2android
{
public class ProgressTask {
private Context mCtx;
private Handler mHandler;
private RunnableOnFinish mTask;
private ProgressDialog mPd;
private IKp2aApp mApp;
public ProgressTask(IKp2aApp app, Context ctx, RunnableOnFinish task, UiStringKey messageKey) {
mTask = task;
mHandler = new Handler();
mApp = app;
// Show process dialog
mPd = new ProgressDialog(ctx);
mPd.SetTitle(mApp.GetResourceString(UiStringKey.progress_title));
mPd.SetMessage(mApp.GetResourceString(messageKey));
// Set code to run when this is finished
mTask.setStatus(new UpdateStatus(mApp, mHandler, mPd));
mTask.mFinish = new AfterTask(task.mFinish, mHandler, mPd);
}
public void run() {
// Show process dialog
mPd.Show();
// Start Thread to Run task
Thread t = new Thread(mTask.run);
t.Start();
}
private class AfterTask : OnFinish {
ProgressDialog mPd;
public AfterTask (OnFinish finish, Handler handler, ProgressDialog pd): base(finish, handler)
{
mPd = pd;
}
public override void run() {
base.run();
// Remove the progress dialog
mHandler.Post(delegate() {mPd.Dismiss();});
}
}
}
}

View File

@@ -0,0 +1,34 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Android.App;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Kp2aBusinessLogic")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Kp2aBusinessLogic")]
[assembly: AssemblyCopyright("Copyright © 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
// Add some common permissions, these can be removed if not needed
[assembly: UsesPermission(Android.Manifest.Permission.Internet)]
[assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)]

View File

@@ -0,0 +1,47 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using KeePassLib;
namespace keepass2android
{
class PwGroupEqualityFromIdComparer: IEqualityComparer<PwGroup>
{
#region IEqualityComparer implementation
public bool Equals (PwGroup x, PwGroup y)
{
return x.Uuid.EqualsValue(y.Uuid);
}
public int GetHashCode (PwGroup obj)
{
return obj.Uuid.ToHexString().GetHashCode();
}
#endregion
}
}

View File

@@ -0,0 +1,49 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using KeePassLib;
namespace keepass2android
{
public class PwUuidEqualityComparer: IEqualityComparer<PwUuid>
{
#region IEqualityComparer implementation
public bool Equals (PwUuid x, PwUuid y)
{
return x.EqualsValue(y);
}
public int GetHashCode (PwUuid obj)
{
return obj.ToHexString().GetHashCode();
}
#endregion
}
}

View File

View File

@@ -0,0 +1,136 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using KeePassLib;
using Android.Preferences;
using System.Text.RegularExpressions;
using KeePassLib.Collections;
using KeePassLib.Interfaces;
using KeePassLib.Utility;
using Android.Util;
namespace keepass2android
{
public class SearchDbHelper
{
private IKp2aApp mApp;
public SearchDbHelper(IKp2aApp app) {
mApp = app;
}
public PwGroup searchForText (Database database, string str)
{
SearchParameters sp = new SearchParameters();
sp.SearchString = str;
return search(database, sp);
}
public PwGroup search(Database database, SearchParameters sp)
{
if(sp.RegularExpression) // Validate regular expression
{
new Regex(sp.SearchString);
}
string strGroupName = mApp.GetResourceString(UiStringKey.search_results) + " (\"" + sp.SearchString + "\")";
PwGroup pgResults = new PwGroup(true, true, strGroupName, PwIcon.EMailSearch);
pgResults.IsVirtual = true;
PwObjectList<PwEntry> listResults = pgResults.Entries;
database.root.SearchEntries(sp, listResults, new NullStatusLogger());
return pgResults;
}
public PwGroup searchForExactUrl (Database database, string url)
{
SearchParameters sp = SearchParameters.None;
sp.SearchInUrls = true;
sp.SearchString = url;
if(sp.RegularExpression) // Validate regular expression
{
new Regex(sp.SearchString);
}
string strGroupName = mApp.GetResourceString(UiStringKey.search_results) + " (\"" + sp.SearchString + "\")";
PwGroup pgResults = new PwGroup(true, true, strGroupName, PwIcon.EMailSearch);
pgResults.IsVirtual = true;
PwObjectList<PwEntry> listResults = pgResults.Entries;
database.root.SearchEntries(sp, listResults, new NullStatusLogger());
return pgResults;
}
private String extractHost(String url)
{
return UrlUtil.GetHost(url.Trim());
}
public PwGroup searchForHost(Database database, String url, bool allowSubdomains)
{
String host = extractHost(url);
string strGroupName = mApp.GetResourceString(UiStringKey.search_results) + " (\"" + host + "\")";
PwGroup pgResults = new PwGroup(true, true, strGroupName, PwIcon.EMailSearch);
pgResults.IsVirtual = true;
if (String.IsNullOrWhiteSpace(host))
return pgResults;
foreach (PwEntry entry in database.entries.Values)
{
String otherHost = extractHost(entry.Strings.ReadSafe(PwDefs.UrlField));
if ((allowSubdomains) && (otherHost.StartsWith("www.")))
otherHost = otherHost.Substring(4); //remove "www."
if (String.IsNullOrWhiteSpace(otherHost))
{
continue;
}
if (host.IndexOf(otherHost, StringComparison.InvariantCultureIgnoreCase) > -1)
{
pgResults.AddEntry(entry, false);
}
}
return pgResults;
}
}
}

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
namespace keepass2android
{
public enum UiStringKey
{
AskDeletePermanentlyGroup,
progress_title,
AskDeletePermanentlyEntry,
search_results,
AskDeletePermanently_title,
saving_database,
keyfile_does_not_exist,
RecycleBin,
progress_create,
loading_database
}
}

View File

@@ -0,0 +1,93 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using KeePassLib.Interfaces;
namespace keepass2android
{
public class UpdateStatus: IStatusLogger {
private ProgressDialog mPD;
IKp2aApp mApp;
private Handler mHandler;
public UpdateStatus() {
}
public UpdateStatus(IKp2aApp app, Handler handler, ProgressDialog pd) {
mApp = app;
mPD = pd;
mHandler = handler;
}
public void updateMessage(UiStringKey stringKey) {
if ( mApp != null && mPD != null && mHandler != null ) {
mHandler.Post( () => {mPD.SetMessage(mApp.GetResourceString(stringKey));});
}
}
public void updateMessage (String message)
{
if ( mApp!= null && mPD != null && mHandler != null ) {
mHandler.Post(() => {mPD.SetMessage(message); } );
}
}
#region IStatusLogger implementation
public void StartLogging (string strOperation, bool bWriteOperationToLog)
{
}
public void EndLogging ()
{
}
public bool SetProgress (uint uPercent)
{
return true;
}
public bool SetText (string strNewText, LogStatusType lsType)
{
updateMessage(strNewText);
return true;
}
public bool ContinueWork ()
{
return true;
}
#endregion
}
}

View File

@@ -0,0 +1,264 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using KeePassLib;
using KeePassLib.Interfaces;
using KeePassLib.Serialization;
namespace keepass2android
{
public class Database {
public Dictionary<PwUuid, PwGroup> groups = new Dictionary<PwUuid, PwGroup>(new PwUuidEqualityComparer());
public Dictionary<PwUuid, PwEntry> entries = new Dictionary<PwUuid, PwEntry>(new PwUuidEqualityComparer());
public HashSet<PwGroup> dirty = new HashSet<PwGroup>(new PwGroupEqualityFromIdComparer());
public PwGroup root;
public PwDatabase pm;
public IOConnectionInfo mIoc;
public DateTime mLastChangeDate;
public SearchDbHelper searchHelper;
public IDrawableFactory drawableFactory;
IKp2aApp app;
public Database(IDrawableFactory drawableFactory, IKp2aApp app)
{
this.drawableFactory = drawableFactory;
this.app = app;
}
private bool loaded = false;
private bool mReloadRequested = false;
public bool ReloadRequested
{
get { return mReloadRequested; }
set { mReloadRequested = value; }
}
public bool Loaded {
get { return loaded;}
set { loaded = value; }
}
public bool Open
{
get { return Loaded && (!Locked); }
}
bool locked;
public bool Locked
{
get
{
return locked;
}
set
{
locked = value;
}
}
public bool DidOpenFileChange()
{
if ((Loaded == false) || (mIoc.IsLocalFile() == false))
{
return false;
}
return System.IO.File.GetLastWriteTimeUtc(mIoc.Path) > mLastChangeDate;
}
public void LoadData(IKp2aApp app, IOConnectionInfo iocInfo, String password, String keyfile, UpdateStatus status)
{
mIoc = iocInfo;
KeePassLib.PwDatabase pwDatabase = new KeePassLib.PwDatabase();
KeePassLib.Keys.CompositeKey key = new KeePassLib.Keys.CompositeKey();
key.AddUserKey(new KeePassLib.Keys.KcpPassword(password));
if (!String.IsNullOrEmpty(keyfile))
{
try
{
key.AddUserKey(new KeePassLib.Keys.KcpKeyFile(keyfile));
} catch (Exception)
{
throw new KeyFileException();
}
}
pwDatabase.Open(iocInfo, key, status);
if (iocInfo.IsLocalFile())
{
mLastChangeDate = System.IO.File.GetLastWriteTimeUtc(iocInfo.Path);
} else
{
mLastChangeDate = DateTime.MinValue;
}
root = pwDatabase.RootGroup;
populateGlobals(root);
Loaded = true;
pm = pwDatabase;
searchHelper = new SearchDbHelper(app);
}
bool quickUnlockEnabled = false;
public bool QuickUnlockEnabled
{
get
{
return quickUnlockEnabled;
}
set
{
quickUnlockEnabled = value;
}
}
//KeyLength of QuickUnlock at time of loading the database.
//This is important to not allow an attacker to set the length to 1 when QuickUnlock is started already.
public int QuickUnlockKeyLength
{
get;
set;
}
public PwGroup SearchForText(String str) {
PwGroup group = searchHelper.searchForText(this, str);
return group;
}
public PwGroup Search(SearchParameters searchParams)
{
return searchHelper.search(this, searchParams);
}
public PwGroup SearchForExactUrl(String url) {
PwGroup group = searchHelper.searchForExactUrl(this, url);
return group;
}
public PwGroup SearchForHost(String url, bool allowSubdomains) {
PwGroup group = searchHelper.searchForHost(this, url, allowSubdomains);
return group;
}
public void SaveData(Context ctx) {
pm.UseFileTransactions = app.GetBooleanPreference(PreferenceKey.UseFileTransactions);
pm.Save(null);
}
class SaveStatusLogger: IStatusLogger
{
#region IStatusLogger implementation
public void StartLogging (string strOperation, bool bWriteOperationToLog)
{
}
public void EndLogging ()
{
}
public bool SetProgress (uint uPercent)
{
Android.Util.Log.Debug("DEBUG", "Progress: " + uPercent+"%");
return true;
}
public bool SetText (string strNewText, LogStatusType lsType)
{
Android.Util.Log.Debug("DEBUG", strNewText);
return true;
}
public bool ContinueWork ()
{
return true;
}
#endregion
}
private void populateGlobals (PwGroup currentGroup)
{
var childGroups = currentGroup.Groups;
var childEntries = currentGroup.Entries;
foreach (PwEntry e in childEntries) {
entries [e.Uuid] = e;
}
foreach (PwGroup g in childGroups) {
groups[g.Uuid] = g;
populateGlobals(g);
}
}
public void Clear() {
groups.Clear();
entries.Clear();
dirty.Clear();
drawableFactory.Clear();
root = null;
pm = null;
mIoc = null;
loaded = false;
locked = false;
mReloadRequested = false;
}
public void markAllGroupsAsDirty() {
foreach ( PwGroup group in groups.Values ) {
dirty.Add(group);
}
}
}
}

View File

@@ -0,0 +1,67 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
namespace keepass2android
{
public class ActionOnFinish: OnFinish
{
public delegate void ActionToPerformOnFinsh(bool success, String message);
ActionToPerformOnFinsh actionToPerform;
public ActionOnFinish(ActionToPerformOnFinsh actionToPerform) : base(null, null)
{
this.actionToPerform = actionToPerform;
}
public ActionOnFinish(ActionToPerformOnFinsh actionToPerform, OnFinish finish) : base(finish)
{
this.actionToPerform = actionToPerform;
}
public ActionOnFinish(ActionToPerformOnFinsh actionToPerform, Handler handler) : base(handler)
{
this.actionToPerform = actionToPerform;
}
public override void run()
{
if (this.mMessage == null)
this.mMessage = "";
if (this.mHandler != null)
{
this.mHandler.Post(() => {actionToPerform(this.mSuccess, this.mMessage);});
}
else
actionToPerform(this.mSuccess, this.mMessage);
base.run();
}
}
}

View File

@@ -0,0 +1,98 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using KeePassLib;
namespace keepass2android
{
public class AddEntry : RunnableOnFinish {
protected Database mDb;
private PwEntry mEntry;
private PwGroup mParentGroup;
private Context mCtx;
public static AddEntry getInstance(Context ctx, Database db, PwEntry entry, PwGroup parentGroup, OnFinish finish) {
return new AddEntry(ctx, db, entry, parentGroup, finish);
}
protected AddEntry(Context ctx, Database db, PwEntry entry, PwGroup parentGroup, OnFinish finish):base(finish) {
mCtx = ctx;
mParentGroup = parentGroup;
mDb = db;
mEntry = entry;
mFinish = new AfterAdd(db, entry, mFinish);
}
public override void run() {
mParentGroup.AddEntry(mEntry, true);
// Commit to disk
SaveDB save = new SaveDB(mCtx, mDb, mFinish);
save.run();
}
private class AfterAdd : OnFinish {
protected Database mDb;
private PwEntry mEntry;
public AfterAdd(Database db, PwEntry entry, OnFinish finish):base(finish) {
mDb = db;
mEntry = entry;
}
public override void run() {
if ( mSuccess ) {
PwGroup parent = mEntry.ParentGroup;
// Mark parent group dirty
mDb.dirty.Add(parent);
// Add entry to global
mDb.entries[mEntry.Uuid] = mEntry;
} else {
//TODO test fail
mEntry.ParentGroup.Entries.Remove(mEntry);
}
base.run();
}
}
}
}

View File

@@ -0,0 +1,103 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using KeePassLib;
namespace keepass2android
{
public class AddGroup : RunnableOnFinish {
internal Database mDb;
private String mName;
private int mIconID;
internal PwGroup mGroup;
internal PwGroup mParent;
protected bool mDontSave;
Context mCtx;
public static AddGroup getInstance(Context ctx, Database db, String name, int iconid, PwGroup parent, OnFinish finish, bool dontSave) {
return new AddGroup(ctx, db, name, iconid, parent, finish, dontSave);
}
private AddGroup(Context ctx, Database db, String name, int iconid, PwGroup parent, OnFinish finish, bool dontSave): base(finish) {
mCtx = ctx;
mDb = db;
mName = name;
mIconID = iconid;
mParent = parent;
mDontSave = dontSave;
mFinish = new AfterAdd(this, mFinish);
}
public override void run() {
PwDatabase pm = mDb.pm;
// Generate new group
mGroup = new PwGroup(true, true, mName, (PwIcon)mIconID);
mParent.AddGroup(mGroup, true);
// Commit to disk
SaveDB save = new SaveDB(mCtx, mDb, mFinish, mDontSave);
save.run();
}
private class AfterAdd : OnFinish {
AddGroup addGroup;
public AfterAdd(AddGroup addGroup,OnFinish finish): base(finish) {
this.addGroup = addGroup;
}
public override void run() {
if ( mSuccess ) {
// Mark parent group dirty
addGroup.mDb.dirty.Add(addGroup.mParent);
// Add group to global list
addGroup.mDb.groups[addGroup.mGroup.Uuid] = addGroup.mGroup;
} else {
addGroup.mParent.Groups.Remove(addGroup.mGroup);
}
base.run();
}
}
}
}

View File

@@ -0,0 +1,88 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using KeePassLib.Serialization;
using KeePassLib.Keys;
namespace keepass2android
{
public class CreateDB : RunnableOnFinish {
private const int DEFAULT_ENCRYPTION_ROUNDS = 1000;
private IOConnectionInfo mIoc;
private bool mDontSave;
private Context mCtx;
private IKp2aApp mApp;
public CreateDB(IKp2aApp app, Context ctx, IOConnectionInfo ioc, OnFinish finish, bool dontSave): base(finish) {
mCtx = ctx;
mIoc = ioc;
mDontSave = dontSave;
mApp = app;
}
public override void run() {
Database db = mApp.CreateNewDatabase();
db.pm = new KeePassLib.PwDatabase();
//Key will be changed/created immediately after creation:
CompositeKey tempKey = new CompositeKey();
db.pm.New(mIoc, tempKey);
db.pm.KeyEncryptionRounds = DEFAULT_ENCRYPTION_ROUNDS;
db.pm.Name = "Keepass2Android Password Database";
// Set Database state
db.root = db.pm.RootGroup;
db.mIoc = mIoc;
db.Loaded = true;
db.searchHelper = new SearchDbHelper(mApp);
// Add a couple default groups
AddGroup internet = AddGroup.getInstance(mCtx, db, "Internet", 1, db.pm.RootGroup, null, true);
internet.run();
AddGroup email = AddGroup.getInstance(mCtx, db, "eMail", 19, db.pm.RootGroup, null, true);
email.run();
// Commit changes
SaveDB save = new SaveDB(mCtx, db, mFinish, mDontSave);
mFinish = null;
save.run();
}
}
}

View File

@@ -0,0 +1,129 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using KeePassLib;
namespace keepass2android
{
public class DeleteEntry : DeleteRunnable {
private PwEntry mEntry;
public DeleteEntry(Context ctx, IKp2aApp app, PwEntry entry, OnFinish finish):base(finish, app) {
mCtx = ctx;
mDb = app.GetDb();
mEntry = entry;
}
public override bool CanRecycle
{
get
{
return CanRecycleGroup(mEntry.ParentGroup);
}
}
protected override UiStringKey QuestionsResourceId
{
get
{
return UiStringKey.AskDeletePermanentlyEntry;
}
}
public override void run() {
PwDatabase pd = mDb.pm;
PwGroup pgRecycleBin = pd.RootGroup.FindGroup(pd.RecycleBinUuid, true);
bool bUpdateGroupList = false;
DateTime dtNow = DateTime.Now;
PwEntry pe = mEntry;
PwGroup pgParent = pe.ParentGroup;
if(pgParent != null)
{
pgParent.Entries.Remove(pe);
if ((DeletePermanently) || (!CanRecycle))
{
PwDeletedObject pdo = new PwDeletedObject(pe.Uuid, dtNow);
pd.DeletedObjects.Add(pdo);
mFinish = new ActionOnFinish( (success, message) =>
{
if ( success ) {
// Mark parent dirty
if ( pgParent != null ) {
mDb.dirty.Add(pgParent);
}
} else {
// Let's not bother recovering from a failure to save a deleted entry. It is too much work.
mApp.SetShutdown();
}
}, this.mFinish);
}
else // Recycle
{
EnsureRecycleBin(ref pgRecycleBin, ref bUpdateGroupList);
pgRecycleBin.AddEntry(pe, true, true);
pe.Touch(false);
mFinish = new ActionOnFinish( (success, message) =>
{
if ( success ) {
// Mark previous parent dirty
if ( pgParent != null ) {
mDb.dirty.Add(pgParent);
}
// Mark new parent dirty
mDb.dirty.Add(pgRecycleBin);
} else {
// Let's not bother recovering from a failure to save a deleted entry. It is too much work.
mApp.SetShutdown();
}
}, this.mFinish);
}
}
// Commit database
SaveDB save = new SaveDB(mCtx, mDb, mFinish, false);
save.run();
}
}
}

View File

@@ -0,0 +1,169 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using KeePassLib;
namespace keepass2android
{
public class DeleteGroup : DeleteRunnable {
private PwGroup mGroup;
private Activity mAct;
protected bool mDontSave;
public DeleteGroup(Context ctx, IKp2aApp app, PwGroup group, Activity act, OnFinish finish)
: base(finish, app)
{
setMembers(ctx, app, group, act, false);
}
/*
public DeleteGroup(Context ctx, Database db, PwGroup group, Activity act, OnFinish finish, bool dontSave)
: base(finish)
{
setMembers(ctx, db, group, act, dontSave);
}
public DeleteGroup(Context ctx, Database db, PwGroup group, OnFinish finish, bool dontSave):base(finish) {
setMembers(ctx, db, group, null, dontSave);
}
*/
private void setMembers(Context ctx, IKp2aApp app, PwGroup group, Activity act, bool dontSave)
{
base.setMembers(ctx, app.GetDb());
mGroup = group;
mAct = act;
mDontSave = dontSave;
}
public override bool CanRecycle
{
get
{
return CanRecycleGroup(mGroup);
}
}
protected override UiStringKey QuestionsResourceId
{
get
{
return UiStringKey.AskDeletePermanentlyGroup;
}
}
public override void run() {
//from KP Desktop
PwGroup pg = mGroup;
PwGroup pgParent = pg.ParentGroup;
if(pgParent == null) return; // Can't remove virtual or root group
PwDatabase pd = mDb.pm;
PwGroup pgRecycleBin = pd.RootGroup.FindGroup(pd.RecycleBinUuid, true);
pgParent.Groups.Remove(pg);
if ((DeletePermanently) || (!CanRecycle))
{
pg.DeleteAllObjects(pd);
PwDeletedObject pdo = new PwDeletedObject(pg.Uuid, DateTime.Now);
pd.DeletedObjects.Add(pdo);
mFinish = new AfterDeletePermanently(mFinish, mApp, mGroup);
}
else // Recycle
{
bool bDummy = false;
EnsureRecycleBin(ref pgRecycleBin, ref bDummy);
pgRecycleBin.AddGroup(pg, true, true);
pg.Touch(false);
mFinish = new ActionOnFinish((success, message) =>
{
if ( success ) {
// Mark new parent (Recycle bin) dirty
PwGroup parent = mGroup.ParentGroup;
if ( parent != null ) {
mDb.dirty.Add(parent);
}
//Mark old parent dirty:
mDb.dirty.Add(pgParent);
} else {
// Let's not bother recovering from a failure to save a deleted group. It is too much work.
mApp.SetShutdown();
}
}, this.mFinish);
}
// Save
SaveDB save = new SaveDB(mCtx, mDb, mFinish, mDontSave);
save.run();
}
private class AfterDeletePermanently : OnFinish {
IKp2aApp mApp;
PwGroup mGroup;
public AfterDeletePermanently(OnFinish finish, IKp2aApp app, PwGroup group):base(finish) {
this.mApp = app;
this.mGroup = group;
}
public override void run() {
if ( mSuccess ) {
// Remove from group global
mApp.GetDb().groups.Remove(mGroup.Uuid);
// Remove group from the dirty global (if it is present), not a big deal if this fails (doesn't throw)
mApp.GetDb().dirty.Remove(mGroup);
// Mark parent dirty
PwGroup parent = mGroup.ParentGroup;
if ( parent != null ) {
mApp.GetDb().dirty.Add(parent);
}
} else {
// Let's not bother recovering from a failure to save a deleted group. It is too much work.
mApp.SetShutdown();
}
base.run();
}
}
}
}

View File

@@ -0,0 +1,142 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using KeePassLib;
namespace keepass2android
{
public abstract class DeleteRunnable : RunnableOnFinish
{
public DeleteRunnable(OnFinish finish, IKp2aApp app):base(finish)
{
mApp = app;
}
protected IKp2aApp mApp;
protected Database mDb;
protected Context mCtx;
protected void setMembers(Context ctx, Database db)
{
mCtx = ctx;
mDb = db;
}
private bool mDeletePermanently = true;
public bool DeletePermanently
{
get
{
return mDeletePermanently;
}
set
{
mDeletePermanently = value;
}
}
public abstract bool CanRecycle
{
get;
}
protected bool CanRecycleGroup(PwGroup pgParent)
{
bool bShiftPressed = false;
PwDatabase pd = mDb.pm;
PwGroup pgRecycleBin = pd.RootGroup.FindGroup(pd.RecycleBinUuid, true);
bool bPermanent = false;
if (pgParent != null)
{
if (pd.RecycleBinEnabled == false)
bPermanent = true;
else if (bShiftPressed)
bPermanent = true;
else if (pgRecycleBin == null)
{
} // Recycle
else if (pgParent == pgRecycleBin)
bPermanent = true;
else if (pgParent.IsContainedIn(pgRecycleBin))
bPermanent = true;
}
return !bPermanent;
}
protected void EnsureRecycleBin(ref PwGroup pgRecycleBin,
ref bool bGroupListUpdateRequired)
{
if ((mDb == null) || (mDb.pm == null)) { return; }
if(pgRecycleBin == mDb.pm.RootGroup)
{
pgRecycleBin = null;
}
if(pgRecycleBin == null)
{
pgRecycleBin = new PwGroup(true, true, mApp.GetResourceString(UiStringKey.RecycleBin),
PwIcon.TrashBin);
pgRecycleBin.EnableAutoType = false;
pgRecycleBin.EnableSearching = false;
pgRecycleBin.IsExpanded = false;
mDb.pm.RootGroup.AddGroup(pgRecycleBin, true);
mDb.pm.RecycleBinUuid = pgRecycleBin.Uuid;
bGroupListUpdateRequired = true;
}
else { System.Diagnostics.Debug.Assert(pgRecycleBin.Uuid.EqualsValue(mDb.pm.RecycleBinUuid)); }
}
protected abstract UiStringKey QuestionsResourceId
{
get;
}
public void start()
{
if (CanRecycle)
{
mApp.AskYesNoCancel(UiStringKey.AskDeletePermanently_title,
QuestionsResourceId,
new EventHandler<DialogClickEventArgs>((dlgSender, dlgEvt) =>
{
DeletePermanently = true;
ProgressTask pt = new ProgressTask(mApp, mCtx, this, UiStringKey.saving_database);
pt.run();
}),
new EventHandler<DialogClickEventArgs>((dlgSender, dlgEvt) => {
DeletePermanently = false;
ProgressTask pt = new ProgressTask(mApp, mCtx, this, UiStringKey.saving_database);
pt.run();
}),
new EventHandler<DialogClickEventArgs>((dlgSender, dlgEvt) => {}),
mCtx);
} else
{
ProgressTask pt = new ProgressTask(mApp, mCtx, this, UiStringKey.saving_database);
pt.run();
}
}
}
}

View File

@@ -0,0 +1,49 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
namespace keepass2android
{
public abstract class FileOnFinish : OnFinish {
private String mFilename = "";
public FileOnFinish(FileOnFinish finish):base(finish) {
}
public void setFilename(String filename) {
mFilename = filename;
}
public String getFilename() {
return mFilename;
}
}
}

View File

@@ -0,0 +1,118 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Preferences;
using KeePassLib.Serialization;
namespace keepass2android
{
public class LoadDB : RunnableOnFinish {
private IOConnectionInfo mIoc;
private String mPass;
private String mKey;
private IKp2aApp mApp;
private Context mCtx;
private bool mRememberKeyfile;
public LoadDB(IKp2aApp app, Context ctx, IOConnectionInfo ioc, String pass, String key, OnFinish finish): base(finish)
{
mApp = app;
mCtx = ctx;
mIoc = ioc;
mPass = pass;
mKey = key;
mRememberKeyfile = app.GetBooleanPreference(PreferenceKey.remember_keyfile);
}
public override void run ()
{
try {
mApp.GetDb().LoadData (mApp, mIoc, mPass, mKey, mStatus);
saveFileData (mIoc, mKey);
} catch (KeyFileException) {
finish(false, /*TODO Localize: use Keepass error text KPRes.KeyFileError (including "or invalid format")*/ mApp.GetResourceString(UiStringKey.keyfile_does_not_exist));
}
catch (Exception e) {
finish(false, "An error occured: " + e.Message);
return;
}
/* catch (InvalidPasswordException e) {
finish(false, mCtx.GetString(Resource.String.InvalidPassword));
return;
} catch (FileNotFoundException e) {
finish(false, mCtx.GetString(Resource.String.FileNotFound));
return;
} catch (IOException e) {
finish(false, e.getMessage());
return;
} catch (KeyFileEmptyException e) {
finish(false, mCtx.GetString(Resource.String.keyfile_is_empty));
return;
} catch (InvalidAlgorithmException e) {
finish(false, mCtx.GetString(Resource.String.invalid_algorithm));
return;
} catch (InvalidKeyFileException e) {
finish(false, mCtx.GetString(Resource.String.keyfile_does_not_exist));
return;
} catch (InvalidDBSignatureException e) {
finish(false, mCtx.GetString(Resource.String.invalid_db_sig));
return;
} catch (InvalidDBVersionException e) {
finish(false, mCtx.GetString(Resource.String.unsupported_db_version));
return;
} catch (InvalidDBException e) {
finish(false, mCtx.GetString(Resource.String.error_invalid_db));
return;
} catch (OutOfMemoryError e) {
finish(false, mCtx.GetString(Resource.String.error_out_of_memory));
return;
}
*/
finish(true);
}
private void saveFileData(IOConnectionInfo ioc, String key) {
if (!mRememberKeyfile)
{
key = "";
}
mApp.StoreOpenedFileAsRecent(ioc, key);
}
}
}

View File

@@ -0,0 +1,92 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
namespace keepass2android
{
public abstract class OnFinish
{
protected bool mSuccess;
protected String mMessage;
protected OnFinish mOnFinish;
protected Handler mHandler;
public OnFinish() {
}
public OnFinish(Handler handler) {
mOnFinish = null;
mHandler = handler;
}
public OnFinish(OnFinish finish, Handler handler) {
mOnFinish = finish;
mHandler = handler;
}
public OnFinish(OnFinish finish) {
mOnFinish = finish;
mHandler = null;
}
public void setResult(bool success, String message) {
mSuccess = success;
mMessage = message;
}
public void setResult(bool success) {
mSuccess = success;
}
public virtual void run() {
if ( mOnFinish != null ) {
// Pass on result on call finish
mOnFinish.setResult(mSuccess, mMessage);
if ( mHandler != null ) {
mHandler.Post(mOnFinish.run);
} else {
mOnFinish.run();
}
}
}
protected void displayMessage(Context ctx) {
displayMessage(ctx, mMessage);
}
public static void displayMessage(Context ctx, string message)
{
if ( !String.IsNullOrEmpty(message) ) {
Toast.MakeText(ctx, message, ToastLength.Long).Show();
}
}
}
}

View File

@@ -0,0 +1,62 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
namespace keepass2android
{
public abstract class RunnableOnFinish {
public OnFinish mFinish;
public UpdateStatus mStatus;
public RunnableOnFinish(OnFinish finish) {
mFinish = finish;
}
protected void finish(bool result, String message) {
if ( mFinish != null ) {
mFinish.setResult(result, message);
mFinish.run();
}
}
protected void finish(bool result) {
if ( mFinish != null ) {
mFinish.setResult(result);
mFinish.run();
}
}
public void setStatus(UpdateStatus status) {
mStatus = status;
}
abstract public void run();
}
}

View File

@@ -0,0 +1,77 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
namespace keepass2android
{
public class SaveDB : RunnableOnFinish {
private Database mDb;
private bool mDontSave;
private Context mCtx;
public SaveDB(Context ctx, Database db, OnFinish finish, bool dontSave): base(finish) {
mCtx = ctx;
mDb = db;
mDontSave = dontSave;
}
public SaveDB(Context ctx, Database db, OnFinish finish):base(finish) {
mCtx = ctx;
mDb = db;
mDontSave = false;
}
public override void run ()
{
if (! mDontSave) {
try {
mDb.SaveData (mCtx);
if (mDb.mIoc.IsLocalFile())
mDb.mLastChangeDate = System.IO.File.GetLastWriteTimeUtc(mDb.mIoc.Path);
} catch (Exception e) {
/* TODO KPDesktop:
* catch(Exception exSave)
{
MessageService.ShowSaveWarning(pd.IOConnectionInfo, exSave, true);
bSuccess = false;
}
*/
finish (false, e.Message);
return;
}
}
finish(true);
}
}
}

View File

@@ -0,0 +1,112 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using KeePassLib;
using KeePassLib.Keys;
namespace keepass2android
{
public class SetPassword : RunnableOnFinish {
private String mPassword;
private String mKeyfile;
private Database mDb;
private bool mDontSave;
private Context mCtx;
public SetPassword(Context ctx, Database db, String password, String keyfile, OnFinish finish): base(finish) {
mCtx = ctx;
mDb = db;
mPassword = password;
mKeyfile = keyfile;
mDontSave = false;
}
public SetPassword(Context ctx, Database db, String password, String keyfile, OnFinish finish, bool dontSave): base(finish) {
mCtx = ctx;
mDb = db;
mPassword = password;
mKeyfile = keyfile;
mDontSave = dontSave;
}
public override void run ()
{
PwDatabase pm = mDb.pm;
CompositeKey newKey = new CompositeKey ();
if (String.IsNullOrEmpty (mPassword) == false) {
newKey.AddUserKey (new KcpPassword (mPassword));
}
if (String.IsNullOrEmpty (mKeyfile) == false) {
try {
newKey.AddUserKey (new KcpKeyFile (mKeyfile));
} catch (Exception exKF) {
//TODO MessageService.ShowWarning (strKeyFile, KPRes.KeyFileError, exKF);
return;
}
}
DateTime previousMasterKeyChanged = pm.MasterKeyChanged;
CompositeKey previousKey = pm.MasterKey;
pm.MasterKeyChanged = DateTime.Now;
pm.MasterKey = newKey;
// Save Database
mFinish = new AfterSave(previousKey, previousMasterKeyChanged, pm, mFinish);
SaveDB save = new SaveDB(mCtx, mDb, mFinish, mDontSave);
save.run();
}
private class AfterSave : OnFinish {
private CompositeKey mBackup;
private DateTime mPreviousKeyChanged;
private PwDatabase mDb;
public AfterSave(CompositeKey backup, DateTime previousKeyChanged, PwDatabase db, OnFinish finish): base(finish) {
mPreviousKeyChanged = previousKeyChanged;
mBackup = backup;
mDb = db;
}
public override void run() {
if ( ! mSuccess ) {
mDb.MasterKey = mBackup;
mDb.MasterKeyChanged = mPreviousKeyChanged;
}
base.run();
}
}
}
}

View File

@@ -0,0 +1,101 @@
/*
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
Keepass2Android is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Keepass2Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using KeePassLib;
namespace keepass2android
{
public class UpdateEntry : RunnableOnFinish {
private Database mDb;
private PwEntry mOldE;
private PwEntry mNewE;
private Context mCtx;
public UpdateEntry(Context ctx, Database db, PwEntry oldE, PwEntry newE, OnFinish finish):base(finish) {
mCtx = ctx;
mDb = db;
mOldE = oldE;
mNewE = newE;
mFinish = new AfterUpdate(oldE, newE, db, finish);
}
public override void run() {
// Commit to disk
SaveDB save = new SaveDB(mCtx, mDb, mFinish);
save.run();
}
private class AfterUpdate : OnFinish {
private PwEntry mBackup;
private PwEntry mUpdatedEntry;
private Database mDb;
public AfterUpdate(PwEntry backup, PwEntry updatedEntry, Database db, OnFinish finish):base(finish) {
mBackup = backup;
mUpdatedEntry = updatedEntry;
mDb = db;
}
public override void run() {
if ( mSuccess ) {
// Mark group dirty if title, icon or Expiry stuff changes
if ( ! mBackup.Strings.ReadSafe (PwDefs.TitleField).Equals(mUpdatedEntry.Strings.ReadSafe (PwDefs.TitleField))
|| ! mBackup.IconId.Equals(mUpdatedEntry.IconId)
|| ! mBackup.CustomIconUuid.EqualsValue(mUpdatedEntry.CustomIconUuid)
|| mBackup.Expires != mUpdatedEntry.Expires
|| (mBackup.Expires && (! mBackup.ExpiryTime.Equals(mUpdatedEntry.ExpiryTime)))
)
{
PwGroup parent = mUpdatedEntry.ParentGroup;
if ( parent != null ) {
// Mark parent group dirty
mDb.dirty.Add(parent);
}
}
} else {
// If we fail to save, back out changes to global structure
//TODO test fail
mUpdatedEntry.AssignProperties(mBackup, false, true, false);
}
base.run();
}
}
}
}