Compare commits
13 Commits
1.07
...
1.06f-none
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8468049935 | ||
![]() |
7cef6c8566 | ||
![]() |
98f2a139e9 | ||
![]() |
832d3b3a95 | ||
![]() |
37867634cd | ||
![]() |
d9713f8e18 | ||
![]() |
c583b58cb9 | ||
![]() |
bfeaf5dbf5 | ||
![]() |
0907fa5685 | ||
![]() |
ff8dc76c75 | ||
![]() |
0b09e2790f | ||
![]() |
781350aa5f | ||
![]() |
9716130336 |
@@ -15,4 +15,4 @@ Beta-releases can be obtained by opting in to the [Beta testing channel](https:/
|
||||
# How do I learn more?
|
||||
Please see the [documentation](Documentation.md).
|
||||
|
||||
[](https://www.bitrise.io/app/43a23ab54dee9f7e)
|
||||
[](https://www.bitrise.io/app/43a23ab54dee9f7e)
|
||||
|
Before Width: | Height: | Size: 3.3 KiB |
@@ -1,64 +0,0 @@
|
||||
<?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>{0B109C0E-0514-4340-8779-5BD6A0DDE84E}</ProjectGuid>
|
||||
<ProjectTypeGuids>{10368E6C-D01B-4462-8E8B-01FC667A7035};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>AdalBindings</RootNamespace>
|
||||
<AssemblyName>AdalBindings</AssemblyName>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk>
|
||||
<TargetFrameworkVersion>v8.1</TargetFrameworkVersion>
|
||||
</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="System" />
|
||||
<Reference Include="System.Core" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Jars\AboutJars.txt" />
|
||||
<None Include="Additions\AboutAdditions.txt" />
|
||||
<LibraryProjectZip Include="Jars\adal-1.14.0.aar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<TransformFile Include="Transforms\Metadata.xml" />
|
||||
<TransformFile Include="Transforms\EnumFields.xml" />
|
||||
<TransformFile Include="Transforms\EnumMethods.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\gson-2.3.1.jar" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.Bindings.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>
|
@@ -1,48 +0,0 @@
|
||||
Additions allow you to add arbitrary C# to the generated classes
|
||||
before they are compiled. This can be helpful for providing convenience
|
||||
methods or adding pure C# classes.
|
||||
|
||||
== Adding Methods to Generated Classes ==
|
||||
|
||||
Let's say the library being bound has a Rectangle class with a constructor
|
||||
that takes an x and y position, and a width and length size. It will look like
|
||||
this:
|
||||
|
||||
public partial class Rectangle
|
||||
{
|
||||
public Rectangle (int x, int y, int width, int height)
|
||||
{
|
||||
// JNI bindings
|
||||
}
|
||||
}
|
||||
|
||||
Imagine we want to add a constructor to this class that takes a Point and
|
||||
Size structure instead of 4 ints. We can add a new file called Rectangle.cs
|
||||
with a partial class containing our new method:
|
||||
|
||||
public partial class Rectangle
|
||||
{
|
||||
public Rectangle (Point location, Size size) :
|
||||
this (location.X, location.Y, size.Width, size.Height)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
At compile time, the additions class will be added to the generated class
|
||||
and the final assembly will a Rectangle class with both constructors.
|
||||
|
||||
|
||||
== Adding C# Classes ==
|
||||
|
||||
Another thing that can be done is adding fully C# managed classes to the
|
||||
generated library. In the above example, let's assume that there isn't a
|
||||
Point class available in Java or our library. The one we create doesn't need
|
||||
to interact with Java, so we'll create it like a normal class in C#.
|
||||
|
||||
By adding a Point.cs file with this class, it will end up in the binding library:
|
||||
|
||||
public class Point
|
||||
{
|
||||
public int X { get; set; }
|
||||
public int Y { get; set; }
|
||||
}
|
@@ -1,24 +0,0 @@
|
||||
This directory is for Android .jars.
|
||||
|
||||
There are 2 types of jars that are supported:
|
||||
|
||||
== Input Jar ==
|
||||
|
||||
This is the jar that bindings should be generated for.
|
||||
|
||||
For example, if you were binding the Google Maps library, this would
|
||||
be Google's "maps.jar".
|
||||
|
||||
Set the build action for these jars in the properties page to "InputJar".
|
||||
|
||||
|
||||
== Reference Jars ==
|
||||
|
||||
These are jars that are referenced by the input jar. C# bindings will
|
||||
not be created for these jars. These jars will be used to resolve
|
||||
types used by the input jar.
|
||||
|
||||
NOTE: Do not add "android.jar" as a reference jar. It will be added automatically
|
||||
based on the Target Framework selected.
|
||||
|
||||
Set the build action for these jars in the properties page to "ReferenceJar".
|
@@ -1,30 +0,0 @@
|
||||
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("AdalBindings")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("AdalBindings")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2018")]
|
||||
[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")]
|
@@ -1,14 +0,0 @@
|
||||
<enum-field-mappings>
|
||||
<!--
|
||||
This example converts the constants Fragment_id, Fragment_name,
|
||||
and Fragment_tag from android.support.v4.app.FragmentActivity.FragmentTag
|
||||
to an enum called Android.Support.V4.App.FragmentTagType with values
|
||||
Id, Name, and Tag.
|
||||
|
||||
<mapping jni-class="android/support/v4/app/FragmentActivity$FragmentTag" clr-enum-type="Android.Support.V4.App.FragmentTagType">
|
||||
<field jni-name="Fragment_name" clr-name="Name" value="0" />
|
||||
<field jni-name="Fragment_id" clr-name="Id" value="1" />
|
||||
<field jni-name="Fragment_tag" clr-name="Tag" value="2" />
|
||||
</mapping>
|
||||
-->
|
||||
</enum-field-mappings>
|
@@ -1,13 +0,0 @@
|
||||
<enum-method-mappings>
|
||||
<!--
|
||||
This example changes the Java method:
|
||||
android.support.v4.app.Fragment.SavedState.writeToParcel (int flags)
|
||||
to be:
|
||||
android.support.v4.app.Fragment.SavedState.writeToParcel (Android.OS.ParcelableWriteFlags flags)
|
||||
when bound in C#.
|
||||
|
||||
<mapping jni-class="android/support/v4/app/Fragment.SavedState">
|
||||
<method jni-name="writeToParcel" parameter="flags" clr-enum-type="Android.OS.ParcelableWriteFlags" />
|
||||
</mapping>
|
||||
-->
|
||||
</enum-method-mappings>
|
@@ -1,13 +0,0 @@
|
||||
<metadata>
|
||||
<!--
|
||||
This sample removes the class: android.support.v4.content.AsyncTaskLoader.LoadTask:
|
||||
<remove-node path="/api/package[@name='android.support.v4.content']/class[@name='AsyncTaskLoader.LoadTask']" />
|
||||
|
||||
This sample removes the method: android.support.v4.content.CursorLoader.loadInBackground:
|
||||
<remove-node path="/api/package[@name='android.support.v4.content']/class[@name='CursorLoader']/method[@name='loadInBackground']" />
|
||||
-->
|
||||
<remove-node path="/api/package[@name='com.microsoft.aad.adal']/class[@name='AuthenticationActivity']" />
|
||||
<remove-node path="/api/package[@name='com.microsoft.aad.adal']/class[@name='DateTimeAdapter']" />
|
||||
<remove-node path="/api/package[@name='com.microsoft.aad.adal']" />
|
||||
|
||||
</metadata>
|
@@ -60,6 +60,7 @@
|
||||
</LibraryProjectZip>
|
||||
<None Include="Jars\AboutJars.txt" />
|
||||
<None Include="Additions\AboutAdditions.txt" />
|
||||
<LibraryProjectZip Include="Jars\adal-1.14.0.aar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<TransformFile Include="Transforms\Metadata.xml" />
|
||||
@@ -80,13 +81,6 @@
|
||||
<Visible>False</Visible>
|
||||
</XamarinComponentReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AdalBindings\AdalBindings.csproj">
|
||||
<Project>{0b109c0e-0514-4340-8779-5bd6a0dde84e}</Project>
|
||||
<Name>AdalBindings</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\PCloudBindings\PCloudBindings.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\okhttp-digest-1.7.jar" />
|
||||
</ItemGroup>
|
||||
|
@@ -11,8 +11,6 @@
|
||||
<remove-node path="/api/package[@name='com.jcraft.jsch.jcraft']" />
|
||||
<remove-node path="/api/package[@name='com.jcraft.jzlib']" />
|
||||
|
||||
<remove-node path="/api/package[@name='com.pcloud.sdk']" />
|
||||
|
||||
<remove-node path="/api/package[@name='com.dropbox.core']" />
|
||||
<remove-node path="/api/package[@name='com.dropbox.core.util']" />
|
||||
<remove-node path="/api/package[@name='com.dropbox.core.http']" />
|
||||
|
116
src/KeePass.sln
@@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27004.2009
|
||||
VisualStudioVersion = 15.0.27130.2010
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeePassLib2Android", "KeePassLib2Android\KeePassLib2Android.csproj", "{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}"
|
||||
EndProject
|
||||
@@ -13,8 +13,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kp2aBusinessLogic", "Kp2aBu
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TwofishCipher", "TwofishCipher\TwofishCipher.csproj", "{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JavaFileStorageBindings", "JavaFileStorageBindings\JavaFileStorageBindings.csproj", "{48574278-4779-4B3A-A9E4-9CF1BC285D0B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AndroidFileChooserBinding", "AndroidFileChooserBinding\AndroidFileChooserBinding.csproj", "{3C0F7FE5-639F-4422-A087-8B26CF862D1B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KP2AKdbLibraryBinding", "KP2AKdbLibraryBinding\KP2AKdbLibraryBinding.csproj", "{70D3844A-D9FA-4A64-B205-A84C6A822196}"
|
||||
@@ -23,14 +21,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginSdkBinding", "PluginS
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZlibAndroid", "ZlibAndroid\ZlibAndroid.csproj", "{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Net.FtpClient.Android", "netftpandroid\System.Net.FtpClient\System.Net.FtpClient.Android.csproj", "{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SamsungPass", "SamsungPass\Xamarin.SamsungPass\SamsungPass\SamsungPass.csproj", "{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PCloudBindings", "PCloudBindings\PCloudBindings.csproj", "{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdalBindings", "AdalBindings\AdalBindings.csproj", "{0B109C0E-0514-4340-8779-5BD6A0DDE84E}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -113,8 +105,8 @@ Global
|
||||
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Release|Win32.Build.0 = Release|Any CPU
|
||||
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Release|x64.Build.0 = Release|Any CPU
|
||||
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
|
||||
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
|
||||
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
|
||||
@@ -155,30 +147,6 @@ Global
|
||||
{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
|
||||
{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
|
||||
{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|Win32.Build.0 = Debug|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|Win32.Build.0 = Release|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|x64.Build.0 = Release|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Win32.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Win32.Build.0 = ReleaseNoNet|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|x64.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|x64.Build.0 = ReleaseNoNet|Any CPU
|
||||
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
@@ -191,8 +159,8 @@ Global
|
||||
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
|
||||
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
|
||||
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
|
||||
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
|
||||
@@ -209,8 +177,8 @@ Global
|
||||
{70D3844A-D9FA-4A64-B205-A84C6A822196}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{70D3844A-D9FA-4A64-B205-A84C6A822196}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{70D3844A-D9FA-4A64-B205-A84C6A822196}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
|
||||
{70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
|
||||
{70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
|
||||
{70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
|
||||
@@ -227,8 +195,8 @@ Global
|
||||
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
|
||||
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
|
||||
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
|
||||
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
|
||||
@@ -257,24 +225,6 @@ Global
|
||||
{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
|
||||
{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
|
||||
{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
|
||||
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
|
||||
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
@@ -293,54 +243,6 @@ Global
|
||||
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
|
||||
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|Win32.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|x64.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Debug|Win32.Build.0 = Debug|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Release|Win32.Build.0 = Release|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.Release|x64.Build.0 = Release|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.ReleaseNoNet|Win32.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.ReleaseNoNet|Win32.Build.0 = ReleaseNoNet|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.ReleaseNoNet|x64.ActiveCfg = ReleaseNoNet|Any CPU
|
||||
{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}.ReleaseNoNet|x64.Build.0 = ReleaseNoNet|Any CPU
|
||||
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Debug|Win32.Build.0 = Debug|Any CPU
|
||||
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Release|Win32.Build.0 = Release|Any CPU
|
||||
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.Release|x64.Build.0 = Release|Any CPU
|
||||
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
|
||||
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
|
||||
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
|
||||
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
|
||||
{0B109C0E-0514-4340-8779-5BD6A0DDE84E}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@@ -2,12 +2,12 @@ namespace keepass2android.Io
|
||||
{
|
||||
public partial class DropboxFileStorage
|
||||
{
|
||||
private const string AppKey = "dummy";
|
||||
private const string AppSecret = "dummy";
|
||||
private const string AppKey = "";
|
||||
private const string AppSecret = "";
|
||||
}
|
||||
public partial class DropboxAppFolderFileStorage
|
||||
{
|
||||
private const string AppKey = "dummy";
|
||||
private const string AppSecret = "dummy";
|
||||
private const string AppKey = "";
|
||||
private const string AppSecret = "";
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,23 +0,0 @@
|
||||
using Android.Content;
|
||||
#if !EXCLUDE_JAVAFILESTORAGE
|
||||
|
||||
namespace keepass2android.Io
|
||||
{
|
||||
public partial class PCloudFileStorage: JavaFileStorage
|
||||
{
|
||||
private const string ClientId = "CkRWTQXY6Lm";
|
||||
|
||||
public PCloudFileStorage(Context ctx, IKp2aApp app) :
|
||||
base(new Keepass2android.Javafilestorage.PCloudFileStorage(ctx, ClientId), app)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public override bool UserShouldBackup
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
@@ -5,8 +5,8 @@ namespace keepass2android.Io
|
||||
{
|
||||
public class SftpFileStorage: JavaFileStorage
|
||||
{
|
||||
public SftpFileStorage(Context ctx, IKp2aApp app) :
|
||||
base(new Keepass2android.Javafilestorage.SftpStorage(ctx.ApplicationContext), app)
|
||||
public SftpFileStorage(IKp2aApp app) :
|
||||
base(new Keepass2android.Javafilestorage.SftpStorage(), app)
|
||||
{
|
||||
}
|
||||
|
||||
|
@@ -30,8 +30,7 @@ namespace keepass2android.Io
|
||||
yield return "http";
|
||||
yield return "https";
|
||||
yield return "owncloud";
|
||||
yield return "nextcloud";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool UserShouldBackup
|
||||
@@ -39,15 +38,12 @@ namespace keepass2android.Io
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public static string owncloudPrefix = "owncloud://";
|
||||
public static string nextcloudPrefix = "nextcloud://";
|
||||
|
||||
public static string Owncloud2Webdav(string owncloudUrl, string prefix)
|
||||
public static string Owncloud2Webdav(string owncloudUrl)
|
||||
{
|
||||
|
||||
if (owncloudUrl.StartsWith(prefix))
|
||||
string owncloudPrefix = "owncloud://";
|
||||
if (owncloudUrl.StartsWith(owncloudPrefix))
|
||||
{
|
||||
owncloudUrl = owncloudUrl.Substring(prefix.Length);
|
||||
owncloudUrl = owncloudUrl.Substring(owncloudPrefix.Length);
|
||||
}
|
||||
if (!owncloudUrl.Contains("://"))
|
||||
owncloudUrl = "https://" + owncloudUrl;
|
||||
|
@@ -31,7 +31,7 @@
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<DefineConstants>TRACE;NoNet;EXCLUDE_JAVAFILESTORAGE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
|
||||
@@ -53,7 +53,6 @@
|
||||
<Reference Include="mscorlib" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="Xamarin.Android.Arch.Core.Common, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
@@ -106,21 +105,12 @@
|
||||
<Compile Include="Io\AndroidContentStorage.cs" />
|
||||
<Compile Include="Io\BuiltInFileStorage.cs" />
|
||||
<Compile Include="Io\CachingFileStorage.cs" />
|
||||
<Compile Include="Io\DropboxFileStorage.cs" />
|
||||
<Compile Include="Io\DropboxFileStorageKeys.cs" />
|
||||
<Compile Include="Io\FileDescription.cs" />
|
||||
<Compile Include="Io\FileStorageSetupActivity.cs" />
|
||||
<Compile Include="Io\FileStorageSetupInitiatorActivity.cs" />
|
||||
<Compile Include="Io\GDriveFileStorage.cs" />
|
||||
<Compile Include="Io\IFileStorage.cs" />
|
||||
<Compile Include="Io\IoUtil.cs" />
|
||||
<Compile Include="Io\JavaFileStorage.cs" />
|
||||
<Compile Include="Io\NetFtpFileStorage.cs" />
|
||||
<Compile Include="Io\OfflineSwitchableFileStorage.cs" />
|
||||
<Compile Include="Io\PCloudFileStorage.cs" />
|
||||
<Compile Include="Io\SftpFileStorage.cs" />
|
||||
<Compile Include="Io\OneDriveFileStorage.cs" />
|
||||
<Compile Include="Io\WebDavFileStorage.cs" />
|
||||
<Compile Include="IProgressDialog.cs" />
|
||||
<Compile Include="PreferenceKey.cs" />
|
||||
<Compile Include="SelectStorageLocationActivityBase.cs" />
|
||||
@@ -129,15 +119,15 @@
|
||||
<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\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\LoadDb.cs" />
|
||||
<Compile Include="database\edit\OnFinish.cs" />
|
||||
<Compile Include="database\edit\RunnableOnFinish.cs" />
|
||||
<Compile Include="database\edit\SaveDB.cs" />
|
||||
<Compile Include="database\edit\SaveDb.cs" />
|
||||
<Compile Include="database\edit\SetPassword.cs" />
|
||||
<Compile Include="database\edit\UpdateEntry.cs" />
|
||||
<Compile Include="IKp2aApp.cs" />
|
||||
@@ -156,14 +146,6 @@
|
||||
<Compile Include="Utils\Spr\SprEngine.PickChars.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AdalBindings\AdalBindings.csproj">
|
||||
<Project>{0b109c0e-0514-4340-8779-5bd6a0dde84e}</Project>
|
||||
<Name>AdalBindings</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>
|
||||
@@ -172,10 +154,6 @@
|
||||
<Project>{70D3844A-D9FA-4A64-B205-A84C6A822196}</Project>
|
||||
<Name>KP2AKdbLibraryBinding</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\netftpandroid\System.Net.FtpClient\System.Net.FtpClient.Android.csproj">
|
||||
<Project>{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}</Project>
|
||||
<Name>System.Net.FtpClient.Android</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\TwofishCipher\TwofishCipher.csproj">
|
||||
<Project>{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}</Project>
|
||||
<Name>TwofishCipher</Name>
|
||||
|
@@ -63,9 +63,6 @@
|
||||
<TransformFile Include="Transforms\EnumMethods.xml" />
|
||||
<TransformFile Include="Transforms\Metadata.xml" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.Bindings.targets" />
|
||||
<ItemGroup>
|
||||
<Folder Include="libs\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildExtensionsPath)\Novell\Xamarin.Android.Bindings.targets" />
|
||||
</Project>
|
@@ -1,48 +0,0 @@
|
||||
Additions allow you to add arbitrary C# to the generated classes
|
||||
before they are compiled. This can be helpful for providing convenience
|
||||
methods or adding pure C# classes.
|
||||
|
||||
== Adding Methods to Generated Classes ==
|
||||
|
||||
Let's say the library being bound has a Rectangle class with a constructor
|
||||
that takes an x and y position, and a width and length size. It will look like
|
||||
this:
|
||||
|
||||
public partial class Rectangle
|
||||
{
|
||||
public Rectangle (int x, int y, int width, int height)
|
||||
{
|
||||
// JNI bindings
|
||||
}
|
||||
}
|
||||
|
||||
Imagine we want to add a constructor to this class that takes a Point and
|
||||
Size structure instead of 4 ints. We can add a new file called Rectangle.cs
|
||||
with a partial class containing our new method:
|
||||
|
||||
public partial class Rectangle
|
||||
{
|
||||
public Rectangle (Point location, Size size) :
|
||||
this (location.X, location.Y, size.Width, size.Height)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
At compile time, the additions class will be added to the generated class
|
||||
and the final assembly will a Rectangle class with both constructors.
|
||||
|
||||
|
||||
== Adding C# Classes ==
|
||||
|
||||
Another thing that can be done is adding fully C# managed classes to the
|
||||
generated library. In the above example, let's assume that there isn't a
|
||||
Point class available in Java or our library. The one we create doesn't need
|
||||
to interact with Java, so we'll create it like a normal class in C#.
|
||||
|
||||
By adding a Point.cs file with this class, it will end up in the binding library:
|
||||
|
||||
public class Point
|
||||
{
|
||||
public int X { get; set; }
|
||||
public int Y { get; set; }
|
||||
}
|
@@ -1,24 +0,0 @@
|
||||
This directory is for Android .jars.
|
||||
|
||||
There are 2 types of jars that are supported:
|
||||
|
||||
== Input Jar ==
|
||||
|
||||
This is the jar that bindings should be generated for.
|
||||
|
||||
For example, if you were binding the Google Maps library, this would
|
||||
be Google's "maps.jar".
|
||||
|
||||
Set the build action for these jars in the properties page to "InputJar".
|
||||
|
||||
|
||||
== Reference Jars ==
|
||||
|
||||
These are jars that are referenced by the input jar. C# bindings will
|
||||
not be created for these jars. These jars will be used to resolve
|
||||
types used by the input jar.
|
||||
|
||||
NOTE: Do not add "android.jar" as a reference jar. It will be added automatically
|
||||
based on the Target Framework selected.
|
||||
|
||||
Set the build action for these jars in the properties page to "ReferenceJar".
|
@@ -1,90 +0,0 @@
|
||||
<?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>
|
||||
<ProjectGuid>{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}</ProjectGuid>
|
||||
|
||||
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{10368E6C-D01B-4462-8E8B-01FC667A7035};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<OutputType>Library</OutputType>
|
||||
|
||||
|
||||
|
||||
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>PCloudBindings</RootNamespace>
|
||||
<AssemblyName>PCouldBindings</AssemblyName>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk>
|
||||
<TargetFrameworkVersion>v8.1</TargetFrameworkVersion>
|
||||
</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>0</WarningLevel>
|
||||
|
||||
<AndroidLinkMode>None</AndroidLinkMode>
|
||||
</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>
|
||||
<AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
|
||||
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseNoNet|AnyCPU'">
|
||||
<OutputPath>bin\ReleaseNoNet\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Mono.Android" />
|
||||
<Reference Include="System" />
|
||||
|
||||
<Reference Include="System.Core" />
|
||||
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
|
||||
|
||||
|
||||
<None Include="Jars\AboutJars.txt" />
|
||||
<None Include="Additions\AboutAdditions.txt" />
|
||||
<LibraryProjectZip Include="Jars\pcloud-sdk-android-1.0.1.aar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<TransformFile Include="Transforms\Metadata.xml" />
|
||||
<TransformFile Include="Transforms\EnumFields.xml" />
|
||||
<TransformFile Include="Transforms\EnumMethods.xml" />
|
||||
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.Bindings.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>
|
||||
-->
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\pcloud-sdk-java-core-1.0.1.jar" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@@ -1,30 +0,0 @@
|
||||
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("PCloudBindings")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("PCloudBindings")]
|
||||
[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")]
|
@@ -1,14 +0,0 @@
|
||||
<enum-field-mappings>
|
||||
<!--
|
||||
This example converts the constants Fragment_id, Fragment_name,
|
||||
and Fragment_tag from android.support.v4.app.FragmentActivity.FragmentTag
|
||||
to an enum called Android.Support.V4.App.FragmentTagType with values
|
||||
Id, Name, and Tag.
|
||||
|
||||
<mapping jni-class="android/support/v4/app/FragmentActivity$FragmentTag" clr-enum-type="Android.Support.V4.App.FragmentTagType">
|
||||
<field jni-name="Fragment_name" clr-name="Name" value="0" />
|
||||
<field jni-name="Fragment_id" clr-name="Id" value="1" />
|
||||
<field jni-name="Fragment_tag" clr-name="Tag" value="2" />
|
||||
</mapping>
|
||||
-->
|
||||
</enum-field-mappings>
|
@@ -1,13 +0,0 @@
|
||||
<enum-method-mappings>
|
||||
<!--
|
||||
This example changes the Java method:
|
||||
android.support.v4.app.Fragment.SavedState.writeToParcel (int flags)
|
||||
to be:
|
||||
android.support.v4.app.Fragment.SavedState.writeToParcel (Android.OS.ParcelableWriteFlags flags)
|
||||
when bound in C#.
|
||||
|
||||
<mapping jni-class="android/support/v4/app/Fragment.SavedState">
|
||||
<method jni-name="writeToParcel" parameter="flags" clr-enum-type="Android.OS.ParcelableWriteFlags" />
|
||||
</mapping>
|
||||
-->
|
||||
</enum-method-mappings>
|
@@ -1,10 +0,0 @@
|
||||
<metadata>
|
||||
<!--
|
||||
This sample removes the class: android.support.v4.content.AsyncTaskLoader.LoadTask:
|
||||
<remove-node path="/api/package[@name='android.support.v4.content']/class[@name='AsyncTaskLoader.LoadTask']" />
|
||||
|
||||
This sample removes the method: android.support.v4.content.CursorLoader.loadInBackground:
|
||||
<remove-node path="/api/package[@name='android.support.v4.content']/class[@name='CursorLoader']/method[@name='loadInBackground']" />
|
||||
-->
|
||||
<remove-node path="/api/package[@name='com.pcloud.sdk']" />
|
||||
</metadata>
|
@@ -1,20 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo '*****************************************'
|
||||
echo '********** Building Java parts **********'
|
||||
echo '*****************************************'
|
||||
./build-java.sh
|
||||
|
||||
echo '*****************************************'
|
||||
echo '******** Building Xamarin parts *********'
|
||||
echo '*****************************************'
|
||||
./build-xamarin.sh
|
||||
|
||||
echo '*****************************************'
|
||||
echo '************** Building APK *************'
|
||||
echo '*****************************************'
|
||||
./build-apk.sh
|
||||
|
||||
echo
|
||||
echo 'Congratulations! You you can find the target APK in src/keepass2android/bin/Debug/.'
|
@@ -1,8 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
pushd ../keepass2android
|
||||
|
||||
xabuild keepass2android.csproj /t:SignAndroidPackage "$@"
|
||||
|
||||
popd
|
@@ -1,18 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
pushd ../java/
|
||||
|
||||
pushd JavaFileStorageTest-AS
|
||||
./gradlew assemble
|
||||
popd
|
||||
|
||||
pushd KP2ASoftkeyboard_AS
|
||||
./gradlew assemble
|
||||
popd
|
||||
|
||||
pushd Keepass2AndroidPluginSDK2
|
||||
./gradlew assemble
|
||||
popd
|
||||
|
||||
popd
|
@@ -6,11 +6,11 @@ if exist "DropboxFileStorageKeys.cs" (
|
||||
)
|
||||
|
||||
cd ..\..\keepass2android
|
||||
call UseManifestDebug.bat
|
||||
call UseManifestNoNet.bat
|
||||
cd ..
|
||||
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86_amd64
|
||||
|
||||
msbuild KeePass.sln /target:keepass2android /p:BuildProjectReferences=true /p:Configuration="Debug" /p:Platform="Any CPU"
|
||||
msbuild KeePass.sln /target:keepass2android /p:BuildProjectReferences=true /p:Configuration="Release" /p:Platform="Any CPU"
|
||||
|
||||
cd build-scripts
|
@@ -1,25 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
pushd ..
|
||||
|
||||
pushd Kp2aBusinessLogic/Io
|
||||
|
||||
if [ -f "DropboxFileStorageKeys.cs" ]
|
||||
then
|
||||
echo "DropboxFileStorageKeys.cs found."
|
||||
else
|
||||
cp DropboxFileStorageKeysDummy.cs DropboxFileStorageKeys.cs
|
||||
fi
|
||||
|
||||
popd
|
||||
|
||||
pushd keepass2android
|
||||
./UseManifestDebug.sh
|
||||
popd
|
||||
|
||||
# call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86_amd64
|
||||
|
||||
xabuild KeePass.sln /target:keepass2android /p:BuildProjectReferences=true /p:Configuration="Debug" /p:Platform="Any CPU" "$@"
|
||||
|
||||
popd
|
@@ -1,55 +0,0 @@
|
||||
# How to build Keepass2Android
|
||||
|
||||
## Overview
|
||||
|
||||
Keepass2Android is a Mono for Android app. This means that you need Xamarin's Mono for Android to build it. However, it also uses several components written in Java, so there are also Android-Studio projects involved. To make things even worse, parts of the keyboard and kdb-library are written in native code.
|
||||
The current build-scripts assume that the native libraries are already built (they are included in the repo).
|
||||
|
||||
To build KP2A from scratch, make sure that you have Xamarin's Mono for Android installed and also install Android Studio. Make sure that both point to the same Android SDK location.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Install Xamarin.Android
|
||||
- Fetch all submodules (`git submodule init && git submodule update`)
|
||||
|
||||
## Build
|
||||
|
||||
### On Windows
|
||||
|
||||
```bat
|
||||
cd build-scripts
|
||||
build-java.bat
|
||||
build-xamarin.bat
|
||||
```
|
||||
|
||||
build-java.bat will call gradlew for several Java modules. build-xamarin.bat will first make sure that you have all files at their place. (There is a "secret" file for Dropbox SDK keys which is not in the repo, this is replaced with a dummy file. There are also different Android Manifest files depending on the configuration which is selected by calling the appropriate script.)
|
||||
|
||||
**Notes:**
|
||||
|
||||
- For building the java parts, it is suggested to keep a short name (e.g. "c:\projects\keepass2android") for the root project directory. Otherwise the Windows path length limit might be hit when building.
|
||||
- Before building the java parts, make sure you have set the ANDROID_HOME variable or create a local.properties file inside the directories with a gradlew file. It is recommended to use the same SDK location as that of the Xamarin build.
|
||||
|
||||
### On Linux
|
||||
|
||||
- Install [Mono](https://www.mono-project.com/)
|
||||
- Install Xamarin.Android
|
||||
- Option 1: Use the mono-project [CI builds](https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android-linux/lastSuccessfulBuild/Azure/)
|
||||
- Option 2: [Build it from source](https://github.com/xamarin/xamarin-android/blob/master/Documentation/README.md#building-from-source)
|
||||
- Setup your environment:
|
||||
- Add `xabuild` to your path: `export PATH=/path/to/xamarin.android-oss/bin/Release/bin/:$PATH`
|
||||
- Setup your `ANDROID_HOME` if it's not already: `export ANDROID_HOME=/path/to/android/`
|
||||
- Alternatively, you can set your `ANDROID_SDK_PATH` and `ANDROID_NDK_PATH`.
|
||||
- Build [jar2xml](https://github.com/xamarin/jar2xml) and copy `jar2xml.jar` to `/path/to/xamarin.android-oss/bin/Release/lib/xamarin.android/xbuild/Xamarin/Android/`
|
||||
- Install [libzip](https://libzip.org/) for your distribution.
|
||||
- Note: Xamarin seems to require `libzip4`, yet most distributions only ships `libzip5`. As a dirty workaround, it's possible to symlink `libzip.so.5` to `libzip.so.4`. Luckily, it appears to be working.
|
||||
- `sudo ln -s /usr/lib/libzip.so.5 /usr/lib/libzip.so.4`
|
||||
- Install NuGet dependencies:
|
||||
- `cd src/ && nuget restore KeePass.sln`
|
||||
- Build:
|
||||
- Option 1: `cd build-scripts && ./build-all.sh`
|
||||
- Option 2:
|
||||
- Build the Java parts: `cd build-scripts/ && ./build-java.sh`
|
||||
- Build the Xamarin parts: `./build-xamarin.sh`
|
||||
- Build the signed APK: `./build-apk.sh`
|
||||
- Enjoy:
|
||||
- `adb install ../keepass2android/bin/Debug/keepass2android.keepass2android_debug-Signed.apk`
|
23
src/build.readme.txt
Normal file
@@ -0,0 +1,23 @@
|
||||
How to build Keepass2Android
|
||||
|
||||
* Overview *
|
||||
Keepass2Android is a Mono for Android app. This means that you need Xamarin's Mono for Android to build it. However, it also uses several components written in Java, so there are also Android-Studio projects involved. To make things even worse, parts of the keyboard and kdb-library are written in native code.
|
||||
The current build-scripts assume that the native libraries are already built (they are included in the repo).
|
||||
|
||||
To build KP2A from scratch, make sure that you have Xamarin's Mono for Android installed and also install Android Studio. Make sure that both point to the same Android SDK location.
|
||||
|
||||
On Windows you can use
|
||||
|
||||
cd build-scripts
|
||||
build-java.bat
|
||||
build-xamarin.bat
|
||||
|
||||
build-java.bat will call gradlew for several Java modules. build-xamarin.bat will first make sure that you have all files at their place. (There is a "secret" file for Dropbox SDK keys which is not in the repo, this is replaced with a dummy file. There are also different Android Manifest files depending on the configuration which is selected by calling the appropriate script.)
|
||||
|
||||
|
||||
* Notes *
|
||||
- Please don't forget to update the git submodules before building.
|
||||
- For building the java parts on Windows, it is suggested to keep a short name (e.g. "c:\projects\keepass2android") for the root project directory. Otherwise the Windows path length limit might be hit when building.
|
||||
- Before building the java parts, make sure you have set the ANDROID_HOME variable or create a local.properties file inside the directories with a gradlew file. It is recommended to use the same SDK location as that of the Xamarin build.
|
||||
|
||||
|
@@ -35,8 +35,6 @@ dependencies {
|
||||
compile('com.onedrive.sdk:onedrive-sdk-android:1.2.0') {
|
||||
transitive = false
|
||||
}
|
||||
compile 'com.pcloud.sdk:java-core:1.0.1'
|
||||
compile 'com.pcloud.sdk:android:1.0.1'
|
||||
compile 'com.google.code.gson:gson:2.3.1'
|
||||
compile 'com.microsoft.services.msa:msa-auth:0.8.6'
|
||||
compile 'com.microsoft.aad:adal:1.14.0'
|
||||
|
@@ -1,21 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="keepass2android.javafilestorage"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="8"
|
||||
android:targetSdkVersion="14" />
|
||||
|
||||
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
|
||||
|
||||
|
||||
<application>
|
||||
<activity
|
||||
android:name=".NotifSlave"
|
||||
android:label="Keepass2Android"></activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
</manifest>
|
||||
|
@@ -132,7 +132,7 @@ public class FileEntry {
|
||||
|
||||
public boolean checkForFileChangeFast(String path, String previousFileVersion) throws Exception;
|
||||
|
||||
public String getCurrentFileVersionFast(String path) throws Exception;
|
||||
public String getCurrentFileVersionFast(String path);
|
||||
|
||||
public InputStream openFileForRead(String path) throws Exception;
|
||||
|
||||
@@ -157,4 +157,4 @@ public class FileEntry {
|
||||
public void onActivityResult(FileStorageSetupActivity activity, int requestCode, int resultCode, Intent data);
|
||||
public void onRequestPermissionsResult(FileStorageSetupActivity activity, int requestCode, String[] permissions, int[] grantResults);
|
||||
|
||||
}
|
||||
}
|
@@ -1,169 +0,0 @@
|
||||
package keepass2android.javafilestorage;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
//based on https://github.com/jwise/dumload/blob/master/src/com/joshuawise/dumload/NotifSlave.java
|
||||
public class NotifSlave extends Activity {
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
private void say(String s) {
|
||||
Toast.makeText(getApplicationContext(), s, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
private int _nextdialog = 0;
|
||||
private Dialog dialog = null;
|
||||
|
||||
@Override
|
||||
protected Dialog onCreateDialog(int id)
|
||||
{
|
||||
Log.e("KP2AJ.NotifSlave", "Create for dialog "+(Integer.toString(id)));
|
||||
if (id != _nextdialog)
|
||||
return null;
|
||||
return dialog;
|
||||
}
|
||||
|
||||
private void showDialog(Dialog d)
|
||||
{
|
||||
_nextdialog++;
|
||||
dialog = d;
|
||||
Log.e("KP2AJ.NotifSlave", "Attempting to show dialog "+(Integer.toString(_nextdialog)));
|
||||
showDialog(_nextdialog);
|
||||
}
|
||||
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
|
||||
Intent i = getIntent(); /* i *am* not an intent! */
|
||||
final Activity thisact = this;
|
||||
|
||||
final Messenger m = (Messenger)i.getParcelableExtra("keepass2android.sftp.returnmessenger");
|
||||
String reqtype = i.getStringExtra("keepass2android.sftp.reqtype");
|
||||
String prompt = i.getStringExtra("keepass2android.sftp.prompt");
|
||||
|
||||
if (prompt == null || reqtype == null || m == null) /* i.e., we got called by a dummy notification */
|
||||
{
|
||||
this.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
if (reqtype.equals("yesno")) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle("Keepass2Android");
|
||||
builder.setMessage(prompt);
|
||||
builder.setCancelable(false);
|
||||
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
Log.e("KP2AJ.NotifSlave", "Responding with a 1.");
|
||||
try {
|
||||
Message me = Message.obtain();
|
||||
me.arg1 = 1;
|
||||
m.send(me);
|
||||
} catch (Exception e) {
|
||||
Log.e("KP2AJ.NotifSlave", "Failed to send a message back to my buddy.");
|
||||
}
|
||||
dialog.cancel();
|
||||
thisact.finish();
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
Log.e("KP2AJ.NotifSlave", "Responding with a 1.");
|
||||
try {
|
||||
Message me = Message.obtain();
|
||||
me.arg1 = 0;
|
||||
m.send(me);
|
||||
} catch (Exception e) {
|
||||
Log.e("KP2AJ.NotifSlave", "Failed to send a message back to my buddy.");
|
||||
}
|
||||
dialog.cancel();
|
||||
thisact.finish();
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
showDialog(alert);
|
||||
} else if (reqtype.equals("message")) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle("Keepass2Android");
|
||||
builder.setMessage(prompt);
|
||||
builder.setCancelable(false);
|
||||
builder.setNeutralButton("OK", new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
try {
|
||||
Message me = Message.obtain();
|
||||
m.send(me);
|
||||
} catch (Exception e) {
|
||||
Log.e("KP2AJ.NotifSlave", "Failed to send a message back to my buddy.");
|
||||
}
|
||||
dialog.cancel();
|
||||
thisact.finish();
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
showDialog(alert);
|
||||
} /*else if (reqtype.equals("password")) {
|
||||
final Dialog d = new Dialog(this);
|
||||
|
||||
d.setContentView(R.layout.notfif_slave);
|
||||
d.setTitle("Keepass2Android");
|
||||
d.setCancelable(false);
|
||||
|
||||
TextView text = (TextView) d.findViewById(R.id.prompt);
|
||||
text.setText(prompt);
|
||||
|
||||
Button ok = (Button) d.findViewById(R.id.ok);
|
||||
ok.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
try {
|
||||
Message me = Message.obtain();
|
||||
me.arg1 = 1;
|
||||
TextView entry = (TextView) d.findViewById(R.id.entry);
|
||||
Bundle b = new Bundle(1);
|
||||
b.putString("response", entry.getText().toString());
|
||||
me.setData(b);
|
||||
m.send(me);
|
||||
} catch (Exception e) {
|
||||
Log.e("KP2AJ.NotifSlave", "Failed to send a message back to my buddy.");
|
||||
}
|
||||
d.cancel();
|
||||
thisact.finish();
|
||||
}
|
||||
});
|
||||
|
||||
Button cancel = (Button) d.findViewById(R.id.cancel);
|
||||
cancel.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
try {
|
||||
Message me = Message.obtain();
|
||||
me.arg1 = 0;
|
||||
m.send(me);
|
||||
} catch (Exception e) {
|
||||
Log.e("KP2AJ.NotifSlave", "Failed to send a message back to my buddy.");
|
||||
}
|
||||
d.cancel();
|
||||
thisact.finish();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
showDialog(d);
|
||||
} */else {
|
||||
Log.e("KP2AJ.NotifSlave", "What's a "+reqtype+"?");
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,404 +0,0 @@
|
||||
package keepass2android.javafilestorage;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.pcloud.sdk.ApiClient;
|
||||
import com.pcloud.sdk.ApiError;
|
||||
import com.pcloud.sdk.Authenticators;
|
||||
import com.pcloud.sdk.AuthorizationActivity;
|
||||
import com.pcloud.sdk.AuthorizationResult;
|
||||
import com.pcloud.sdk.Call;
|
||||
import com.pcloud.sdk.DataSource;
|
||||
import com.pcloud.sdk.PCloudSdk;
|
||||
import com.pcloud.sdk.RemoteEntry;
|
||||
import com.pcloud.sdk.RemoteFile;
|
||||
import com.pcloud.sdk.RemoteFolder;
|
||||
|
||||
/**
|
||||
* FileStorage implementation for PCloud provider.
|
||||
* https://www.pcloud.com/
|
||||
*/
|
||||
public class PCloudFileStorage extends JavaFileStorageBase
|
||||
{
|
||||
final static private int PCLOUD_AUTHORIZATION_REQUEST_CODE = 1001845497;
|
||||
|
||||
final static private String SHARED_PREF_NAME = "PCLOUD";
|
||||
final static private String SHARED_PREF_AUTH_TOKEN = "AUTH_TOKEN";
|
||||
|
||||
private final Context ctx;
|
||||
|
||||
private ApiClient apiClient;
|
||||
private String clientId;
|
||||
|
||||
public PCloudFileStorage(Context ctx, String clientId) {
|
||||
this.ctx = ctx;
|
||||
this.clientId = clientId;
|
||||
this.apiClient = createApiClientFromSharedPrefs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresSetup(String path) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startSelectFile(FileStorageSetupInitiatorActivity activity, boolean isForSave, int requestCode) {
|
||||
String path = getProtocolId() + "://";
|
||||
activity.startSelectFileProcess(path, isForSave, requestCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareFileUsage(Context appContext, String path) throws Throwable {
|
||||
if (!isConnected()) {
|
||||
throw new UserInteractionRequiredException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareFileUsage(FileStorageSetupInitiatorActivity activity, String path, int requestCode,
|
||||
boolean alwaysReturnSuccess) {
|
||||
if (this.isConnected()) {
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(EXTRA_PATH, path);
|
||||
activity.onImmediateResult(requestCode, RESULT_FILEUSAGE_PREPARED, intent);
|
||||
} else {
|
||||
activity.startFileUsageProcess(path, requestCode, alwaysReturnSuccess);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProtocolId() {
|
||||
return "pcloud";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayName(String path) {
|
||||
return path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFilename(String path) {
|
||||
return path.substring(path.lastIndexOf("/") + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkForFileChangeFast(String path, String previousFileVersion) throws Exception {
|
||||
if (previousFileVersion == null || "".equals(previousFileVersion)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
path = this.cleanPath(path);
|
||||
|
||||
RemoteFile remoteFile = this.getRemoteFileByPath(path);
|
||||
|
||||
return !remoteFile.hash().equals(previousFileVersion);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentFileVersionFast(String path) throws Exception {
|
||||
path = this.cleanPath(path);
|
||||
|
||||
RemoteFile remoteFile = this.getRemoteFileByPath(path);
|
||||
|
||||
return remoteFile.hash();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream openFileForRead(String path) throws Exception {
|
||||
path = this.cleanPath(path);
|
||||
|
||||
RemoteFile remoteFile = this.getRemoteFileByPath(path);
|
||||
|
||||
return remoteFile.byteStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uploadFile(String path, byte[] data, boolean writeTransactional) throws Exception {
|
||||
path = this.cleanPath(path);
|
||||
|
||||
DataSource dataSource = DataSource.create(data);
|
||||
String filename = path.substring(path.lastIndexOf("/") + 1);
|
||||
String filePath = path.substring(0, path.lastIndexOf("/") + 1);
|
||||
RemoteFolder remoteFolder = this.getRemoteFolderByPath(filePath);
|
||||
|
||||
try {
|
||||
this.apiClient.createFile(remoteFolder, filename, dataSource).execute();
|
||||
} catch (ApiError e) {
|
||||
throw convertApiError(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createFolder(String parentPath, String newDirName) throws Exception {
|
||||
String parentPathWithoutProtocol = this.cleanPath(parentPath);
|
||||
|
||||
RemoteFolder remoteFolder = this.getRemoteFolderByPath(parentPathWithoutProtocol);
|
||||
|
||||
try {
|
||||
this.apiClient.createFolder(remoteFolder, newDirName).execute();
|
||||
} catch (ApiError e) {
|
||||
throw convertApiError(e);
|
||||
}
|
||||
|
||||
return this.createFilePath(parentPath, newDirName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createFilePath(String parentPath, String newFileName) throws Exception {
|
||||
return (
|
||||
this.getProtocolId() + "://" +
|
||||
this.cleanPath(parentPath) +
|
||||
("".equals(newFileName) ? "" : "/") +
|
||||
newFileName
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FileEntry> listFiles(String parentPath) throws Exception {
|
||||
parentPath = this.cleanPath(parentPath);
|
||||
|
||||
ArrayList<FileEntry> fileEntries = new ArrayList<>();
|
||||
|
||||
RemoteFolder remoteFolder = this.getRemoteFolderByPath(parentPath);
|
||||
|
||||
for (RemoteEntry remoteEntry : remoteFolder.children()) {
|
||||
fileEntries.add(this.convertRemoteEntryToFileEntry(remoteEntry, parentPath));
|
||||
}
|
||||
|
||||
return fileEntries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileEntry getFileEntry(String path) throws Exception {
|
||||
path = this.cleanPath(path);
|
||||
|
||||
RemoteEntry remoteEntry = this.getRemoteEntryByPath(path);
|
||||
|
||||
return this.convertRemoteEntryToFileEntry(
|
||||
remoteEntry,
|
||||
path.substring(0, path.lastIndexOf("/"))
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(String path) throws Exception {
|
||||
path = this.cleanPath(path);
|
||||
|
||||
RemoteEntry remoteEntry = this.getRemoteFileByPath(path);
|
||||
|
||||
try {
|
||||
this.apiClient.delete(remoteEntry).execute();
|
||||
} catch (ApiError e) {
|
||||
throw convertApiError(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(FileStorageSetupActivity activity, Bundle savedInstanceState) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume(FileStorageSetupActivity activity) {
|
||||
if (activity.getProcessName().equals(PROCESS_NAME_SELECTFILE)) {
|
||||
activity.getState().putString(EXTRA_PATH, activity.getPath());
|
||||
}
|
||||
|
||||
if (this.isConnected()) {
|
||||
finishActivityWithSuccess(activity);
|
||||
} else if (!activity.getState().getBoolean("hasStartedAuth", false)) {
|
||||
Activity castedActivity = (Activity)activity;
|
||||
Intent authIntent = AuthorizationActivity.createIntent(castedActivity, this.clientId);
|
||||
castedActivity.startActivityForResult(authIntent, PCLOUD_AUTHORIZATION_REQUEST_CODE);
|
||||
activity.getState().putBoolean("hasStartedAuth", true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(FileStorageSetupActivity activity, int requestCode, int resultCode, Intent data) {
|
||||
if (requestCode == PCLOUD_AUTHORIZATION_REQUEST_CODE && data != null) {
|
||||
activity.getState().putBoolean("hasStartedAuth", false);
|
||||
AuthorizationResult result = (AuthorizationResult)(
|
||||
data.getSerializableExtra(AuthorizationActivity.KEY_AUTHORIZATION_RESULT)
|
||||
);
|
||||
this.handleAuthResult(activity, result, data);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleAuthResult(FileStorageSetupActivity activity, AuthorizationResult authorizationResult,
|
||||
Intent data) {
|
||||
if (authorizationResult == AuthorizationResult.ACCESS_GRANTED) {
|
||||
String authToken = data.getStringExtra(AuthorizationActivity.KEY_ACCESS_TOKEN);
|
||||
setAuthToken(authToken);
|
||||
finishActivityWithSuccess(activity);
|
||||
} else {
|
||||
Activity castedActivity = (Activity)activity;
|
||||
Intent resultData = new Intent();
|
||||
resultData.putExtra(EXTRA_ERROR_MESSAGE, "Authentication failed.");
|
||||
castedActivity.setResult(Activity.RESULT_CANCELED, resultData);
|
||||
castedActivity.finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(FileStorageSetupActivity activity) {
|
||||
|
||||
}
|
||||
|
||||
private ApiClient createApiClientFromSharedPrefs() {
|
||||
SharedPreferences prefs = this.ctx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
|
||||
String authToken = prefs.getString(SHARED_PREF_AUTH_TOKEN, null);
|
||||
return this.createApiClient(authToken);
|
||||
}
|
||||
|
||||
private ApiClient createApiClient(String authToken) {
|
||||
if (authToken == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
PCloudSdk.newClientBuilder()
|
||||
.authenticator(Authenticators.newOAuthAuthenticator(authToken))
|
||||
.create()
|
||||
);
|
||||
}
|
||||
|
||||
private boolean isConnected() {
|
||||
return (this.apiClient != null);
|
||||
}
|
||||
|
||||
private void clearAuthToken() {
|
||||
this.apiClient = null;
|
||||
SharedPreferences prefs = this.ctx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.clear();
|
||||
edit.apply();
|
||||
}
|
||||
|
||||
private void setAuthToken(String authToken) {
|
||||
this.apiClient = this.createApiClient(authToken);
|
||||
SharedPreferences prefs = this.ctx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putString(SHARED_PREF_AUTH_TOKEN, authToken);
|
||||
edit.apply();
|
||||
}
|
||||
|
||||
private String cleanPath(String path) {
|
||||
return (
|
||||
"/" + path.replaceAll("^(" + Pattern.quote(this.getProtocolId()) + "://)?/*", "")
|
||||
);
|
||||
}
|
||||
|
||||
private RemoteFile getRemoteFileByPath(String path) throws Exception {
|
||||
RemoteEntry remoteEntry = this.getRemoteEntryByPath(path);
|
||||
|
||||
try {
|
||||
return remoteEntry.asFile();
|
||||
} catch (IllegalStateException e) {
|
||||
throw new FileNotFoundException(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private RemoteFolder getRemoteFolderByPath(String path) throws Exception {
|
||||
RemoteEntry remoteEntry = this.getRemoteEntryByPath(path);
|
||||
|
||||
try {
|
||||
return remoteEntry.asFolder();
|
||||
} catch (IllegalStateException e) {
|
||||
throw new FileNotFoundException(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private RemoteEntry getRemoteEntryByPath(String path) throws Exception {
|
||||
Call<RemoteFolder> call = this.apiClient.listFolder(RemoteFolder.ROOT_FOLDER_ID, true);
|
||||
|
||||
RemoteFolder folder;
|
||||
try {
|
||||
folder = call.execute();
|
||||
} catch (ApiError apiError) {
|
||||
throw convertApiError(apiError);
|
||||
}
|
||||
|
||||
if ("/".equals(path)) {
|
||||
return folder;
|
||||
}
|
||||
|
||||
String[] fileNames = path.substring(1).split("/");
|
||||
RemoteFolder currentFolder = folder;
|
||||
Iterator<String> fileNamesIterator = Arrays.asList(fileNames).iterator();
|
||||
while (true) {
|
||||
String fileName = fileNamesIterator.next();
|
||||
|
||||
Iterator<RemoteEntry> entryIterator = currentFolder.children().iterator();
|
||||
while (true) {
|
||||
RemoteEntry remoteEntry;
|
||||
try {
|
||||
remoteEntry = entryIterator.next();
|
||||
} catch (NoSuchElementException e) {
|
||||
throw new FileNotFoundException(e.toString());
|
||||
}
|
||||
|
||||
if (currentFolder.folderId() == remoteEntry.parentFolderId() && fileName.equals(remoteEntry.name())) {
|
||||
if (!fileNamesIterator.hasNext()) {
|
||||
return remoteEntry;
|
||||
}
|
||||
|
||||
try {
|
||||
currentFolder = remoteEntry.asFolder();
|
||||
} catch (IllegalStateException e) {
|
||||
throw new FileNotFoundException(e.toString());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Exception convertApiError(ApiError e) {
|
||||
String strErrorCode = String.valueOf(e.errorCode());
|
||||
if (strErrorCode.startsWith("1") || "2000".equals(strErrorCode)) {
|
||||
this.clearAuthToken();
|
||||
return new UserInteractionRequiredException("Unlinked from PCloud! User must re-link.", e);
|
||||
} else if (strErrorCode.startsWith("2")) {
|
||||
return new FileNotFoundException(e.toString());
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
private FileEntry convertRemoteEntryToFileEntry(RemoteEntry remoteEntry, String parentPath) {
|
||||
FileEntry fileEntry = new FileEntry();
|
||||
fileEntry.canRead = true;
|
||||
fileEntry.canWrite = true;
|
||||
fileEntry.path = (
|
||||
this.getProtocolId() + "://" +
|
||||
("/".equals(parentPath) ? "" : parentPath) +
|
||||
"/" + remoteEntry.name()
|
||||
);
|
||||
fileEntry.displayName = remoteEntry.name();
|
||||
fileEntry.isDirectory = !remoteEntry.isFile();
|
||||
fileEntry.lastModifiedTime = remoteEntry.lastModified().getTime();
|
||||
|
||||
if (remoteEntry.isFile()) {
|
||||
fileEntry.sizeInBytes = remoteEntry.asFile().size();
|
||||
}
|
||||
|
||||
return fileEntry;
|
||||
}
|
||||
}
|
@@ -2,9 +2,7 @@ package keepass2android.javafilestorage;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
@@ -15,7 +13,6 @@ import com.jcraft.jsch.ChannelSftp;
|
||||
import com.jcraft.jsch.ChannelSftp.LsEntry;
|
||||
import com.jcraft.jsch.JSch;
|
||||
import com.jcraft.jsch.JSchException;
|
||||
import com.jcraft.jsch.KeyPair;
|
||||
import com.jcraft.jsch.Session;
|
||||
import com.jcraft.jsch.SftpATTRS;
|
||||
import com.jcraft.jsch.SftpException;
|
||||
@@ -24,7 +21,6 @@ import com.jcraft.jsch.UserInfo;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
public class SftpStorage extends JavaFileStorageBase {
|
||||
|
||||
@@ -39,10 +35,8 @@ public class SftpStorage extends JavaFileStorageBase {
|
||||
public String localPath;
|
||||
public int port;
|
||||
}
|
||||
Context _appContext;
|
||||
|
||||
public SftpStorage(Context appContext) {
|
||||
_appContext = appContext;
|
||||
public SftpStorage() {
|
||||
|
||||
}
|
||||
|
||||
@@ -324,28 +318,12 @@ public class SftpStorage extends JavaFileStorageBase {
|
||||
jsch = new JSch();
|
||||
ConnectionInfo ci = splitStringToConnectionInfo(filename);
|
||||
|
||||
String base_dir = getBaseDir();
|
||||
jsch.setKnownHosts(base_dir + "/known_hosts");
|
||||
|
||||
String key_filename = getKeyFileName();
|
||||
try{
|
||||
createKeyPair(key_filename);
|
||||
} catch (Exception ex) {
|
||||
System.out.println(ex);
|
||||
}
|
||||
|
||||
try {
|
||||
jsch.addIdentity(key_filename);
|
||||
} catch (java.lang.Exception e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Session session = jsch.getSession(ci.username, ci.host, ci.port);
|
||||
UserInfo ui = new SftpUserInfo(ci.password,_appContext);
|
||||
UserInfo ui = new SftpUserInfo(ci.password);
|
||||
session.setUserInfo(ui);
|
||||
|
||||
session.setConfig("PreferredAuthentications", "publickey,password");
|
||||
session.setConfig("PreferredAuthentications",
|
||||
"password,publickey");
|
||||
|
||||
session.connect();
|
||||
|
||||
@@ -358,37 +336,6 @@ public class SftpStorage extends JavaFileStorageBase {
|
||||
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private String getBaseDir() {
|
||||
return _appContext.getFilesDir().getAbsolutePath();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private String getKeyFileName() {
|
||||
return getBaseDir() + "/id_kp2a_rsa";
|
||||
}
|
||||
|
||||
public String createKeyPair() throws IOException, JSchException {
|
||||
return createKeyPair(getKeyFileName());
|
||||
|
||||
}
|
||||
|
||||
private String createKeyPair(String key_filename) throws JSchException, IOException {
|
||||
String public_key_filename = key_filename + ".pub";
|
||||
File file = new File(key_filename);
|
||||
if (file.exists())
|
||||
return public_key_filename;
|
||||
int type = KeyPair.RSA;
|
||||
KeyPair kpair = KeyPair.genKeyPair(jsch, type, 2048);
|
||||
kpair.writePrivateKey(key_filename);
|
||||
|
||||
kpair.writePublicKey(public_key_filename, "generated by Keepass2Android");
|
||||
//ret = "Fingerprint: " + kpair.getFingerPrint();
|
||||
kpair.dispose();
|
||||
return public_key_filename;
|
||||
|
||||
}
|
||||
|
||||
public ConnectionInfo splitStringToConnectionInfo(String filename)
|
||||
throws UnsupportedEncodingException {
|
||||
ConnectionInfo ci = new ConnectionInfo();
|
||||
|
@@ -1,119 +1,14 @@
|
||||
package keepass2android.javafilestorage;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.os.SystemClock;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.util.Log;
|
||||
|
||||
import com.jcraft.jsch.UserInfo;
|
||||
|
||||
public class SftpUserInfo implements UserInfo {
|
||||
|
||||
private Object /* pick one type, and fixate on it */ dance(final String type, final String text) /* for inside the thread */
|
||||
{
|
||||
|
||||
final Message msg = Message.obtain();
|
||||
|
||||
/* t(*A*t) */
|
||||
Thread t = new Thread() {
|
||||
public void run() {
|
||||
Looper.prepare();
|
||||
int bogon = (int)SystemClock.elapsedRealtime();
|
||||
|
||||
NotificationManager mNotificationManager = (NotificationManager)_appContext.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(_appContext);
|
||||
builder.setContentText("SFTP prompt");
|
||||
builder.setSmallIcon(R.drawable.ic_logo_green_foreground);
|
||||
|
||||
|
||||
Handler h = new Handler() {
|
||||
public void handleMessage(Message M) {
|
||||
msg.copyFrom(M);
|
||||
Looper.myLooper().quit();
|
||||
}
|
||||
};
|
||||
Messenger m = new Messenger(h);
|
||||
|
||||
Intent intent = new Intent(_appContext, NotifSlave.class);
|
||||
|
||||
intent.setAction("keepass2android.sftp.NotifSlave");
|
||||
intent.putExtra("keepass2android.sftp.returnmessenger", m);
|
||||
intent.putExtra("keepass2android.sftp.reqtype", type);
|
||||
intent.putExtra("keepass2android.sftp.prompt", text);
|
||||
intent.setData((Uri.parse("suckit://"+SystemClock.elapsedRealtime())));
|
||||
|
||||
PendingIntent contentIntent = PendingIntent.getActivity(_appContext, 0, intent, 0);
|
||||
builder.setContentIntent(contentIntent);
|
||||
|
||||
{
|
||||
Intent directIntent = new Intent(_appContext, NotifSlave.class);
|
||||
directIntent.setAction("keepass2android.sftp.NotifSlave");
|
||||
directIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
|
||||
directIntent.putExtra("keepass2android.sftp.returnmessenger", m);
|
||||
directIntent.putExtra("keepass2android.sftp.reqtype", type);
|
||||
directIntent.putExtra("keepass2android.sftp.prompt", text);
|
||||
directIntent.setData((Uri.parse("suckit://" + SystemClock.elapsedRealtime())));
|
||||
_appContext.startActivity(directIntent);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Log.e("KP2AJFS[thread]", "Notifying...");
|
||||
|
||||
mNotificationManager.notify(bogon, builder.build());
|
||||
|
||||
|
||||
|
||||
Log.e("KP2AJFS[thread]", "About to go to 'sleep'...");
|
||||
Looper.loop();
|
||||
Log.e("KP2AJFS[thread]", "And we're alive!");
|
||||
|
||||
Log.e("KP2AJFS[thread]", "result was: "+(Integer.toString(msg.arg1)));
|
||||
|
||||
mNotificationManager.cancel(bogon);
|
||||
}
|
||||
};
|
||||
|
||||
t.start();
|
||||
try {
|
||||
t.join();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (type.equals("yesno"))
|
||||
return new Boolean(msg.arg1 == 1);
|
||||
else if (type.equals("message"))
|
||||
return null;
|
||||
else if (type.equals("password")) {
|
||||
if (msg.arg1 == 0)
|
||||
return null;
|
||||
Bundle b = msg.getData();
|
||||
return b.getString("response");
|
||||
} else
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Context _appContext;
|
||||
|
||||
String _password;
|
||||
|
||||
public SftpUserInfo(String password, Context appContext)
|
||||
{
|
||||
public SftpUserInfo(String password) {
|
||||
_password = password;
|
||||
_appContext = appContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -140,15 +35,12 @@ public class SftpUserInfo implements UserInfo {
|
||||
|
||||
@Override
|
||||
public boolean promptYesNo(String message) {
|
||||
return (Boolean)dance("yesno", message);
|
||||
|
||||
//test with https://www.sftp.net/public-online-sftp-servers?
|
||||
return true; //continue all operations without user action
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showMessage(String message)
|
||||
{
|
||||
dance("message", message);
|
||||
public void showMessage(String message) {
|
||||
Log.d("KP2AJ", message);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,4 +0,0 @@
|
||||
<vector android:height="24dp" android:viewportHeight="800.0"
|
||||
android:viewportWidth="800.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#ffffff" android:fillType="evenOdd" android:pathData="m318.7,232c13.6,0 24.6,10.9 24.6,24.4 0,13.5 -11,24.4 -24.6,24.4 -13.6,0 -24.6,-10.9 -24.6,-24.4 0,-13.5 11,-24.4 24.6,-24.4zM453.5,256.4c0,13.5 11,24.4 24.6,24.4 13.6,0 24.6,-10.9 24.6,-24.4 0,-13.5 -11,-24.4 -24.6,-24.4 -13.6,0 -24.6,10.9 -24.6,24.4zM399.8,177.7M140.2,600.6v47h517.3v-47zM140.2,350.9v47h517.3v-47zM140.1,481.2h191.8c-0.8,-4.1 -1.2,-8.3 -1.2,-12.4 0,-12.4 3.4,-24.2 9.9,-34.6L140.1,434.2ZM657.5,481.2v-47L454.9,434.2c6.5,10.4 9.8,22.2 9.8,34.6 0,4.1 -0.4,8.3 -1.2,12.4zM140.1,517.4v47h186.6l14.3,-47zM454.3,517.4 L468.7,564.4h188.8v-47zM432.7,565.8 L411.7,496.9 414.4,495.3c10.3,-5.9 16.7,-16.9 16.7,-28.6 0,-18.2 -15,-33 -33.3,-33 -18.3,0 -33.3,14.8 -33.3,33 0,11.8 6.4,22.7 16.7,28.6l2.7,1.6 -21.1,68.9zM507.5,158.5 L507.7,158.2 543.3,106.9c2.4,-3.5 1.8,-8.1 -1.4,-10.3 -3.2,-2.2 -7.7,-1.1 -10.2,2.4l-37.2,53.5 -0.1,0.3c-29.3,-11.8 -62.1,-18.5 -96.8,-18.5 -35.2,0 -68.5,6.9 -98.1,19L261.8,99c-2.4,-3.5 -7,-4.6 -10.2,-2.4 -3.2,2.2 -3.8,6.8 -1.4,10.3l36.2,52.2c-66.8,32.2 -111.9,92.4 -111.9,161.3h42.9c0,-79.1 80.8,-143.5 180.1,-143.5 99.3,0 180.1,64.3 180.1,143.5h42.9c0.2,-69.3 -45.4,-129.8 -113,-161.9z"/>
|
||||
</vector>
|
0
src/java/JavaFileStorage/gradlew
vendored
Executable file → Normal file
@@ -135,12 +135,7 @@ package com.crocoapps.javafilestoragetest;
|
||||
import group.pals.android.lib.ui.filechooser.FileChooserActivity;
|
||||
import group.pals.android.lib.ui.filechooser.providers.BaseFileProviderUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -531,9 +526,9 @@ public class MainActivity extends Activity implements JavaFileStorage.FileStorag
|
||||
}
|
||||
|
||||
static JavaFileStorage createStorageToTest(Context ctx, Context appContext, boolean simulateRestart) {
|
||||
storageToTest = new SftpStorage(ctx.getApplicationContext());
|
||||
//storageToTest = new SftpStorage();
|
||||
//storageToTest = new SkyDriveFileStorage("000000004010C234", appContext);
|
||||
//storageToTest = new OneDriveStorage(appContext, "000000004010C234");
|
||||
storageToTest = new OneDriveStorage(appContext, "000000004010C234");
|
||||
//storageToTest = new GoogleDriveFileStorage();
|
||||
/*storageToTest = new WebDavStorage(new ICertificateErrorHandler() {
|
||||
@Override
|
||||
@@ -667,20 +662,6 @@ public class MainActivity extends Activity implements JavaFileStorage.FileStorag
|
||||
return this;
|
||||
}
|
||||
|
||||
public static String readStream(InputStream is) {
|
||||
StringBuilder sb = new StringBuilder(512);
|
||||
try {
|
||||
Reader r = new InputStreamReader(is, "UTF-8");
|
||||
int c = 0;
|
||||
while ((c = r.read()) != -1) {
|
||||
sb.append((char) c);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performManualFileSelect(boolean isForSave, final int requestCode,
|
||||
String protocolId)
|
||||
@@ -688,30 +669,6 @@ public class MainActivity extends Activity implements JavaFileStorage.FileStorag
|
||||
if (protocolId.equals("sftp"))
|
||||
{
|
||||
final View view = getLayoutInflater().inflate(R.layout.sftp_credentials, null);
|
||||
|
||||
view.findViewById(R.id.send_public_key).setOnClickListener(v -> {
|
||||
Intent sendIntent = new Intent();
|
||||
|
||||
|
||||
SftpStorage sftpStorage = (SftpStorage)storageToTest;
|
||||
try {
|
||||
String pub_filename = sftpStorage.createKeyPair();
|
||||
|
||||
sendIntent.setAction(Intent.ACTION_SEND);
|
||||
sendIntent.putExtra(Intent.EXTRA_TEXT, readStream(new FileInputStream(pub_filename)));
|
||||
|
||||
sendIntent.putExtra(Intent.EXTRA_SUBJECT, "Keepass2Android sftp public key");
|
||||
sendIntent.setType("text/plain");
|
||||
this.startActivity(Intent.createChooser(sendIntent, "Send public key to..."));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Toast.makeText(this,"Failed to create key pair: " + ex.getMessage(), Toast.LENGTH_LONG);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
new AlertDialog.Builder(this)
|
||||
.setView(view)
|
||||
.setTitle("Enter SFTP credentials")
|
||||
|
@@ -63,9 +63,6 @@
|
||||
android:singleLine="true"
|
||||
android:text="/home/philipp"
|
||||
/>
|
||||
<Button android:id="@+id/send_public_key"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="send public key" />
|
||||
|
||||
|
||||
</LinearLayout>
|
0
src/java/JavaFileStorageTest-AS/gradlew
vendored
Executable file → Normal file
@@ -1368,8 +1368,7 @@ public class KP2AKeyboard extends InputMethodService
|
||||
}
|
||||
|
||||
private void onKp2aPasswordKeyPressed() {
|
||||
if (KeyboardData.availableFields.size() > KeyboardData.kp2aFieldIndex+1) //some entries may have only title, then there are no two buttons available
|
||||
commitStringForTyping(KeyboardData.availableFields.get(KeyboardData.kp2aFieldIndex+1));
|
||||
commitStringForTyping(KeyboardData.availableFields.get(KeyboardData.kp2aFieldIndex+1));
|
||||
}
|
||||
|
||||
|
||||
|
0
src/java/KP2ASoftkeyboard_AS/gradlew
vendored
Executable file → Normal file
0
src/java/Keepass2AndroidPluginSDK2/gradlew
vendored
Executable file → Normal file
@@ -30,61 +30,21 @@ using Android.Widget;
|
||||
using Android.Preferences;
|
||||
using Android.Text.Method;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using Android.Content.PM;
|
||||
using Android.Webkit;
|
||||
using Android.Graphics;
|
||||
using Java.IO;
|
||||
using keepass2android.EntryActivityClasses;
|
||||
using KeePassLib;
|
||||
using KeePassLib.Security;
|
||||
using KeePassLib.Utility;
|
||||
using Keepass2android.Pluginsdk;
|
||||
using keepass2android.Io;
|
||||
using KeePass.DataExchange;
|
||||
using KeePass.Util.Spr;
|
||||
using KeePassLib.Interfaces;
|
||||
using KeePassLib.Serialization;
|
||||
using File = Java.IO.File;
|
||||
using Uri = Android.Net.Uri;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
public class ExportBinaryProcessManager : FileSaveProcessManager
|
||||
{
|
||||
private readonly string _binaryToSave;
|
||||
|
||||
public ExportBinaryProcessManager(int requestCode, Activity activity, string key) : base(requestCode, activity)
|
||||
{
|
||||
_binaryToSave = key;
|
||||
}
|
||||
|
||||
public ExportBinaryProcessManager(int requestCode, EntryActivity activity, Bundle savedInstanceState) : base(requestCode, activity)
|
||||
{
|
||||
_binaryToSave = savedInstanceState.GetString("BinaryToSave", null);
|
||||
}
|
||||
|
||||
protected override void SaveFile(IOConnectionInfo ioc)
|
||||
{
|
||||
var task = new EntryActivity.WriteBinaryTask(_activity, App.Kp2a, new ActionOnFinish(_activity, (success, message, activity) =>
|
||||
{
|
||||
if (!success)
|
||||
Toast.MakeText(activity, message, ToastLength.Long).Show();
|
||||
}
|
||||
), ((EntryActivity)_activity).Entry.Binaries.Get(_binaryToSave), ioc);
|
||||
ProgressTask pt = new ProgressTask(App.Kp2a, _activity, task);
|
||||
pt.Run();
|
||||
|
||||
}
|
||||
|
||||
public override void OnSaveInstanceState(Bundle outState)
|
||||
{
|
||||
outState.PutString("BinaryToSave", _binaryToSave);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
[Activity (Label = "@string/app_name", ConfigurationChanges=ConfigChanges.Orientation|ConfigChanges.KeyboardHidden,
|
||||
Theme = "@style/MyTheme_ActionBar")]
|
||||
@@ -95,12 +55,7 @@ namespace keepass2android
|
||||
public const String KeyCloseAfterCreate = "close_after_create";
|
||||
public const String KeyGroupFullPath = "groupfullpath_key";
|
||||
|
||||
public const int requestCodeBinaryFilename = 42376;
|
||||
public const int requestCodeSelFileStorageForWriteAttachment = 42377;
|
||||
|
||||
|
||||
|
||||
public static void Launch(Activity act, PwEntry pw, int pos, AppTask appTask, ActivityFlags? flags = null)
|
||||
public static void Launch(Activity act, PwEntry pw, int pos, AppTask appTask, ActivityFlags? flags = null)
|
||||
{
|
||||
Intent i = new Intent(act, typeof(EntryActivity));
|
||||
|
||||
@@ -128,7 +83,7 @@ namespace keepass2android
|
||||
_activityDesign = new ActivityDesign(this);
|
||||
}
|
||||
|
||||
public PwEntry Entry;
|
||||
protected PwEntry Entry;
|
||||
|
||||
private static Typeface _passwordFont;
|
||||
|
||||
@@ -157,10 +112,9 @@ namespace keepass2android
|
||||
private PluginActionReceiver _pluginActionReceiver;
|
||||
private PluginFieldReceiver _pluginFieldReceiver;
|
||||
private ActivityDesign _activityDesign;
|
||||
|
||||
|
||||
|
||||
protected void SetEntryView()
|
||||
protected void SetEntryView()
|
||||
{
|
||||
SetContentView(Resource.Layout.entry_view);
|
||||
}
|
||||
@@ -361,14 +315,8 @@ namespace keepass2android
|
||||
|
||||
protected override void OnCreate(Bundle savedInstanceState)
|
||||
{
|
||||
if (savedInstanceState != null)
|
||||
{
|
||||
_exportBinaryProcessManager =
|
||||
new ExportBinaryProcessManager(requestCodeSelFileStorageForWriteAttachment, this, savedInstanceState);
|
||||
|
||||
}
|
||||
|
||||
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(this);
|
||||
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(this);
|
||||
|
||||
long usageCount = prefs.GetLong(GetString(Resource.String.UsageCount_key), 0);
|
||||
|
||||
@@ -578,83 +526,71 @@ namespace keepass2android
|
||||
_popupMenuItems[popupKey] = new List<IPopupMenuItem>();
|
||||
return _popupMenuItems[popupKey];
|
||||
}
|
||||
|
||||
internal Uri WriteBinaryToFile(string key, bool writeToCacheDirectory)
|
||||
{
|
||||
ProtectedBinary pb = Entry.Binaries.Get(key);
|
||||
System.Diagnostics.Debug.Assert(pb != null);
|
||||
if (pb == null)
|
||||
throw new ArgumentException();
|
||||
internal Uri WriteBinaryToFile(string key, bool writeToCacheDirectory)
|
||||
{
|
||||
ProtectedBinary pb = Entry.Binaries.Get(key);
|
||||
System.Diagnostics.Debug.Assert(pb != null);
|
||||
if (pb == null)
|
||||
throw new ArgumentException();
|
||||
|
||||
|
||||
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(this);
|
||||
string binaryDirectory = prefs.GetString(GetString(Resource.String.BinaryDirectory_key),
|
||||
GetString(Resource.String.BinaryDirectory_default));
|
||||
if (writeToCacheDirectory)
|
||||
{
|
||||
binaryDirectory = CacheDir.Path + File.Separator + AttachmentContentProvider.AttachmentCacheSubDir;
|
||||
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(this);
|
||||
string binaryDirectory = prefs.GetString(GetString(Resource.String.BinaryDirectory_key), GetString(Resource.String.BinaryDirectory_default));
|
||||
if (writeToCacheDirectory)
|
||||
binaryDirectory = CacheDir.Path + File.Separator + AttachmentContentProvider.AttachmentCacheSubDir;
|
||||
|
||||
string filepart = key;
|
||||
Java.Lang.String javaFilename = new Java.Lang.String(filepart);
|
||||
filepart = javaFilename.ReplaceAll("[^a-zA-Z0-9.-]", "_");
|
||||
string filepart = key;
|
||||
if (writeToCacheDirectory)
|
||||
filepart = filepart.Replace(" ", "");
|
||||
var targetFile = new File(binaryDirectory, filepart);
|
||||
|
||||
var targetFile = new File(binaryDirectory, filepart);
|
||||
File parent = targetFile.ParentFile;
|
||||
|
||||
File parent = targetFile.ParentFile;
|
||||
if (parent == null || (parent.Exists() && !parent.IsDirectory))
|
||||
{
|
||||
Toast.MakeText(this,
|
||||
Resource.String.error_invalid_path,
|
||||
ToastLength.Long).Show();
|
||||
return null;
|
||||
}
|
||||
|
||||
if (parent == null || (parent.Exists() && !parent.IsDirectory))
|
||||
{
|
||||
Toast.MakeText(this,
|
||||
Resource.String.error_invalid_path,
|
||||
ToastLength.Long).Show();
|
||||
return null;
|
||||
}
|
||||
if (!parent.Exists())
|
||||
{
|
||||
// Create parent directory
|
||||
if (!parent.Mkdirs())
|
||||
{
|
||||
Toast.MakeText(this,
|
||||
Resource.String.error_could_not_create_parent,
|
||||
ToastLength.Long).Show();
|
||||
return null;
|
||||
|
||||
if (!parent.Exists())
|
||||
{
|
||||
// Create parent directory
|
||||
if (!parent.Mkdirs())
|
||||
{
|
||||
Toast.MakeText(this,
|
||||
Resource.String.error_could_not_create_parent,
|
||||
ToastLength.Long).Show();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
string filename = targetFile.AbsolutePath;
|
||||
Uri fileUri = Uri.FromFile(targetFile);
|
||||
|
||||
}
|
||||
}
|
||||
string filename = targetFile.AbsolutePath;
|
||||
|
||||
byte[] pbData = pb.ReadData();
|
||||
try
|
||||
{
|
||||
System.IO.File.WriteAllBytes(filename, pbData);
|
||||
}
|
||||
catch (Exception exWrite)
|
||||
{
|
||||
Toast.MakeText(this,
|
||||
GetString(Resource.String.SaveAttachment_Failed, new Java.Lang.Object[] {filename})
|
||||
+ exWrite.Message, ToastLength.Long).Show();
|
||||
return null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
MemUtil.ZeroByteArray(pbData);
|
||||
}
|
||||
Toast.MakeText(this,
|
||||
GetString(Resource.String.SaveAttachment_doneMessage, new Java.Lang.Object[] {filename}),
|
||||
ToastLength.Short).Show();
|
||||
return Uri.Parse("content://" + AttachmentContentProvider.Authority + "/"
|
||||
+ filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
_exportBinaryProcessManager =
|
||||
new ExportBinaryProcessManager(requestCodeSelFileStorageForWriteAttachment, this, key);
|
||||
_exportBinaryProcessManager.StartProcess();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
byte[] pbData = pb.ReadData();
|
||||
try
|
||||
{
|
||||
System.IO.File.WriteAllBytes(filename, pbData);
|
||||
}
|
||||
catch (Exception exWrite)
|
||||
{
|
||||
Toast.MakeText(this, GetString(Resource.String.SaveAttachment_Failed, new Java.Lang.Object[] { filename })
|
||||
+ exWrite.Message, ToastLength.Long).Show();
|
||||
return null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
MemUtil.ZeroByteArray(pbData);
|
||||
}
|
||||
Toast.MakeText(this, GetString(Resource.String.SaveAttachment_doneMessage, new Java.Lang.Object[] { filename }), ToastLength.Short).Show();
|
||||
if (writeToCacheDirectory)
|
||||
{
|
||||
return Uri.Parse("content://" + AttachmentContentProvider.Authority + "/"
|
||||
+ filename);
|
||||
}
|
||||
return fileUri;
|
||||
}
|
||||
|
||||
internal void OpenBinaryFile(Android.Net.Uri uri)
|
||||
@@ -964,16 +900,10 @@ namespace keepass2android
|
||||
_appTask.ToIntent(ret);
|
||||
SetResult(KeePass.ExitRefresh, ret);
|
||||
}
|
||||
|
||||
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) {
|
||||
|
||||
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) {
|
||||
base.OnActivityResult(requestCode, resultCode, data);
|
||||
|
||||
if (_exportBinaryProcessManager?.OnActivityResult(requestCode, resultCode, data) == true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (AppTask.TryGetFromActivityResult(data, ref _appTask))
|
||||
if (AppTask.TryGetFromActivityResult(data, ref _appTask))
|
||||
{
|
||||
//make sure app task is passed to calling activity.
|
||||
//the result code might be modified later.
|
||||
@@ -993,71 +923,7 @@ namespace keepass2android
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class WriteBinaryTask : RunnableOnFinish
|
||||
{
|
||||
private readonly IKp2aApp _app;
|
||||
private readonly ProtectedBinary _data;
|
||||
private IOConnectionInfo _targetIoc;
|
||||
|
||||
public WriteBinaryTask(Activity activity, IKp2aApp app, OnFinish onFinish, ProtectedBinary data, IOConnectionInfo targetIoc) : base(activity, onFinish)
|
||||
{
|
||||
_app = app;
|
||||
_data = data;
|
||||
_targetIoc = targetIoc;
|
||||
}
|
||||
|
||||
public override void Run()
|
||||
{
|
||||
try
|
||||
{
|
||||
var fileStorage = _app.GetFileStorage(_targetIoc);
|
||||
if (fileStorage is IOfflineSwitchable)
|
||||
{
|
||||
((IOfflineSwitchable)fileStorage).IsOffline = false;
|
||||
}
|
||||
using (var writeTransaction = fileStorage.OpenWriteTransaction(_targetIoc, _app.GetDb().KpDatabase.UseFileTransactions))
|
||||
{
|
||||
Stream sOut = writeTransaction.OpenFile();
|
||||
|
||||
byte[] byteArray = _data.ReadData();
|
||||
sOut.Write(byteArray, 0, byteArray.Length);
|
||||
|
||||
sOut.Close();
|
||||
|
||||
writeTransaction.CommitWrite();
|
||||
|
||||
}
|
||||
if (fileStorage is IOfflineSwitchable)
|
||||
{
|
||||
((IOfflineSwitchable)fileStorage).IsOffline = App.Kp2a.OfflineMode;
|
||||
}
|
||||
|
||||
Finish(true);
|
||||
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Finish(false, ex.Message);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private ExportBinaryProcessManager _exportBinaryProcessManager;
|
||||
|
||||
protected override void OnSaveInstanceState(Bundle outState)
|
||||
{
|
||||
|
||||
|
||||
_exportBinaryProcessManager?.OnSaveInstanceState(outState);
|
||||
|
||||
base.OnSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
public override bool OnCreateOptionsMenu(IMenu menu)
|
||||
public override bool OnCreateOptionsMenu(IMenu menu)
|
||||
{
|
||||
_menu = menu;
|
||||
base.OnCreateOptionsMenu(menu);
|
||||
@@ -1156,12 +1022,7 @@ namespace keepass2android
|
||||
{
|
||||
case Resource.Id.menu_donate:
|
||||
return Util.GotoDonateUrl(this);
|
||||
case Resource.Id.menu_delete:
|
||||
DeleteEntry task = new DeleteEntry(this, App.Kp2a, Entry,
|
||||
new ActionOnFinish(this, (success, message, activity) => { if (success) { RequiresRefresh(); Finish();}}));
|
||||
task.Start();
|
||||
break;
|
||||
case Resource.Id.menu_toggle_pass:
|
||||
case Resource.Id.menu_toggle_pass:
|
||||
if (_showPassword)
|
||||
{
|
||||
item.SetTitle(Resource.String.show_password);
|
||||
|
@@ -279,63 +279,7 @@ namespace keepass2android
|
||||
|
||||
}
|
||||
|
||||
protected override void OnStart()
|
||||
{
|
||||
base.OnStart();
|
||||
if (PreferenceManager.GetDefaultSharedPreferences(this)
|
||||
.GetBoolean(GetString(Resource.String.UseKp2aKeyboardInKp2a_key), false))
|
||||
{
|
||||
CopyToClipboardService.ActivateKeyboard(this);
|
||||
}
|
||||
}
|
||||
|
||||
void AddBinaryOrAsk(Uri filename)
|
||||
{
|
||||
|
||||
string strItem = GetFileName(filename);
|
||||
if (String.IsNullOrEmpty(strItem))
|
||||
strItem = "attachment.bin";
|
||||
|
||||
if (State.Entry.Binaries.Get(strItem) != null)
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.SetTitle(GetString(Resource.String.AskOverwriteBinary_title));
|
||||
|
||||
builder.SetMessage(GetString(Resource.String.AskOverwriteBinary));
|
||||
|
||||
builder.SetPositiveButton(GetString(Resource.String.AskOverwriteBinary_yes), (dlgSender, dlgEvt) =>
|
||||
{
|
||||
AddBinary(filename, true);
|
||||
});
|
||||
|
||||
builder.SetNegativeButton(GetString(Resource.String.AskOverwriteBinary_no), (dlgSender, dlgEvt) =>
|
||||
{
|
||||
AddBinary(filename, false);
|
||||
});
|
||||
|
||||
builder.SetNeutralButton(GetString(Android.Resource.String.Cancel),
|
||||
(dlgSender, dlgEvt) => { });
|
||||
|
||||
Dialog dialog = builder.Create();
|
||||
dialog.Show();
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
AddBinary(filename, true);
|
||||
}
|
||||
|
||||
protected override void OnResume()
|
||||
{
|
||||
if (_uriToAddOrAsk != null)
|
||||
{
|
||||
AddBinaryOrAsk(_uriToAddOrAsk);
|
||||
_uriToAddOrAsk = null;
|
||||
}
|
||||
base.OnResume();
|
||||
}
|
||||
|
||||
private void CreateNewFromKpEntryTemplate(Database db, PwEntry templateEntry)
|
||||
private void CreateNewFromKpEntryTemplate(Database db, PwEntry templateEntry)
|
||||
{
|
||||
var entry = new PwEntry(true, true);
|
||||
KpEntryTemplatedEdit.InitializeEntry(entry, templateEntry);
|
||||
@@ -620,7 +564,41 @@ namespace keepass2android
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void AddBinaryOrAsk(Uri filename)
|
||||
{
|
||||
|
||||
string strItem = GetFileName(filename);
|
||||
if (String.IsNullOrEmpty(strItem))
|
||||
strItem = "attachment.bin";
|
||||
|
||||
if(State.Entry.Binaries.Get(strItem) != null)
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.SetTitle(GetString(Resource.String.AskOverwriteBinary_title));
|
||||
|
||||
builder.SetMessage(GetString(Resource.String.AskOverwriteBinary));
|
||||
|
||||
builder.SetPositiveButton(GetString(Resource.String.AskOverwriteBinary_yes), (dlgSender, dlgEvt) =>
|
||||
{
|
||||
AddBinary(filename, true);
|
||||
});
|
||||
|
||||
builder.SetNegativeButton(GetString(Resource.String.AskOverwriteBinary_no), (dlgSender, dlgEvt) =>
|
||||
{
|
||||
AddBinary(filename, false);
|
||||
});
|
||||
|
||||
builder.SetNeutralButton(GetString(Android.Resource.String.Cancel),
|
||||
(dlgSender, dlgEvt) => {});
|
||||
|
||||
Dialog dialog = builder.Create();
|
||||
dialog.Show();
|
||||
|
||||
|
||||
} else
|
||||
AddBinary(filename, true);
|
||||
}
|
||||
|
||||
void AddBinary(Uri filename, bool overwrite)
|
||||
{
|
||||
string strItem = GetFileName(filename);
|
||||
@@ -774,8 +752,12 @@ namespace keepass2android
|
||||
}
|
||||
uri = Uri.Parse(s);
|
||||
}
|
||||
_uriToAddOrAsk = uri; //we can't launch a dialog in onActivityResult, so delay this to onResume
|
||||
AddBinaryOrAsk(uri);
|
||||
|
||||
}
|
||||
Reload();
|
||||
|
||||
|
||||
break;
|
||||
case Result.Canceled:
|
||||
Reload();
|
||||
@@ -913,7 +895,6 @@ namespace keepass2android
|
||||
|
||||
private string[] _additionalKeys = null;
|
||||
private List<View> _editModeHiddenViews;
|
||||
private Uri _uriToAddOrAsk;
|
||||
|
||||
public string[] AdditionalKeys
|
||||
{
|
||||
|
@@ -13,31 +13,6 @@ using keepass2android.Io;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
public class ExportDbProcessManager: FileSaveProcessManager
|
||||
{
|
||||
private readonly FileFormatProvider _ffp;
|
||||
|
||||
public ExportDbProcessManager(int requestCode, Activity activity, FileFormatProvider ffp) : base(requestCode, activity)
|
||||
{
|
||||
_ffp = ffp;
|
||||
}
|
||||
|
||||
protected override void SaveFile(IOConnectionInfo ioc)
|
||||
{
|
||||
var exportDb = new ExportDatabaseActivity.ExportDb(_activity, App.Kp2a, new ActionOnFinish(_activity, (success, message, activity) =>
|
||||
{
|
||||
if (!success)
|
||||
Toast.MakeText(activity, message, ToastLength.Long).Show();
|
||||
else
|
||||
Toast.MakeText(activity, _activity.GetString(Resource.String.export_database_successful), ToastLength.Long).Show();
|
||||
activity.Finish();
|
||||
}
|
||||
), _ffp, ioc);
|
||||
ProgressTask pt = new ProgressTask(App.Kp2a, _activity, exportDb);
|
||||
pt.Run();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
[Activity(Label = "@string/app_name",
|
||||
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden,
|
||||
@@ -54,9 +29,7 @@ namespace keepass2android
|
||||
|
||||
private int _fileFormatIndex;
|
||||
|
||||
private ExportDbProcessManager _exportDbProcessManager;
|
||||
|
||||
protected override void OnCreate(Android.OS.Bundle savedInstanceState)
|
||||
protected override void OnCreate(Android.OS.Bundle savedInstanceState)
|
||||
{
|
||||
base.OnCreate(savedInstanceState);
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
@@ -64,10 +37,12 @@ namespace keepass2android
|
||||
builder.SetSingleChoiceItems(Resource.Array.export_fileformat_options, _fileFormatIndex,
|
||||
delegate(object sender, DialogClickEventArgs args) { _fileFormatIndex = args.Which; });
|
||||
builder.SetPositiveButton(Android.Resource.String.Ok, delegate
|
||||
{
|
||||
_exportDbProcessManager = new ExportDbProcessManager(0, this, _ffp[_fileFormatIndex]);
|
||||
_exportDbProcessManager.StartProcess();
|
||||
});
|
||||
{
|
||||
Intent intent = new Intent(this, typeof(FileStorageSelectionActivity));
|
||||
//intent.PutExtra(FileStorageSelectionActivity.AllowThirdPartyAppSend, true);
|
||||
|
||||
StartActivityForResult(intent, 0);
|
||||
});
|
||||
builder.SetNegativeButton(Resource.String.cancel, delegate {
|
||||
Finish();
|
||||
});
|
||||
@@ -78,19 +53,143 @@ namespace keepass2android
|
||||
{
|
||||
base.OnActivityResult(requestCode, resultCode, data);
|
||||
|
||||
if (_exportDbProcessManager?.OnActivityResult(requestCode, resultCode, data) == true)
|
||||
return;
|
||||
if (resultCode == KeePass.ExitFileStorageSelectionOk)
|
||||
{
|
||||
string protocolId = data.GetStringExtra("protocolId");
|
||||
if (protocolId == "content")
|
||||
{
|
||||
Util.ShowBrowseDialog(this, RequestCodeDbFilename, true, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
FileSelectHelper fileSelectHelper = new FileSelectHelper(this, true, RequestCodeDbFilename)
|
||||
{
|
||||
DefaultExtension = _ffp[_fileFormatIndex].DefaultExtension
|
||||
};
|
||||
fileSelectHelper.OnOpen += (sender, ioc) =>
|
||||
{
|
||||
ExportTo(ioc);
|
||||
};
|
||||
App.Kp2a.GetFileStorage(protocolId).StartSelectFile(
|
||||
new FileStorageSetupInitiatorActivity(this, OnActivityResult, s => fileSelectHelper.PerformManualFileSelect(s)),
|
||||
true,
|
||||
RequestCodeDbFilename,
|
||||
protocolId);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (resultCode == Result.Ok)
|
||||
{
|
||||
if (requestCode == RequestCodeDbFilename)
|
||||
{
|
||||
|
||||
if (data.Data.Scheme == "content")
|
||||
{
|
||||
if ((int)Android.OS.Build.VERSION.SdkInt >= 19)
|
||||
{
|
||||
//try to take persistable permissions
|
||||
try
|
||||
{
|
||||
Kp2aLog.Log("TakePersistableUriPermission");
|
||||
var takeFlags = data.Flags
|
||||
& (ActivityFlags.GrantReadUriPermission
|
||||
| ActivityFlags.GrantWriteUriPermission);
|
||||
this.ContentResolver.TakePersistableUriPermission(data.Data, takeFlags);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Kp2aLog.Log(e.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
string filename = Util.IntentToFilename(data, this);
|
||||
if (filename == null)
|
||||
filename = data.DataString;
|
||||
|
||||
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(this, new ActionOnFinish(this, (success, messageOrFilename, activity) =>
|
||||
{
|
||||
if (!success)
|
||||
{
|
||||
Toast.MakeText(activity, 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);
|
||||
new FileSelectHelper(this, true, RequestCodeDbFilename)
|
||||
{ DefaultExtension = _ffp[_fileFormatIndex].DefaultExtension}
|
||||
.StartFileChooser(ioc.Path);
|
||||
return;
|
||||
}
|
||||
Finish();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void ExportTo(IOConnectionInfo ioc)
|
||||
{
|
||||
var exportDb = new ExportDb(this, App.Kp2a, new ActionOnFinish(this, (success, message, activity) =>
|
||||
{
|
||||
if (!success)
|
||||
Toast.MakeText(activity, message, ToastLength.Long).Show();
|
||||
else
|
||||
Toast.MakeText(activity, GetString(Resource.String.export_database_successful), ToastLength.Long).Show();
|
||||
activity.Finish();
|
||||
}
|
||||
), _ffp[_fileFormatIndex], ioc);
|
||||
ProgressTask pt = new ProgressTask(App.Kp2a, this, exportDb);
|
||||
pt.Run();
|
||||
}
|
||||
|
||||
protected int RequestCodeDbFilename
|
||||
{
|
||||
get { return 0; }
|
||||
}
|
||||
|
||||
private static string ConvertFilenameToIocPath(string filename)
|
||||
{
|
||||
if ((filename != null) && (filename.StartsWith("file://")))
|
||||
{
|
||||
filename = filename.Substring(7);
|
||||
filename = Java.Net.URLDecoder.Decode(filename);
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
public class ExportDb : RunnableOnFinish
|
||||
{
|
||||
private readonly IKp2aApp _app;
|
||||
|
@@ -1,165 +0,0 @@
|
||||
using System;
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Widget;
|
||||
using keepass2android.Io;
|
||||
using KeePassLib.Serialization;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
public abstract class FileSaveProcessManager
|
||||
{
|
||||
private static string ConvertFilenameToIocPath(string filename)
|
||||
{
|
||||
if ((filename != null) && (filename.StartsWith("file://")))
|
||||
{
|
||||
filename = filename.Substring(7);
|
||||
filename = Java.Net.URLDecoder.Decode(filename);
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
|
||||
protected readonly int _requestCode;
|
||||
protected readonly Activity _activity;
|
||||
|
||||
public FileSaveProcessManager(int requestCode, Activity activity)
|
||||
{
|
||||
_requestCode = requestCode;
|
||||
_activity = activity;
|
||||
}
|
||||
|
||||
public bool OnActivityResult(int requestCode, Result resultCode, Intent data)
|
||||
{
|
||||
|
||||
|
||||
if (requestCode == _requestCode)
|
||||
{
|
||||
if (resultCode == KeePass.ExitFileStorageSelectionOk)
|
||||
{
|
||||
string protocolId = data.GetStringExtra("protocolId");
|
||||
if (protocolId == "content")
|
||||
{
|
||||
Util.ShowBrowseDialog(_activity, _requestCode, true, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
FileSelectHelper fileSelectHelper = new FileSelectHelper(_activity, true, _requestCode);
|
||||
fileSelectHelper.OnOpen += (sender, ioc) =>
|
||||
{
|
||||
SaveFile(ioc);
|
||||
};
|
||||
App.Kp2a.GetFileStorage(protocolId).StartSelectFile(
|
||||
new FileStorageSetupInitiatorActivity(_activity, (i, result, arg3) => OnActivityResult(i, result, arg3), s => fileSelectHelper.PerformManualFileSelect(s)),
|
||||
true,
|
||||
_requestCode,
|
||||
protocolId);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (resultCode == (Result)FileStorageResults.FileUsagePrepared)
|
||||
{
|
||||
var ioc = new IOConnectionInfo();
|
||||
PasswordActivity.SetIoConnectionFromIntent(ioc, data);
|
||||
SaveFile(ioc);
|
||||
return true;
|
||||
}
|
||||
if (resultCode == (Result)FileStorageResults.FileChooserPrepared)
|
||||
{
|
||||
IOConnectionInfo ioc = new IOConnectionInfo();
|
||||
PasswordActivity.SetIoConnectionFromIntent(ioc, data);
|
||||
new FileSelectHelper(_activity, true, _requestCode).StartFileChooser(ioc.Path);
|
||||
return true;
|
||||
}
|
||||
if (resultCode == Result.Ok)
|
||||
{
|
||||
if (requestCode == _requestCode)
|
||||
{
|
||||
|
||||
if (data.Data.Scheme == "content")
|
||||
{
|
||||
if ((int)Android.OS.Build.VERSION.SdkInt >= 19)
|
||||
{
|
||||
//try to take persistable permissions
|
||||
try
|
||||
{
|
||||
Kp2aLog.Log("TakePersistableUriPermission");
|
||||
var takeFlags = data.Flags
|
||||
& (ActivityFlags.GrantReadUriPermission
|
||||
| ActivityFlags.GrantWriteUriPermission);
|
||||
_activity.ContentResolver.TakePersistableUriPermission(data.Data, takeFlags);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Kp2aLog.Log(e.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
string filename = Util.IntentToFilename(data, _activity);
|
||||
if (filename == null)
|
||||
filename = data.DataString;
|
||||
|
||||
bool fileExists = data.GetBooleanExtra("group.pals.android.lib.ui.filechooser.FileChooserActivity.result_file_exists", true);
|
||||
|
||||
if (fileExists)
|
||||
{
|
||||
SaveFile(new IOConnectionInfo { Path = ConvertFilenameToIocPath(filename) });
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
var task = new CreateNewFilename(_activity, new ActionOnFinish(_activity, (success, messageOrFilename, activity) =>
|
||||
{
|
||||
if (!success)
|
||||
{
|
||||
Toast.MakeText(activity, messageOrFilename, ToastLength.Long).Show();
|
||||
return;
|
||||
}
|
||||
SaveFile(new IOConnectionInfo { Path = ConvertFilenameToIocPath(messageOrFilename) });
|
||||
|
||||
|
||||
}), filename);
|
||||
|
||||
new ProgressTask(App.Kp2a, _activity, task).Run();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual void Clear()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected abstract void SaveFile(IOConnectionInfo ioc);
|
||||
|
||||
public void StartProcess()
|
||||
{
|
||||
Intent intent = new Intent(_activity, typeof(FileStorageSelectionActivity));
|
||||
//intent.PutExtra(FileStorageSelectionActivity.AllowThirdPartyAppSend, true);
|
||||
_activity.StartActivityForResult(intent, _requestCode);
|
||||
}
|
||||
|
||||
public virtual void OnSaveInstanceState(Bundle outState)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@@ -3,6 +3,8 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
#if !NoNet
|
||||
using System.Net.FtpClient;
|
||||
using Keepass2android.Javafilestorage;
|
||||
|
||||
#endif
|
||||
using System.Text;
|
||||
|
||||
@@ -14,7 +16,6 @@ using Android.Views;
|
||||
using Android.Widget;
|
||||
using Java.IO;
|
||||
using keepass2android.Io;
|
||||
using Keepass2android.Javafilestorage;
|
||||
using KeePassLib.Serialization;
|
||||
using KeePassLib.Utility;
|
||||
|
||||
@@ -42,49 +43,15 @@ namespace keepass2android
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||
View dlgContents = activity.LayoutInflater.Inflate(Resource.Layout.sftpcredentials, null);
|
||||
|
||||
var spinner = dlgContents.FindViewById<Spinner>(Resource.Id.sftp_auth_mode_spinner);
|
||||
dlgContents.FindViewById<Button>(Resource.Id.send_public_key_button).Click += (sender, args) =>
|
||||
if (!defaultPath.EndsWith(_schemeSeparator))
|
||||
{
|
||||
var fileStorage = new Keepass2android.Javafilestorage.SftpStorage(activity.ApplicationContext);
|
||||
string pub_filename = fileStorage.CreateKeyPair();
|
||||
|
||||
Intent sendIntent = new Intent();
|
||||
sendIntent.SetAction(Intent.ActionSend);
|
||||
sendIntent.PutExtra(Intent.ExtraText, System.IO.File.ReadAllText(pub_filename));
|
||||
|
||||
sendIntent.PutExtra(Intent.ExtraSubject, "Keepass2Android sftp public key");
|
||||
sendIntent.SetType("text/plain");
|
||||
activity.StartActivity(Intent.CreateChooser(sendIntent, "Send public key to..."));
|
||||
};
|
||||
|
||||
|
||||
spinner.ItemSelected += (sender, args) =>
|
||||
{
|
||||
if (spinner.SelectedItemPosition == 0)
|
||||
{
|
||||
dlgContents.FindViewById<EditText>(Resource.Id.sftp_password).Visibility = ViewStates.Visible;
|
||||
dlgContents.FindViewById<Button>(Resource.Id.send_public_key_button).Visibility = ViewStates.Gone;
|
||||
}
|
||||
else
|
||||
{
|
||||
dlgContents.FindViewById<EditText>(Resource.Id.sftp_password).Visibility = ViewStates.Gone;
|
||||
dlgContents.FindViewById<Button>(Resource.Id.send_public_key_button).Visibility = ViewStates.Visible;
|
||||
}
|
||||
};
|
||||
|
||||
if (!defaultPath.EndsWith(_schemeSeparator))
|
||||
{
|
||||
var fileStorage = new Keepass2android.Javafilestorage.SftpStorage(activity.ApplicationContext);
|
||||
var fileStorage = new Keepass2android.Javafilestorage.SftpStorage();
|
||||
SftpStorage.ConnectionInfo ci = fileStorage.SplitStringToConnectionInfo(defaultPath);
|
||||
dlgContents.FindViewById<EditText>(Resource.Id.sftp_host).Text = ci.Host;
|
||||
dlgContents.FindViewById<EditText>(Resource.Id.sftp_port).Text = ci.Port.ToString();
|
||||
dlgContents.FindViewById<EditText>(Resource.Id.sftp_user).Text = ci.Username;
|
||||
dlgContents.FindViewById<EditText>(Resource.Id.sftp_password).Text = ci.Password;
|
||||
dlgContents.FindViewById<EditText>(Resource.Id.sftp_initial_dir).Text = ci.LocalPath;
|
||||
if (string.IsNullOrEmpty(ci.Password))
|
||||
{
|
||||
spinner.SetSelection(1);
|
||||
}
|
||||
}
|
||||
|
||||
builder.SetView(dlgContents);
|
||||
@@ -101,7 +68,7 @@ namespace keepass2android
|
||||
string initialPath = dlgContents.FindViewById<EditText>(Resource.Id.sftp_initial_dir).Text;
|
||||
if (string.IsNullOrEmpty(initialPath))
|
||||
initialPath = "/";
|
||||
string sftpPath = new Keepass2android.Javafilestorage.SftpStorage(activity.ApplicationContext).BuildFullPath(host, port, initialPath, user,
|
||||
string sftpPath = new Keepass2android.Javafilestorage.SftpStorage().BuildFullPath(host, port, initialPath, user,
|
||||
password);
|
||||
onStartBrowse(sftpPath);
|
||||
});
|
||||
@@ -222,10 +189,8 @@ namespace keepass2android
|
||||
else if ((defaultPath.StartsWith("http://")) || (defaultPath.StartsWith("https://")))
|
||||
ShowHttpDialog(_activity, ReturnFileOrStartFileChooser, ReturnCancel, defaultPath);
|
||||
else if (defaultPath.StartsWith("owncloud://"))
|
||||
ShowOwncloudDialog(_activity, ReturnFileOrStartFileChooser, ReturnCancel, defaultPath, "owncloud");
|
||||
else if (defaultPath.StartsWith("nextcloud://"))
|
||||
ShowOwncloudDialog(_activity, ReturnFileOrStartFileChooser, ReturnCancel, defaultPath, "nextcloud");
|
||||
else
|
||||
ShowOwncloudDialog(_activity, ReturnFileOrStartFileChooser, ReturnCancel, defaultPath);
|
||||
else
|
||||
{
|
||||
Func<string, Dialog, bool> onOpen = OnOpenButton;
|
||||
Util.ShowFilenameDialog(_activity,
|
||||
@@ -240,13 +205,12 @@ namespace keepass2android
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowOwncloudDialog(Activity activity, Util.FileSelectedHandler onStartBrowse, Action onCancel, string defaultPath, string subtype)
|
||||
private void ShowOwncloudDialog(Activity activity, Util.FileSelectedHandler onStartBrowse, Action onCancel, string defaultPath)
|
||||
{
|
||||
#if !EXCLUDE_JAVAFILESTORAGE && !NoNet
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||
View dlgContents = activity.LayoutInflater.Inflate(Resource.Layout.owncloudcredentials, null);
|
||||
builder.SetView(dlgContents);
|
||||
|
||||
builder.SetPositiveButton(Android.Resource.String.Ok,
|
||||
(sender, args) =>
|
||||
{
|
||||
@@ -258,17 +222,17 @@ namespace keepass2android
|
||||
string scheme = defaultPath.Substring(0,defaultPath.IndexOf(_schemeSeparator, StringComparison.Ordinal));
|
||||
if (host.Contains(_schemeSeparator) == false)
|
||||
host = scheme + _schemeSeparator + host;
|
||||
string httpPath = new Keepass2android.Javafilestorage.WebDavStorage(null).BuildFullPath(WebDavFileStorage.Owncloud2Webdav(host, subtype == "owncloud" ? WebDavFileStorage.owncloudPrefix : WebDavFileStorage.nextcloudPrefix), user,
|
||||
string httpPath = new Keepass2android.Javafilestorage.WebDavStorage(null).BuildFullPath(WebDavFileStorage.Owncloud2Webdav(host), user,
|
||||
password);
|
||||
onStartBrowse(httpPath);
|
||||
});
|
||||
EventHandler<DialogClickEventArgs> evtH = new EventHandler<DialogClickEventArgs>((sender, e) => onCancel());
|
||||
|
||||
builder.SetNegativeButton(Android.Resource.String.Cancel, evtH);
|
||||
builder.SetTitle(activity.GetString(subtype == "owncloud" ? Resource.String.enter_owncloud_login_title : Resource.String.enter_nextcloud_login_title));
|
||||
builder.SetTitle(activity.GetString(Resource.String.enter_owncloud_login_title));
|
||||
Dialog dialog = builder.Create();
|
||||
dlgContents.FindViewById<EditText>(Resource.Id.owncloud_url).SetHint(subtype == "owncloud" ? Resource.String.hint_owncloud_url : Resource.String.hint_nextcloud_url);
|
||||
dialog.Show();
|
||||
|
||||
dialog.Show();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@@ -19,7 +19,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
@@ -38,12 +38,16 @@ using Android.Preferences;
|
||||
using Android.Text;
|
||||
using Android.Content.PM;
|
||||
using Android.Graphics;
|
||||
using Android.Hardware.Fingerprints;
|
||||
using Android.Provider;
|
||||
using Android.Support.Design.Widget;
|
||||
using Android.Support.V4.Widget;
|
||||
using Android.Support.V7.App;
|
||||
using Java.Lang;
|
||||
using keepass2android;
|
||||
using KeePassLib.Keys;
|
||||
using KeePassLib.Serialization;
|
||||
using KeePassLib.Utility;
|
||||
using Keepass2android.Pluginsdk;
|
||||
using OtpKeyProv;
|
||||
using keepass2android.Io;
|
||||
@@ -56,10 +60,12 @@ using Object = Java.Lang.Object;
|
||||
using Process = Android.OS.Process;
|
||||
|
||||
using KeeChallenge;
|
||||
using KeePassLib.Cryptography.KeyDerivation;
|
||||
using AlertDialog = Android.App.AlertDialog;
|
||||
using Enum = System.Enum;
|
||||
using Exception = System.Exception;
|
||||
using String = System.String;
|
||||
using Toolbar = Android.Support.V7.Widget.Toolbar;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
@@ -74,13 +80,15 @@ namespace keepass2android
|
||||
|
||||
enum KeyProviders
|
||||
{
|
||||
//int values correspond to indices in passwordSpinner
|
||||
None = 0,
|
||||
KeyFile = 1,
|
||||
Otp = 2,
|
||||
OtpRecovery = 3,
|
||||
Challenge = 4,
|
||||
ChalRecovery = 5,
|
||||
ChallengeXC = 6, //KeepassXC compatible Challenge-Response
|
||||
}
|
||||
ChallengeXC = 6 //KeepassXC compatible Challenge-Response
|
||||
}
|
||||
|
||||
public const String KeyDefaultFilename = "defaultFileName";
|
||||
|
||||
@@ -98,9 +106,9 @@ namespace keepass2android
|
||||
private const string KeyProviderIdChallenge = "KP2A-Chal";
|
||||
private const string KeyProviderIdChallengeRecovery = "KP2A-ChalSecret";
|
||||
private const string KeyProviderIdChallengeXC = "KP2A-ChalXC";
|
||||
|
||||
|
||||
|
||||
private const int RequestCodePrepareDbFile = 1000;
|
||||
private const int RequestCodePrepareDbFile = 1000;
|
||||
private const int RequestCodePrepareOtpAuxFile = 1001;
|
||||
|
||||
private const int RequestCodeSelectKeyfile = 1003;
|
||||
@@ -112,7 +120,7 @@ namespace keepass2android
|
||||
private bool _loadDbTaskOffline; //indicate if preloading was started with offline mode
|
||||
|
||||
private IOConnectionInfo _ioConnection;
|
||||
private String _keyFile;
|
||||
private String _keyFileOrProvider;
|
||||
bool _showPassword;
|
||||
|
||||
internal AppTask AppTask;
|
||||
@@ -122,8 +130,27 @@ namespace keepass2android
|
||||
private List<String> _pendingOtps = new List<string>();
|
||||
|
||||
|
||||
private HashSet<KeyProviders> KeyProviderTypes = new HashSet<KeyProviders>();
|
||||
|
||||
|
||||
KeyProviders KeyProviderType
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_keyFileOrProvider == null)
|
||||
return KeyProviders.None;
|
||||
if (_keyFileOrProvider == KeyProviderIdOtp)
|
||||
return KeyProviders.Otp;
|
||||
if (_keyFileOrProvider == KeyProviderIdOtpRecovery)
|
||||
return KeyProviders.OtpRecovery;
|
||||
if (_keyFileOrProvider == KeyProviderIdChallenge)
|
||||
return KeyProviders.Challenge;
|
||||
if (_keyFileOrProvider == KeyProviderIdChallengeRecovery)
|
||||
return KeyProviders.ChalRecovery;
|
||||
if (_keyFileOrProvider == KeyProviderIdChallengeXC)
|
||||
return KeyProviders.ChallengeXC;
|
||||
return KeyProviders.KeyFile;
|
||||
}
|
||||
}
|
||||
|
||||
private bool _rememberKeyfile;
|
||||
ISharedPreferences _prefs;
|
||||
|
||||
@@ -226,6 +253,7 @@ namespace keepass2android
|
||||
|
||||
AppTask.TryGetFromActivityResult(data, ref AppTask);
|
||||
|
||||
//NOTE: original code from k eepassdroid used switch ((Android.App.Result)requestCode) { (but doesn't work here, although k eepassdroid works)
|
||||
switch(resultCode) {
|
||||
|
||||
case KeePass.ExitNormal: // Returned to this screen using the Back key
|
||||
@@ -243,13 +271,13 @@ namespace keepass2android
|
||||
// The database has already been locked, and the quick unlock screen will be shown if appropriate
|
||||
|
||||
_rememberKeyfile = _prefs.GetBoolean(GetString(Resource.String.keyfile_key), Resources.GetBoolean(Resource.Boolean.keyfile_default)); //update value
|
||||
if (KeyProviderHasKeyFile() && (_rememberKeyfile))
|
||||
if ((KeyProviderType == KeyProviders.KeyFile) && (_rememberKeyfile))
|
||||
{
|
||||
//check if the keyfile was changed (by importing to internal directory)
|
||||
var newKeyProviderString = LoadKeyProviderStringForIoc(_ioConnection.Path);
|
||||
if (newKeyProviderString != GetKeyProviderString())
|
||||
var newKeyFile = GetKeyFile(_ioConnection.Path);
|
||||
if (newKeyFile != _keyFileOrProvider)
|
||||
{
|
||||
SetKeyProviderFromString(newKeyProviderString);
|
||||
_keyFileOrProvider = newKeyFile;
|
||||
UpdateKeyfileIocView();
|
||||
}
|
||||
}
|
||||
@@ -282,7 +310,7 @@ namespace keepass2android
|
||||
Handler handler = new Handler();
|
||||
OnFinish onFinish = new AfterLoad(handler, this, _ioConnection);
|
||||
_performingLoad = true;
|
||||
LoadDb task = new LoadDb(this, App.Kp2a, _ioConnection, _loadDbFileTask, compositeKey, GetKeyProviderString(), onFinish);
|
||||
LoadDb task = new LoadDb(this, App.Kp2a, _ioConnection, _loadDbFileTask, compositeKey, _keyFileOrProvider, onFinish);
|
||||
_loadDbFileTask = null; // prevent accidental re-use
|
||||
new ProgressTask(App.Kp2a, this, task).Run();
|
||||
}
|
||||
@@ -293,20 +321,20 @@ namespace keepass2android
|
||||
{
|
||||
IOConnectionInfo ioc = new IOConnectionInfo();
|
||||
SetIoConnectionFromIntent(ioc, data);
|
||||
_keyFile = IOConnectionInfo.SerializeToString(ioc);
|
||||
_keyFileOrProvider = IOConnectionInfo.SerializeToString(ioc);
|
||||
UpdateKeyfileIocView();
|
||||
}
|
||||
break;
|
||||
case (Result)FileStorageResults.FileUsagePrepared:
|
||||
if (requestCode == RequestCodePrepareDbFile)
|
||||
{
|
||||
if (KeyProviderTypes.Contains(KeyProviders.KeyFile))
|
||||
if (KeyProviderType == KeyProviders.KeyFile)
|
||||
{
|
||||
|
||||
//if the user has not yet selected a keyfile, _keyFile is empty
|
||||
if (string.IsNullOrEmpty(_keyFile) == false)
|
||||
|
||||
//if the user has not yet selected a keyfile, _keyFileOrProvider is empty
|
||||
if (string.IsNullOrEmpty(_keyFileOrProvider) == false)
|
||||
{
|
||||
var iocKeyfile = IOConnectionInfo.UnserializeFromString(_keyFile);
|
||||
var iocKeyfile = IOConnectionInfo.UnserializeFromString(_keyFileOrProvider);
|
||||
|
||||
App.Kp2a.GetFileStorage(iocKeyfile)
|
||||
.PrepareFileUsage(new FileStorageSetupInitiatorActivity(this, OnActivityResult, null), iocKeyfile,
|
||||
@@ -400,17 +428,16 @@ namespace keepass2android
|
||||
else
|
||||
{
|
||||
Toast.MakeText(this, Resource.String.bad_resp, ToastLength.Long).Show();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private AuxFileLoader GetAuxFileLoader()
|
||||
private AuxFileLoader GetAuxFileLoader()
|
||||
{
|
||||
if (KeyProviderTypes.Contains(KeyProviders.Challenge))
|
||||
{
|
||||
if (_keyFileOrProvider == KeyProviderIdChallenge)
|
||||
{
|
||||
return new ChallengeAuxFileLoader(this);
|
||||
}
|
||||
else
|
||||
@@ -421,8 +448,8 @@ namespace keepass2android
|
||||
private void UpdateKeyfileIocView()
|
||||
{
|
||||
//store keyfile in the view so that we can show the selected keyfile again if the user switches to another key provider and back to key file
|
||||
FindViewById<TextView>(Resource.Id.label_keyfilename).Tag = _keyFile;
|
||||
if (string.IsNullOrEmpty(_keyFile))
|
||||
FindViewById<TextView>(Resource.Id.label_keyfilename).Tag = _keyFileOrProvider;
|
||||
if (string.IsNullOrEmpty(_keyFileOrProvider))
|
||||
{
|
||||
FindViewById<TextView>(Resource.Id.filestorage_label).Visibility = ViewStates.Gone;
|
||||
FindViewById<ImageView>(Resource.Id.filestorage_logo).Visibility = ViewStates.Gone;
|
||||
@@ -430,7 +457,7 @@ namespace keepass2android
|
||||
|
||||
return;
|
||||
}
|
||||
var ioc = IOConnectionInfo.UnserializeFromString(_keyFile);
|
||||
var ioc = IOConnectionInfo.UnserializeFromString(_keyFileOrProvider);
|
||||
string displayPath = App.Kp2a.GetFileStorage(ioc).GetDisplayName(ioc);
|
||||
int protocolSeparatorPos = displayPath.IndexOf("://", StringComparison.Ordinal);
|
||||
string protocolId = protocolSeparatorPos < 0 ?
|
||||
@@ -504,7 +531,7 @@ namespace keepass2android
|
||||
intent.PutExtra(FileStorageSelectionActivity.AllowThirdPartyAppGet, true);
|
||||
intent.PutExtra(FileStorageSelectionActivity.AllowThirdPartyAppSend, false);
|
||||
intent.PutExtra(FileStorageSetupDefs.ExtraIsForSave, false);
|
||||
intent.PutExtra(SelectStorageLocationActivity.ExtraKeyWritableRequirements, (int)SelectStorageLocationActivityBase.WritableRequirements.WriteDemanded);
|
||||
intent.PutExtra(SelectStorageLocationActivity.ExtraKeyWritableRequirements, (int)SelectStorageLocationActivity.WritableRequirements.WriteDemanded);
|
||||
Activity.StartActivityForResult(intent, RequestCodeSelectAuxFile);
|
||||
}
|
||||
else
|
||||
@@ -559,7 +586,16 @@ namespace keepass2android
|
||||
IOConnectionInfo iocAux = fileStorage.GetFilePath(parentPath, filename);
|
||||
return iocAux;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private static IOConnectionInfo GetAuxFileIoc(KeyProviderQueryContext ctx)
|
||||
{
|
||||
IOConnectionInfo ioc = ctx.DatabaseIOInfo.CloneDeep();
|
||||
var iocAux = GetAuxFileIoc(ioc);
|
||||
|
||||
return iocAux;
|
||||
}
|
||||
|
||||
protected override void HandleSuccess()
|
||||
{
|
||||
@@ -664,7 +700,9 @@ namespace keepass2android
|
||||
|
||||
int count = 1;
|
||||
|
||||
|
||||
private DrawerLayout mDrawerLayout;
|
||||
//private RecyclerView mDrawerList;
|
||||
|
||||
private string mDrawerTitle;
|
||||
private MeasuringRelativeLayout.MeasureArgs _measureArgs;
|
||||
private ActivityDesign _activityDesign;
|
||||
@@ -678,7 +716,7 @@ namespace keepass2android
|
||||
{
|
||||
PasswordActivity owner;
|
||||
|
||||
public MyActionBarDrawerToggle(PasswordActivity activity, DrawerLayout layout, int openRes, int closeRes)
|
||||
public MyActionBarDrawerToggle(PasswordActivity activity, DrawerLayout layout, int imgRes, int openRes, int closeRes)
|
||||
: base(activity, layout, openRes, closeRes)
|
||||
{
|
||||
owner = activity;
|
||||
@@ -784,22 +822,19 @@ namespace keepass2android
|
||||
if (keyFileFromIntent != null)
|
||||
{
|
||||
Kp2aLog.Log("try get keyfile from intent");
|
||||
_keyFile = IOConnectionInfo.SerializeToString(IOConnectionInfo.FromPath(keyFileFromIntent));
|
||||
KeyProviderTypes.Clear();
|
||||
KeyProviderTypes.Add(KeyProviders.KeyFile);
|
||||
_keyFileOrProvider = IOConnectionInfo.SerializeToString(IOConnectionInfo.FromPath(keyFileFromIntent));
|
||||
Kp2aLog.Log("try get keyfile from intent ok");
|
||||
}
|
||||
else
|
||||
{
|
||||
_keyFile = null;
|
||||
KeyProviderTypes.Clear();
|
||||
}
|
||||
_password = i.GetStringExtra(KeyPassword) ?? "";
|
||||
if (!KeyProviderTypes.Any())
|
||||
{
|
||||
SetKeyProviderFromString(LoadKeyProviderStringForIoc(_ioConnection.Path));
|
||||
_keyFileOrProvider = null;
|
||||
}
|
||||
if ((!string.IsNullOrEmpty(_keyFile)) || (_password != ""))
|
||||
_password = i.GetStringExtra(KeyPassword) ?? "";
|
||||
if (string.IsNullOrEmpty(_keyFileOrProvider))
|
||||
{
|
||||
_keyFileOrProvider = GetKeyFile(_ioConnection.Path);
|
||||
}
|
||||
if ((!string.IsNullOrEmpty(_keyFileOrProvider)) || (_password != ""))
|
||||
{
|
||||
_keepPasswordInOnResume = true;
|
||||
}
|
||||
@@ -818,7 +853,7 @@ namespace keepass2android
|
||||
|
||||
InitializeFilenameView();
|
||||
|
||||
if (KeyProviderTypes.Contains(KeyProviders.KeyFile))
|
||||
if (KeyProviderType == KeyProviders.KeyFile)
|
||||
{
|
||||
UpdateKeyfileIocView();
|
||||
}
|
||||
@@ -870,8 +905,8 @@ namespace keepass2android
|
||||
}
|
||||
|
||||
|
||||
mDrawerTitle = Title;
|
||||
FindViewById<DrawerLayout>(Resource.Id.drawer_layout);
|
||||
mDrawerTitle = this.Title;
|
||||
mDrawerLayout = FindViewById<DrawerLayout>(Resource.Id.drawer_layout);
|
||||
var rootview = FindViewById<MeasuringRelativeLayout>(Resource.Id.relative_layout);
|
||||
rootview.ViewTreeObserver.GlobalLayout += (sender, args2) =>
|
||||
{
|
||||
@@ -889,116 +924,16 @@ namespace keepass2android
|
||||
rootview.MeasureEvent += (sender, args) =>
|
||||
{
|
||||
//Snackbar.Make(rootview, "height="+args.ActualHeight, Snackbar.LengthLong).Show();
|
||||
_measureArgs = args;
|
||||
this._measureArgs = args;
|
||||
};
|
||||
|
||||
if ((int)Build.VERSION.SdkInt >= 23)
|
||||
RequestPermissions(new[] { Manifest.Permission.UseFingerprint }, FingerprintPermissionRequestCode);
|
||||
|
||||
}
|
||||
const int FingerprintPermissionRequestCode = 99;
|
||||
|
||||
private const string Kp2aKeyProviderStringPrefix = "_KP2A_KEYTYPES:";
|
||||
|
||||
private string GetKeyProviderString()
|
||||
{
|
||||
if (!KeyProviderTypes.Any())
|
||||
return null;
|
||||
string result = Kp2aKeyProviderStringPrefix;
|
||||
foreach (KeyProviders type in KeyProviderTypes)
|
||||
{
|
||||
result += type.ToString();
|
||||
|
||||
if (type == KeyProviders.KeyFile)
|
||||
{
|
||||
result += WebUtility.UrlEncode(_keyFile) + ";";
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void SetKeyProviderFromString(string keyProviderString)
|
||||
{
|
||||
KeyProviderTypes.Clear();
|
||||
if (string.IsNullOrEmpty(keyProviderString))
|
||||
{
|
||||
_keyFile = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (keyProviderString.StartsWith(Kp2aKeyProviderStringPrefix))
|
||||
{
|
||||
keyProviderString = keyProviderString.Substring(Kp2aKeyProviderStringPrefix.Length);
|
||||
foreach (string type in keyProviderString.Split(';'))
|
||||
{
|
||||
if (!type.Trim().Any())
|
||||
continue;
|
||||
if (type.StartsWith(KeyProviders.KeyFile.ToString()))
|
||||
{
|
||||
_keyFile = WebUtility.UrlDecode(type.Substring(KeyProviders.KeyFile.ToString().Length));
|
||||
KeyProviderTypes.Add(KeyProviders.KeyFile);
|
||||
continue;
|
||||
}
|
||||
foreach (KeyProviders providerType in Enum.GetValues(typeof(KeyProviders)))
|
||||
{
|
||||
if (type == providerType.ToString())
|
||||
{
|
||||
KeyProviderTypes.Add(providerType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
//legacy mode
|
||||
_keyFile = null;
|
||||
|
||||
if (keyProviderString == KeyProviderIdOtp)
|
||||
KeyProviderTypes.Add(KeyProviders.Otp);
|
||||
else if (keyProviderString == KeyProviderIdOtpRecovery)
|
||||
KeyProviderTypes.Add(KeyProviders.OtpRecovery);
|
||||
else if (keyProviderString == KeyProviderIdChallenge)
|
||||
KeyProviderTypes.Add(KeyProviders.Challenge);
|
||||
else if (keyProviderString == KeyProviderIdChallengeRecovery)
|
||||
KeyProviderTypes.Add(KeyProviders.ChalRecovery);
|
||||
else if (keyProviderString == KeyProviderIdChallengeXC)
|
||||
KeyProviderTypes.Add(KeyProviders.ChallengeXC);
|
||||
else
|
||||
{
|
||||
KeyProviderTypes.Add(KeyProviders.KeyFile);
|
||||
_keyFile = keyProviderString;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (KeyProviderTypes.Contains(KeyProviders.KeyFile))
|
||||
{
|
||||
//test if the filename is properly encoded.
|
||||
try
|
||||
{
|
||||
Kp2aLog.Log("test if stored filename is ok");
|
||||
IOConnectionInfo.UnserializeFromString(_keyFile);
|
||||
Kp2aLog.Log("...ok");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
//it's not. This is probably because we're upgrading from app version <= 45
|
||||
//where the keyfile was stored plain text and not serialized
|
||||
Kp2aLog.Log("no, it's not: " + e.GetType().Name);
|
||||
var serializedKeyFile = IOConnectionInfo.SerializeToString(IOConnectionInfo.FromPath(_keyFile));
|
||||
Kp2aLog.Log("now it is!");
|
||||
_keyFile = serializedKeyFile;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const int FingerprintPermissionRequestCode = 99;
|
||||
|
||||
|
||||
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
|
||||
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
|
||||
{
|
||||
if ((requestCode == FingerprintPermissionRequestCode) && (grantResults.Length > 0) && (grantResults[0] == Permission.Granted))
|
||||
{
|
||||
@@ -1047,10 +982,9 @@ namespace keepass2android
|
||||
{
|
||||
var masterPassword = _fingerprintDec.DecryptStored(Database.GetFingerprintPrefKey(_ioConnection));
|
||||
_password = FindViewById<EditText>(Resource.Id.password_edit).Text = masterPassword;
|
||||
FindViewById<EditText>(Resource.Id.password_edit).Enabled = false; //prevent accidental modification of password
|
||||
|
||||
}
|
||||
catch (Java.Security.GeneralSecurityException)
|
||||
}
|
||||
catch (Java.Security.GeneralSecurityException ex)
|
||||
{
|
||||
HandleFingerprintKeyInvalidated();
|
||||
return;
|
||||
@@ -1058,9 +992,8 @@ namespace keepass2android
|
||||
|
||||
btn.PostDelayed(() =>
|
||||
{
|
||||
//fire
|
||||
OnOk(true);
|
||||
FindViewById<EditText>(Resource.Id.password_edit).Enabled = true;
|
||||
//fire
|
||||
OnOk(true);
|
||||
}, 500);
|
||||
|
||||
}
|
||||
@@ -1078,7 +1011,7 @@ namespace keepass2android
|
||||
};
|
||||
FindViewById(Resource.Id.btn_nav_donate).Visibility =
|
||||
PreferenceManager.GetDefaultSharedPreferences(this)
|
||||
.GetBoolean(GetString(Resource.String.NoDonateOption_key), false)
|
||||
.GetBoolean(this.GetString(Resource.String.NoDonateOption_key), false)
|
||||
? ViewStates.Gone
|
||||
: ViewStates.Visible;
|
||||
FindViewById(Resource.Id.btn_nav_about).Click += (sender, args) =>
|
||||
@@ -1126,7 +1059,7 @@ namespace keepass2android
|
||||
Resource.String.menu_close);
|
||||
|
||||
|
||||
_drawerLayout?.SetDrawerListener(mDrawerToggle);
|
||||
_drawerLayout.SetDrawerListener(mDrawerToggle);
|
||||
|
||||
|
||||
SupportActionBar.SetDisplayHomeAsUpEnabled(true);
|
||||
@@ -1193,10 +1126,9 @@ namespace keepass2android
|
||||
}
|
||||
|
||||
//assume user wants to use OTP (for static password, they need to open KP2A first and select the key provider type, then see OnNewIntent)
|
||||
KeyProviderTypes.Clear();
|
||||
KeyProviderTypes.Add(KeyProviders.Otp);
|
||||
_keyFileOrProvider = KeyProviderIdOtp;
|
||||
|
||||
if (savedInstanceState == null) //only when not re-creating
|
||||
if (savedInstanceState == null) //only when not re-creating
|
||||
{
|
||||
//remember the OTP for later use
|
||||
_pendingOtps.Add(i.GetStringExtra(Intents.OtpExtraKey));
|
||||
@@ -1246,7 +1178,7 @@ namespace keepass2android
|
||||
}
|
||||
|
||||
|
||||
SetKeyProviderFromString(LoadKeyProviderStringForIoc(_ioConnection.Path));
|
||||
_keyFileOrProvider = GetKeyFile(_ioConnection.Path);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1309,58 +1241,33 @@ namespace keepass2android
|
||||
if (passwordModeSpinner != null)
|
||||
{
|
||||
UpdateKeyProviderUiState();
|
||||
|
||||
int spinnerPos = 0;
|
||||
if (KeyProviderTypes.Contains(KeyProviders.KeyFile))
|
||||
{
|
||||
if (KeyProviderTypes.Contains(KeyProviders.ChallengeXC))
|
||||
spinnerPos = 7;
|
||||
else spinnerPos = 1;
|
||||
}
|
||||
else if (KeyProviderTypes.Contains(KeyProviders.Otp))
|
||||
spinnerPos = 2;
|
||||
else if (KeyProviderTypes.Contains(KeyProviders.OtpRecovery))
|
||||
spinnerPos = 3;
|
||||
else if (KeyProviderTypes.Contains(KeyProviders.Challenge))
|
||||
spinnerPos = 4;
|
||||
else if (KeyProviderTypes.Contains(KeyProviders.ChalRecovery))
|
||||
spinnerPos = 5;
|
||||
else if (KeyProviderTypes.Contains(KeyProviders.ChallengeXC))
|
||||
spinnerPos = 6;
|
||||
|
||||
passwordModeSpinner.SetSelection(spinnerPos);
|
||||
passwordModeSpinner.SetSelection((int) KeyProviderType);
|
||||
passwordModeSpinner.ItemSelected += (sender, args) =>
|
||||
{
|
||||
KeyProviderTypes.Clear();
|
||||
_keyFile = null;
|
||||
{
|
||||
switch (args.Position)
|
||||
{
|
||||
case 0:
|
||||
_keyFileOrProvider = null;
|
||||
break;
|
||||
case 1:
|
||||
//don't set to "" to prevent losing the filename. (ItemSelected is also called during recreation!)
|
||||
_keyFile = (FindViewById(Resource.Id.label_keyfilename).Tag ?? "").ToString();
|
||||
KeyProviderTypes.Add(KeyProviders.KeyFile);
|
||||
//don't set to "" to prevent losing the filename. (ItemSelected is also called during recreation!)
|
||||
_keyFileOrProvider = (FindViewById(Resource.Id.label_keyfilename).Tag ?? "").ToString();
|
||||
break;
|
||||
case 2:
|
||||
KeyProviderTypes.Add(KeyProviders.Otp);
|
||||
break;
|
||||
_keyFileOrProvider = KeyProviderIdOtp;
|
||||
break;
|
||||
case 3:
|
||||
KeyProviderTypes.Add(KeyProviders.OtpRecovery);
|
||||
break;
|
||||
_keyFileOrProvider = KeyProviderIdOtpRecovery;
|
||||
break;
|
||||
case 4:
|
||||
KeyProviderTypes.Add(KeyProviders.Challenge);
|
||||
break;
|
||||
_keyFileOrProvider = KeyProviderIdChallenge;
|
||||
break;
|
||||
case 5:
|
||||
KeyProviderTypes.Add(KeyProviders.ChalRecovery);
|
||||
break;
|
||||
_keyFileOrProvider = KeyProviderIdChallengeRecovery;
|
||||
break;
|
||||
case 6:
|
||||
KeyProviderTypes.Add(KeyProviders.ChallengeXC);
|
||||
break;
|
||||
case 7:
|
||||
KeyProviderTypes.Add(KeyProviders.ChallengeXC);
|
||||
KeyProviderTypes.Add(KeyProviders.KeyFile);
|
||||
break;
|
||||
_keyFileOrProvider = KeyProviderIdChallengeXC;
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Unexpected position " + args.Position + " / " +
|
||||
((ICursor) ((AdapterView) sender).GetItemAtPosition(args.Position)).GetString(1));
|
||||
@@ -1384,7 +1291,7 @@ namespace keepass2android
|
||||
_showPassword = savedInstanceState.GetBoolean(ShowpasswordKey, false);
|
||||
MakePasswordMaskedOrVisible();
|
||||
|
||||
SetKeyProviderFromString(savedInstanceState.GetString(KeyFileOrProviderKey));
|
||||
_keyFileOrProvider = savedInstanceState.GetString(KeyFileOrProviderKey);
|
||||
_password = FindViewById<EditText>(Resource.Id.password_edit).Text = savedInstanceState.GetString(PasswordKey);
|
||||
|
||||
_pendingOtps = new List<string>(savedInstanceState.GetStringArrayList(PendingOtpsKey));
|
||||
@@ -1412,66 +1319,77 @@ namespace keepass2android
|
||||
|
||||
private void UpdateOkButtonState()
|
||||
{
|
||||
bool enabled = true;
|
||||
if (KeyProviderTypes.Contains(KeyProviders.KeyFile))
|
||||
enabled &= _keyFile != "" || _password != "";
|
||||
|
||||
if (KeyProviderTypes.Contains(KeyProviders.Otp))
|
||||
{
|
||||
if (_otpInfo == null)
|
||||
enabled = false;
|
||||
else
|
||||
{
|
||||
int c = 0;
|
||||
foreach (int otpId in _otpTextViewIds)
|
||||
{
|
||||
c++;
|
||||
var otpTextView = FindViewById<EditText>(otpId);
|
||||
if ((c <= _otpInfo.OtpsRequired) && (otpTextView.Text == ""))
|
||||
{
|
||||
enabled = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (KeyProviderTypes.Contains(KeyProviders.OtpRecovery) || KeyProviderTypes.Contains(KeyProviders.ChalRecovery))
|
||||
{
|
||||
enabled &= FindViewById<EditText>(Resource.Id.pass_otpsecret).Text != "";
|
||||
}
|
||||
|
||||
if (KeyProviderTypes.Contains(KeyProviders.Challenge))
|
||||
enabled &= _challengeSecret != null;
|
||||
|
||||
bool enabled = false;
|
||||
switch (KeyProviderType)
|
||||
{
|
||||
case KeyProviders.None:
|
||||
enabled = true;
|
||||
break;
|
||||
case KeyProviders.KeyFile:
|
||||
enabled = _keyFileOrProvider != "" || _password != "";
|
||||
break;
|
||||
case KeyProviders.Otp:
|
||||
|
||||
enabled = true;
|
||||
if (_otpInfo == null)
|
||||
enabled = false;
|
||||
else
|
||||
{
|
||||
int c = 0;
|
||||
foreach (int otpId in _otpTextViewIds)
|
||||
{
|
||||
c++;
|
||||
var otpTextView = FindViewById<EditText>(otpId);
|
||||
if ((c <= _otpInfo.OtpsRequired) && (otpTextView.Text == ""))
|
||||
{
|
||||
enabled = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
case KeyProviders.OtpRecovery:
|
||||
case KeyProviders.ChalRecovery:
|
||||
enabled = FindViewById<EditText>(Resource.Id.pass_otpsecret).Text != "";
|
||||
break;
|
||||
case KeyProviders.ChallengeXC:
|
||||
enabled = true;
|
||||
break;
|
||||
case KeyProviders.Challenge:
|
||||
enabled = _challengeSecret != null;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
FindViewById(Resource.Id.pass_ok).Enabled = enabled;
|
||||
|
||||
}
|
||||
|
||||
private void UpdateKeyProviderUiState()
|
||||
{
|
||||
FindViewById(Resource.Id.keyfileLine).Visibility = KeyProviderHasKeyFile()
|
||||
FindViewById(Resource.Id.keyfileLine).Visibility = KeyProviderType == KeyProviders.KeyFile
|
||||
? ViewStates.Visible
|
||||
: ViewStates.Gone;
|
||||
if (KeyProviderHasKeyFile())
|
||||
if (KeyProviderType == KeyProviders.KeyFile)
|
||||
{
|
||||
UpdateKeyfileIocView();
|
||||
}
|
||||
|
||||
FindViewById(Resource.Id.otpView).Visibility = KeyProviderTypes.Contains(KeyProviders.Otp)
|
||||
FindViewById(Resource.Id.otpView).Visibility = KeyProviderType == KeyProviders.Otp
|
||||
? ViewStates.Visible
|
||||
: ViewStates.Gone;
|
||||
|
||||
FindViewById(Resource.Id.otpSecretLine).Visibility = (KeyProviderTypes.Contains(KeyProviders.OtpRecovery) || KeyProviderTypes.Contains(KeyProviders.ChalRecovery))
|
||||
FindViewById(Resource.Id.otpSecretLine).Visibility = (KeyProviderType == KeyProviders.OtpRecovery || KeyProviderType == KeyProviders.ChalRecovery)
|
||||
? ViewStates.Visible
|
||||
: ViewStates.Gone;
|
||||
if (KeyProviderTypes.Contains(KeyProviders.Otp))
|
||||
if (KeyProviderType == KeyProviders.Otp)
|
||||
{
|
||||
FindViewById(Resource.Id.otps_pending).Visibility = _pendingOtps.Count > 0 ? ViewStates.Visible : ViewStates.Gone;
|
||||
}
|
||||
|
||||
if (KeyProviderTypes.Contains(KeyProviders.Challenge))
|
||||
if (KeyProviderType == KeyProviders.Challenge)
|
||||
{
|
||||
FindViewById (Resource.Id.otpView).Visibility = ViewStates.Visible;
|
||||
FindViewById(Resource.Id.otps_pending).Visibility = ViewStates.Gone;
|
||||
@@ -1479,12 +1397,7 @@ namespace keepass2android
|
||||
UpdateOkButtonState();
|
||||
}
|
||||
|
||||
private bool KeyProviderHasKeyFile()
|
||||
{
|
||||
return KeyProviderTypes.Contains(KeyProviders.KeyFile);
|
||||
}
|
||||
|
||||
private void PerformLoadDatabase()
|
||||
private void PerformLoadDatabase()
|
||||
{
|
||||
_currentlyWaitingKey = null;
|
||||
if (_performingLoad)
|
||||
@@ -1537,10 +1450,10 @@ namespace keepass2android
|
||||
|
||||
Handler handler = new Handler();
|
||||
OnFinish onFinish = new AfterLoad(handler, this, _ioConnection);
|
||||
LoadDb task = (KeyProviderTypes.Contains(KeyProviders.Otp))
|
||||
? new SaveOtpAuxFileAndLoadDb(App.Kp2a, _ioConnection, _loadDbFileTask, compositeKey, GetKeyProviderString(),
|
||||
LoadDb task = (KeyProviderType == KeyProviders.Otp)
|
||||
? new SaveOtpAuxFileAndLoadDb(App.Kp2a, _ioConnection, _loadDbFileTask, compositeKey, _keyFileOrProvider,
|
||||
onFinish, this)
|
||||
: new LoadDb(this, App.Kp2a, _ioConnection, _loadDbFileTask, compositeKey, GetKeyProviderString(), onFinish);
|
||||
: new LoadDb(this, App.Kp2a, _ioConnection, _loadDbFileTask, compositeKey, _keyFileOrProvider, onFinish);
|
||||
_loadDbFileTask = null; // prevent accidental re-use
|
||||
|
||||
SetNewDefaultFile();
|
||||
@@ -1549,7 +1462,7 @@ namespace keepass2android
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Kp2aLog.LogUnexpectedError(new Exception("cannot load database: "+e + ", c: " + (compositeKey != null) + (_ioConnection != null) + (_keyFile != null), e));
|
||||
Kp2aLog.LogUnexpectedError(new Exception("cannot load database: "+e + ", c: " + (compositeKey != null) + (_ioConnection != null) + (_keyFileOrProvider != null), e));
|
||||
throw;
|
||||
}
|
||||
|
||||
@@ -1561,13 +1474,13 @@ namespace keepass2android
|
||||
//no need to check for validity of password because if this method is called, the Ok button was enabled (i.e. there was a valid password)
|
||||
compositeKey = new CompositeKey();
|
||||
compositeKey.AddUserKey(new KcpPassword(_password));
|
||||
if (KeyProviderTypes.Contains(KeyProviders.KeyFile))
|
||||
if (KeyProviderType == KeyProviders.KeyFile)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_keyFile == "")
|
||||
if (_keyFileOrProvider == "")
|
||||
throw new System.IO.FileNotFoundException();
|
||||
var ioc = IOConnectionInfo.UnserializeFromString(_keyFile);
|
||||
var ioc = IOConnectionInfo.UnserializeFromString(_keyFileOrProvider);
|
||||
using (var stream = App.Kp2a.GetFileStorage(ioc).OpenFileForRead(ioc))
|
||||
{
|
||||
byte[] keyfileData = StreamToMemoryStream(stream).ToArray();
|
||||
@@ -1587,7 +1500,7 @@ namespace keepass2android
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (KeyProviderTypes.Contains(KeyProviders.Otp))
|
||||
else if (KeyProviderType == KeyProviders.Otp)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -1604,7 +1517,7 @@ namespace keepass2android
|
||||
}
|
||||
compositeKey.AddUserKey(new KcpCustomKey(OathHotpKeyProv.Name, _otpInfo.Secret, true));
|
||||
}
|
||||
if ((KeyProviderTypes.Contains(KeyProviders.OtpRecovery)) || (KeyProviderTypes.Contains(KeyProviders.ChalRecovery)))
|
||||
else if ((KeyProviderType == KeyProviders.OtpRecovery) || (KeyProviderType == KeyProviders.ChalRecovery))
|
||||
{
|
||||
Spinner stpDataFmtSpinner = FindViewById<Spinner>(Resource.Id.otpsecret_format_spinner);
|
||||
EditText secretEdit = FindViewById<EditText>(Resource.Id.pass_otpsecret);
|
||||
@@ -1620,11 +1533,11 @@ namespace keepass2android
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (KeyProviderTypes.Contains(KeyProviders.Challenge))
|
||||
else if (KeyProviderType == KeyProviders.Challenge)
|
||||
{
|
||||
compositeKey.AddUserKey(new KcpCustomKey(KeeChallengeProv.Name, _challengeSecret, true));
|
||||
}
|
||||
if (KeyProviderTypes.Contains(KeyProviders.ChallengeXC))
|
||||
else if (KeyProviderType == KeyProviders.ChallengeXC)
|
||||
{
|
||||
_currentlyWaitingKey = new ChallengeXCKey(this, RequestCodeChallengeYubikey);
|
||||
compositeKey.AddUserKey(_currentlyWaitingKey);
|
||||
@@ -1711,13 +1624,7 @@ namespace keepass2android
|
||||
base.OnStart();
|
||||
_starting = true;
|
||||
|
||||
if (PreferenceManager.GetDefaultSharedPreferences(this)
|
||||
.GetBoolean(GetString(Resource.String.UseKp2aKeyboardInKp2a_key), false))
|
||||
{
|
||||
CopyToClipboardService.ActivateKeyboard(this);
|
||||
}
|
||||
|
||||
AppTask.CanActivateSearchViewOnStart = true;
|
||||
AppTask.CanActivateSearchViewOnStart = true;
|
||||
DonateReminder.ShowDonateReminderIfAppropriate(this);
|
||||
|
||||
|
||||
@@ -1753,7 +1660,7 @@ namespace keepass2android
|
||||
AppTask.ToBundle(outState);
|
||||
outState.PutBoolean(ShowpasswordKey, _showPassword);
|
||||
|
||||
outState.PutString(KeyFileOrProviderKey, GetKeyProviderString());
|
||||
outState.PutString(KeyFileOrProviderKey, _keyFileOrProvider);
|
||||
outState.PutString(PasswordKey, _password);
|
||||
outState.PutStringArrayList(PendingOtpsKey, _pendingOtps);
|
||||
if (_otpInfo != null)
|
||||
@@ -1788,7 +1695,7 @@ namespace keepass2android
|
||||
{
|
||||
string otp = intent.GetStringExtra(Intents.OtpExtraKey);
|
||||
_keepPasswordInOnResume = true;
|
||||
if (KeyProviderTypes.Contains(KeyProviders.Otp))
|
||||
if (this.KeyProviderType == KeyProviders.Otp)
|
||||
{
|
||||
|
||||
if (_otpInfo == null)
|
||||
@@ -1893,7 +1800,7 @@ namespace keepass2android
|
||||
|
||||
UpdateOkButtonState();
|
||||
|
||||
if (KeyProviderTypes.Contains(KeyProviders.Challenge))
|
||||
if (KeyProviderType == KeyProviders.Challenge)
|
||||
{
|
||||
FindViewById(Resource.Id.otpInitView).Visibility = _challengeSecret == null ? ViewStates.Visible : ViewStates.Gone;
|
||||
}
|
||||
@@ -1928,7 +1835,7 @@ namespace keepass2android
|
||||
if (_loadDbFileTask == null && _prefs.GetBoolean(GetString(Resource.String.PreloadDatabaseEnabled_key), true))
|
||||
{
|
||||
// Create task to kick off file loading while the user enters the password
|
||||
_loadDbFileTask = Task.Factory.StartNew(PreloadDbFile);
|
||||
_loadDbFileTask = Task.Factory.StartNew<MemoryStream>(PreloadDbFile);
|
||||
_loadDbTaskOffline = App.Kp2a.OfflineMode;
|
||||
}
|
||||
}
|
||||
@@ -1953,7 +1860,7 @@ namespace keepass2android
|
||||
EditText pwd = (EditText)FindViewById(Resource.Id.password_edit);
|
||||
pwd.PostDelayed(() =>
|
||||
{
|
||||
InputMethodManager keyboard = (InputMethodManager)GetSystemService(InputMethodService);
|
||||
InputMethodManager keyboard = (InputMethodManager)GetSystemService(Context.InputMethodService);
|
||||
if (showKeyboard)
|
||||
keyboard.ShowSoftInput(pwd, 0);
|
||||
else
|
||||
@@ -1997,7 +1904,7 @@ namespace keepass2android
|
||||
{
|
||||
//exception can happen here if the app was restored from Google Backup (including preferences) but no fingerprint data is there.
|
||||
btn.SetImageResource(Resource.Drawable.ic_fingerprint_error);
|
||||
Kp2aLog.Log("failed to init fingerprint unlock:" + e);
|
||||
Kp2aLog.Log("failed to init fingerprint unlock:" + e.ToString());
|
||||
string error = GetString(Resource.String.FingerprintInitFailed) + " " +
|
||||
GetString(Resource.String.fingerprint_reenable2);
|
||||
|
||||
@@ -2035,12 +1942,32 @@ namespace keepass2android
|
||||
|
||||
}
|
||||
|
||||
private String LoadKeyProviderStringForIoc(String filename) {
|
||||
private String GetKeyFile(String filename) {
|
||||
if ( _rememberKeyfile ) {
|
||||
string keyfile = App.Kp2a.FileDbHelper.GetKeyFileForFile(filename);
|
||||
if (String.IsNullOrEmpty(keyfile))
|
||||
return null; //signal no key file
|
||||
|
||||
|
||||
if (KeyProviderType == KeyProviders.KeyFile)
|
||||
{
|
||||
//test if the filename is properly encoded.
|
||||
try
|
||||
{
|
||||
Kp2aLog.Log("test if stored filename is ok");
|
||||
IOConnectionInfo.UnserializeFromString(keyfile);
|
||||
Kp2aLog.Log("...ok");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
//it's not. This is probably because we're upgrading from app version <= 45
|
||||
//where the keyfile was stored plain text and not serialized
|
||||
Kp2aLog.Log("no, it's not: " + e.GetType().Name);
|
||||
var serializedKeyFile = IOConnectionInfo.SerializeToString(IOConnectionInfo.FromPath(keyfile));
|
||||
Kp2aLog.Log("now it is!");
|
||||
return serializedKeyFile;
|
||||
|
||||
}
|
||||
}
|
||||
return keyfile;
|
||||
} else {
|
||||
return null;
|
||||
@@ -2167,8 +2094,8 @@ namespace keepass2android
|
||||
{
|
||||
if (_act._prefs.GetBoolean(IoUtil.GetIocPrefKey(_ioConnection, "has_local_backup"), false))
|
||||
{
|
||||
Object changeDb = _act.GetString(Resource.String.menu_change_db);
|
||||
Message += _act.GetString(Resource.String.HintLocalBackupOtherError, changeDb);
|
||||
Java.Lang.Object changeDb = _act.GetString(Resource.String.menu_change_db);
|
||||
Message += _act.GetString(Resource.String.HintLocalBackupOtherError, new Java.Lang.Object[] { changeDb });
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -6,7 +6,6 @@
|
||||
<application android:label="keepass2android"
|
||||
android:icon="@mipmap/ic_launcher_online"
|
||||
android:roundIcon="@mipmap/ic_launcher_online_round"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
>
|
||||
|
||||
<activity android:name="com.dropbox.core.android.AuthActivity" android:launchMode="singleTask" android:configChanges="orientation|keyboard">
|
||||
@@ -28,6 +27,12 @@
|
||||
<provider android:name="group.pals.android.lib.ui.filechooser.providers.localfile.LocalFileProvider" android:authorities="keepass2android.keepass2android_debug.android-filechooser.localfile" android:exported="false" />
|
||||
<provider android:name="group.pals.android.lib.ui.filechooser.providers.history.HistoryProvider" android:authorities="keepass2android.keepass2android_debug.android-filechooser.history" android:exported="false" />
|
||||
<activity android:name="group.pals.android.lib.ui.filechooser.FileChooserActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenSize" android:screenOrientation="user" android:theme="@style/Afc.Theme.Light">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.GET_CONTENT" />
|
||||
<data android:mimeType="*/*" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.OPENABLE" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<service android:name="keepass2android.softkeyboard.KP2AKeyboard" android:permission="android.permission.BIND_INPUT_METHOD">
|
||||
<intent-filter>
|
||||
@@ -117,7 +122,6 @@
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
|
||||
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
|
||||
<uses-permission android:name="keepass2android.keepass2android_debug.permission.KP2aInternalFileBrowsing" />
|
||||
|
@@ -11,8 +11,6 @@
|
||||
<application android:label="keepass2android"
|
||||
android:icon="@mipmap/ic_launcher_online"
|
||||
android:roundIcon="@mipmap/ic_launcher_online_round"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
|
||||
>
|
||||
<activity android:name="com.dropbox.core.android.AuthActivity" android:launchMode="singleTask" android:configChanges="orientation|keyboard">
|
||||
<intent-filter>
|
||||
@@ -33,6 +31,12 @@
|
||||
<provider android:name="group.pals.android.lib.ui.filechooser.providers.localfile.LocalFileProvider" android:authorities="keepass2android.keepass2android.android-filechooser.localfile" android:exported="false" />
|
||||
<provider android:name="group.pals.android.lib.ui.filechooser.providers.history.HistoryProvider" android:authorities="keepass2android.keepass2android.android-filechooser.history" android:exported="false" />
|
||||
<activity android:name="group.pals.android.lib.ui.filechooser.FileChooserActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenSize" android:screenOrientation="user" android:theme="@style/Afc.Theme.Light">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.GET_CONTENT" />
|
||||
<data android:mimeType="*/*" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.OPENABLE" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<service android:name="keepass2android.softkeyboard.KP2AKeyboard" android:permission="android.permission.BIND_INPUT_METHOD">
|
||||
@@ -143,7 +147,6 @@
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.USE_CREDENTIALS" android:maxSdkVersion="22" />
|
||||
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" android:maxSdkVersion="22" />
|
||||
<uses-permission android:name="keepass2android.keepass2android.permission.KP2aInternalFileBrowsing" />
|
||||
|
@@ -1,20 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:versionCode="93"
|
||||
android:versionName="1.01-g"
|
||||
android:versionCode="127"
|
||||
android:versionName="1.06f"
|
||||
package="keepass2android.keepass2android_nonet"
|
||||
android:installLocation="auto">
|
||||
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="23" />
|
||||
<permission android:description="@string/permission_desc2" android:icon="@drawable/ic_launcher" android:label="KP2A entry search" android:name="keepass2android.keepass2android_nonet.permission.KP2aInternalSearch" android:protectionLevel="signature" />
|
||||
<permission android:description="@string/permission_desc3" android:icon="@drawable/ic_launcher" android:label="KP2A choose autofill dataset" android:name="keepass2android.keepass2android_nonet.permission.Kp2aChooseAutofill" android:protectionLevel="signature" />
|
||||
<application
|
||||
android:label="keepass2android"
|
||||
android:icon="@mipmap/ic_launcher_offline"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
>
|
||||
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="26" />
|
||||
<permission android:description="@string/permission_desc2" android:icon="@drawable/ic_launcher_offline" android:label="KP2A entry search" android:name="keepass2android.keepass2android_nonet.permission.KP2aInternalSearch" android:protectionLevel="signature" />
|
||||
<permission android:description="@string/permission_desc3" android:icon="@drawable/ic_launcher_offline" android:label="KP2A choose autofill dataset" android:name="keepass2android.keepass2android_nonet.permission.Kp2aChooseAutofill" android:protectionLevel="signature" />
|
||||
<application android:label="keepass2android" android:icon="@mipmap/ic_launcher_offline">
|
||||
<provider android:name="group.pals.android.lib.ui.filechooser.providers.localfile.LocalFileProvider" android:authorities="keepass2android.keepass2android_nonet.android-filechooser.localfile" android:exported="false" />
|
||||
<provider android:name="group.pals.android.lib.ui.filechooser.providers.history.HistoryProvider" android:authorities="keepass2android.keepass2android_nonet.android-filechooser.history" android:exported="false" />
|
||||
<activity android:name="group.pals.android.lib.ui.filechooser.FileChooserActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenSize" android:screenOrientation="user" android:theme="@style/Afc.Theme.Light">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.GET_CONTENT" />
|
||||
<data android:mimeType="*/*" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.OPENABLE" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<service android:name="keepass2android.softkeyboard.KP2AKeyboard" android:permission="android.permission.BIND_INPUT_METHOD">
|
||||
@@ -40,7 +42,6 @@
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:configChanges="orientation|keyboard|keyboardHidden" android:label="@string/app_name" android:theme="@style/MyTheme_Blue" android:name="keepass2android.PasswordActivity" android:windowSoftInputMode="adjustResize">
|
||||
<intent-filter android:label="@string/app_name">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
@@ -50,12 +51,13 @@
|
||||
<data android:mimeType="application/octet-stream" />
|
||||
<data android:host="*" />
|
||||
</intent-filter>
|
||||
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="kp2a.action.PasswordActivity" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
|
||||
|
||||
<intent-filter android:label="@string/app_name">
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<action android:name="android.intent.action.SEND_MULTIPLE" />
|
||||
@@ -124,8 +126,8 @@
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
||||
|
||||
<uses-permission android:name="keepass2android.keepass2android.permission.KP2aInternalFileBrowsing" />
|
||||
<uses-permission android:name="keepass2android.keepass2android.permission.KP2aInternalSearch" />
|
||||
<uses-permission android:name="keepass2android.keepass2android_nonet.permission.KP2aInternalFileBrowsing" />
|
||||
<uses-permission android:name="keepass2android.keepass2android_nonet.permission.KP2aInternalSearch" />
|
||||
<!-- Samsung Pass permission -->
|
||||
<uses-permission android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY" />
|
||||
</manifest>
|
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 861 B |
After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 1.9 KiB |
@@ -39,26 +39,6 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:hint="@string/hint_username" />
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/auth_mode_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/sftp_auth_mode" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/sftp_auth_mode_spinner"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="-4dp"
|
||||
android:entries="@array/sftp_auth_modes" />
|
||||
</LinearLayout>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/sftp_password"
|
||||
@@ -68,11 +48,6 @@
|
||||
android:singleLine="true"
|
||||
android:hint="@string/hint_pass"
|
||||
android:importantForAccessibility="no"/>
|
||||
<Button android:id="@+id/send_public_key_button"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/send_public_key" />
|
||||
|
||||
|
||||
<TextView android:id="@+id/initial_dir"
|
||||
android:layout_width="wrap_content"
|
||||
|
@@ -27,11 +27,6 @@
|
||||
android:icon="@drawable/ic_menu_view"
|
||||
app:showAsAction="ifRoom"
|
||||
/>
|
||||
<item android:id="@+id/menu_delete"
|
||||
android:icon="@drawable/ic_menu_delete"
|
||||
android:title="@string/menu_delete"
|
||||
app:showAsAction="ifRoom"
|
||||
/>
|
||||
<item android:id="@+id/menu_donate"
|
||||
android:title="@string/menu_donate"
|
||||
app:showAsAction="ifRoom"
|
||||
|
@@ -917,7 +917,6 @@ Erstes öffentliches Release</string>
|
||||
<item>Passwort + Challenge-Response</item>
|
||||
<item>Passwort + Challenge-Response-Secret (Recovery-Modus)</item>
|
||||
<item>Passwort + Challenge-Response für Keepass XC</item>
|
||||
<item>Password + Schlüsseldatei + Challenge-Response für Keepass XC</item>
|
||||
</string-array>
|
||||
<string-array name="AcceptAllServerCertificates_options">
|
||||
<item>Fehler bei Zertifikatsvalidierung ignorieren</item>
|
||||
|
@@ -48,8 +48,7 @@
|
||||
|
||||
|
||||
<!-- Preference settings -->
|
||||
<string name="AutoReturnFromQuery_key">AutoReturnFromQuery_key</string>
|
||||
<string name="algorithm_key">algorithm</string>
|
||||
<string name="algorithm_key">algorithm</string>
|
||||
<string name="app_key">app</string>
|
||||
<string name="app_timeout_key">app_timeout_key</string>
|
||||
<string name="show_kill_app_key">show_kill_app_key</string>
|
||||
@@ -115,10 +114,8 @@
|
||||
<string name="UseFileTransactions_key">UseFileTransactions</string>
|
||||
<string name="LockWhenScreenOff_key">LockWhenScreenOff</string>
|
||||
<string name="LockWhenNavigateBack_key">kp2a_switch_rootedLockWhenNavigateBack</string>
|
||||
<string name="UseKp2aKeyboardInKp2a_key">UseKp2aKeyboardInKp2a</string>
|
||||
|
||||
|
||||
<string name="NoDonateOption_key">NoDonateOption</string>
|
||||
<string name="NoDonateOption_key">NoDonateOption</string>
|
||||
<string name="NoDonationReminder_key">NoDonationReminder</string>
|
||||
|
||||
<string name="UseOfflineCache_key">UseOfflineCache</string>
|
||||
|
@@ -221,8 +221,6 @@
|
||||
<string name="edit">Edit</string>
|
||||
<string name="rijndael">Rijndael (AES)</string>
|
||||
<string name="root">Root</string>
|
||||
<string name="AutoReturnFromQuery_title">Automatically return from query screen</string>
|
||||
<string name="AutoReturnFromQuery_summary">When looking up an entry for an app or website: automatically return from query screen if there is only one matching entry in the database.</string>
|
||||
|
||||
<string name="KeyDerivFunc">Key derivation function</string>
|
||||
|
||||
@@ -314,7 +312,7 @@
|
||||
<string name="BinaryDirectory_summary">Directory where file attachments are saved to.</string>
|
||||
<string name="SaveAttachmentDialog_title">Save attachment</string>
|
||||
<string name="SaveAttachmentDialog_text">Please select where to save the attachment.</string>
|
||||
<string name="SaveAttachmentDialog_save">Export to file...</string>
|
||||
<string name="SaveAttachmentDialog_save">Save to SD card</string>
|
||||
<string name="SaveAttachmentDialog_open">Save to cache and open</string>
|
||||
<string name="ShowAttachedImage">Show with internal image viewer</string>
|
||||
|
||||
@@ -348,11 +346,6 @@
|
||||
<string name="LockWhenNavigateBack_title">Lock when leaving app</string>
|
||||
<string name="LockWhenNavigateBack_summary">Lock the database when leaving the app by pressing the back button.</string>
|
||||
|
||||
<string name="UseKp2aKeyboardInKp2a_title">Use built-in keyboard inside Keepass2Android</string>
|
||||
<string name="UseKp2aKeyboardInKp2a_summary">If you do not trust your standard keyboard provider, check this option to use the built-in keyboard when entering your master password or editing entries.</string>
|
||||
|
||||
|
||||
|
||||
<string name="ActivateSearchViewOnStart_title">Activate search field on start</string>
|
||||
<string name="ActivateSearchViewOnStart_summary">Activates search field in the group view after unlocking or when searching for an entry</string>
|
||||
|
||||
@@ -512,16 +505,11 @@
|
||||
|
||||
<string name="enter_owncloud_login_title">Enter OwnCloud login data:</string>
|
||||
<string name="hint_owncloud_url">OwnCloud URL (ex: owncloud.me.com)</string>
|
||||
|
||||
<string name="enter_nextcloud_login_title">Enter NextCloud login data:</string>
|
||||
<string name="hint_nextcloud_url">NextCloud URL (ex: nextcloud.me.com)</string>
|
||||
|
||||
<string name="hint_sftp_host">host (ex: 192.168.0.1)</string>
|
||||
<string name="hint_sftp_port">port</string>
|
||||
<string name="initial_directory">Initial directory (optional):</string>
|
||||
<string name="enter_sftp_login_title">Enter SFTP login data:</string>
|
||||
<string name="sftp_auth_mode">Authentication mode</string>
|
||||
<string name="send_public_key">Send public key...</string>
|
||||
|
||||
<string name="enter_ftp_login_title">Enter FTP login data:</string>
|
||||
|
||||
@@ -536,12 +524,10 @@
|
||||
<string name="filestoragename_http">HTTP (WebDav)</string>
|
||||
<string name="filestoragename_https">HTTPS (WebDav)</string>
|
||||
<string name="filestoragename_owncloud">OwnCloud</string>
|
||||
<string name="filestoragename_nextcloud">NextCloud</string>
|
||||
<string name="filestoragename_dropbox">Dropbox</string>
|
||||
<string name="filestoragename_dropboxKP2A">Dropbox (KP2A folder)</string>
|
||||
<string name="filestoragehelp_dropboxKP2A">If you do not want to give KP2A access to your full Dropbox, you may select this option. It will request only access to the folder Apps/Keepass2Android. This is especially suited when creating a new database. If you already have a database, click this option to create the folder, then place your file inside the folder (from your PC) and then select this option again for opening the file.</string>
|
||||
<string name="filestoragename_gdrive">Google Drive</string>
|
||||
<string name="filestoragename_pcloud">PCloud</string>
|
||||
<string name="filestoragename_onedrive">OneDrive</string>
|
||||
<string name="filestoragename_sftp">SFTP (SSH File Transfer)</string>
|
||||
<string name="filestoragename_content">System file picker</string>
|
||||
@@ -1120,12 +1106,7 @@ Initial public release
|
||||
<item>Password + Challenge-Response</item>
|
||||
<item>Password + Challenge-Response secret (recovery mode)</item>
|
||||
<item>Password + Challenge-Response for Keepass XC</item>
|
||||
<item>Password + Key file + Challenge-Response for Keepass XC</item>
|
||||
</string-array>
|
||||
<string-array name="sftp_auth_modes">
|
||||
<item>Password</item>
|
||||
<item>Private/Public key</item>
|
||||
</string-array>
|
||||
<string-array name="AcceptAllServerCertificates_options">
|
||||
<item>Ignore certificate validation failures</item>
|
||||
<item>Warn when validation fails</item>
|
||||
|
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config>
|
||||
<base-config cleartextTrafficPermitted="true">
|
||||
<trust-anchors>
|
||||
<certificates src="system" />
|
||||
<certificates src="user" />
|
||||
</trust-anchors>
|
||||
</base-config>
|
||||
</network-security-config>
|
@@ -200,14 +200,6 @@
|
||||
android:title="@string/ClearPasswordOnLeave_title"
|
||||
android:key="@string/ClearPasswordOnLeave_key" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:enabled="true"
|
||||
android:persistent="true"
|
||||
android:summary="@string/UseKp2aKeyboardInKp2a_summary"
|
||||
android:defaultValue="false"
|
||||
android:title="@string/UseKp2aKeyboardInKp2a_title"
|
||||
android:key="@string/UseKp2aKeyboardInKp2a_key" />
|
||||
|
||||
|
||||
</PreferenceScreen>
|
||||
<PreferenceScreen
|
||||
@@ -402,14 +394,6 @@
|
||||
|
||||
</Preference>
|
||||
|
||||
<CheckBoxPreference
|
||||
android:enabled="true"
|
||||
android:persistent="true"
|
||||
android:summary="@string/AutoReturnFromQuery_summary"
|
||||
android:defaultValue="true"
|
||||
android:title="@string/AutoReturnFromQuery_title"
|
||||
android:key="@string/AutoReturnFromQuery_key" />
|
||||
|
||||
</PreferenceScreen>
|
||||
<PreferenceScreen
|
||||
android:key="@string/QuickUnlock_prefs_key"
|
||||
|
@@ -25,7 +25,6 @@ using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using Android.Content.PM;
|
||||
using Android.Preferences;
|
||||
using KeePassLib.Utility;
|
||||
|
||||
namespace keepass2android
|
||||
@@ -135,7 +134,7 @@ namespace keepass2android
|
||||
}
|
||||
|
||||
//if there is exactly one match: open the entry
|
||||
if ((Group.Entries.Count() == 1) && autoReturnFromQuery && PreferenceManager.GetDefaultSharedPreferences(this).GetBoolean(GetString(Resource.String.AutoReturnFromQuery_key),true))
|
||||
if ((Group.Entries.Count() == 1) && autoReturnFromQuery)
|
||||
{
|
||||
LaunchActivityForEntry(Group.Entries.Single(),0);
|
||||
return;
|
||||
|
@@ -1,5 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo 'Copying debug manifest.'
|
||||
cp Properties/AndroidManifest_debug.xml Properties/AndroidManifest.xml
|
@@ -45,7 +45,6 @@ using KeePassLib.Utility;
|
||||
#if !NoNet
|
||||
using Keepass2android.Javafilestorage;
|
||||
using GoogleDriveFileStorage = keepass2android.Io.GoogleDriveFileStorage;
|
||||
using PCloudFileStorage = keepass2android.Io.PCloudFileStorage;
|
||||
#endif
|
||||
namespace keepass2android
|
||||
{
|
||||
@@ -586,10 +585,9 @@ namespace keepass2android
|
||||
new DropboxAppFolderFileStorage(Application.Context, this),
|
||||
new GoogleDriveFileStorage(Application.Context, this),
|
||||
new OneDriveFileStorage(Application.Context, this),
|
||||
new SftpFileStorage(Application.Context, this),
|
||||
new SftpFileStorage(this),
|
||||
new NetFtpFileStorage(Application.Context, this),
|
||||
new WebDavFileStorage(this),
|
||||
new PCloudFileStorage(Application.Context, this),
|
||||
//new LegacyWebDavStorage(this),
|
||||
//new LegacyFtpStorage(this),
|
||||
#endif
|
||||
|
@@ -65,7 +65,7 @@
|
||||
</CustomCommands>
|
||||
</CustomCommands>
|
||||
<DeployExternal>True</DeployExternal>
|
||||
<DefineConstants>RELEASE</DefineConstants>
|
||||
<DefineConstants>RELEASE;NoNet</DefineConstants>
|
||||
<AndroidLinkSkip>System.Core%3b</AndroidLinkSkip>
|
||||
<EmbedAssembliesIntoApk>True</EmbedAssembliesIntoApk>
|
||||
<AndroidLinkMode>SdkOnly</AndroidLinkMode>
|
||||
@@ -99,6 +99,10 @@
|
||||
</JavaOptions>
|
||||
<AndroidStoreUncompressedFileExtensions>
|
||||
</AndroidStoreUncompressedFileExtensions>
|
||||
<AotAssemblies>false</AotAssemblies>
|
||||
<EnableLLVM>false</EnableLLVM>
|
||||
<BundleAssemblies>false</BundleAssemblies>
|
||||
<EnableProguard>true</EnableProguard>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Java.Interop" />
|
||||
@@ -159,23 +163,10 @@
|
||||
<Reference Include="Xamarin.Android.Support.Vector.Drawable, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Xamarin.Android.Support.Vector.Drawable.26.1.0.1\lib\MonoAndroid80\Xamarin.Android.Support.Vector.Drawable.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xamarin.GooglePlayServices.Base">
|
||||
<HintPath>..\packages\Xamarin.GooglePlayServices.Base.27.0.0.0\lib\MonoAndroid41\Xamarin.GooglePlayServices.Base.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Xamarin.GooglePlayServices.Basement">
|
||||
<HintPath>..\packages\Xamarin.GooglePlayServices.Basement.27.0.0.0\lib\MonoAndroid41\Xamarin.GooglePlayServices.Basement.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Xamarin.GooglePlayServices.Drive">
|
||||
<HintPath>..\packages\Xamarin.GooglePlayServices.Drive.27.0.0.0\lib\MonoAndroid41\Xamarin.GooglePlayServices.Drive.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ChallengeXCKey.cs" />
|
||||
<Compile Include="EntryActivityClasses\ViewImagePopupItem.cs" />
|
||||
<Compile Include="FileSaveProcessManager.cs" />
|
||||
<Compile Include="fileselect\FilteredCursor.cs" />
|
||||
<Compile Include="ImageViewActivity.cs" />
|
||||
<Compile Include="addons\OtpKeyProv\EncodingUtil.cs" />
|
||||
@@ -489,7 +480,6 @@
|
||||
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_androidsend.png" />
|
||||
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_content.png" />
|
||||
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_dropbox.png" />
|
||||
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_pcloud.png" />
|
||||
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_dropboxKP2A.png" />
|
||||
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_file.png" />
|
||||
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_ftp.png" />
|
||||
@@ -829,18 +819,6 @@
|
||||
<Folder Include="SupportLib\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AdalBindings\AdalBindings.csproj">
|
||||
<Project>{0b109c0e-0514-4340-8779-5bd6a0dde84e}</Project>
|
||||
<Name>AdalBindings</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\JavaFileStorageBindings\JavaFileStorageBindings.csproj">
|
||||
<Project>{48574278-4779-4B3A-A9E4-9CF1BC285D0B}</Project>
|
||||
<Name>JavaFileStorageBindings</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\PCloudBindings\PCloudBindings.csproj">
|
||||
<Project>{2DB80C77-D46F-4970-B967-E9FFA9B2AC2E}</Project>
|
||||
<Name>PCloudBindings</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\KeePassLib2Android\KeePassLib2Android.csproj">
|
||||
<Project>{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}</Project>
|
||||
<Name>KeePassLib2Android</Name>
|
||||
@@ -857,10 +835,6 @@
|
||||
<Project>{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}</Project>
|
||||
<Name>Kp2aKeyboardBinding</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\netftpandroid\System.Net.FtpClient\System.Net.FtpClient.Android.csproj">
|
||||
<Project>{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}</Project>
|
||||
<Name>System.Net.FtpClient.Android</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\PluginSdkBinding\PluginSdkBinding.csproj">
|
||||
<Project>{3DA3911E-36DE-465E-8F15-F1991B6437E5}</Project>
|
||||
<Name>PluginSdkBinding</Name>
|
||||
@@ -1156,9 +1130,6 @@
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\ic_storage_dropboxKP2A.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\ic_storage_pcloud.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\ic_storage_file.png" />
|
||||
</ItemGroup>
|
||||
@@ -1875,13 +1846,13 @@
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\vdots_bright.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\xml\network_security_config.xml" />
|
||||
<AndroidResource Include="Resources\drawable-hdpi-v4\ic_launcher_offline.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\ic_storage_nextcloud.png" />
|
||||
<AndroidResource Include="Resources\drawable-mdpi-v4\ic_launcher_offline.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_nextcloud.png" />
|
||||
<AndroidResource Include="Resources\drawable-xhdpi-v4\ic_launcher_offline.png" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
|
||||
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" />
|
||||
|
@@ -385,16 +385,7 @@ namespace keepass2android
|
||||
{
|
||||
|
||||
var intent = new Intent(Settings.ActionRequestSetAutofillService);
|
||||
if (((AutofillManager) Activity.GetSystemService(Java.Lang.Class.FromType(typeof(AutofillManager))))
|
||||
.HasEnabledAutofillServices)
|
||||
{
|
||||
intent.SetData(Android.Net.Uri.Parse("package:" + Context.PackageName + "notexisting")); //if we use our package name, the activity won't launch
|
||||
}
|
||||
else
|
||||
{
|
||||
intent.SetData(Android.Net.Uri.Parse("package:" + Context.PackageName));
|
||||
}
|
||||
|
||||
intent.SetData(Android.Net.Uri.Parse("package:" + Context.PackageName));
|
||||
try
|
||||
{
|
||||
Context.StartActivity(intent);
|
||||
@@ -410,10 +401,6 @@ namespace keepass2android
|
||||
.Show();
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Kp2aLog.LogUnexpectedError(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -540,6 +527,11 @@ namespace keepass2android
|
||||
else
|
||||
{
|
||||
autofillPref.Summary = Activity.GetString(Resource.String.not_enabled);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|