Compare commits

..

13 Commits

Author SHA1 Message Date
Philipp Crocoll
8468049935 manifest for 1.06f release 2018-11-10 08:38:13 +01:00
Philipp Crocoll
7cef6c8566 Merge branch 'nonet' of https://github.com/PhilippC/keepass2android into nonet
# Conflicts:
#	src/keepass2android/Properties/AndroidManifest_nonet.xml
#	src/keepass2android/keepass2android.csproj
2018-11-08 05:23:10 +01:00
Philipp Crocoll
98f2a139e9 Merge remote-tracking branch 'remotes/origin/1.06' into nonet
# Conflicts:
#	src/keepass2android/Properties/AndroidManifest_nonet.xml
2018-11-08 04:55:44 +01:00
Philipp Crocoll
832d3b3a95 1.05d release for nonet 2018-06-23 09:07:47 +02:00
Philipp Crocoll
37867634cd Merge branch 'master' into nonet
Conflicts:
	src/keepass2android/Properties/AndroidManifest_nonet.xml
2018-06-18 13:08:07 +02:00
Philipp Crocoll
d9713f8e18 switch to using Release build type instead of ReleaseNoNet (separation no longer required because a custom branch exists for the offline variant) 2018-02-28 06:06:26 +01:00
Philipp Crocoll
c583b58cb9 adjust manifest version for 1.04b release 2018-02-27 06:06:35 +01:00
Philipp Crocoll
bfeaf5dbf5 Merge branch '1.04' into nonet
Conflicts:
	src/keepass2android/Properties/AndroidManifest_nonet.xml
2018-02-21 05:58:01 +01:00
Philipp Crocoll
0907fa5685 manifest for 1.03-nonet release 2017-12-02 15:30:04 +01:00
Philipp Crocoll
ff8dc76c75 Merge branch 'master' into nonet
Conflicts:
	docs/README.md
2017-12-02 14:25:37 +01:00
Philipp Crocoll
0b09e2790f remove online file storages from project file 2017-10-25 06:49:02 +02:00
Philipp Crocoll
781350aa5f manifest for 1.02 release 2017-10-25 06:24:01 +02:00
Philipp Crocoll
9716130336 remove references to libraries only required for online build, adjust build script and README 2017-10-25 06:23:53 +02:00
80 changed files with 575 additions and 2511 deletions

View File

@@ -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).
[![Build Status](https://www.bitrise.io/app/43a23ab54dee9f7e/status.svg?token=2vryTsMQzTX3XRPikhgRwA&branch=master)](https://www.bitrise.io/app/43a23ab54dee9f7e)
[![Build Status](https://www.bitrise.io/app/43a23ab54dee9f7e/status.svg?token=2vryTsMQzTX3XRPikhgRwA&branch=nonet)](https://www.bitrise.io/app/43a23ab54dee9f7e)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

View File

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

View File

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

View File

@@ -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".

Binary file not shown.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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']" />

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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".

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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/.'

View File

@@ -1,8 +0,0 @@
#!/bin/bash
set -e
pushd ../keepass2android
xabuild keepass2android.csproj /t:SignAndroidPackage "$@"
popd

View File

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

View File

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

View File

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

View File

@@ -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
View 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.

View File

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

View File

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

View File

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

View File

@@ -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+"?");
}
}
}

View File

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

View File

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

View File

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

View File

@@ -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
View File

View 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")

View File

@@ -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
View File

View 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
View File

0
src/java/Keepass2AndroidPluginSDK2/gradlew vendored Executable file → Normal file
View File

View 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);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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" />

View File

@@ -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" />

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 861 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +0,0 @@
#!/bin/bash
set -e
echo 'Copying debug manifest.'
cp Properties/AndroidManifest_debug.xml Properties/AndroidManifest.xml

View File

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

View File

@@ -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')" />

View File

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