mirror of
https://github.com/moparisthebest/keepass2android
synced 2025-01-30 14:40:21 -05:00
Added option to export database
Fixed problem with native key transform
This commit is contained in:
parent
d7109fc630
commit
2d53021f78
@ -20,7 +20,7 @@
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>False</Optimize>
|
||||
<OutputPath>bin\Debug</OutputPath>
|
||||
<DefineConstants>DEBUG;EXCLUDE_TWOFISH;INCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;EXCLUDE_FILECHOOSER;EXCLUDE_JAVAFILESTORAGE</DefineConstants>
|
||||
<DefineConstants>DEBUG;EXCLUDE_TWOFISH;INCLUDE_KEYBOARD;INCLUDE_FILECHOOSER;EXCLUDE_JAVAFILESTORAGE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ConsolePause>False</ConsolePause>
|
||||
|
119
src/Kp2aBusinessLogic/DataExchange/FileFormatProvider.cs
Normal file
119
src/Kp2aBusinessLogic/DataExchange/FileFormatProvider.cs
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Drawing;
|
||||
|
||||
using KeePassLib;
|
||||
using KeePassLib.Interfaces;
|
||||
|
||||
namespace KeePass.DataExchange
|
||||
{
|
||||
public abstract class FileFormatProvider
|
||||
{
|
||||
public abstract bool SupportsImport { get; }
|
||||
public abstract bool SupportsExport { get; }
|
||||
|
||||
public abstract string FormatName { get; }
|
||||
|
||||
public virtual string DisplayName
|
||||
{
|
||||
get { return this.FormatName; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default file name extension, without leading dot.
|
||||
/// If there are multiple default/equivalent extensions
|
||||
/// (like e.g. "html" and "htm"), specify all of them
|
||||
/// separated by a '|' (e.g. "html|htm").
|
||||
/// </summary>
|
||||
public virtual string DefaultExtension
|
||||
{
|
||||
get { return string.Empty; }
|
||||
}
|
||||
|
||||
|
||||
public virtual bool RequiresFile
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public virtual bool SupportsUuids
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public virtual bool RequiresKey
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This property specifies if entries are only appended to the
|
||||
/// end of the root group. This is true for example if the
|
||||
/// file format doesn't support groups (i.e. no hierarchy).
|
||||
/// </summary>
|
||||
public virtual bool ImportAppendsToRootGroupOnly
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Called before the <c>Export</c> method is invoked.
|
||||
/// </summary>
|
||||
/// <returns>Returns <c>true</c>, if the <c>Export</c> method
|
||||
/// can be invoked. If it returns <c>false</c>, something has
|
||||
/// failed and the export process should be aborted.</returns>
|
||||
public virtual bool TryBeginExport()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Import a stream into a database. Throws an exception if an error
|
||||
/// occurs. Do not call the base class method when overriding it.
|
||||
/// </summary>
|
||||
/// <param name="pwStorage">Data storage into which the data will be imported.</param>
|
||||
/// <param name="sInput">Input stream to read the data from.</param>
|
||||
/// <param name="slLogger">Status logger. May be <c>null</c>.</param>
|
||||
public abstract void Import(PwDatabase pwStorage, Stream sInput,
|
||||
IStatusLogger slLogger);
|
||||
/// <summary>
|
||||
/// Export data into a stream. Throws an exception if an error
|
||||
/// occurs (like writing to stream fails, etc.). Returns <c>true</c>,
|
||||
/// if the export was successful.
|
||||
/// </summary>
|
||||
/// <param name="pwExportInfo">Contains the data source and detailed
|
||||
/// information about which entries should be exported.</param>
|
||||
/// <param name="sOutput">Output stream to write the data to.</param>
|
||||
/// <param name="slLogger">Status logger. May be <c>null</c>.</param>
|
||||
/// <returns>Returns <c>false</c>, if the user has aborted the export
|
||||
/// process (like clicking Cancel in an additional export settings
|
||||
/// dialog).</returns>
|
||||
public virtual bool Export(PwExportInfo pwExportInfo, Stream sOutput,
|
||||
IStatusLogger slLogger)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
}
|
183
src/Kp2aBusinessLogic/DataExchange/Formats/KeePassCsv1x.cs
Normal file
183
src/Kp2aBusinessLogic/DataExchange/Formats/KeePassCsv1x.cs
Normal file
@ -0,0 +1,183 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
||||
using KeePassLib;
|
||||
using KeePassLib.Delegates;
|
||||
using KeePassLib.Interfaces;
|
||||
using KeePassLib.Utility;
|
||||
|
||||
namespace KeePass.DataExchange.Formats
|
||||
{
|
||||
public sealed class KeePassCsv1x : FileFormatProvider
|
||||
{
|
||||
public override bool SupportsImport { get { return false; } }
|
||||
public override bool SupportsExport { get { return true; } }
|
||||
|
||||
public override string FormatName { get { return "KeePass CSV (1.x)"; } }
|
||||
public override string DefaultExtension { get { return "csv"; } }
|
||||
|
||||
// public override bool ImportAppendsToRootGroupOnly { get { return true; } }
|
||||
|
||||
/* public override void Import(PwDatabase pwStorage, Stream sInput,
|
||||
IStatusLogger slLogger)
|
||||
{
|
||||
StreamReader sr = new StreamReader(sInput, Encoding.UTF8);
|
||||
string strFileContents = sr.ReadToEnd();
|
||||
sr.Close();
|
||||
|
||||
CharStream csSource = new CharStream(strFileContents);
|
||||
|
||||
while(true)
|
||||
{
|
||||
if(ReadEntry(pwStorage, csSource) == false)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool ReadEntry(PwDatabase pwStorage, CharStream csSource)
|
||||
{
|
||||
PwEntry pe = new PwEntry(true, true);
|
||||
|
||||
string strTitle = ReadCsvField(csSource);
|
||||
if(strTitle == null) return false; // No entry available
|
||||
|
||||
string strUser = ReadCsvField(csSource);
|
||||
if(strUser == null) throw new InvalidDataException();
|
||||
|
||||
string strPassword = ReadCsvField(csSource);
|
||||
if(strPassword == null) throw new InvalidDataException();
|
||||
|
||||
string strUrl = ReadCsvField(csSource);
|
||||
if(strUrl == null) throw new InvalidDataException();
|
||||
|
||||
string strNotes = ReadCsvField(csSource);
|
||||
if(strNotes == null) throw new InvalidDataException();
|
||||
|
||||
if((strTitle == "Account") && (strUser == "Login Name") &&
|
||||
(strPassword == "Password") && (strUrl == "Web Site") &&
|
||||
(strNotes == "Comments"))
|
||||
{
|
||||
return true; // Ignore header entry
|
||||
}
|
||||
|
||||
pe.Strings.Set(PwDefs.TitleField, new ProtectedString(
|
||||
pwStorage.MemoryProtection.ProtectTitle, strTitle));
|
||||
pe.Strings.Set(PwDefs.UserNameField, new ProtectedString(
|
||||
pwStorage.MemoryProtection.ProtectUserName, strUser));
|
||||
pe.Strings.Set(PwDefs.PasswordField, new ProtectedString(
|
||||
pwStorage.MemoryProtection.ProtectPassword, strPassword));
|
||||
pe.Strings.Set(PwDefs.UrlField, new ProtectedString(
|
||||
pwStorage.MemoryProtection.ProtectUrl, strUrl));
|
||||
pe.Strings.Set(PwDefs.NotesField, new ProtectedString(
|
||||
pwStorage.MemoryProtection.ProtectNotes, strNotes));
|
||||
|
||||
pwStorage.RootGroup.AddEntry(pe, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static string ReadCsvField(CharStream csSource)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
bool bInField = false;
|
||||
|
||||
while(true)
|
||||
{
|
||||
char ch = csSource.ReadChar();
|
||||
if(ch == char.MinValue)
|
||||
return null;
|
||||
|
||||
if((ch == '\"') && !bInField)
|
||||
bInField = true;
|
||||
else if((ch == '\"') && bInField)
|
||||
break;
|
||||
else if(ch == '\\')
|
||||
{
|
||||
char chSub = csSource.ReadChar();
|
||||
if(chSub == char.MinValue)
|
||||
throw new InvalidDataException();
|
||||
|
||||
sb.Append(chSub);
|
||||
}
|
||||
else if(bInField)
|
||||
sb.Append(ch);
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
} */
|
||||
|
||||
public override void Import(PwDatabase pwStorage, Stream sInput, IStatusLogger slLogger)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool Export(PwExportInfo pwExportInfo, Stream sOutput,
|
||||
IStatusLogger slLogger)
|
||||
{
|
||||
PwGroup pg = (pwExportInfo.DataGroup ?? ((pwExportInfo.ContextDatabase !=
|
||||
null) ? pwExportInfo.ContextDatabase.RootGroup : null));
|
||||
|
||||
StreamWriter sw = new StreamWriter(sOutput, StrUtil.Utf8);
|
||||
sw.Write("\"Account\",\"Login Name\",\"Password\",\"Web Site\",\"Comments\"\r\n");
|
||||
|
||||
EntryHandler eh = delegate(PwEntry pe)
|
||||
{
|
||||
WriteCsvEntry(sw, pe);
|
||||
return true;
|
||||
};
|
||||
|
||||
if(pg != null) pg.TraverseTree(TraversalMethod.PreOrder, null, eh);
|
||||
|
||||
sw.Close();
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void WriteCsvEntry(StreamWriter sw, PwEntry pe)
|
||||
{
|
||||
if(sw == null) { Debug.Assert(false); return; }
|
||||
if(pe == null) { Debug.Assert(false); return; }
|
||||
|
||||
const string strSep = "\",\"";
|
||||
|
||||
sw.Write("\"");
|
||||
WriteCsvString(sw, pe.Strings.ReadSafe(PwDefs.TitleField), strSep);
|
||||
WriteCsvString(sw, pe.Strings.ReadSafe(PwDefs.UserNameField), strSep);
|
||||
WriteCsvString(sw, pe.Strings.ReadSafe(PwDefs.PasswordField), strSep);
|
||||
WriteCsvString(sw, pe.Strings.ReadSafe(PwDefs.UrlField), strSep);
|
||||
WriteCsvString(sw, pe.Strings.ReadSafe(PwDefs.NotesField), "\"\r\n");
|
||||
}
|
||||
|
||||
private static void WriteCsvString(StreamWriter sw, string strText,
|
||||
string strAppend)
|
||||
{
|
||||
string str = strText;
|
||||
if(!string.IsNullOrEmpty(str))
|
||||
{
|
||||
str = str.Replace("\\", "\\\\");
|
||||
str = str.Replace("\"", "\\\"");
|
||||
|
||||
sw.Write(str);
|
||||
}
|
||||
|
||||
if(!string.IsNullOrEmpty(strAppend)) sw.Write(strAppend);
|
||||
}
|
||||
}
|
||||
}
|
60
src/Kp2aBusinessLogic/DataExchange/Formats/KeePassKdb2x.cs
Normal file
60
src/Kp2aBusinessLogic/DataExchange/Formats/KeePassKdb2x.cs
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
|
||||
|
||||
using KeePassLib;
|
||||
using KeePassLib.Interfaces;
|
||||
using KeePassLib.Serialization;
|
||||
|
||||
namespace KeePass.DataExchange.Formats
|
||||
{
|
||||
public sealed class KeePassKdb2x : FileFormatProvider
|
||||
{
|
||||
public override bool SupportsImport { get { return true; } }
|
||||
public override bool SupportsExport { get { return true; } }
|
||||
|
||||
public override string FormatName { get { return "KeePass KDBX (2.x)"; } }
|
||||
public override string DefaultExtension { get { return "kdbx"; } }
|
||||
|
||||
public override bool SupportsUuids { get { return true; } }
|
||||
public override bool RequiresKey { get { return true; } }
|
||||
|
||||
|
||||
public override void Import(PwDatabase pwStorage, Stream sInput,
|
||||
IStatusLogger slLogger)
|
||||
{
|
||||
KdbxFile kdbx = new KdbxFile(pwStorage);
|
||||
kdbx.Load(sInput, KdbxFormat.Default, slLogger);
|
||||
}
|
||||
|
||||
public override bool Export(PwExportInfo pwExportInfo, Stream sOutput,
|
||||
IStatusLogger slLogger)
|
||||
{
|
||||
KdbxFile kdbx = new KdbxFile(pwExportInfo.ContextDatabase);
|
||||
kdbx.Save(sOutput, pwExportInfo.DataGroup, KdbxFormat.Default, slLogger);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
72
src/Kp2aBusinessLogic/DataExchange/Formats/KeePassXml2x.cs
Normal file
72
src/Kp2aBusinessLogic/DataExchange/Formats/KeePassXml2x.cs
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
|
||||
|
||||
using KeePassLib;
|
||||
using KeePassLib.Collections;
|
||||
using KeePassLib.Interfaces;
|
||||
using KeePassLib.Serialization;
|
||||
|
||||
namespace KeePass.DataExchange.Formats
|
||||
{
|
||||
public sealed class KeePassXml2x : FileFormatProvider
|
||||
{
|
||||
public override bool SupportsImport { get { return true; } }
|
||||
public override bool SupportsExport { get { return true; } }
|
||||
|
||||
public override string FormatName { get { return "KeePass XML (2.x)"; } }
|
||||
public override string DefaultExtension { get { return "xml"; } }
|
||||
|
||||
public override bool SupportsUuids { get { return true; } }
|
||||
|
||||
public override void Import(PwDatabase pwStorage, Stream sInput,
|
||||
IStatusLogger slLogger)
|
||||
{
|
||||
KdbxFile kdbx = new KdbxFile(pwStorage);
|
||||
kdbx.Load(sInput, KdbxFormat.PlainXml, slLogger);
|
||||
}
|
||||
|
||||
public override bool Export(PwExportInfo pwExportInfo, Stream sOutput,
|
||||
IStatusLogger slLogger)
|
||||
{
|
||||
PwDatabase pd = (pwExportInfo.ContextDatabase ?? new PwDatabase());
|
||||
|
||||
PwObjectList<PwDeletedObject> vDel = null;
|
||||
if(pwExportInfo.ExportDeletedObjects == false)
|
||||
{
|
||||
vDel = pd.DeletedObjects.CloneShallow();
|
||||
pd.DeletedObjects.Clear();
|
||||
}
|
||||
|
||||
KdbxFile kdb = new KdbxFile(pd);
|
||||
kdb.Save(sOutput, pwExportInfo.DataGroup, KdbxFormat.PlainXml, slLogger);
|
||||
|
||||
// Restore deleted objects list
|
||||
if(vDel != null) pd.DeletedObjects.Add(vDel);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
82
src/Kp2aBusinessLogic/DataExchange/PwExportInfo.cs
Normal file
82
src/Kp2aBusinessLogic/DataExchange/PwExportInfo.cs
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
using KeePassLib;
|
||||
|
||||
namespace KeePass.DataExchange
|
||||
{
|
||||
public sealed class PwExportInfo
|
||||
{
|
||||
private PwGroup m_pg;
|
||||
/// <summary>
|
||||
/// This group contains all entries and subgroups that should
|
||||
/// be exported. Is never <c>null</c>.
|
||||
/// </summary>
|
||||
public PwGroup DataGroup
|
||||
{
|
||||
get { return m_pg; }
|
||||
}
|
||||
|
||||
private PwDatabase m_pd;
|
||||
/// <summary>
|
||||
/// Optional context database reference. May be <c>null</c>.
|
||||
/// </summary>
|
||||
public PwDatabase ContextDatabase
|
||||
{
|
||||
get { return m_pd; }
|
||||
}
|
||||
|
||||
private bool m_bExpDel = true;
|
||||
/// <summary>
|
||||
/// Indicates whether deleted objects should be exported, if
|
||||
/// the data format supports it.
|
||||
/// </summary>
|
||||
public bool ExportDeletedObjects
|
||||
{
|
||||
get { return m_bExpDel; }
|
||||
}
|
||||
|
||||
public PwExportInfo(PwGroup pgDataSource, PwDatabase pwContextInfo)
|
||||
{
|
||||
ConstructEx(pgDataSource, pwContextInfo, null);
|
||||
}
|
||||
|
||||
public PwExportInfo(PwGroup pgDataSource, PwDatabase pwContextInfo,
|
||||
bool bExportDeleted)
|
||||
{
|
||||
ConstructEx(pgDataSource, pwContextInfo, bExportDeleted);
|
||||
}
|
||||
|
||||
private void ConstructEx(PwGroup pgDataSource, PwDatabase pwContextInfo,
|
||||
bool? bExportDeleted)
|
||||
{
|
||||
if(pgDataSource == null) throw new ArgumentNullException("pgDataSource");
|
||||
// pwContextInfo may be null.
|
||||
|
||||
m_pg = pgDataSource;
|
||||
m_pd = pwContextInfo;
|
||||
|
||||
if(bExportDeleted.HasValue) m_bExpDel = bExportDeleted.Value;
|
||||
}
|
||||
}
|
||||
}
|
@ -20,7 +20,7 @@
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>TRACE;DEBUG;EXCLUDE_TWOFISH;INCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;EXCLUDE_FILECHOOSER;EXCLUDE_JAVAFILESTORAGE</DefineConstants>
|
||||
<DefineConstants>TRACE;DEBUG;EXCLUDE_TWOFISH;INCLUDE_KEYBOARD;INCLUDE_FILECHOOSER;EXCLUDE_JAVAFILESTORAGE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
@ -59,6 +59,11 @@
|
||||
<Compile Include="database\KdbDatabaseLoader.cs" />
|
||||
<Compile Include="database\KdbxDatabaseLoader.cs" />
|
||||
<Compile Include="database\SynchronizeCachedDatabase.cs" />
|
||||
<Compile Include="DataExchange\FileFormatProvider.cs" />
|
||||
<Compile Include="DataExchange\Formats\KeePassCsv1x.cs" />
|
||||
<Compile Include="DataExchange\Formats\KeePassKdb2x.cs" />
|
||||
<Compile Include="DataExchange\Formats\KeePassXml2x.cs" />
|
||||
<Compile Include="DataExchange\PwExportInfo.cs" />
|
||||
<Compile Include="Io\BuiltInFileStorage.cs" />
|
||||
<Compile Include="Io\CachingFileStorage.cs" />
|
||||
<Compile Include="Io\DropboxFileStorage.cs" />
|
||||
|
@ -47,6 +47,7 @@ namespace keepass2android
|
||||
ErrorOcurred,
|
||||
SynchronizingOtpAuxFile,
|
||||
SavingOtpAuxFile,
|
||||
CertificateFailure
|
||||
CertificateFailure,
|
||||
exporting_database
|
||||
}
|
||||
}
|
@ -717,14 +717,7 @@ public class KP2AKeyboard extends InputMethodService
|
||||
ExtractedTextRequest etr = new ExtractedTextRequest();
|
||||
etr.token = 0; // anything is fine here
|
||||
ExtractedText et = ic.getExtractedText(etr, 0);
|
||||
if (et == null)
|
||||
{
|
||||
Log.d("KP2AK", "et == null");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.d("KP2AK", "et != null "+et.text);
|
||||
}
|
||||
|
||||
boolean hasTextInField = (et != null) && (!TextUtils.isEmpty(et.text));
|
||||
if (!hasTextInField) //only auto-fill if target field is empty
|
||||
{
|
||||
|
@ -534,34 +534,6 @@ namespace keepass2android
|
||||
}
|
||||
|
||||
|
||||
private class CreateNewFilename: RunnableOnFinish
|
||||
{
|
||||
private readonly string _filename;
|
||||
|
||||
public CreateNewFilename(OnFinish finish, string filename)
|
||||
: base(finish)
|
||||
{
|
||||
_filename = filename;
|
||||
}
|
||||
|
||||
public override void Run()
|
||||
{
|
||||
try
|
||||
{
|
||||
int lastIndexOfSlash = _filename.LastIndexOf("/", StringComparison.Ordinal);
|
||||
string parent = _filename.Substring(0, lastIndexOfSlash);
|
||||
string newFilename = _filename.Substring(lastIndexOfSlash + 1);
|
||||
|
||||
string resultingFilename = App.Kp2a.GetFileStorage(new IOConnectionInfo { Path = parent }).CreateFilePath(parent, newFilename);
|
||||
|
||||
Finish(true, resultingFilename);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Finish(false, e.Message);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
35
src/keepass2android/CreateNewFilename.cs
Normal file
35
src/keepass2android/CreateNewFilename.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using KeePassLib.Serialization;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
class CreateNewFilename : RunnableOnFinish
|
||||
{
|
||||
private readonly string _filename;
|
||||
|
||||
public CreateNewFilename(OnFinish finish, string filename)
|
||||
: base(finish)
|
||||
{
|
||||
_filename = filename;
|
||||
}
|
||||
|
||||
public override void Run()
|
||||
{
|
||||
try
|
||||
{
|
||||
int lastIndexOfSlash = _filename.LastIndexOf("/", StringComparison.Ordinal);
|
||||
string parent = _filename.Substring(0, lastIndexOfSlash);
|
||||
string newFilename = _filename.Substring(lastIndexOfSlash + 1);
|
||||
|
||||
string resultingFilename = App.Kp2a.GetFileStorage(new IOConnectionInfo { Path = parent }).CreateFilePath(parent, newFilename);
|
||||
|
||||
Finish(true, resultingFilename);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Finish(false, e.Message);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
258
src/keepass2android/ExportDatabaseActivity.cs
Normal file
258
src/keepass2android/ExportDatabaseActivity.cs
Normal file
@ -0,0 +1,258 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.Content.PM;
|
||||
using Android.Util;
|
||||
using Android.Widget;
|
||||
using KeePass.DataExchange;
|
||||
using KeePass.DataExchange.Formats;
|
||||
using KeePassLib.Interfaces;
|
||||
using KeePassLib.Serialization;
|
||||
using keepass2android.Io;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
|
||||
[Activity(Label = "@string/app_name",
|
||||
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden,
|
||||
Theme = "@style/Base")]
|
||||
[IntentFilter(new[] {"keepass2android.ExportDatabaseActivity"}, Categories = new[] {Intent.CategoryDefault})]
|
||||
public class ExportDatabaseActivity : LockCloseActivity
|
||||
{
|
||||
FileFormatProvider[] _ffp = new FileFormatProvider[]
|
||||
{
|
||||
new KeePassKdb2x(),
|
||||
new KeePassXml2x(),
|
||||
new KeePassCsv1x()
|
||||
};
|
||||
|
||||
private int _fileFormatIndex;
|
||||
|
||||
protected override void OnCreate(Android.OS.Bundle savedInstanceState)
|
||||
{
|
||||
base.OnCreate(savedInstanceState);
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.SetTitle(Resource.String.export_fileformats_title);
|
||||
builder.SetSingleChoiceItems(Resource.Array.export_fileformat_options, _fileFormatIndex,
|
||||
delegate(object sender, DialogClickEventArgs args) { _fileFormatIndex = args.Which; });
|
||||
builder.SetPositiveButton(Resource.String.ok, delegate
|
||||
{
|
||||
Intent intent = new Intent(this, typeof(FileStorageSelectionActivity));
|
||||
//intent.PutExtra(FileStorageSelectionActivity.AllowThirdPartyAppSend, true);
|
||||
|
||||
StartActivityForResult(intent, 0);
|
||||
});
|
||||
builder.SetNegativeButton(Resource.String.cancel, delegate {
|
||||
Finish();
|
||||
});
|
||||
builder.Show();
|
||||
}
|
||||
|
||||
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
|
||||
{
|
||||
base.OnActivityResult(requestCode, resultCode, data);
|
||||
|
||||
if (resultCode == KeePass.ExitFileStorageSelectionOk)
|
||||
{
|
||||
string protocolId = data.GetStringExtra("protocolId");
|
||||
App.Kp2a.GetFileStorage(protocolId).StartSelectFile(new FileStorageSetupInitiatorActivity(this,
|
||||
OnActivityResult,
|
||||
defaultPath =>
|
||||
{
|
||||
if (defaultPath.StartsWith("sftp://"))
|
||||
Util.ShowSftpDialog(this, OnReceiveSftpData);
|
||||
else
|
||||
Util.ShowFilenameDialog(this, OnCreateButton, null, false, defaultPath, GetString(Resource.String.enter_filename_details_url),
|
||||
Intents.RequestCodeFileBrowseForOpen);
|
||||
}
|
||||
), true, RequestCodeDbFilename, protocolId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (resultCode == Result.Ok)
|
||||
{
|
||||
if (requestCode == RequestCodeDbFilename)
|
||||
{
|
||||
string filename = Util.IntentToFilename(data, this);
|
||||
|
||||
bool fileExists = data.GetBooleanExtra("group.pals.android.lib.ui.filechooser.FileChooserActivity.result_file_exists", true);
|
||||
|
||||
if (fileExists)
|
||||
{
|
||||
ExportTo(new IOConnectionInfo { Path = ConvertFilenameToIocPath(filename) });
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
var task = new CreateNewFilename(new ActionOnFinish((success, messageOrFilename) =>
|
||||
{
|
||||
if (!success)
|
||||
{
|
||||
Toast.MakeText(this, messageOrFilename, ToastLength.Long).Show();
|
||||
return;
|
||||
}
|
||||
ExportTo(new IOConnectionInfo { Path = ConvertFilenameToIocPath(messageOrFilename) });
|
||||
|
||||
|
||||
}), filename);
|
||||
|
||||
new ProgressTask(App.Kp2a, this, task).Run();
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
if (resultCode == (Result)FileStorageResults.FileUsagePrepared)
|
||||
{
|
||||
var ioc = new IOConnectionInfo();
|
||||
PasswordActivity.SetIoConnectionFromIntent(ioc, data);
|
||||
ExportTo(ioc);
|
||||
return;
|
||||
}
|
||||
if (resultCode == (Result)FileStorageResults.FileChooserPrepared)
|
||||
{
|
||||
IOConnectionInfo ioc = new IOConnectionInfo();
|
||||
PasswordActivity.SetIoConnectionFromIntent(ioc, data);
|
||||
StartFileChooser(ioc.Path, RequestCodeDbFilename, true);
|
||||
return;
|
||||
}
|
||||
Finish();
|
||||
|
||||
}
|
||||
|
||||
private void ExportTo(IOConnectionInfo ioc)
|
||||
{
|
||||
var exportDb = new ExportDb(App.Kp2a, new ActionOnFinish(delegate(bool success, string message)
|
||||
{
|
||||
if (!success)
|
||||
Toast.MakeText(this, message, ToastLength.Long).Show();
|
||||
else
|
||||
Toast.MakeText(this, GetString(Resource.String.export_database_successful), ToastLength.Long).Show();
|
||||
Finish();
|
||||
}
|
||||
), _ffp[_fileFormatIndex], ioc);
|
||||
ProgressTask pt = new ProgressTask(App.Kp2a, this, exportDb);
|
||||
pt.Run();
|
||||
}
|
||||
|
||||
protected int RequestCodeDbFilename
|
||||
{
|
||||
get { return 0; }
|
||||
}
|
||||
|
||||
private bool OnCreateButton(string filename)
|
||||
{
|
||||
if (filename.Length == 0)
|
||||
{
|
||||
Toast.MakeText(this,
|
||||
Resource.String.error_filename_required,
|
||||
ToastLength.Long).Show();
|
||||
return false;
|
||||
}
|
||||
|
||||
IOConnectionInfo ioc = new IOConnectionInfo { Path = filename };
|
||||
try
|
||||
{
|
||||
App.Kp2a.GetFileStorage(ioc);
|
||||
}
|
||||
catch (NoFileStorageFoundException)
|
||||
{
|
||||
Toast.MakeText(this,
|
||||
"Unexpected scheme in " + filename,
|
||||
ToastLength.Long).Show();
|
||||
return false;
|
||||
}
|
||||
|
||||
ExportTo(new IOConnectionInfo() { Path = filename });
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool OnReceiveSftpData(string filename)
|
||||
{
|
||||
StartFileChooser(filename, RequestCodeDbFilename, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static string ConvertFilenameToIocPath(string filename)
|
||||
{
|
||||
if ((filename != null) && (filename.StartsWith("file://")))
|
||||
{
|
||||
filename = filename.Substring(7);
|
||||
filename = Java.Net.URLDecoder.Decode(filename);
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
private void StartFileChooser(string defaultPath, int requestCode, bool forSave)
|
||||
{
|
||||
#if !EXCLUDE_FILECHOOSER
|
||||
Kp2aLog.Log("FSA: defaultPath=" + defaultPath);
|
||||
string fileProviderAuthority = FileChooserFileProvider.TheAuthority;
|
||||
if (defaultPath.StartsWith("file://"))
|
||||
{
|
||||
fileProviderAuthority = "keepass2android."+AppNames.PackagePart+".android-filechooser.localfile";
|
||||
}
|
||||
Intent i = Keepass2android.Kp2afilechooser.Kp2aFileChooserBridge.GetLaunchFileChooserIntent(this, fileProviderAuthority,
|
||||
defaultPath);
|
||||
|
||||
if (forSave)
|
||||
{
|
||||
i.PutExtra("group.pals.android.lib.ui.filechooser.FileChooserActivity.save_dialog", true);
|
||||
i.PutExtra("group.pals.android.lib.ui.filechooser.FileChooserActivity.default_file_ext", _ffp[_fileFormatIndex].DefaultExtension);
|
||||
}
|
||||
|
||||
StartActivityForResult(i, requestCode);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
public class ExportDb : RunnableOnFinish
|
||||
{
|
||||
private readonly IKp2aApp _app;
|
||||
private readonly FileFormatProvider _fileFormat;
|
||||
private IOConnectionInfo _targetIoc;
|
||||
|
||||
public ExportDb(IKp2aApp app, OnFinish onFinish, FileFormatProvider fileFormat, IOConnectionInfo targetIoc) : base(onFinish)
|
||||
{
|
||||
_app = app;
|
||||
this._fileFormat = fileFormat;
|
||||
_targetIoc = targetIoc;
|
||||
}
|
||||
|
||||
public override void Run()
|
||||
{
|
||||
StatusLogger.UpdateMessage(UiStringKey.exporting_database);
|
||||
var pd = _app.GetDb().KpDatabase;
|
||||
PwExportInfo pwInfo = new PwExportInfo(pd.RootGroup, pd, true);
|
||||
|
||||
try
|
||||
{
|
||||
using (var writeTransaction =_app.GetFileStorage(_targetIoc).OpenWriteTransaction(_targetIoc, _app.GetDb().KpDatabase.UseFileTransactions))
|
||||
{
|
||||
Stream sOut = writeTransaction.OpenFile();
|
||||
_fileFormat.Export(pwInfo, sOut, new NullStatusLogger());
|
||||
|
||||
if (sOut != null) sOut.Close();
|
||||
|
||||
writeTransaction.CommitWrite();
|
||||
|
||||
}
|
||||
Finish(true);
|
||||
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Finish(false, ex.Message);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -31,7 +31,7 @@ namespace keepass2android
|
||||
//which may be used "outside" the database (e.g. GeneratePassword for creating a master password)
|
||||
protected const string NoLockCheck = "NO_LOCK_CHECK";
|
||||
|
||||
private IOConnectionInfo _ioc;
|
||||
protected IOConnectionInfo _ioc;
|
||||
private BroadcastReceiver _intentReceiver;
|
||||
|
||||
protected override void OnCreate(Bundle savedInstanceState)
|
||||
|
@ -48,11 +48,10 @@ using String = System.String;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
[Activity (Label = "@string/app_name",
|
||||
ConfigurationChanges=ConfigChanges.Orientation|ConfigChanges.KeyboardHidden,
|
||||
LaunchMode = LaunchMode.SingleInstance,
|
||||
Theme="@style/Base")]
|
||||
|
||||
[Activity(Label = "@string/app_name",
|
||||
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden,
|
||||
LaunchMode = LaunchMode.SingleInstance,
|
||||
Theme = "@style/Base")]
|
||||
public class PasswordActivity : LockingActivity {
|
||||
|
||||
enum KeyProviders
|
||||
@ -1173,7 +1172,5 @@ namespace keepass2android
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
7005
src/keepass2android/Resources/Resource.designer.cs
generated
7005
src/keepass2android/Resources/Resource.designer.cs
generated
File diff suppressed because it is too large
Load Diff
@ -116,7 +116,8 @@
|
||||
<item>3600000</item>
|
||||
<item>-1</item>
|
||||
</string-array>
|
||||
<string name="list_size_default">20</string>
|
||||
|
||||
<string name="list_size_default">20</string>
|
||||
<string-array name="list_size_values">
|
||||
<item>15</item>
|
||||
<item>20</item>
|
||||
|
@ -32,6 +32,7 @@
|
||||
<string name="QuickUnlock_prefs">QuickUnlock</string>
|
||||
<string name="FileHandling_prefs">File handling</string>
|
||||
<string name="keyboard_prefs">Keyboard</string>
|
||||
<string name="export_prefs">Export database...</string>
|
||||
<string name="brackets">Brackets</string>
|
||||
<string name="cancel">Cancel</string>
|
||||
<string name="ClearClipboard">Clipboard cleared.</string>
|
||||
@ -160,7 +161,10 @@
|
||||
<string name="database_name">Database name</string>
|
||||
<string name="default_username">Default user name for new entries</string>
|
||||
<string name="saving_database">Saving database…</string>
|
||||
<string name="space">Space</string>
|
||||
<string name="exporting_database">Exporting database…</string>
|
||||
<string name="export_database_successful">Database exported successfully!</string>
|
||||
|
||||
<string name="space">Space</string>
|
||||
<string name="search_label">Search</string>
|
||||
<string name="show_password">Show password</string>
|
||||
<string name="sort_name">Sort by name</string>
|
||||
@ -398,6 +402,8 @@
|
||||
|
||||
<string name="CertificateWarning">Warning: Server certificate validation failed: %1$s. Install appropriate root certificate on your device or see settings!</string>
|
||||
<string name="CertificateFailure">Error: Server certificate validation failed! Install appropriate root certificate on your device or see settings!</string>
|
||||
|
||||
<string name="export_fileformats_title">Select file format</string>
|
||||
|
||||
<string name="ChangeLog_title">Change log</string>
|
||||
|
||||
@ -520,6 +526,11 @@ Initial public release
|
||||
<item>1 hour</item>
|
||||
<item>Never</item>
|
||||
</string-array>
|
||||
<string-array name="export_fileformat_options">
|
||||
<item>Keepass 2 database (.kdbx)</item>
|
||||
<item>Keepass 2 XML (unencrypted) (.xml)</item>
|
||||
<item>Keepass CSV (unencrypted) (.csv)</item>
|
||||
</string-array>
|
||||
<string-array name="list_size_options">
|
||||
<item>Small</item>
|
||||
<item>Medium</item>
|
||||
|
@ -44,6 +44,14 @@
|
||||
android:persistent="false"
|
||||
android:key="@string/default_username_key"/>
|
||||
|
||||
<PreferenceScreen
|
||||
android:key="export_prefs"
|
||||
android:title="@string/export_prefs"
|
||||
>
|
||||
<intent android:action="keepass2android.ExportDatabaseActivity"/>
|
||||
</PreferenceScreen>
|
||||
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
<PreferenceScreen
|
||||
@ -258,7 +266,7 @@
|
||||
>
|
||||
<intent android:action="keepass2android.softkeyboard.LatinIMESettings"/>
|
||||
</PreferenceScreen>
|
||||
|
||||
|
||||
|
||||
</PreferenceScreen>
|
||||
</PreferenceScreen>
|
||||
|
@ -30,7 +30,7 @@
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug</OutputPath>
|
||||
<DefineConstants>DEBUG;EXCLUDE_TWOFISH;INCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;EXCLUDE_FILECHOOSER;EXCLUDE_JAVAFILESTORAGE</DefineConstants>
|
||||
<DefineConstants>DEBUG;EXCLUDE_TWOFISH;INCLUDE_KEYBOARD;INCLUDE_FILECHOOSER;EXCLUDE_JAVAFILESTORAGE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ConsolePause>False</ConsolePause>
|
||||
@ -92,6 +92,8 @@
|
||||
<Compile Include="app\NoFileStorageFoundException.cs" />
|
||||
<Compile Include="app\OtpAuxCacheSupervisor.cs" />
|
||||
<Compile Include="CreateDatabaseActivity.cs" />
|
||||
<Compile Include="CreateNewFilename.cs" />
|
||||
<Compile Include="ExportDatabaseActivity.cs" />
|
||||
<Compile Include="fileselect\FileChooserFileProvider.cs" />
|
||||
<Compile Include="fileselect\FileStorageSetupActivity.cs" />
|
||||
<Compile Include="fileselect\FileStorageSetupInitiatorActivity.cs" />
|
||||
@ -170,6 +172,12 @@
|
||||
<AndroidAsset Include="Assets\fontawesome-webfont.ttf" />
|
||||
<AndroidAsset Include="Assets\DejaVuSansMono.ttf" />
|
||||
<AndroidAsset Include="Assets\LICENSE_dejavu" />
|
||||
<AndroidNativeLibrary Include="..\java\KP2AKdbLibrary\libs\armeabi-v7a\libfinal-key.so">
|
||||
<Link>libs\armeabi-v7a\libfinal-key.so</Link>
|
||||
</AndroidNativeLibrary>
|
||||
<AndroidNativeLibrary Include="..\java\KP2AKdbLibrary\libs\armeabi\libfinal-key.so">
|
||||
<Link>libs\armeabi\libfinal-key.so</Link>
|
||||
</AndroidNativeLibrary>
|
||||
<None Include="Resources\AboutResources.txt" />
|
||||
<None Include="Resources\drawable\Thumbs.db">
|
||||
<Visible>False</Visible>
|
||||
@ -665,10 +673,6 @@
|
||||
<Project>{23233a28-d74f-4bf8-b4d8-834060840bd7}</Project>
|
||||
<Name>AppCompatV7Binding</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\JavaFileStorageBindings\JavaFileStorageBindings.csproj">
|
||||
<Project>{48574278-4779-4b3a-a9e4-9cf1bc285d0b}</Project>
|
||||
<Name>JavaFileStorageBindings</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\KeePassLib2Android\KeePassLib2Android.csproj">
|
||||
<Project>{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}</Project>
|
||||
<Name>KeePassLib2Android</Name>
|
||||
|
Loading…
Reference in New Issue
Block a user