Compare commits
17 Commits
1.08d-r5
...
1.07b-r0-o
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f2ca846093 | ||
![]() |
38cee50f34 | ||
![]() |
d45fd99235 | ||
![]() |
05eea4aae1 | ||
![]() |
8468049935 | ||
![]() |
7cef6c8566 | ||
![]() |
98f2a139e9 | ||
![]() |
832d3b3a95 | ||
![]() |
37867634cd | ||
![]() |
d9713f8e18 | ||
![]() |
c583b58cb9 | ||
![]() |
bfeaf5dbf5 | ||
![]() |
0907fa5685 | ||
![]() |
ff8dc76c75 | ||
![]() |
0b09e2790f | ||
![]() |
781350aa5f | ||
![]() |
9716130336 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -169,5 +169,3 @@ src/java/Keepass2AndroidPluginSDK2/build/generated/mockable-Google-Inc.-Google-A
|
||||
/src/java/KP2AKdbLibrary/app/build
|
||||
/src/java/KP2ASoftkeyboard_AS/app/.cxx
|
||||
/src/java/KP2ASoftkeyboard_AS/app/src/main/libs
|
||||
/src/java/KP2AKdbLibrary/app/.cxx
|
||||
/src/ActionViewFilterTest
|
||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,6 +1,9 @@
|
||||
[submodule "src/SamsungPass"]
|
||||
path = src/SamsungPass
|
||||
url = https://github.com/PhilippC/Xamarin-Samsung-Pass.git
|
||||
[submodule "src/netftpandroid"]
|
||||
path = src/netftpandroid
|
||||
url = https://github.com/PhilippC/netftpandroid.git
|
||||
[submodule "src/java/argon2/phc-winner-argon2"]
|
||||
path = src/java/argon2/phc-winner-argon2
|
||||
url = https://github.com/P-H-C/phc-winner-argon2
|
||||
|
24
crowdin.yml
24
crowdin.yml
@@ -8,27 +8,3 @@ files:
|
||||
two_letters_code:
|
||||
zh-CN: zh
|
||||
zh-TW: zh-rTW
|
||||
pt-PT: pt
|
||||
pt-BR: pt-rBR
|
||||
- source: src/java/android-filechooser-AS/app/src/main/res/values/strings.xml
|
||||
translation: >-
|
||||
/src/java/android-filechooser-AS/app/src/main/res/values-%two_letters_code%/%original_file_name%
|
||||
translate_attributes: '0'
|
||||
content_segmentation: '0'
|
||||
languages_mapping:
|
||||
two_letters_code:
|
||||
zh-CN: zh
|
||||
zh-TW: zh-rTW
|
||||
pt-PT: pt
|
||||
pt-BR: pt-rBR
|
||||
- source: src/java/KP2ASoftkeyboard_AS/app/src/main/res/values/strings.xml
|
||||
translation: >-
|
||||
/src/java/KP2ASoftkeyboard_AS/app/src/main/res/values-%two_letters_code%/%original_file_name%
|
||||
translate_attributes: '0'
|
||||
content_segmentation: '0'
|
||||
languages_mapping:
|
||||
two_letters_code:
|
||||
zh-CN: zh
|
||||
zh-TW: zh-rTW
|
||||
pt-PT: pt
|
||||
pt-BR: pt-rBR
|
||||
|
@@ -77,10 +77,6 @@ The KP2A keyboard is meant to quickly "paste" or "type" values from your databas
|
||||
## Is it safe to store my kdbx file in the cloud?
|
||||
While it may happen that someone gets access to your kdbx file in the cloud, there is still no need to worry: the purpose of encryption is to protect the data even in case someone gets the kdbx file! As long as you are using a safe master key, you're safe! [Key files](https://keepass.info/help/base/keys.html#keyfiles) can help with securing the database even more.
|
||||
|
||||
## Doesn't Keepass2Android create automatic backups?
|
||||
Yes and no. Yes: Keepass2Android stores the last successfully opened file as a read-only backup locally on the phone (unless you disable this is in the settings). This should make sure that even if the file gets destroyed during a save operation or gets deleted by accident, you should always have a version that can be opened. (Don't mix this up with the internal file cache which is not meant as a backup and can easily be overwritten even with a corrupt file. This internal file cache is meant for providing writable access even when the original file is not reachable, e.g. when you're offline.)
|
||||
No: The local backup has two shortcomings: It is only one backup and does not allow to revert to older versions. So if you deleted an entry from the database, it might be deleted in the local backup soon as well. The even more important shortcoming is that it is just a local backup. It won't help when your phone gets lost or broken. Please create additional backups on seperate storage!
|
||||
|
||||
## How do I backup the database?
|
||||
If you have stored your database on the cloud, you might rely on your cloud storage providers backups. Make sure they allow you to revert to older revisions in case the file gets corrupted for some reason.
|
||||
If you are working with a local database file, make sure you create regular backups. I suggest you have an aumotated mechanism, e.g. with FolderSync (Lite) which can copy local files from your device to other locations, e.g. your PC in a local network. You can also use USB or tools like MyPhoneExploror to transfer data to your PC. Or, you use a removable storage like an SD card which you keep in a safe place after making the backup.
|
||||
@@ -98,23 +94,6 @@ It's time for action! As soon as possible, select Settings - Database - Export a
|
||||
## Why is Keepass2Android's apk so big?
|
||||
Please see [Keepass2Android Apk](Keepass2Android-Apk.md) for more information.
|
||||
|
||||
## I get a message "File is trashed" when reading or writing a file on Google Drive
|
||||
This happens because ocaml-fuse (I guess you are on Linux and use that) moves files to trash and then creates a new one instead of correctly updating the file on Google Drive (each file has a unique ID which Keepass2Android uses). Fortunately, this was fixed: https://github.com/astrada/google-drive-ocamlfuse/issues/494After activating this option, please select "Change database" in KP2A, tap ,"Open file" and browse to the file on Google Drive again. After that, the message should no longer pop up.
|
||||
|
||||
## I get a message "The name must not be empty: null" when opening from Google Drive
|
||||
Please follow these steps:
|
||||
|
||||
* select "Change database" on the password screen, then "Open database" and browse to your file again
|
||||
* go to Android app settings and disable all permissions for the KP2A app. Then try again to open the database file.
|
||||
* reboot the device
|
||||
|
||||
(Before running the following steps, make sure you don't have local changes in your database which have not been synchronized with Google Drive (this can happen if you worked offline). If you have, please open the database from the local cache and go to settings - database settings - export database and make a backup copy of the data.)
|
||||
|
||||
* clear KP2A's app cache in the Android settings
|
||||
* uninstall & reinstall
|
||||
|
||||
One of these has helped all users so far, but unfortunately it's not totally clear to me why different steps are required (or nothing for most users).
|
||||
|
||||
# For developers
|
||||
If you are interested in adding new features, you have two options:
|
||||
Either your features can be implemented as a plug-in. Please see [How to create a plug-in?](How-to-create-a-plug-in_.md) for more information. Or you add the features directly in the source code of the projects and create a pull request.
|
||||
|
@@ -54,7 +54,7 @@ Please also add a few strings in your resource files (e.g. strings.xml) with the
|
||||
These strings will be displayed to the user when KP2A asks if access should be granted.
|
||||
|
||||
## Modifying the entry view
|
||||
You can add menu options for the full entry or for individual fields of the entry when displayed to the user. This is done, for example, by the QR plugin ([https://play.google.com/store/apps/details?id=keepass2android.plugin.qr](https://play.google.com/store/apps/details?id=keepass2android.plugin.qr)).
|
||||
You can add menu options for the full entry or for individual fields of the entry when displayed to the user. This is done, for example, by the QR plugin ([https://play.google.com/store/apps/details?id=keepass2android.plugin.qr](https___play.google.com_store_apps_details_id=keepass2android.plugin.qr)).
|
||||
In addition, it is even possible to add new fields or modify existing fields. Please see the sample plugin "PluginA" in the KP2A repository for a simple example on how to do this:
|
||||
[https://keepass2android.codeplex.com/SourceControl/latest#src/java/PluginA/src/keepass2android/plugina/PluginAActionReceiver.java](https://keepass2android.codeplex.com/SourceControl/latest#src/java/PluginA/src/keepass2android/plugina/PluginAActionReceiver.java)
|
||||
|
||||
|
@@ -8,15 +8,14 @@ The password database file can be synchronized across different devices. This wo
|
||||
# Where to get it?
|
||||
Regular stable releases of Keepass2Android are available on [Google Play](https://play.google.com/store/apps/details?id=keepass2android.keepass2android).
|
||||
|
||||
Beta-releases can be obtained by opting in to the [Beta testing channel](https://play.google.com/apps/testing/keepass2android.keepass2android) or [Beta testing channel for Keepass2Android Offline](https://play.google.com/apps/testing/keepass2android.keepass2android_nonet).
|
||||
Beta-releases can be obtained by opting in to the [Beta testing channel](https://play.google.com/apps/testing/keepass2android.keepass2android) or [Beta testing channel for Keepass2Android Offline](https://play.google.com/apps/testing/keepass2android.keepass2android_nonet). Please join the [Beta tester group](https://plus.google.com/communities/107293657110547776032) for news and discussions about the latest beta releases.
|
||||
|
||||
# How can I contribute?
|
||||
* Help to translate Keepass2Android into your language or improve translations at [our Crowdin page](http://crowdin.net/project/keepass2android)
|
||||
* Add features by [creating a plugin](How-to-create-a-plug-in_.md) or creating a pull request. You might want to contact me before you start working so I can coordinate efforts.
|
||||
* [Become a GitHub sponsor to boost 🚀 development](https://github.com/sponsors/PhilippC)
|
||||
* [Make a donation](http://philipp.crocoll.net/donate.php)
|
||||
|
||||
# How do I learn more?
|
||||
Please see the [documentation](Documentation.md).
|
||||
|
||||
[](https://www.bitrise.io/app/43a23ab54dee9f7e)
|
||||
[](https://www.bitrise.io/app/43a23ab54dee9f7e)
|
||||
|
@@ -12,7 +12,6 @@
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkVersion>v8.0</TargetFrameworkVersion>
|
||||
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
|
||||
<AndroidCodegenTarget>XAJavaInterop1</AndroidCodegenTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
|
BIN
src/JavaFileStorageBindings/Jars/okhttp-3.9.0.jar
Normal file
BIN
src/JavaFileStorageBindings/Jars/okhttp-3.9.0.jar
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/JavaFileStorageBindings/Jars/okhttp-digest-1.7.jar
Normal file
BIN
src/JavaFileStorageBindings/Jars/okhttp-digest-1.7.jar
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/JavaFileStorageBindings/Jars/okio-1.13.0.jar
Normal file
BIN
src/JavaFileStorageBindings/Jars/okio-1.13.0.jar
Normal file
Binary file not shown.
Binary file not shown.
@@ -13,7 +13,6 @@
|
||||
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
|
||||
<TargetFrameworkVersion>v8.0</TargetFrameworkVersion>
|
||||
<AndroidClassParser>class-parse</AndroidClassParser>
|
||||
<AndroidCodegenTarget>XAJavaInterop1</AndroidCodegenTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -85,6 +84,9 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\PCloudBindings\PCloudBindings.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\okhttp-digest-1.7.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\msa-auth-0.8.6\classes-msa-auth.jar" />
|
||||
</ItemGroup>
|
||||
@@ -139,19 +141,16 @@
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\jackson-core-2.7.4.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\okhttp-3.9.0.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\okio-1.13.0.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedJar Include="Jars\dropbox-core-sdk-3.1.1.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\gson-2.8.1.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\okhttp-digest-2.5.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\okio-2.9.0.jar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\okhttp-4.10.0-RC1.jar" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@@ -12,7 +12,6 @@
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkVersion>v8.0</TargetFrameworkVersion>
|
||||
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
|
||||
<AndroidCodegenTarget>XAJavaInterop1</AndroidCodegenTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
|
@@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29418.71
|
||||
# Visual Studio 15
|
||||
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}"
|
||||
@@ -109,8 +107,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
|
||||
@@ -187,8 +185,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
|
||||
@@ -205,8 +203,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
|
||||
@@ -223,8 +221,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
|
||||
|
@@ -367,27 +367,5 @@ namespace KeePassLib.Cryptography
|
||||
Debug.Assert(iPos == pbRes.Length);
|
||||
return pbRes;
|
||||
}
|
||||
|
||||
|
||||
private static int g_iWeakSeed = 0;
|
||||
public static Random NewWeakRandom()
|
||||
{
|
||||
long s64 = DateTime.UtcNow.ToBinary();
|
||||
int s32 = (int)((s64 >> 32) ^ s64);
|
||||
|
||||
lock (g_oSyncRoot)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
g_iWeakSeed += 0x78A8C4B7; // Prime number
|
||||
s32 ^= g_iWeakSeed;
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent overflow in the Random constructor of .NET 2.0
|
||||
if (s32 == int.MinValue) s32 = int.MaxValue;
|
||||
|
||||
return new Random(s32);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2020 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -20,67 +20,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
#if !KeePassUAP
|
||||
using System.Security.Cryptography;
|
||||
#endif
|
||||
|
||||
using KeePassLib.Native;
|
||||
using KeePassLib.Utility;
|
||||
|
||||
namespace KeePassLib.Cryptography
|
||||
{
|
||||
public static class CryptoUtil
|
||||
{
|
||||
private static bool? g_obProtData = null;
|
||||
public static bool IsProtectedDataSupported
|
||||
{
|
||||
get
|
||||
{
|
||||
if (g_obProtData.HasValue) return g_obProtData.Value;
|
||||
|
||||
bool b = false;
|
||||
try
|
||||
{
|
||||
Random r = CryptoRandom.NewWeakRandom();
|
||||
|
||||
byte[] pbData = new byte[137];
|
||||
r.NextBytes(pbData);
|
||||
|
||||
byte[] pbEnt = new byte[41];
|
||||
r.NextBytes(pbEnt);
|
||||
|
||||
byte[] pbEnc = ProtectedData.Protect(pbData, pbEnt,
|
||||
DataProtectionScope.CurrentUser);
|
||||
if ((pbEnc != null) && !MemUtil.ArraysEqual(pbEnc, pbData))
|
||||
{
|
||||
byte[] pbDec = ProtectedData.Unprotect(pbEnc, pbEnt,
|
||||
DataProtectionScope.CurrentUser);
|
||||
if ((pbDec != null) && MemUtil.ArraysEqual(pbDec, pbData))
|
||||
b = true;
|
||||
}
|
||||
}
|
||||
catch (Exception) { Debug.Assert(false); }
|
||||
|
||||
Debug.Assert(b); // Should be supported on all systems
|
||||
g_obProtData = b;
|
||||
return b;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] HashSha256(byte[] pbData)
|
||||
{
|
||||
if (pbData == null) throw new ArgumentNullException("pbData");
|
||||
if(pbData == null) throw new ArgumentNullException("pbData");
|
||||
|
||||
return HashSha256(pbData, 0, pbData.Length);
|
||||
}
|
||||
|
||||
public static byte[] HashSha256(byte[] pbData, int iOffset, int cbCount)
|
||||
{
|
||||
if (pbData == null) throw new ArgumentNullException("pbData");
|
||||
if(pbData == null) throw new ArgumentNullException("pbData");
|
||||
|
||||
#if DEBUG
|
||||
byte[] pbCopy = new byte[pbData.Length];
|
||||
@@ -88,7 +49,7 @@ namespace KeePassLib.Cryptography
|
||||
#endif
|
||||
|
||||
byte[] pbHash;
|
||||
using (SHA256Managed h = new SHA256Managed())
|
||||
using(SHA256Managed h = new SHA256Managed())
|
||||
{
|
||||
pbHash = h.ComputeHash(pbData, iOffset, cbCount);
|
||||
}
|
||||
@@ -105,22 +66,6 @@ namespace KeePassLib.Cryptography
|
||||
return pbHash;
|
||||
}
|
||||
|
||||
internal static byte[] HashSha256(string strFilePath)
|
||||
{
|
||||
byte[] pbHash = null;
|
||||
|
||||
using (FileStream fs = new FileStream(strFilePath, FileMode.Open,
|
||||
FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
using (SHA256Managed h = new SHA256Managed())
|
||||
{
|
||||
pbHash = h.ComputeHash(fs);
|
||||
}
|
||||
}
|
||||
|
||||
return pbHash;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a cryptographic key of length <paramref name="cbOut" />
|
||||
/// (in bytes) from <paramref name="pbIn" />.
|
||||
@@ -128,34 +73,34 @@ namespace KeePassLib.Cryptography
|
||||
public static byte[] ResizeKey(byte[] pbIn, int iInOffset,
|
||||
int cbIn, int cbOut)
|
||||
{
|
||||
if (pbIn == null) throw new ArgumentNullException("pbIn");
|
||||
if (cbOut < 0) throw new ArgumentOutOfRangeException("cbOut");
|
||||
if(pbIn == null) throw new ArgumentNullException("pbIn");
|
||||
if(cbOut < 0) throw new ArgumentOutOfRangeException("cbOut");
|
||||
|
||||
if (cbOut == 0) return MemUtil.EmptyByteArray;
|
||||
if(cbOut == 0) return MemUtil.EmptyByteArray;
|
||||
|
||||
byte[] pbHash;
|
||||
if (cbOut <= 32) pbHash = HashSha256(pbIn, iInOffset, cbIn);
|
||||
if(cbOut <= 32) pbHash = HashSha256(pbIn, iInOffset, cbIn);
|
||||
else
|
||||
{
|
||||
using (SHA512Managed h = new SHA512Managed())
|
||||
using(SHA512Managed h = new SHA512Managed())
|
||||
{
|
||||
pbHash = h.ComputeHash(pbIn, iInOffset, cbIn);
|
||||
}
|
||||
}
|
||||
|
||||
if (cbOut == pbHash.Length) return pbHash;
|
||||
if(cbOut == pbHash.Length) return pbHash;
|
||||
|
||||
byte[] pbRet = new byte[cbOut];
|
||||
if (cbOut < pbHash.Length)
|
||||
if(cbOut < pbHash.Length)
|
||||
Array.Copy(pbHash, pbRet, cbOut);
|
||||
else
|
||||
{
|
||||
int iPos = 0;
|
||||
ulong r = 0;
|
||||
while (iPos < cbOut)
|
||||
while(iPos < cbOut)
|
||||
{
|
||||
Debug.Assert(pbHash.Length == 64);
|
||||
using (HMACSHA256 h = new HMACSHA256(pbHash))
|
||||
using(HMACSHA256 h = new HMACSHA256(pbHash))
|
||||
{
|
||||
byte[] pbR = MemUtil.UInt64ToBytes(r);
|
||||
byte[] pbPart = h.ComputeHash(pbR);
|
||||
@@ -180,75 +125,5 @@ namespace KeePassLib.Cryptography
|
||||
MemUtil.ZeroByteArray(pbHash);
|
||||
return pbRet;
|
||||
}
|
||||
|
||||
#if !KeePassUAP
|
||||
private static bool? g_obAesCsp = null;
|
||||
internal static SymmetricAlgorithm CreateAes()
|
||||
{
|
||||
if (g_obAesCsp.HasValue)
|
||||
return (g_obAesCsp.Value ? CreateAesCsp() : new RijndaelManaged());
|
||||
|
||||
SymmetricAlgorithm a = CreateAesCsp();
|
||||
g_obAesCsp = (a != null);
|
||||
return (a ?? new RijndaelManaged());
|
||||
}
|
||||
|
||||
private static SymmetricAlgorithm CreateAesCsp()
|
||||
{
|
||||
try
|
||||
{
|
||||
// On Windows, the CSP implementation is only minimally
|
||||
// faster (and for key derivations it's not used anyway,
|
||||
// as KeePass uses a native implementation based on
|
||||
// CNG/BCrypt, which is much faster)
|
||||
if (!NativeLib.IsUnix()) return null;
|
||||
|
||||
string strFqn = Assembly.CreateQualifiedName(
|
||||
"System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
|
||||
"System.Security.Cryptography.AesCryptoServiceProvider");
|
||||
|
||||
Type t = Type.GetType(strFqn);
|
||||
if (t == null) return null;
|
||||
|
||||
return (Activator.CreateInstance(t) as SymmetricAlgorithm);
|
||||
}
|
||||
catch (Exception) { Debug.Assert(false); }
|
||||
|
||||
return null;
|
||||
}
|
||||
#endif
|
||||
|
||||
public static byte[] ProtectData(byte[] pb, byte[] pbOptEntropy,
|
||||
DataProtectionScope s)
|
||||
{
|
||||
return ProtectDataPriv(pb, true, pbOptEntropy, s);
|
||||
}
|
||||
|
||||
public static byte[] UnprotectData(byte[] pb, byte[] pbOptEntropy,
|
||||
DataProtectionScope s)
|
||||
{
|
||||
return ProtectDataPriv(pb, false, pbOptEntropy, s);
|
||||
}
|
||||
|
||||
private static byte[] ProtectDataPriv(byte[] pb, bool bProtect,
|
||||
byte[] pbOptEntropy, DataProtectionScope s)
|
||||
{
|
||||
if (pb == null) throw new ArgumentNullException("pb");
|
||||
|
||||
if ((pbOptEntropy != null) && (pbOptEntropy.Length == 0))
|
||||
pbOptEntropy = null;
|
||||
|
||||
if (CryptoUtil.IsProtectedDataSupported)
|
||||
{
|
||||
if (bProtect)
|
||||
return ProtectedData.Protect(pb, pbOptEntropy, s);
|
||||
return ProtectedData.Unprotect(pb, pbOptEntropy, s);
|
||||
}
|
||||
|
||||
Debug.Assert(false);
|
||||
byte[] pbCopy = new byte[pb.Length];
|
||||
Array.Copy(pb, pbCopy, pb.Length);
|
||||
return pbCopy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -46,8 +46,6 @@ namespace KeePassLib.Cryptography.KeyDerivation
|
||||
private const ulong NbBlockSizeInQW = NbBlockSize / 8UL;
|
||||
private const ulong NbSyncPoints = 4;
|
||||
|
||||
private const ulong NbAddressesInBlock = 128;
|
||||
|
||||
private const int NbPreHashDigestLength = 64;
|
||||
private const int NbPreHashSeedLength = NbPreHashDigestLength + 8;
|
||||
|
||||
@@ -58,7 +56,6 @@ namespace KeePassLib.Cryptography.KeyDerivation
|
||||
|
||||
private sealed class Argon2Ctx
|
||||
{
|
||||
public Argon2Type Type = Argon2Type.D;
|
||||
public uint Version = 0;
|
||||
|
||||
public ulong Lanes = 0;
|
||||
@@ -92,9 +89,9 @@ namespace KeePassLib.Cryptography.KeyDerivation
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] Argon2Transform(byte[] pbMsg, byte[] pbSalt, uint uParallel,
|
||||
ulong uMem, ulong uIt, int cbOut, uint uVersion, byte[] pbSecretKey,
|
||||
byte[] pbAssocData)
|
||||
private static byte[] Argon2d(byte[] pbMsg, byte[] pbSalt, uint uParallel,
|
||||
ulong uMem, ulong uIt, int cbOut, uint uVersion, byte[] pbSecretKey,
|
||||
byte[] pbAssocData)
|
||||
{
|
||||
pbSecretKey = (pbSecretKey ?? MemUtil.EmptyByteArray);
|
||||
pbAssocData = (pbAssocData ?? MemUtil.EmptyByteArray);
|
||||
@@ -104,7 +101,6 @@ namespace KeePassLib.Cryptography.KeyDerivation
|
||||
#endif
|
||||
|
||||
Argon2Ctx ctx = new Argon2Ctx();
|
||||
ctx.Type = m_t;
|
||||
ctx.Version = uVersion;
|
||||
|
||||
ctx.Lanes = uParallel;
|
||||
@@ -141,7 +137,7 @@ namespace KeePassLib.Cryptography.KeyDerivation
|
||||
h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
|
||||
MemUtil.UInt32ToBytesEx(uVersion, pbBuf, 0);
|
||||
h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
|
||||
MemUtil.UInt32ToBytesEx((uint)m_t, pbBuf, 0);
|
||||
MemUtil.UInt32ToBytesEx(0, pbBuf, 0); // Argon2d type = 0
|
||||
h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
|
||||
MemUtil.UInt32ToBytesEx((uint)pbMsg.Length, pbBuf, 0);
|
||||
h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
|
||||
@@ -491,43 +487,18 @@ namespace KeePassLib.Cryptography.KeyDerivation
|
||||
private static void FillSegmentThr(object o)
|
||||
{
|
||||
Argon2ThreadInfo ti = (o as Argon2ThreadInfo);
|
||||
if (ti == null) { Debug.Assert(false); return; }
|
||||
if(ti == null) { Debug.Assert(false); return; }
|
||||
|
||||
try
|
||||
{
|
||||
Argon2Ctx ctx = ti.Context;
|
||||
if (ctx == null) { Debug.Assert(false); return; }
|
||||
if(ctx == null) { Debug.Assert(false); return; }
|
||||
|
||||
Debug.Assert(ctx.Version >= MinVersion);
|
||||
bool bCanXor = (ctx.Version >= 0x13U);
|
||||
|
||||
ulong[] pbR = new ulong[NbBlockSizeInQW];
|
||||
ulong[] pbTmp = new ulong[NbBlockSizeInQW];
|
||||
ulong[] pbAddrInputZero = null;
|
||||
|
||||
bool bDataIndependentAddr = ((ctx.Type == Argon2Type.ID) &&
|
||||
(ti.Pass == 0) && (ti.Slice < (NbSyncPoints / 2)));
|
||||
if (bDataIndependentAddr)
|
||||
{
|
||||
pbAddrInputZero = new ulong[NbBlockSizeInQW * 3];
|
||||
|
||||
const int iInput = (int)NbBlockSizeInQW;
|
||||
pbAddrInputZero[iInput] = ti.Pass;
|
||||
pbAddrInputZero[iInput + 1] = ti.Lane;
|
||||
pbAddrInputZero[iInput + 2] = ti.Slice;
|
||||
pbAddrInputZero[iInput + 3] = ctx.MemoryBlocks;
|
||||
pbAddrInputZero[iInput + 4] = ctx.TCost;
|
||||
pbAddrInputZero[iInput + 5] = (ulong)ctx.Type;
|
||||
}
|
||||
|
||||
ulong uStart = 0;
|
||||
if ((ti.Pass == 0) && (ti.Slice == 0))
|
||||
{
|
||||
uStart = 2;
|
||||
|
||||
if (bDataIndependentAddr)
|
||||
NextAddresses(pbAddrInputZero, pbR, pbTmp);
|
||||
}
|
||||
if((ti.Pass == 0) && (ti.Slice == 0)) uStart = 2;
|
||||
|
||||
ulong uCur = (ti.Lane * ctx.LaneLength) + (ti.Slice *
|
||||
ctx.SegmentLength) + uStart;
|
||||
@@ -535,23 +506,17 @@ namespace KeePassLib.Cryptography.KeyDerivation
|
||||
ulong uPrev = (((uCur % ctx.LaneLength) == 0) ?
|
||||
(uCur + ctx.LaneLength - 1UL) : (uCur - 1UL));
|
||||
|
||||
for (ulong i = uStart; i < ctx.SegmentLength; ++i)
|
||||
ulong[] pbR = new ulong[NbBlockSizeInQW];
|
||||
ulong[] pbTmp = new ulong[NbBlockSizeInQW];
|
||||
|
||||
for(ulong i = uStart; i < ctx.SegmentLength; ++i)
|
||||
{
|
||||
if ((uCur % ctx.LaneLength) == 1)
|
||||
if((uCur % ctx.LaneLength) == 1)
|
||||
uPrev = uCur - 1UL;
|
||||
|
||||
ulong uPseudoRand;
|
||||
if (bDataIndependentAddr)
|
||||
{
|
||||
ulong iMod = i % NbAddressesInBlock;
|
||||
if (iMod == 0)
|
||||
NextAddresses(pbAddrInputZero, pbR, pbTmp);
|
||||
uPseudoRand = pbAddrInputZero[iMod];
|
||||
}
|
||||
else uPseudoRand = ctx.Mem[uPrev * NbBlockSizeInQW];
|
||||
|
||||
ulong uPseudoRand = ctx.Mem[uPrev * NbBlockSizeInQW];
|
||||
ulong uRefLane = (uPseudoRand >> 32) % ctx.Lanes;
|
||||
if ((ti.Pass == 0) && (ti.Slice == 0))
|
||||
if((ti.Pass == 0) && (ti.Slice == 0))
|
||||
uRefLane = ti.Lane;
|
||||
|
||||
ti.Index = i;
|
||||
@@ -571,12 +536,11 @@ namespace KeePassLib.Cryptography.KeyDerivation
|
||||
|
||||
MemUtil.ZeroArray<ulong>(pbR);
|
||||
MemUtil.ZeroArray<ulong>(pbTmp);
|
||||
if (pbAddrInputZero != null) MemUtil.ZeroArray<ulong>(pbAddrInputZero);
|
||||
}
|
||||
catch (Exception) { Debug.Assert(false); }
|
||||
catch(Exception) { Debug.Assert(false); }
|
||||
|
||||
try { ti.Finished.Set(); }
|
||||
catch (Exception) { Debug.Assert(false); }
|
||||
catch(Exception) { Debug.Assert(false); }
|
||||
}
|
||||
|
||||
#if ARGON2_B2ROUND_ARRAYS
|
||||
@@ -646,19 +610,6 @@ namespace KeePassLib.Cryptography.KeyDerivation
|
||||
XorBlock(pMem, uNext, pbR, 0);
|
||||
}
|
||||
|
||||
private static void NextAddresses(ulong[] pbAddrInputZero, ulong[] pbR,
|
||||
ulong[] pbTmp)
|
||||
{
|
||||
// pbAddrInputZero contains an address block, an input block and a zero block
|
||||
const ulong uAddr = 0;
|
||||
const ulong uInput = NbBlockSizeInQW;
|
||||
const ulong uZero = NbBlockSizeInQW * 2;
|
||||
|
||||
++pbAddrInputZero[uInput + 6];
|
||||
FillBlock(pbAddrInputZero, uZero, uInput, uAddr, false, pbR, pbTmp);
|
||||
FillBlock(pbAddrInputZero, uZero, uAddr, uAddr, false, pbR, pbTmp);
|
||||
}
|
||||
|
||||
private static byte[] FinalHash(Argon2Ctx ctx, int cbOut, Blake2b h)
|
||||
{
|
||||
ulong[] pqBlockHash = new ulong[NbBlockSizeInQW];
|
||||
|
@@ -25,22 +25,11 @@ using System.Text;
|
||||
|
||||
namespace KeePassLib.Cryptography.KeyDerivation
|
||||
{
|
||||
public enum Argon2Type
|
||||
{
|
||||
// The values must be the same as in the Argon2 specification
|
||||
D = 0,
|
||||
ID = 2
|
||||
}
|
||||
public sealed partial class Argon2Kdf : KdfEngine
|
||||
public sealed partial class Argon2Kdf : KdfEngine
|
||||
{
|
||||
|
||||
|
||||
private static readonly PwUuid g_uuidD = new PwUuid(new byte[] {
|
||||
0xEF, 0x63, 0x6D, 0xDF, 0x8C, 0x29, 0x44, 0x4B,
|
||||
0x91, 0xF7, 0xA9, 0xA4, 0x03, 0xE3, 0x0A, 0x0C });
|
||||
private static readonly PwUuid g_uuidID = new PwUuid(new byte[] {
|
||||
0x9E, 0x29, 0x8B, 0x19, 0x56, 0xDB, 0x47, 0x73,
|
||||
0xB2, 0x3D, 0xFC, 0x3E, 0xC6, 0xF0, 0xA1, 0xE6 });
|
||||
private static readonly PwUuid g_uuid = new PwUuid(new byte[] {
|
||||
0xEF, 0x63, 0x6D, 0xDF, 0x8C, 0x29, 0x44, 0x4B,
|
||||
0x91, 0xF7, 0xA9, 0xA4, 0x03, 0xE3, 0x0A, 0x0C });
|
||||
|
||||
public const string ParamSalt = "S"; // Byte[]
|
||||
public const string ParamParallelism = "P"; // UInt32
|
||||
@@ -66,37 +55,28 @@ namespace KeePassLib.Cryptography.KeyDerivation
|
||||
internal const uint MinParallelism = 1;
|
||||
internal const uint MaxParallelism = (1 << 24) - 1;
|
||||
|
||||
internal const ulong DefaultIterations = 2;
|
||||
internal const ulong DefaultMemory = 64 * 1024 * 1024; // 64 MB
|
||||
internal const uint DefaultParallelism = 2;
|
||||
internal const ulong DefaultIterations = 2;
|
||||
internal const ulong DefaultMemory = 1024 * 1024; // 1 MB
|
||||
internal const uint DefaultParallelism = 2;
|
||||
|
||||
private readonly Argon2Type m_t;
|
||||
public override PwUuid Uuid
|
||||
{
|
||||
get { return g_uuid; }
|
||||
}
|
||||
|
||||
public override PwUuid Uuid
|
||||
{
|
||||
get { return ((m_t == Argon2Type.D) ? g_uuidD : g_uuidID); }
|
||||
}
|
||||
public override string Name
|
||||
{
|
||||
get { return "Argon2"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return ((m_t == Argon2Type.D) ? "Argon2d" : "Argon2id"); }
|
||||
}
|
||||
|
||||
public Argon2Kdf() : this(Argon2Type.D)
|
||||
{
|
||||
}
|
||||
|
||||
public Argon2Kdf(Argon2Type t)
|
||||
{
|
||||
if ((t != Argon2Type.D) && (t != Argon2Type.ID))
|
||||
throw new NotSupportedException();
|
||||
|
||||
m_t = t;
|
||||
}
|
||||
public override byte[] GetSeed(KdfParameters p)
|
||||
{ return p.GetByteArray(ParamSalt); }
|
||||
|
||||
public override KdfParameters GetDefaultParameters()
|
||||
public Argon2Kdf()
|
||||
{
|
||||
}
|
||||
|
||||
public override KdfParameters GetDefaultParameters()
|
||||
{
|
||||
KdfParameters p = base.GetDefaultParameters();
|
||||
|
||||
@@ -112,7 +92,7 @@ namespace KeePassLib.Cryptography.KeyDerivation
|
||||
public override void Randomize(KdfParameters p)
|
||||
{
|
||||
if(p == null) { Debug.Assert(false); return; }
|
||||
Debug.Assert(p.KdfUuid.Equals(this.Uuid));
|
||||
Debug.Assert(g_uuid.Equals(p.KdfUuid));
|
||||
|
||||
byte[] pb = CryptoRandom.Instance.GetRandomBytes(32);
|
||||
p.SetByteArray(ParamSalt, pb);
|
||||
@@ -148,59 +128,46 @@ namespace KeePassLib.Cryptography.KeyDerivation
|
||||
byte[] pbSecretKey = p.GetByteArray(ParamSecretKey);
|
||||
byte[] pbAssocData = p.GetByteArray(ParamAssocData);
|
||||
|
||||
byte[] pbRet;
|
||||
|
||||
if (m_t == Argon2Type.ID)
|
||||
{
|
||||
pbRet = Argon2Transform(pbMsg, pbSalt, uPar, uMem,
|
||||
uIt, 32, v, pbSecretKey, pbAssocData);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pbSecretKey != null)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("Unsupported configuration: non-null pbSecretKey");
|
||||
}
|
||||
|
||||
if (pbAssocData != null)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("Unsupported configuration: non-null pbAssocData");
|
||||
}
|
||||
|
||||
/*
|
||||
byte[] pbRet = Argon2d(pbMsg, pbSalt, uPar, uMem, uIt,
|
||||
32, v, pbSecretKey, pbAssocData);
|
||||
*/
|
||||
|
||||
IntPtr msgPtr = Marshal.AllocHGlobal(pbMsg.Length);
|
||||
IntPtr saltPtr = Marshal.AllocHGlobal(pbSalt.Length);
|
||||
IntPtr retPtr = Marshal.AllocHGlobal(32);
|
||||
Marshal.Copy(pbMsg, 0, msgPtr, pbMsg.Length);
|
||||
Marshal.Copy(pbSalt, 0, saltPtr, pbSalt.Length);
|
||||
|
||||
const UInt32 Argon2_d = 0;
|
||||
|
||||
int ret = argon2_hash(
|
||||
(UInt32)uIt, (UInt32)(uMem / 1024), uPar,
|
||||
msgPtr, (IntPtr)pbMsg.Length,
|
||||
saltPtr, (IntPtr)pbSalt.Length,
|
||||
retPtr, (IntPtr)32,
|
||||
(IntPtr)0, (IntPtr)0, Argon2_d, v);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
throw new Exception("argon2_hash failed with " + ret);
|
||||
}
|
||||
|
||||
pbRet = new byte[32];
|
||||
Marshal.Copy(retPtr, pbRet, 0, 32);
|
||||
|
||||
Marshal.FreeHGlobal(msgPtr);
|
||||
Marshal.FreeHGlobal(saltPtr);
|
||||
Marshal.FreeHGlobal(retPtr);
|
||||
if (pbSecretKey != null) {
|
||||
throw new ArgumentOutOfRangeException("Unsupported configuration: non-null pbSecretKey");
|
||||
}
|
||||
|
||||
if(uMem > (100UL * 1024UL * 1024UL)) GC.Collect();
|
||||
if (pbAssocData != null) {
|
||||
throw new ArgumentOutOfRangeException("Unsupported configuration: non-null pbAssocData");
|
||||
}
|
||||
|
||||
/*
|
||||
byte[] pbRet = Argon2d(pbMsg, pbSalt, uPar, uMem, uIt,
|
||||
32, v, pbSecretKey, pbAssocData);
|
||||
*/
|
||||
|
||||
IntPtr msgPtr = Marshal.AllocHGlobal(pbMsg.Length);
|
||||
IntPtr saltPtr = Marshal.AllocHGlobal(pbSalt.Length);
|
||||
IntPtr retPtr = Marshal.AllocHGlobal(32);
|
||||
Marshal.Copy(pbMsg, 0, msgPtr, pbMsg.Length);
|
||||
Marshal.Copy(pbSalt, 0, saltPtr, pbSalt.Length);
|
||||
|
||||
const UInt32 Argon2_d = 0;
|
||||
|
||||
int ret = argon2_hash(
|
||||
(UInt32)uIt, (UInt32)(uMem / 1024), uPar,
|
||||
msgPtr, (IntPtr)pbMsg.Length,
|
||||
saltPtr, (IntPtr)pbSalt.Length,
|
||||
retPtr, (IntPtr)32,
|
||||
(IntPtr)0, (IntPtr)0, Argon2_d, v);
|
||||
|
||||
if (ret != 0) {
|
||||
throw new Exception("argon2_hash failed with " + ret);
|
||||
}
|
||||
|
||||
byte[] pbRet = new byte[32];
|
||||
Marshal.Copy(retPtr, pbRet, 0, 32);
|
||||
|
||||
Marshal.FreeHGlobal(msgPtr);
|
||||
Marshal.FreeHGlobal(saltPtr);
|
||||
Marshal.FreeHGlobal(retPtr);
|
||||
|
||||
if(uMem > (100UL * 1024UL * 1024UL)) GC.Collect();
|
||||
return pbRet;
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2020 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2020 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -41,11 +41,10 @@ namespace KeePassLib.Cryptography.KeyDerivation
|
||||
|
||||
private static void EnsureInitialized()
|
||||
{
|
||||
if(g_l.Count != 0) return;
|
||||
if(g_l.Count > 0) return;
|
||||
|
||||
g_l.Add(new AesKdf());
|
||||
g_l.Add(new Argon2Kdf(Argon2Type.D));
|
||||
g_l.Add(new Argon2Kdf(Argon2Type.ID));
|
||||
g_l.Add(new Argon2Kdf());
|
||||
}
|
||||
|
||||
internal static KdfParameters GetDefaultParameters()
|
||||
|
@@ -50,7 +50,6 @@
|
||||
<HintPath>..\ProtoBuf\protobuf-net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Security" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="Mono.Android" />
|
||||
@@ -72,7 +71,6 @@
|
||||
<Compile Include="Cryptography\KeyDerivation\KdfParameters.cs" />
|
||||
<Compile Include="Cryptography\KeyDerivation\KdfPool.cs" />
|
||||
<Compile Include="IDatabaseFormat.cs" />
|
||||
<Compile Include="Keys\KcpKeyFile.Xml.cs" />
|
||||
<Compile Include="Kp2aLog.cs" />
|
||||
<Compile Include="Resources\Resource.designer.cs" />
|
||||
<Compile Include="Resources\KLRes.Generated.cs" />
|
||||
@@ -162,7 +160,6 @@
|
||||
<Compile Include="Utility\UrlUtil.cs" />
|
||||
<Compile Include="Utility\TimeUtil.cs" />
|
||||
<Compile Include="Delegates\Handlers.cs" />
|
||||
<Compile Include="Utility\XmlUtilEx.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
|
@@ -1,281 +0,0 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2021 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
using KeePassLib.Cryptography;
|
||||
using KeePassLib.Resources;
|
||||
using KeePassLib.Serialization;
|
||||
using KeePassLib.Utility;
|
||||
|
||||
namespace KeePassLib.Keys
|
||||
{
|
||||
[XmlType("KeyFile")]
|
||||
public sealed class KfxFile
|
||||
{
|
||||
private const ulong KfxVersionCriticalMask = 0xFFFF000000000000UL;
|
||||
private const int KfxDataHashLength = 4;
|
||||
|
||||
private KfxMeta m_meta = new KfxMeta();
|
||||
public KfxMeta Meta
|
||||
{
|
||||
get { return m_meta; }
|
||||
set
|
||||
{
|
||||
if(value == null) throw new ArgumentNullException("value");
|
||||
m_meta = value;
|
||||
}
|
||||
}
|
||||
|
||||
private KfxKey m_key = new KfxKey();
|
||||
public KfxKey Key
|
||||
{
|
||||
get { return m_key; }
|
||||
set
|
||||
{
|
||||
if(value == null) throw new ArgumentNullException("value");
|
||||
m_key = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static KfxFile Create(ulong uVersion, byte[] pbKey, byte[] pbHash)
|
||||
{
|
||||
if(pbKey == null) throw new ArgumentNullException("pbKey");
|
||||
if(pbKey.Length == 0) throw new ArgumentOutOfRangeException("pbKey");
|
||||
|
||||
if(uVersion == 0) uVersion = 0x0002000000000000;
|
||||
|
||||
// Null hash: generate one, empty hash: store no hash
|
||||
if(pbHash == null) pbHash = HashData(pbKey);
|
||||
VerifyHash(pbKey, pbHash);
|
||||
|
||||
KfxFile kf = new KfxFile();
|
||||
|
||||
if(uVersion == 0x0001000000000000)
|
||||
kf.Meta.Version = "1.00"; // KeePass <= 2.46 used two zeros
|
||||
else kf.Meta.Version = StrUtil.VersionToString(uVersion, 2);
|
||||
|
||||
if(uVersion == 0x0001000000000000)
|
||||
kf.Key.Data.Value = Convert.ToBase64String(pbKey);
|
||||
else if(uVersion == 0x0002000000000000)
|
||||
{
|
||||
kf.Key.Data.Value = FormatKeyHex(pbKey, 3);
|
||||
|
||||
if(pbHash.Length != 0)
|
||||
kf.Key.Data.Hash = MemUtil.ByteArrayToHexString(pbHash);
|
||||
}
|
||||
else throw new NotSupportedException(KLRes.FileVersionUnsupported);
|
||||
|
||||
return kf;
|
||||
}
|
||||
|
||||
internal static KfxFile Create(ulong uVersion, string strKey, string strHash)
|
||||
{
|
||||
byte[] pbKey = ParseKey(uVersion, strKey);
|
||||
byte[] pbHash = ((strHash != null) ? ParseHash(strHash) : null);
|
||||
|
||||
return Create(uVersion, pbKey, pbHash);
|
||||
}
|
||||
|
||||
internal static bool CanLoad(string strFilePath)
|
||||
{
|
||||
if(string.IsNullOrEmpty(strFilePath)) { Debug.Assert(false); return false; }
|
||||
|
||||
try
|
||||
{
|
||||
IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFilePath);
|
||||
using(Stream s = IOConnection.OpenRead(ioc))
|
||||
{
|
||||
return (Load(s) != null);
|
||||
}
|
||||
}
|
||||
catch(Exception) { }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static KfxFile Load(Stream s)
|
||||
{
|
||||
return XmlUtilEx.Deserialize<KfxFile>(s);
|
||||
}
|
||||
|
||||
public void Save(Stream s)
|
||||
{
|
||||
XmlUtilEx.Serialize<KfxFile>(s, this, true);
|
||||
}
|
||||
|
||||
private static string FormatKeyHex(byte[] pb, int cTabs)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
string str = MemUtil.ByteArrayToHexString(pb);
|
||||
|
||||
for(int i = 0; i < str.Length; ++i)
|
||||
{
|
||||
if((i & 0x1F) == 0)
|
||||
{
|
||||
sb.AppendLine();
|
||||
sb.Append('\t', cTabs);
|
||||
}
|
||||
else if((i & 0x07) == 0) sb.Append(' ');
|
||||
|
||||
sb.Append(str[i]);
|
||||
}
|
||||
|
||||
sb.AppendLine();
|
||||
if(cTabs > 0) sb.Append('\t', cTabs - 1);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private ulong GetVersion()
|
||||
{
|
||||
string str = m_meta.Version;
|
||||
if(string.IsNullOrEmpty(str)) return 0;
|
||||
|
||||
return StrUtil.ParseVersion(str);
|
||||
}
|
||||
|
||||
public byte[] GetKey()
|
||||
{
|
||||
ulong uVersion = GetVersion();
|
||||
|
||||
byte[] pbKey = ParseKey(uVersion, m_key.Data.Value);
|
||||
if((pbKey == null) || (pbKey.Length == 0))
|
||||
throw new FormatException(KLRes.FileCorrupted);
|
||||
|
||||
byte[] pbHash = ParseHash(m_key.Data.Hash);
|
||||
VerifyHash(pbKey, pbHash);
|
||||
|
||||
return pbKey;
|
||||
}
|
||||
|
||||
private static byte[] HashData(byte[] pb)
|
||||
{
|
||||
return MemUtil.Mid(CryptoUtil.HashSha256(pb), 0, KfxDataHashLength);
|
||||
}
|
||||
|
||||
private static void VerifyHash(byte[] pbKey, byte[] pbHash)
|
||||
{
|
||||
// The hash is optional; empty hash means success
|
||||
if((pbHash == null) || (pbHash.Length == 0)) return;
|
||||
|
||||
byte[] pbHashCmp = HashData(pbKey);
|
||||
if(!MemUtil.ArraysEqual(pbHash, pbHashCmp))
|
||||
throw new Exception("Keyfile hash mismatch!");
|
||||
}
|
||||
|
||||
private static byte[] ParseKey(ulong uVersion, string strKey)
|
||||
{
|
||||
if(strKey == null) throw new ArgumentNullException("strKey");
|
||||
|
||||
strKey = StrUtil.RemoveWhiteSpace(strKey);
|
||||
if(string.IsNullOrEmpty(strKey)) return MemUtil.EmptyByteArray;
|
||||
|
||||
uVersion &= KfxVersionCriticalMask;
|
||||
|
||||
byte[] pbKey;
|
||||
if(uVersion == 0x0001000000000000)
|
||||
pbKey = Convert.FromBase64String(strKey);
|
||||
else if(uVersion == 0x0002000000000000)
|
||||
pbKey = ParseHex(strKey);
|
||||
else throw new NotSupportedException(KLRes.FileVersionUnsupported);
|
||||
|
||||
return pbKey;
|
||||
}
|
||||
|
||||
private static byte[] ParseHash(string strHash)
|
||||
{
|
||||
return ParseHex(strHash);
|
||||
}
|
||||
|
||||
private static byte[] ParseHex(string str)
|
||||
{
|
||||
if(str == null) throw new ArgumentNullException("str");
|
||||
if(str.Length == 0) return MemUtil.EmptyByteArray;
|
||||
|
||||
if(((str.Length & 1) != 0) || !StrUtil.IsHexString(str, true))
|
||||
throw new FormatException();
|
||||
|
||||
return MemUtil.HexStringToByteArray(str);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class KfxMeta
|
||||
{
|
||||
private string m_strVersion = string.Empty;
|
||||
[DefaultValue("")]
|
||||
public string Version
|
||||
{
|
||||
get { return m_strVersion; }
|
||||
set
|
||||
{
|
||||
if(value == null) throw new ArgumentNullException("value");
|
||||
m_strVersion = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class KfxKey
|
||||
{
|
||||
private KfxData m_data = new KfxData();
|
||||
public KfxData Data
|
||||
{
|
||||
get { return m_data; }
|
||||
set
|
||||
{
|
||||
if(value == null) throw new ArgumentNullException("value");
|
||||
m_data = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class KfxData
|
||||
{
|
||||
private string m_strHash = string.Empty;
|
||||
[DefaultValue("")]
|
||||
[XmlAttribute("Hash")]
|
||||
public string Hash
|
||||
{
|
||||
get { return m_strHash; }
|
||||
set
|
||||
{
|
||||
if(value == null) throw new ArgumentNullException("value");
|
||||
m_strHash = value;
|
||||
}
|
||||
}
|
||||
|
||||
private string m_strValue = string.Empty;
|
||||
[DefaultValue("")]
|
||||
[XmlText]
|
||||
public string Value
|
||||
{
|
||||
get { return m_strValue; }
|
||||
set
|
||||
{
|
||||
if(value == null) throw new ArgumentNullException("value");
|
||||
m_strValue = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -127,9 +127,10 @@ namespace KeePassLib.Keys
|
||||
#endif
|
||||
}
|
||||
|
||||
byte[] pbKey = LoadKeyFile(pbFileData);
|
||||
byte[] pbKey = LoadXmlKeyFile(pbFileData);
|
||||
if(pbKey == null) pbKey = LoadKeyFile(pbFileData);
|
||||
|
||||
if (pbKey == null) throw new InvalidOperationException();
|
||||
if(pbKey == null) throw new InvalidOperationException();
|
||||
|
||||
m_ioc = iocKeyFile;
|
||||
m_pbKeyData = new ProtectedBinary(true, pbKey);
|
||||
@@ -149,60 +150,54 @@ namespace KeePassLib.Keys
|
||||
// }
|
||||
|
||||
|
||||
private static byte[] LoadKeyFile(byte[] pbFileData)
|
||||
{
|
||||
if (pbFileData == null) throw new ArgumentNullException("pbFileData");
|
||||
private static byte[] LoadKeyFile(byte[] pbFileData)
|
||||
{
|
||||
if(pbFileData == null) { Debug.Assert(false); return null; }
|
||||
|
||||
byte[] pbKey = LoadKeyFileXml(pbFileData);
|
||||
if (pbKey != null) return pbKey;
|
||||
int iLength = pbFileData.Length;
|
||||
|
||||
int cb = pbFileData.Length;
|
||||
if (cb == 32) return pbFileData;
|
||||
byte[] pbKey = null;
|
||||
if(iLength == 32) pbKey = LoadBinaryKey32(pbFileData);
|
||||
else if(iLength == 64) pbKey = LoadHexKey32(pbFileData);
|
||||
|
||||
if (cb == 64)
|
||||
{
|
||||
pbKey = LoadKeyFileHex(pbFileData);
|
||||
if (pbKey != null) return pbKey;
|
||||
}
|
||||
if(pbKey == null)
|
||||
pbKey = CryptoUtil.HashSha256(pbFileData);
|
||||
|
||||
return CryptoUtil.HashSha256(pbFileData);
|
||||
}
|
||||
return pbKey;
|
||||
}
|
||||
|
||||
private static byte[] LoadKeyFileXml(byte[] pbFileData)
|
||||
{
|
||||
KfxFile kf;
|
||||
try
|
||||
{
|
||||
using (MemoryStream ms = new MemoryStream(pbFileData, false))
|
||||
{
|
||||
kf = KfxFile.Load(ms);
|
||||
}
|
||||
}
|
||||
catch (Exception) { return null; }
|
||||
private static byte[] LoadBinaryKey32(byte[] pbFileData)
|
||||
{
|
||||
if(pbFileData == null) { Debug.Assert(false); return null; }
|
||||
if(pbFileData.Length != 32) { Debug.Assert(false); return null; }
|
||||
|
||||
// We have a syntactically valid XML key file;
|
||||
// failing to verify the key should throw an exception
|
||||
return ((kf != null) ? kf.GetKey() : null);
|
||||
}
|
||||
return pbFileData;
|
||||
}
|
||||
|
||||
private static byte[] LoadKeyFileHex(byte[] pbFileData)
|
||||
{
|
||||
if (pbFileData == null) { Debug.Assert(false); return null; }
|
||||
private static byte[] LoadHexKey32(byte[] pbFileData)
|
||||
{
|
||||
if(pbFileData == null) { Debug.Assert(false); return null; }
|
||||
if(pbFileData.Length != 64) { Debug.Assert(false); return null; }
|
||||
|
||||
try
|
||||
{
|
||||
int cc = pbFileData.Length;
|
||||
if ((cc & 1) != 0) { Debug.Assert(false); return null; }
|
||||
try
|
||||
{
|
||||
if(!StrUtil.IsHexString(pbFileData, true)) return null;
|
||||
|
||||
if (!StrUtil.IsHexString(pbFileData, true)) return null;
|
||||
string strHex = StrUtil.Utf8.GetString(pbFileData);
|
||||
byte[] pbKey = MemUtil.HexStringToByteArray(strHex);
|
||||
if((pbKey == null) || (pbKey.Length != 32))
|
||||
{
|
||||
Debug.Assert(false);
|
||||
return null;
|
||||
}
|
||||
|
||||
string strHex = StrUtil.Utf8.GetString(pbFileData);
|
||||
return MemUtil.HexStringToByteArray(strHex);
|
||||
}
|
||||
catch (Exception) { Debug.Assert(false); }
|
||||
return pbKey;
|
||||
}
|
||||
catch(Exception) { Debug.Assert(false); }
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
/// <summary>
|
||||
/// Create a new, random key-file.
|
||||
/// </summary>
|
||||
|
@@ -118,10 +118,5 @@ namespace keepass2android
|
||||
sendIntent.SetType("text/plain");
|
||||
ctx.StartActivity(Intent.CreateChooser(sendIntent, "Send log to..."));
|
||||
}
|
||||
|
||||
public static void LogTask(object task, string activityName)
|
||||
{
|
||||
Log($"Task in activity {activityName} changed to {task?.GetType()?.Name ?? "null"}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -23,7 +23,7 @@ using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using keepass2android;
|
||||
|
||||
#if !KeePassUAP
|
||||
using System.Drawing;
|
||||
#endif
|
||||
@@ -872,17 +872,8 @@ namespace KeePassLib.Serialization
|
||||
pb = pb8;
|
||||
}
|
||||
long lSec = MemUtil.BytesToInt64(pb);
|
||||
try
|
||||
{
|
||||
return new DateTime(lSec * TimeSpan.TicksPerSecond, DateTimeKind.Utc);
|
||||
}
|
||||
catch (System.ArgumentOutOfRangeException e)
|
||||
{
|
||||
//files might contain bad data, e.g. see #868. Fall back to MinValue
|
||||
Kp2aLog.Log("Failed to read date from file.");
|
||||
return DateTime.MinValue;
|
||||
}
|
||||
}
|
||||
return new DateTime(lSec * TimeSpan.TicksPerSecond, DateTimeKind.Utc);
|
||||
}
|
||||
else
|
||||
{
|
||||
string str = ReadString(xr);
|
||||
|
@@ -375,16 +375,13 @@ namespace KeePassLib.Serialization
|
||||
|
||||
// See also KeePassKdb2x3.Export (KDBX 3.1 export module)
|
||||
uint minVersionForKeys = m_pwDatabase.MasterKey.UserKeys.Select(key => key.GetMinKdbxVersion()).Max();
|
||||
|
||||
uint minRequiredVersion = Math.Max(minVersionForKeys, m_uFileVersion); //don't save a version lower than what we read
|
||||
|
||||
|
||||
|
||||
AesKdf kdfAes = new AesKdf();
|
||||
if(!kdfAes.Uuid.Equals(m_pwDatabase.KdfParameters.KdfUuid))
|
||||
return Math.Max(FileVersion32, minRequiredVersion);
|
||||
return Math.Max(FileVersion32, minVersionForKeys);
|
||||
|
||||
if(m_pwDatabase.PublicCustomData.Count > 0)
|
||||
return Math.Max(FileVersion32, minRequiredVersion);
|
||||
return Math.Max(FileVersion32, minVersionForKeys);
|
||||
|
||||
|
||||
|
||||
@@ -404,9 +401,9 @@ namespace KeePassLib.Serialization
|
||||
gh(m_pwDatabase.RootGroup);
|
||||
m_pwDatabase.RootGroup.TraverseTree(TraversalMethod.PreOrder, gh, eh);
|
||||
if(bCustomData)
|
||||
return Math.Max(FileVersion32, minRequiredVersion);
|
||||
return Math.Max(FileVersion32, minVersionForKeys);
|
||||
|
||||
return Math.Max(FileVersion32_3, minRequiredVersion); ; // KDBX 3.1 is sufficient
|
||||
return Math.Max(FileVersion32_3, minVersionForKeys); ; // KDBX 3.1 is sufficient
|
||||
}
|
||||
|
||||
private void ComputeKeys(out byte[] pbCipherKey, int cbCipherKey,
|
||||
|
@@ -28,9 +28,9 @@ namespace KeePassLib.Serialization
|
||||
/// </summary>
|
||||
public static KdbxFormat GetFormatToUse(string fileExt)
|
||||
{
|
||||
return fileExt.Equals(KdbpFile.FileNameExtension, StringComparison.OrdinalIgnoreCase) ? KdbxFormat.ProtocolBuffers :
|
||||
(fileExt.Equals("xml", StringComparison.OrdinalIgnoreCase) ? KdbxFormat.PlainXml : KdbxFormat.Default);
|
||||
}
|
||||
// If the filename ends in .kdbp, use ProtocolBuffers format.
|
||||
return fileExt.Equals(KdbpFile.FileNameExtension, StringComparison.OrdinalIgnoreCase) ? KdbxFormat.ProtocolBuffers : KdbxFormat.Default;
|
||||
}
|
||||
|
||||
public static void WriteDocument(PwDatabase database, Stream stream, byte[] protectedStreamKey, byte[] hashOfHeader)
|
||||
{
|
||||
|
@@ -37,7 +37,7 @@ namespace KeePassLib.Utility
|
||||
/// </summary>
|
||||
public static class MemUtil
|
||||
{
|
||||
public static readonly byte[] EmptyByteArray = new byte[0];
|
||||
internal static readonly byte[] EmptyByteArray = new byte[0];
|
||||
|
||||
private static readonly uint[] m_vSBox = new uint[256] {
|
||||
0xCD2FACB3, 0xE78A7F5C, 0x6F0803FC, 0xBCF6E230,
|
||||
|
@@ -1734,24 +1734,5 @@ namespace KeePassLib.Utility
|
||||
// behavior of Notepad (on Windows 10)
|
||||
return str.Replace('\0', ' ');
|
||||
}
|
||||
|
||||
internal static string RemoveWhiteSpace(string str)
|
||||
{
|
||||
if (str == null) { Debug.Assert(false); return string.Empty; }
|
||||
|
||||
int cc = str.Length;
|
||||
if (cc == 0) return string.Empty;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < cc; ++i)
|
||||
{
|
||||
char ch = str[i];
|
||||
if (char.IsWhiteSpace(ch)) continue;
|
||||
sb.Append(ch);
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,290 +0,0 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2021 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
using System.Xml.XPath;
|
||||
|
||||
using KeePassLib.Delegates;
|
||||
using KeePassLib.Interfaces;
|
||||
using KeePassLib.Serialization;
|
||||
|
||||
namespace KeePassLib.Utility
|
||||
{
|
||||
public static class XmlUtilEx
|
||||
{
|
||||
public static XmlDocument CreateXmlDocument()
|
||||
{
|
||||
XmlDocument d = new XmlDocument();
|
||||
|
||||
// .NET 4.5.2 and newer do not resolve external XML resources
|
||||
// by default; for older .NET versions, we explicitly
|
||||
// prevent resolving
|
||||
d.XmlResolver = null; // Default in old .NET: XmlUrlResolver object
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
public static XmlReaderSettings CreateXmlReaderSettings()
|
||||
{
|
||||
XmlReaderSettings xrs = new XmlReaderSettings();
|
||||
|
||||
xrs.CloseInput = false;
|
||||
xrs.IgnoreComments = true;
|
||||
xrs.IgnoreProcessingInstructions = true;
|
||||
xrs.IgnoreWhitespace = true;
|
||||
|
||||
#if KeePassUAP
|
||||
xrs.DtdProcessing = DtdProcessing.Prohibit;
|
||||
#else
|
||||
// Also see PrepMonoDev.sh script
|
||||
xrs.ProhibitDtd = true; // Obsolete in .NET 4, but still there
|
||||
// xrs.DtdProcessing = DtdProcessing.Prohibit; // .NET 4 only
|
||||
#endif
|
||||
|
||||
xrs.ValidationType = ValidationType.None;
|
||||
xrs.XmlResolver = null;
|
||||
|
||||
return xrs;
|
||||
}
|
||||
|
||||
public static XmlReader CreateXmlReader(Stream s)
|
||||
{
|
||||
if(s == null) { Debug.Assert(false); throw new ArgumentNullException("s"); }
|
||||
|
||||
return XmlReader.Create(s, CreateXmlReaderSettings());
|
||||
}
|
||||
|
||||
public static XmlWriterSettings CreateXmlWriterSettings()
|
||||
{
|
||||
XmlWriterSettings xws = new XmlWriterSettings();
|
||||
|
||||
xws.CloseOutput = false;
|
||||
xws.Encoding = StrUtil.Utf8;
|
||||
xws.Indent = true;
|
||||
xws.IndentChars = "\t";
|
||||
xws.NewLineOnAttributes = false;
|
||||
|
||||
return xws;
|
||||
}
|
||||
|
||||
public static XmlWriter CreateXmlWriter(Stream s)
|
||||
{
|
||||
if(s == null) { Debug.Assert(false); throw new ArgumentNullException("s"); }
|
||||
|
||||
return XmlWriter.Create(s, CreateXmlWriterSettings());
|
||||
}
|
||||
|
||||
public static T Deserialize<T>(Stream s)
|
||||
{
|
||||
if(s == null) { Debug.Assert(false); throw new ArgumentNullException("s"); }
|
||||
|
||||
XmlSerializer xs = new XmlSerializer(typeof(T));
|
||||
|
||||
T t = default(T);
|
||||
using(XmlReader xr = CreateXmlReader(s))
|
||||
{
|
||||
t = (T)xs.Deserialize(xr);
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
public static void Serialize<T>(Stream s, T t)
|
||||
{
|
||||
if(s == null) { Debug.Assert(false); throw new ArgumentNullException("s"); }
|
||||
|
||||
XmlSerializer xs = new XmlSerializer(typeof(T));
|
||||
using(XmlWriter xw = CreateXmlWriter(s))
|
||||
{
|
||||
xs.Serialize(xw, t);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Serialize<T>(Stream s, T t, bool bRemoveXsdXsi)
|
||||
{
|
||||
// One way to remove the "xsd" and "xsi" namespace declarations
|
||||
// is to use an XmlSerializerNamespaces object containing only
|
||||
// a ""/"" pair; this seems to work, but Microsoft's
|
||||
// documentation explicitly states that it isn't supported:
|
||||
// https://docs.microsoft.com/en-us/dotnet/api/system.xml.serialization.xmlserializernamespaces
|
||||
// There are other, more complex ways, but these either rely on
|
||||
// undocumented details or require the type T to be modified.
|
||||
|
||||
string str;
|
||||
using(MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
Serialize<T>(ms, t);
|
||||
|
||||
str = StrUtil.Utf8.GetString(ms.ToArray());
|
||||
}
|
||||
|
||||
Func<string, string, bool> fFindPfx = delegate(string strText, string strSub)
|
||||
{
|
||||
int i = strText.IndexOf(strSub, StringComparison.Ordinal);
|
||||
if(i < 0) return false;
|
||||
if(i == 0) return true;
|
||||
return char.IsWhiteSpace(strText[i - 1]);
|
||||
};
|
||||
|
||||
if(bRemoveXsdXsi)
|
||||
{
|
||||
if(!fFindPfx(str, "xsd:") && !fFindPfx(str, "xsi:"))
|
||||
{
|
||||
Debug.Assert(str.IndexOf("xmlns:xsd") > 0);
|
||||
str = str.Replace(" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"", string.Empty);
|
||||
Debug.Assert(str.IndexOf("xmlns:xsd") < 0);
|
||||
|
||||
Debug.Assert(str.IndexOf("xmlns:xsi") > 0);
|
||||
str = str.Replace(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"", string.Empty);
|
||||
Debug.Assert(str.IndexOf("xmlns:xsi") < 0);
|
||||
}
|
||||
else { Debug.Assert(false); } // "xsd"/"xsi" decl. may be required
|
||||
}
|
||||
|
||||
MemUtil.Write(s, StrUtil.Utf8.GetBytes(str));
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
internal static void ValidateXml(string strXml, bool bReplaceStdEntities)
|
||||
{
|
||||
if(strXml == null) throw new ArgumentNullException("strXml");
|
||||
if(strXml.Length == 0) { Debug.Assert(false); return; }
|
||||
|
||||
string str = strXml;
|
||||
|
||||
if(bReplaceStdEntities)
|
||||
str = str.Replace(" ", " ");
|
||||
|
||||
XmlDocument d = new XmlDocument();
|
||||
d.LoadXml(str);
|
||||
}
|
||||
#endif
|
||||
|
||||
internal static XPathNodeIterator FindNodes(PwDatabase pd, string strXPath,
|
||||
IStatusLogger sl, out XmlDocument xd)
|
||||
{
|
||||
if(pd == null) throw new ArgumentNullException("pd");
|
||||
if(strXPath == null) { Debug.Assert(false); strXPath = string.Empty; }
|
||||
|
||||
KdbxFile kdbx = new KdbxFile(pd);
|
||||
|
||||
byte[] pbXml;
|
||||
using(MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
kdbx.Save(ms, null, KdbxFormat.PlainXml, sl);
|
||||
pbXml = ms.ToArray();
|
||||
}
|
||||
string strXml = StrUtil.Utf8.GetString(pbXml);
|
||||
|
||||
xd = CreateXmlDocument();
|
||||
xd.LoadXml(strXml);
|
||||
|
||||
XPathNavigator xpNav = xd.CreateNavigator();
|
||||
return xpNav.Select(strXPath);
|
||||
// XPathExpression xpExpr = xpNav.Compile(strXPath);
|
||||
// xpExpr.SetContext(new XuXsltContext());
|
||||
// return xpNav.Select(xpExpr);
|
||||
}
|
||||
|
||||
/* private sealed class XuFnMatches : IXsltContextFunction
|
||||
{
|
||||
private readonly XPathResultType[] m_vArgTypes = new XPathResultType[] {
|
||||
XPathResultType.String, XPathResultType.String, XPathResultType.String
|
||||
};
|
||||
public XPathResultType[] ArgTypes { get { return m_vArgTypes; } }
|
||||
|
||||
public int Maxargs { get { return 3; } }
|
||||
public int Minargs { get { return 2; } }
|
||||
|
||||
public XPathResultType ReturnType { get { return XPathResultType.Boolean; } }
|
||||
|
||||
private static string GetArgString(object[] args, int i, string strDefault)
|
||||
{
|
||||
if(args == null) { Debug.Assert(false); return strDefault; }
|
||||
if(i >= args.Length) return strDefault;
|
||||
|
||||
object o = args[i];
|
||||
if(o == null) return strDefault;
|
||||
|
||||
XPathNodeIterator it = (o as XPathNodeIterator);
|
||||
if(it != null) o = it.Current.Value;
|
||||
|
||||
return (o.ToString() ?? strDefault);
|
||||
}
|
||||
|
||||
public object Invoke(XsltContext xsltContext, object[] args,
|
||||
XPathNavigator docContext)
|
||||
{
|
||||
string strInput = GetArgString(args, 0, string.Empty);
|
||||
string strPattern = GetArgString(args, 1, string.Empty);
|
||||
string strFlags = GetArgString(args, 2, null);
|
||||
|
||||
RegexOptions ro = RegexOptions.None;
|
||||
if(!string.IsNullOrEmpty(strFlags))
|
||||
{
|
||||
if(strFlags.IndexOf('s') >= 0) ro |= RegexOptions.Singleline;
|
||||
if(strFlags.IndexOf('m') >= 0) ro |= RegexOptions.Multiline;
|
||||
if(strFlags.IndexOf('i') >= 0) ro |= RegexOptions.IgnoreCase;
|
||||
if(strFlags.IndexOf('x') >= 0) ro |= RegexOptions.IgnorePatternWhitespace;
|
||||
}
|
||||
|
||||
return Regex.IsMatch(strInput, strPattern, ro);
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class XuXsltContext : XsltContext
|
||||
{
|
||||
public override bool Whitespace { get { return false; } }
|
||||
|
||||
public override int CompareDocument(string baseUri, string nextbaseUri)
|
||||
{
|
||||
return string.CompareOrdinal(baseUri, nextbaseUri);
|
||||
}
|
||||
|
||||
public override bool PreserveWhitespace(XPathNavigator node)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override IXsltContextFunction ResolveFunction(string prefix,
|
||||
string name, XPathResultType[] ArgTypes)
|
||||
{
|
||||
if(prefix != "kp") { Debug.Assert(false); return null; }
|
||||
|
||||
if(name == "matches") return new XuFnMatches();
|
||||
|
||||
Debug.Assert(false);
|
||||
return null;
|
||||
}
|
||||
|
||||
public override IXsltContextVariable ResolveVariable(string prefix,
|
||||
string name)
|
||||
{
|
||||
Debug.Assert(false);
|
||||
return null;
|
||||
}
|
||||
} */
|
||||
}
|
||||
}
|
@@ -11,7 +11,7 @@ using KeePassLib.Keys;
|
||||
using KeePassLib.Serialization;
|
||||
using keepass2android.Io;
|
||||
using KeePassLib.Interfaces;
|
||||
#if !NoNet && !EXCLUDE_JAVAFILESTORAGE
|
||||
#if !NoNet
|
||||
using Keepass2android.Javafilestorage;
|
||||
#endif
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace keepass2android
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Interface through which Activities and the logic layer can access some app specific functionalities and Application static data
|
||||
/// </summary>
|
||||
/// This also contains methods which are UI specific and should be replacable for testing.
|
||||
@@ -38,7 +38,7 @@ namespace keepass2android
|
||||
/// <summary>
|
||||
/// Locks all currently open databases, quicklocking if available (unless false is passed for allowQuickUnlock)
|
||||
/// </summary>
|
||||
void Lock(bool allowQuickUnlock, bool lockWasTriggeredByTimeout);
|
||||
void Lock(bool allowQuickUnlock);
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -123,7 +123,7 @@ namespace keepass2android
|
||||
|
||||
|
||||
bool CheckForDuplicateUuids { get; }
|
||||
#if !NoNet && !EXCLUDE_JAVAFILESTORAGE
|
||||
#if !NoNet
|
||||
ICertificateErrorHandler CertificateErrorHandler { get; }
|
||||
|
||||
|
||||
|
@@ -270,7 +270,7 @@ namespace keepass2android.Io
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
else return false;
|
||||
else throw new Exception("couldn't move to first result element: " + (cursor == null) + uri.ToString());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -333,13 +333,12 @@ namespace keepass2android.Io
|
||||
|
||||
public void CommitWrite()
|
||||
{
|
||||
ParcelFileDescriptor fileDescriptor = _ctx.ContentResolver.OpenFileDescriptor(Android.Net.Uri.Parse(_path), "rwt");
|
||||
ParcelFileDescriptor fileDescriptor = _ctx.ContentResolver.OpenFileDescriptor(Android.Net.Uri.Parse(_path), "w");
|
||||
|
||||
using (var outputStream = new FileOutputStream(fileDescriptor.FileDescriptor))
|
||||
{
|
||||
byte[] data = _memoryStream.ToArray();
|
||||
|
||||
outputStream.Write(data);
|
||||
outputStream.Write(data, 0, data.Length);
|
||||
outputStream.Close();
|
||||
}
|
||||
fileDescriptor.Close();
|
||||
|
@@ -120,14 +120,10 @@ namespace keepass2android.Io
|
||||
|
||||
public bool IsCached(IOConnectionInfo ioc)
|
||||
{
|
||||
bool result = File.Exists(CachedFilePath(ioc))
|
||||
return File.Exists(CachedFilePath(ioc))
|
||||
&& File.Exists(VersionFilePath(ioc))
|
||||
&& File.Exists(BaseVersionFilePath(ioc));
|
||||
|
||||
Kp2aLog.Log(ioc.GetDisplayName() + " isCached = " + result);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public void Delete(IOConnectionInfo ioc)
|
||||
{
|
||||
@@ -597,15 +593,11 @@ namespace keepass2android.Io
|
||||
|
||||
public string GetBaseVersionHash(IOConnectionInfo ioc)
|
||||
{
|
||||
string hash = File.ReadAllText(BaseVersionFilePath(ioc));
|
||||
Kp2aLog.Log(ioc.GetDisplayName() + " baseVersionHash = " + hash);
|
||||
return hash;
|
||||
}
|
||||
return File.ReadAllText(BaseVersionFilePath(ioc));
|
||||
}
|
||||
public string GetLocalVersionHash(IOConnectionInfo ioc)
|
||||
{
|
||||
string hash = File.ReadAllText(VersionFilePath(ioc));
|
||||
Kp2aLog.Log(ioc.GetDisplayName() + " localVersionHash = " + hash);
|
||||
return hash;
|
||||
return File.ReadAllText(VersionFilePath(ioc));
|
||||
}
|
||||
public bool HasLocalChanges(IOConnectionInfo ioc)
|
||||
{
|
||||
|
@@ -3,12 +3,12 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.FtpClient;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Preferences;
|
||||
using FluentFTP;
|
||||
using KeePassLib;
|
||||
using KeePassLib.Serialization;
|
||||
using KeePassLib.Utility;
|
||||
@@ -17,6 +17,73 @@ namespace keepass2android.Io
|
||||
{
|
||||
public class NetFtpFileStorage: IFileStorage
|
||||
{
|
||||
class RetryConnectFtpClient : FtpClient
|
||||
{
|
||||
protected override FtpClient CloneConnection()
|
||||
{
|
||||
RetryConnectFtpClient conn = new RetryConnectFtpClient();
|
||||
|
||||
conn.m_isClone = true;
|
||||
|
||||
foreach (PropertyInfo prop in GetType().GetProperties())
|
||||
{
|
||||
object[] attributes = prop.GetCustomAttributes(typeof(FtpControlConnectionClone), true);
|
||||
|
||||
if (attributes != null && attributes.Length > 0)
|
||||
{
|
||||
prop.SetValue(conn, prop.GetValue(this, null), null);
|
||||
}
|
||||
}
|
||||
|
||||
// always accept certficate no matter what because if code execution ever
|
||||
// gets here it means the certificate on the control connection object being
|
||||
// cloned was already accepted.
|
||||
conn.ValidateCertificate += new FtpSslValidation(
|
||||
delegate(FtpClient obj, FtpSslValidationEventArgs e)
|
||||
{
|
||||
e.Accept = true;
|
||||
});
|
||||
|
||||
return conn;
|
||||
}
|
||||
|
||||
private static T DoInRetryLoop<T>(Func<T> func)
|
||||
{
|
||||
double timeout = 30.0;
|
||||
double timePerRequest = 1.0;
|
||||
var startTime = DateTime.Now;
|
||||
while (true)
|
||||
{
|
||||
var attemptStartTime = DateTime.Now;
|
||||
try
|
||||
{
|
||||
return func();
|
||||
}
|
||||
catch (System.Net.Sockets.SocketException e)
|
||||
{
|
||||
if ((e.ErrorCode != 10061) || (DateTime.Now > startTime.AddSeconds(timeout)))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
double secondsSinceAttemptStart = (DateTime.Now - attemptStartTime).TotalSeconds;
|
||||
if (secondsSinceAttemptStart < timePerRequest)
|
||||
{
|
||||
Thread.Sleep(TimeSpan.FromSeconds(timePerRequest - secondsSinceAttemptStart));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public override void Connect()
|
||||
{
|
||||
DoInRetryLoop(() =>
|
||||
{
|
||||
base.Connect();
|
||||
return true;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public struct ConnectionSettings
|
||||
{
|
||||
public FtpEncryptionMode EncryptionMode {get; set; }
|
||||
@@ -80,8 +147,9 @@ namespace keepass2android.Io
|
||||
|
||||
public NetFtpFileStorage(Context context, ICertificateValidationHandler app)
|
||||
{
|
||||
_app = app;
|
||||
_app = app;
|
||||
traceStream = new MemoryStream();
|
||||
FtpTrace.AddListener(new System.Diagnostics.TextWriterTraceListener(traceStream));
|
||||
|
||||
}
|
||||
|
||||
@@ -104,9 +172,9 @@ namespace keepass2android.Io
|
||||
{
|
||||
using (FtpClient client = GetClient(ioc))
|
||||
{
|
||||
string localPath = IocToLocalPath(ioc);
|
||||
string localPath = IocToUri(ioc).PathAndQuery;
|
||||
if (client.DirectoryExists(localPath))
|
||||
client.DeleteDirectory(localPath);
|
||||
client.DeleteDirectory(localPath, true);
|
||||
else
|
||||
client.DeleteFile(localPath);
|
||||
}
|
||||
@@ -137,8 +205,7 @@ namespace keepass2android.Io
|
||||
{
|
||||
var settings = ConnectionSettings.FromIoc(ioc);
|
||||
|
||||
FtpClient client = new FtpClient();
|
||||
client.RetryAttempts = 3;
|
||||
FtpClient client = new RetryConnectFtpClient();
|
||||
if ((settings.Username.Length > 0) || (settings.Password.Length > 0))
|
||||
client.Credentials = new NetworkCredential(settings.Username, settings.Password);
|
||||
else
|
||||
@@ -183,22 +250,20 @@ namespace keepass2android.Io
|
||||
path = path.Substring(settings.Length + 1);
|
||||
|
||||
}
|
||||
Kp2aLog.Log("FTP: IocToUri out = " + scheme + "://" + path);
|
||||
return new Uri(scheme + "://" + path);
|
||||
return new Uri(scheme + "://" + path);
|
||||
}
|
||||
|
||||
private string IocPathFromUri(IOConnectionInfo baseIoc, string uri)
|
||||
private string IocPathFromUri(IOConnectionInfo baseIoc, Uri uri)
|
||||
{
|
||||
string basePath = baseIoc.Path;
|
||||
string basePath = baseIoc.Path;
|
||||
int schemeLength = basePath.IndexOf("://", StringComparison.Ordinal);
|
||||
string scheme = basePath.Substring(0, schemeLength);
|
||||
basePath = basePath.Substring(schemeLength + 3);
|
||||
string baseSettings = basePath.Substring(0, basePath.IndexOf(ConnectionSettings.SettingsPostFix, StringComparison.Ordinal));
|
||||
basePath = basePath.Substring(baseSettings.Length+1);
|
||||
string baseHost = basePath.Substring(0, basePath.IndexOf("/", StringComparison.Ordinal));
|
||||
string result = scheme + "://" + baseSettings + ConnectionSettings.SettingsPostFix + baseHost + uri; //TODO does this contain Query?
|
||||
return result;
|
||||
}
|
||||
return scheme + "://" + baseSettings + ConnectionSettings.SettingsPostFix + baseHost + uri.AbsolutePath; //TODO does this contain Query?
|
||||
}
|
||||
|
||||
|
||||
public bool CheckForFileChangeFast(IOConnectionInfo ioc, string previousFileVersion)
|
||||
@@ -216,12 +281,9 @@ namespace keepass2android.Io
|
||||
try
|
||||
{
|
||||
using (var cl = GetClient(ioc))
|
||||
{
|
||||
var memStream = new MemoryStream();
|
||||
cl.OpenRead(IocToLocalPath(ioc), FtpDataType.Binary, 0).CopyTo(memStream);
|
||||
memStream.Seek(0, SeekOrigin.Begin);
|
||||
return memStream;
|
||||
}
|
||||
{
|
||||
return cl.OpenRead(IocToUri(ioc).PathAndQuery, FtpDataType.Binary, 0);
|
||||
}
|
||||
}
|
||||
catch (FtpCommandException ex)
|
||||
{
|
||||
@@ -268,7 +330,7 @@ namespace keepass2android.Io
|
||||
{
|
||||
using (var client = GetClient(ioc))
|
||||
{
|
||||
client.CreateDirectory(IocToLocalPath(GetFilePath(ioc, newDirName)));
|
||||
client.CreateDirectory(IocToUri(GetFilePath(ioc, newDirName)).PathAndQuery);
|
||||
}
|
||||
}
|
||||
catch (FtpCommandException ex)
|
||||
@@ -277,19 +339,14 @@ namespace keepass2android.Io
|
||||
}
|
||||
}
|
||||
|
||||
public static string IocToLocalPath(IOConnectionInfo ioc)
|
||||
{
|
||||
return WebUtility.UrlDecode(IocToUri(ioc).PathAndQuery);
|
||||
}
|
||||
|
||||
public IEnumerable<FileDescription> ListContents(IOConnectionInfo ioc)
|
||||
public IEnumerable<FileDescription> ListContents(IOConnectionInfo ioc)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var client = GetClient(ioc))
|
||||
using (var client = GetClient(ioc))
|
||||
{
|
||||
List<FileDescription> files = new List<FileDescription>();
|
||||
foreach (FtpListItem item in client.GetListing(IocToLocalPath(ioc),
|
||||
foreach (FtpListItem item in client.GetListing(IocToUri(ioc).PathAndQuery,
|
||||
FtpListOption.Modify | FtpListOption.Size | FtpListOption.DerefLinks))
|
||||
{
|
||||
|
||||
@@ -303,7 +360,7 @@ namespace keepass2android.Io
|
||||
DisplayName = item.Name,
|
||||
IsDirectory = true,
|
||||
LastModified = item.Modified,
|
||||
Path = IocPathFromUri(ioc, item.FullName)
|
||||
Path = IocPathFromUri(ioc, new Uri(item.FullName))
|
||||
});
|
||||
break;
|
||||
case FtpFileSystemObjectType.File:
|
||||
@@ -314,7 +371,7 @@ namespace keepass2android.Io
|
||||
DisplayName = item.Name,
|
||||
IsDirectory = false,
|
||||
LastModified = item.Modified,
|
||||
Path = IocPathFromUri(ioc, item.FullName),
|
||||
Path = IocPathFromUri(ioc, new Uri(item.FullName)),
|
||||
SizeInBytes = item.Size
|
||||
});
|
||||
break;
|
||||
@@ -339,10 +396,10 @@ namespace keepass2android.Io
|
||||
//is it very inefficient to connect for each description?
|
||||
|
||||
using (FtpClient client = GetClient(ioc))
|
||||
{
|
||||
|
||||
|
||||
string path = IocToLocalPath(ioc);
|
||||
{
|
||||
|
||||
var uri = IocToUri(ioc);
|
||||
string path = uri.PathAndQuery;
|
||||
if (!client.FileExists(path) && (!client.DirectoryExists(path)))
|
||||
throw new FileNotFoundException();
|
||||
var fileDesc = new FileDescription()
|
||||
@@ -454,7 +511,7 @@ namespace keepass2android.Io
|
||||
{
|
||||
using (var client = GetClient(ioc))
|
||||
{
|
||||
return client.OpenWrite(IocToLocalPath(ioc));
|
||||
return client.OpenWrite(IocToUri(ioc).PathAndQuery);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -523,7 +580,7 @@ namespace keepass2android.Io
|
||||
{
|
||||
|
||||
_client = _fileStorage.GetClient(_ioc, false);
|
||||
_stream = _client.OpenWrite(NetFtpFileStorage.IocToLocalPath(_iocTemp));
|
||||
_stream = _client.OpenWrite(NetFtpFileStorage.IocToUri(_iocTemp).PathAndQuery);
|
||||
return _stream;
|
||||
}
|
||||
catch (FtpCommandException ex)
|
||||
@@ -538,11 +595,22 @@ namespace keepass2android.Io
|
||||
{
|
||||
Android.Util.Log.Debug("NETFTP","connected: " + _client.IsConnected.ToString());
|
||||
_stream.Close();
|
||||
_stream.Dispose();
|
||||
_client.GetReply();
|
||||
Android.Util.Log.Debug("NETFTP", "connected: " + _client.IsConnected.ToString());
|
||||
|
||||
_client.MoveFile(NetFtpFileStorage.IocToLocalPath(_iocTemp),
|
||||
NetFtpFileStorage.IocToLocalPath(_ioc));
|
||||
//make sure target file does not exist:
|
||||
//try
|
||||
{
|
||||
if (_client.FileExists(NetFtpFileStorage.IocToUri(_ioc).PathAndQuery))
|
||||
_client.DeleteFile(NetFtpFileStorage.IocToUri(_ioc).PathAndQuery);
|
||||
|
||||
}
|
||||
//catch (FtpCommandException)
|
||||
{
|
||||
//TODO get a new clien? might be stale
|
||||
}
|
||||
|
||||
_client.Rename(NetFtpFileStorage.IocToUri(_iocTemp).PathAndQuery,
|
||||
NetFtpFileStorage.IocToUri(_ioc).PathAndQuery);
|
||||
|
||||
}
|
||||
catch (FtpCommandException ex)
|
||||
|
@@ -204,7 +204,6 @@ namespace keepass2android.Io
|
||||
private readonly string _specialFolder;
|
||||
public IGraphServiceClient client;
|
||||
public OneDrive2ItemLocation<OneDrive2PrefixContainerType> itemLocation;
|
||||
public bool verbose;
|
||||
|
||||
public PathItemBuilder(string specialFolder)
|
||||
{
|
||||
@@ -214,7 +213,6 @@ namespace keepass2android.Io
|
||||
|
||||
public IDriveItemRequestBuilder getPathItem()
|
||||
{
|
||||
Kp2aLog.Log("getPathItem for " + itemLocation.ToString());
|
||||
IDriveItemRequestBuilder pathItem;
|
||||
if (!hasShare())
|
||||
{
|
||||
@@ -222,33 +220,20 @@ namespace keepass2android.Io
|
||||
}
|
||||
if ("me".Equals(itemLocation.Share.Id))
|
||||
{
|
||||
if (verbose) Kp2aLog.Log("Path share is me");
|
||||
|
||||
|
||||
if (_specialFolder == null)
|
||||
{
|
||||
if (verbose) Kp2aLog.Log("No special folder. Use drive root.");
|
||||
pathItem = client.Me.Drive.Root;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (verbose) Kp2aLog.Log("Special folder = " + _specialFolder);
|
||||
pathItem = client.Me.Drive.Special[_specialFolder];
|
||||
}
|
||||
|
||||
if (itemLocation.LocalPath.Any())
|
||||
{
|
||||
if (verbose) Kp2aLog.Log("LocalPath = " + itemLocation.LocalPathString);
|
||||
pathItem = pathItem.ItemWithPath(itemLocation.LocalPathString);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (verbose) Kp2aLog.Log("Path share is not me");
|
||||
if (!itemLocation.LocalPath.Any())
|
||||
{
|
||||
String webUrl = itemLocation.Share.WebUrl;
|
||||
if (verbose) Kp2aLog.Log("Share WebUrl = " + webUrl);
|
||||
var encodedShareId = CalculateEncodedShareId(webUrl);
|
||||
return client.Shares[encodedShareId].Root;
|
||||
}
|
||||
@@ -264,7 +249,6 @@ namespace keepass2android.Io
|
||||
Android.Util.Log.Debug("KP2A", "encodedShareId = " + encodedShareId);
|
||||
pathItem = client.Shares[encodedShareId].Root;
|
||||
*/
|
||||
if (verbose) Kp2aLog.Log("Using driveId=" + itemLocation.DriveId + " and item id=" + itemLocation.LocalPath.Last().Id);
|
||||
return client.Drives[itemLocation.DriveId].Items[itemLocation.LocalPath.Last().Id];
|
||||
}
|
||||
|
||||
@@ -530,25 +514,18 @@ namespace keepass2android.Io
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
PathItemBuilder pathItemBuilder = await GetPathItemBuilder(path);
|
||||
return await
|
||||
pathItemBuilder
|
||||
.getPathItem()
|
||||
.Content
|
||||
.Request()
|
||||
.PutAsync<DriveItem>(stream);
|
||||
|
||||
PathItemBuilder pathItemBuilder = await GetPathItemBuilder(path);
|
||||
return await
|
||||
pathItemBuilder
|
||||
.getPathItem()
|
||||
.Content
|
||||
.Request()
|
||||
.PutAsync<DriveItem>(stream);
|
||||
}).Wait();
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
PathItemBuilder pathItemBuilder = await GetPathItemBuilder(path);
|
||||
pathItemBuilder.verbose = true;
|
||||
pathItemBuilder.getPathItem();
|
||||
}).Wait();
|
||||
throw convertException(e);
|
||||
}
|
||||
}
|
||||
@@ -1051,6 +1028,9 @@ namespace keepass2android.Io
|
||||
|
||||
private async Task<string> CreateFilePathAsync(string parent, string newFilename)
|
||||
{
|
||||
DriveItem driveItem = new DriveItem();
|
||||
driveItem.Name = newFilename;
|
||||
driveItem.File = new File();
|
||||
PathItemBuilder pathItemBuilder = await GetPathItemBuilder(parent);
|
||||
|
||||
//see if such a file exists already:
|
||||
@@ -1064,11 +1044,9 @@ namespace keepass2android.Io
|
||||
logDebug("building request for " + pathItemBuilder.itemLocation);
|
||||
|
||||
DriveItem res = await pathItemBuilder.getPathItem()
|
||||
|
||||
.ItemWithPath(newFilename)
|
||||
.Content
|
||||
.Children
|
||||
.Request()
|
||||
.PutAsync<DriveItem>(new MemoryStream());
|
||||
.AddAsync(driveItem);
|
||||
|
||||
return pathItemBuilder.itemLocation.BuildLocalChildLocation(res.Name, res.Id, res.ParentReference?.DriveId)
|
||||
.ToString();
|
||||
|
@@ -9,14 +9,14 @@ using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
#if !NoNet && !EXCLUDE_JAVAFILESTORAGE
|
||||
#if !NoNet
|
||||
using Keepass2android.Javafilestorage;
|
||||
#endif
|
||||
using KeePassLib.Serialization;
|
||||
|
||||
namespace keepass2android.Io
|
||||
{
|
||||
#if !NoNet && !EXCLUDE_JAVAFILESTORAGE
|
||||
#if !NoNet
|
||||
public class WebDavFileStorage: JavaFileStorage
|
||||
{
|
||||
public WebDavFileStorage(IKp2aApp app) : base(new Keepass2android.Javafilestorage.WebDavStorage(app.CertificateErrorHandler), app)
|
||||
|
@@ -12,7 +12,7 @@
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile>
|
||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
||||
<TargetFrameworkVersion>v10.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v9.0</TargetFrameworkVersion>
|
||||
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
@@ -22,7 +22,7 @@
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;_EXCLUDE_TWOFISH;_EXCLUDE_KEYBOARD;_EXCLUDE_FILECHOOSER;_EXCLUDE_JAVAFILESTORAGE;INCLUDE_KEYTRANSFORM</DefineConstants>
|
||||
<DefineConstants>DEBUG;EXCLUDE_TWOFISH;_EXCLUDE_KEYBOARD;_EXCLUDE_FILECHOOSER;_EXCLUDE_JAVAFILESTORAGE;INCLUDE_KEYTRANSFORM</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AndroidLinkMode>None</AndroidLinkMode>
|
||||
@@ -31,10 +31,9 @@
|
||||
<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>
|
||||
<JavaMaximumHeapSize>4G</JavaMaximumHeapSize>
|
||||
<AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseNoNet|AnyCPU'">
|
||||
@@ -54,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" />
|
||||
</ItemGroup>
|
||||
@@ -78,23 +76,13 @@
|
||||
<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\OneDrive2FileStorage.cs" />
|
||||
<Compile Include="Io\OneDrive2PrefixContainer.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" />
|
||||
@@ -130,14 +118,6 @@
|
||||
<Compile Include="Utils\Spr\SprEngine.PickChars.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AndroidFileChooserBinding\AndroidFileChooserBinding.csproj">
|
||||
<Project>{3c0f7fe5-639f-4422-a087-8b26cf862d1b}</Project>
|
||||
<Name>AndroidFileChooserBinding</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>
|
||||
@@ -146,10 +126,7 @@
|
||||
<Project>{70D3844A-D9FA-4A64-B205-A84C6A822196}</Project>
|
||||
<Name>KP2AKdbLibraryBinding</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\PCloudBindings\PCloudBindings.csproj">
|
||||
<Project>{2db80c77-d46f-4970-b967-e9ffa9b2ac2e}</Project>
|
||||
<Name>PCloudBindings</Name>
|
||||
</ProjectReference>
|
||||
|
||||
<ProjectReference Include="..\TwofishCipher\TwofishCipher.csproj">
|
||||
<Project>{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}</Project>
|
||||
<Name>TwofishCipher</Name>
|
||||
@@ -162,119 +139,107 @@
|
||||
<None Include="app.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentFTP">
|
||||
<Version>31.3.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Graph">
|
||||
<Version>1.21.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Graph.Auth">
|
||||
<Version>1.0.0-preview.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Identity.Client">
|
||||
<Version>4.8.2</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Arch.Core.Common">
|
||||
<Version>1.1.1.3</Version>
|
||||
<Version>1.1.1.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Arch.Core.Runtime">
|
||||
<Version>1.1.1.3</Version>
|
||||
<Version>1.1.1.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Arch.Lifecycle.Common">
|
||||
<Version>1.1.1.3</Version>
|
||||
<Version>1.1.1.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Arch.Lifecycle.LiveData">
|
||||
<Version>1.1.1.3</Version>
|
||||
<Version>1.1.1.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Arch.Lifecycle.LiveData.Core">
|
||||
<Version>1.1.1.3</Version>
|
||||
<Version>1.1.1.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Arch.Lifecycle.Runtime">
|
||||
<Version>1.1.1.3</Version>
|
||||
<Version>1.1.1.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Arch.Lifecycle.ViewModel">
|
||||
<Version>1.1.1.3</Version>
|
||||
<Version>1.1.1.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.Animated.Vector.Drawable">
|
||||
<Version>28.0.0.3</Version>
|
||||
<Version>28.0.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.Annotations">
|
||||
<Version>28.0.0.3</Version>
|
||||
<Version>28.0.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.AsyncLayoutInflater">
|
||||
<Version>28.0.0.3</Version>
|
||||
<Version>28.0.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.Collections">
|
||||
<Version>28.0.0.3</Version>
|
||||
<Version>28.0.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.Compat">
|
||||
<Version>28.0.0.3</Version>
|
||||
<Version>28.0.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.CoordinaterLayout">
|
||||
<Version>28.0.0.3</Version>
|
||||
<Version>28.0.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.Core.UI">
|
||||
<Version>28.0.0.3</Version>
|
||||
<Version>28.0.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.Core.Utils">
|
||||
<Version>28.0.0.3</Version>
|
||||
<Version>28.0.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.CursorAdapter">
|
||||
<Version>28.0.0.3</Version>
|
||||
<Version>28.0.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.CustomTabs">
|
||||
<Version>28.0.0.3</Version>
|
||||
<Version>28.0.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.CustomView">
|
||||
<Version>28.0.0.3</Version>
|
||||
<Version>28.0.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.DocumentFile">
|
||||
<Version>28.0.0.3</Version>
|
||||
<Version>28.0.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.DrawerLayout">
|
||||
<Version>28.0.0.3</Version>
|
||||
<Version>28.0.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.Fragment">
|
||||
<Version>28.0.0.3</Version>
|
||||
<Version>28.0.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.Interpolator">
|
||||
<Version>28.0.0.3</Version>
|
||||
<Version>28.0.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.Loader">
|
||||
<Version>28.0.0.3</Version>
|
||||
<Version>28.0.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.LocalBroadcastManager">
|
||||
<Version>28.0.0.3</Version>
|
||||
<Version>28.0.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.Media.Compat">
|
||||
<Version>28.0.0.3</Version>
|
||||
<Version>28.0.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.Print">
|
||||
<Version>28.0.0.3</Version>
|
||||
<Version>28.0.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.SlidingPaneLayout">
|
||||
<Version>28.0.0.3</Version>
|
||||
<Version>28.0.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.SwipeRefreshLayout">
|
||||
<Version>28.0.0.3</Version>
|
||||
<Version>28.0.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.v13">
|
||||
<Version>28.0.0.3</Version>
|
||||
<Version>28.0.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.v4">
|
||||
<Version>28.0.0.3</Version>
|
||||
<Version>28.0.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.v7.AppCompat">
|
||||
<Version>28.0.0.3</Version>
|
||||
<Version>28.0.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.Vector.Drawable">
|
||||
<Version>28.0.0.3</Version>
|
||||
<Version>28.0.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.VersionedParcelable">
|
||||
<Version>28.0.0.3</Version>
|
||||
<Version>28.0.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.ViewPager">
|
||||
<Version>28.0.0.3</Version>
|
||||
<Version>28.0.0.1</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
|
||||
|
@@ -49,11 +49,6 @@ namespace keepass2android
|
||||
get { return _activeActivity; }
|
||||
private set
|
||||
{
|
||||
if (_activeActivity != null && _activeActivity != _previouslyActiveActivity)
|
||||
{
|
||||
_previouslyActiveActivity = _activeActivity;
|
||||
|
||||
}
|
||||
_activeActivity = value;
|
||||
if (_task != null)
|
||||
_task.ActiveActivity = _activeActivity;
|
||||
@@ -65,18 +60,12 @@ namespace keepass2android
|
||||
}
|
||||
}
|
||||
|
||||
public Activity PreviouslyActiveActivity
|
||||
{
|
||||
get { return _previouslyActiveActivity; }
|
||||
|
||||
}
|
||||
|
||||
private readonly Handler _handler;
|
||||
private readonly Handler _handler;
|
||||
private readonly RunnableOnFinish _task;
|
||||
private IProgressDialog _progressDialog;
|
||||
private readonly IKp2aApp _app;
|
||||
private Thread _thread;
|
||||
private Activity _activeActivity, _previouslyActiveActivity;
|
||||
private Activity _activeActivity;
|
||||
private ProgressDialogStatusLogger _progressDialogStatusLogger;
|
||||
|
||||
public ProgressTask(IKp2aApp app, Activity activity, RunnableOnFinish task)
|
||||
|
6568
src/Kp2aBusinessLogic/Resources/Resource.Designer.cs
generated
6568
src/Kp2aBusinessLogic/Resources/Resource.Designer.cs
generated
File diff suppressed because it is too large
Load Diff
@@ -72,8 +72,8 @@ namespace keepass2android
|
||||
SearchParameters sp = SearchParameters.None;
|
||||
sp.SearchInUrls = true;
|
||||
sp.SearchString = url;
|
||||
|
||||
if(sp.RegularExpression) // Validate regular expression
|
||||
|
||||
if(sp.RegularExpression) // Validate regular expression
|
||||
{
|
||||
new Regex(sp.SearchString);
|
||||
}
|
||||
@@ -104,9 +104,7 @@ namespace keepass2android
|
||||
if (String.IsNullOrWhiteSpace(host))
|
||||
return pgResults;
|
||||
foreach (PwEntry entry in database.EntriesById.Values)
|
||||
{
|
||||
if (!entry.GetSearchingEnabled())
|
||||
continue;
|
||||
{
|
||||
string otherUrl = entry.Strings.ReadSafe(PwDefs.UrlField);
|
||||
otherUrl = SprEngine.Compile(otherUrl, new SprContext(entry, database.KpDatabase, SprCompileFlags.References));
|
||||
String otherHost = ExtractHost(otherUrl);
|
||||
|
@@ -88,7 +88,6 @@ namespace keepass2android
|
||||
ReadOnlyReason_ReadOnlyKitKat,
|
||||
ReadOnlyReason_LocalBackup,
|
||||
Ok,
|
||||
cancel,
|
||||
FileNotFound
|
||||
cancel
|
||||
}
|
||||
}
|
||||
|
@@ -27,7 +27,7 @@ namespace keepass2android
|
||||
}
|
||||
|
||||
public byte[] HashOfLastStream { get; private set; }
|
||||
public bool CanWrite { get { return _format != KdbxFormat.PlainXml; } }
|
||||
public bool CanWrite { get { return true; } }
|
||||
public string SuccessMessage { get { return null; } }
|
||||
public void Save(PwDatabase kpDatabase, Stream stream)
|
||||
{
|
||||
|
@@ -43,21 +43,17 @@ namespace keepass2android
|
||||
try
|
||||
{
|
||||
remoteData = cachingFileStorage.GetRemoteDataAndHash(ioc, out hash);
|
||||
Kp2aLog.Log("Checking for file change. Current hash = " + hash);
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
StatusLogger.UpdateSubMessage(_app.GetResourceString(UiStringKey.RestoringRemoteFile));
|
||||
cachingFileStorage.UpdateRemoteFile(ioc, _app.GetBooleanPreference(PreferenceKey.UseFileTransactions));
|
||||
Finish(true, _app.GetResourceString(UiStringKey.SynchronizedDatabaseSuccessfully));
|
||||
Kp2aLog.Log("Checking for file change: file not found");
|
||||
return;
|
||||
}
|
||||
|
||||
//check if remote file was modified:
|
||||
var baseVersionHash = cachingFileStorage.GetBaseVersionHash(ioc);
|
||||
Kp2aLog.Log("Checking for file change. baseVersionHash = " + baseVersionHash);
|
||||
if (baseVersionHash != hash)
|
||||
if (cachingFileStorage.GetBaseVersionHash(ioc) != hash)
|
||||
{
|
||||
//remote file is modified
|
||||
if (cachingFileStorage.HasLocalChanges(ioc))
|
||||
|
@@ -36,11 +36,8 @@ namespace keepass2android
|
||||
{
|
||||
_actionToPerform = actionToPerform;
|
||||
}
|
||||
|
||||
//if set to true, the previously active active will be passed to ActionToPerformOnFinish instead null if no activity is on foreground
|
||||
public bool AllowInactiveActivity { get; set; }
|
||||
|
||||
public override void Run()
|
||||
|
||||
public override void Run()
|
||||
{
|
||||
if (Message == null)
|
||||
Message = "";
|
||||
@@ -49,7 +46,7 @@ namespace keepass2android
|
||||
Handler.Post(() => {_actionToPerform(Success, Message, ActiveActivity);});
|
||||
}
|
||||
else
|
||||
_actionToPerform(Success, Message, AllowInactiveActivity ? (ActiveActivity ?? PreviouslyActiveActivity) : ActiveActivity);
|
||||
_actionToPerform(Success, Message, ActiveActivity);
|
||||
base.Run();
|
||||
}
|
||||
}
|
||||
|
@@ -31,17 +31,15 @@ namespace keepass2android
|
||||
private readonly PwEntry _entry;
|
||||
private readonly PwGroup _parentGroup;
|
||||
private readonly Activity _ctx;
|
||||
private readonly Database _db;
|
||||
|
||||
public static AddEntry GetInstance(Activity ctx, IKp2aApp app, PwEntry entry, PwGroup parentGroup, OnFinish finish) {
|
||||
|
||||
public static AddEntry GetInstance(Activity ctx, IKp2aApp app, PwEntry entry, PwGroup parentGroup, OnFinish finish, Database db) {
|
||||
|
||||
return new AddEntry(ctx, db, app, entry, parentGroup, finish);
|
||||
return new AddEntry(ctx, app, entry, parentGroup, finish);
|
||||
}
|
||||
|
||||
public AddEntry(Activity ctx, Database db, IKp2aApp app, PwEntry entry, PwGroup parentGroup, OnFinish finish):base(ctx, finish) {
|
||||
public AddEntry(Activity ctx, IKp2aApp app, PwEntry entry, PwGroup parentGroup, OnFinish finish):base(ctx, finish) {
|
||||
_ctx = ctx;
|
||||
_db = db;
|
||||
_parentGroup = parentGroup;
|
||||
_parentGroup = parentGroup;
|
||||
_app = app;
|
||||
_entry = entry;
|
||||
|
||||
@@ -59,13 +57,10 @@ namespace keepass2android
|
||||
{
|
||||
_parentGroup.AddEntry(_entry, true);
|
||||
}
|
||||
|
||||
// Add entry to global
|
||||
_db.EntriesById[_entry.Uuid] = _entry;
|
||||
_db.Elements.Add(_entry);
|
||||
|
||||
// Commit to disk
|
||||
SaveDb save = new SaveDb(_ctx, _app, _app.CurrentDb, OnFinishToRun);
|
||||
|
||||
|
||||
// Commit to disk
|
||||
SaveDb save = new SaveDb(_ctx, _app, _app.CurrentDb, OnFinishToRun);
|
||||
save.SetStatusLogger(StatusLogger);
|
||||
save.Run();
|
||||
}
|
||||
@@ -91,7 +86,9 @@ namespace keepass2android
|
||||
// Mark parent group dirty
|
||||
_app.DirtyGroups.Add(parent);
|
||||
|
||||
|
||||
// Add entry to global
|
||||
_db.EntriesById[_entry.Uuid] = _entry;
|
||||
_db.Elements.Add(_entry);
|
||||
|
||||
} else
|
||||
{
|
||||
|
@@ -16,8 +16,8 @@ namespace keepass2android.database.edit
|
||||
{
|
||||
public class CopyEntry: AddEntry
|
||||
{
|
||||
public CopyEntry(Activity ctx, IKp2aApp app, PwEntry entry, OnFinish finish, Database db)
|
||||
: base(ctx, db, app, CreateCopy(entry, app), entry.ParentGroup, finish)
|
||||
public CopyEntry(Activity ctx, IKp2aApp app, PwEntry entry, OnFinish finish)
|
||||
: base(ctx, app, CreateCopy(entry, app), entry.ParentGroup, finish)
|
||||
{
|
||||
}
|
||||
|
||||
|
@@ -234,7 +234,7 @@ namespace keepass2android
|
||||
else
|
||||
{
|
||||
// Let's not bother recovering from a failure to save. It is too much work.
|
||||
App.Lock(false, false);
|
||||
App.Lock(false);
|
||||
}
|
||||
}, OnFinishToRun);
|
||||
|
||||
|
@@ -82,7 +82,7 @@ namespace keepass2android
|
||||
_editGroup.App.DirtyGroups.Add(_editGroup.Group.ParentGroup);
|
||||
} else
|
||||
{
|
||||
_editGroup._app.Lock(false, false);
|
||||
_editGroup._app.Lock(false);
|
||||
}
|
||||
|
||||
base.Run();
|
||||
|
@@ -123,7 +123,7 @@ namespace keepass2android
|
||||
{
|
||||
if (!(e is InvalidCompositeKeyException))
|
||||
Kp2aLog.LogUnexpectedError(e);
|
||||
Finish(false, _app.GetResourceString(UiStringKey.ErrorOcurred) + " " + (e.Message ?? (e is FileNotFoundException ? _app.GetResourceString(UiStringKey.FileNotFound) : "")), false, Exception);
|
||||
Finish(false, _app.GetResourceString(UiStringKey.ErrorOcurred) + " " + e.Message, false, Exception);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -39,7 +39,7 @@ namespace keepass2android
|
||||
protected OnFinish BaseOnFinish;
|
||||
protected Handler Handler;
|
||||
private ProgressDialogStatusLogger _statusLogger = new ProgressDialogStatusLogger(); //default: no logging but not null -> can be used whenever desired
|
||||
private Activity _activeActivity, _previouslyActiveActivity;
|
||||
private Activity _activeActivity;
|
||||
|
||||
|
||||
public ProgressDialogStatusLogger StatusLogger
|
||||
@@ -53,12 +53,7 @@ namespace keepass2android
|
||||
get { return _activeActivity; }
|
||||
set
|
||||
{
|
||||
if (_activeActivity != null && _activeActivity != _previouslyActiveActivity)
|
||||
{
|
||||
_previouslyActiveActivity = _activeActivity;
|
||||
|
||||
}
|
||||
_activeActivity = value;
|
||||
_activeActivity = value;
|
||||
if (BaseOnFinish != null)
|
||||
{
|
||||
BaseOnFinish.ActiveActivity = value;
|
||||
@@ -66,15 +61,8 @@ namespace keepass2android
|
||||
}
|
||||
}
|
||||
|
||||
public Activity PreviouslyActiveActivity
|
||||
{
|
||||
get { return _previouslyActiveActivity; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected OnFinish(Activity activeActivity, Handler handler)
|
||||
protected OnFinish(Activity activeActivity, Handler handler)
|
||||
{
|
||||
ActiveActivity = activeActivity;
|
||||
BaseOnFinish = null;
|
||||
|
@@ -116,18 +116,14 @@ namespace keepass2android
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool hasStreamForOrigFile = (_streamForOrigFile != null);
|
||||
bool hasChangeFast = hasStreamForOrigFile ||
|
||||
fileStorage.CheckForFileChangeFast(ioc, _db.LastFileVersion); //first try to use the fast change detection;
|
||||
bool hasHashChanged = hasChangeFast ||
|
||||
(FileHashChanged(ioc, _db.KpDatabase.HashOfFileOnDisk) ==
|
||||
FileHashChange.Changed); //if that fails, hash the file and compare:
|
||||
|
||||
if (hasHashChanged)
|
||||
if (
|
||||
(_streamForOrigFile != null)
|
||||
|| fileStorage.CheckForFileChangeFast(ioc, _db.LastFileVersion) //first try to use the fast change detection
|
||||
|| (FileHashChanged(ioc, _db.KpDatabase.HashOfFileOnDisk) == FileHashChange.Changed) //if that fails, hash the file and compare:
|
||||
)
|
||||
{
|
||||
Kp2aLog.Log("Conflict. " + hasStreamForOrigFile + " " + hasChangeFast + " " + hasHashChanged);
|
||||
|
||||
//ask user...
|
||||
_app.AskYesNoCancel(UiStringKey.TitleSyncQuestion, UiStringKey.MessageSyncQuestion,
|
||||
|
@@ -11,8 +11,7 @@
|
||||
<MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix>
|
||||
<AssemblyName>Kp2aKeyboardBinding</AssemblyName>
|
||||
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
|
||||
<TargetFrameworkVersion>v10.0</TargetFrameworkVersion>
|
||||
<AndroidCodegenTarget>XAJavaInterop1</AndroidCodegenTarget>
|
||||
<TargetFrameworkVersion>v8.0</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>True</DebugSymbols>
|
||||
|
BIN
src/PCloudBindings/Jars/pcloud-sdk-android-1.1.0.aar
Normal file
BIN
src/PCloudBindings/Jars/pcloud-sdk-android-1.1.0.aar
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/PCloudBindings/Jars/pcloud-sdk-java-core-1.1.0.jar
Normal file
BIN
src/PCloudBindings/Jars/pcloud-sdk-java-core-1.1.0.jar
Normal file
Binary file not shown.
Binary file not shown.
@@ -12,7 +12,6 @@
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
|
||||
<TargetFrameworkVersion>v8.0</TargetFrameworkVersion>
|
||||
<AndroidCodegenTarget>XAJavaInterop1</AndroidCodegenTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -55,7 +54,7 @@
|
||||
<ItemGroup>
|
||||
<None Include="Jars\AboutJars.txt" />
|
||||
<None Include="Additions\AboutAdditions.txt" />
|
||||
<LibraryProjectZip Include="Jars\pcloud-sdk-android-1.2.0.aar" />
|
||||
<LibraryProjectZip Include="Jars\pcloud-sdk-android-1.1.0.aar" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<TransformFile Include="Transforms\Metadata.xml" />
|
||||
@@ -71,6 +70,6 @@
|
||||
</Target>
|
||||
-->
|
||||
<ItemGroup>
|
||||
<EmbeddedReferenceJar Include="Jars\pcloud-sdk-java-core-1.2.0.jar" />
|
||||
<EmbeddedReferenceJar Include="Jars\pcloud-sdk-java-core-1.1.0.jar" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@@ -12,7 +12,6 @@
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
|
||||
<TargetFrameworkVersion>v8.0</TargetFrameworkVersion>
|
||||
<AndroidCodegenTarget>XAJavaInterop1</AndroidCodegenTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -54,7 +53,7 @@
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<LibraryProjectZip Include="..\java\Keepass2AndroidPluginSDK2\app\build\outputs\aar\app-release.aar">
|
||||
<LibraryProjectZip Include="..\java\Keepass2AndroidPluginSDK2\app\build\outputs\aar\Keepass2AndroidPluginSDK2-release.aar">
|
||||
<Link>Jars\Keepass2AndroidPluginSDK2-release.aar</Link>
|
||||
</LibraryProjectZip>
|
||||
<None Include="Jars\AboutJars.txt" />
|
||||
|
Submodule src/SamsungPass updated: 56538a5be1...f3c6bbe224
@@ -1,18 +1,17 @@
|
||||
cd ..\java\JavaFileStorageTest-AS
|
||||
./gradlew clean assemble
|
||||
|
||||
call gradlew assemble
|
||||
|
||||
cd ..\KP2ASoftkeyboard_AS
|
||||
./gradlew clean assemble
|
||||
call gradlew assemble
|
||||
|
||||
cd ..\Keepass2AndroidPluginSDK2
|
||||
./gradlew clean assemble
|
||||
call gradlew assemble
|
||||
|
||||
|
||||
cd ..\KP2AKdbLibrary
|
||||
./gradlew clean assemble
|
||||
call gradlew assemble
|
||||
|
||||
cd ..\PluginQR
|
||||
./gradlew clean assemble
|
||||
call gradlew assemble
|
||||
|
||||
cd ..\..\build-scripts
|
||||
|
@@ -6,11 +6,11 @@ if exist "DropboxFileStorageKeys.cs" (
|
||||
)
|
||||
|
||||
cd ..\..\keepass2android
|
||||
call UseManifestDebug.bat
|
||||
call UseManifestNoNet.bat
|
||||
cd ..
|
||||
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86_amd64
|
||||
|
||||
msbuild KeePass.sln /target:keepass2android /p:BuildProjectReferences=true /p:Configuration="Debug" /p:Platform="Any CPU"
|
||||
msbuild KeePass.sln /target:keepass2android /p:BuildProjectReferences=true /p:Configuration="Release" /p:Platform="Any CPU"
|
||||
|
||||
cd build-scripts
|
@@ -1,17 +0,0 @@
|
||||
cd ..\java\JavaFileStorageTest-AS
|
||||
./gradlew -q :app:dependencies > ../../build-scripts/dependencies-JavaFileStorageTest-AS.txt
|
||||
|
||||
cd ..\KP2ASoftkeyboard_AS
|
||||
./gradlew -q :app:dependencies > ../../build-scripts/dependencies-KP2ASoftkeyboard_AS.txt
|
||||
|
||||
cd ..\Keepass2AndroidPluginSDK2
|
||||
./gradlew -q :app:dependencies > ../../build-scripts/dependencies-Keepass2AndroidPluginSDK2.txt
|
||||
|
||||
|
||||
cd ..\KP2AKdbLibrary
|
||||
./gradlew -q :app:dependencies > ../../build-scripts/dependencies-KP2AKdbLibrary.txt
|
||||
|
||||
cd ..\PluginQR
|
||||
./gradlew -q :app:dependencies > ../../build-scripts/dependencies-PluginQR.txt
|
||||
|
||||
cd ..\..\build-scripts
|
@@ -1,11 +1,11 @@
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
compileSdkVersion 26
|
||||
buildToolsVersion '28.0.3'
|
||||
defaultConfig {
|
||||
minSdkVersion 15
|
||||
targetSdkVersion 28
|
||||
targetSdkVersion 23
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
@@ -26,9 +26,8 @@ NOTE: If you change dependencies here, don't forget to update the jar files in J
|
||||
*/
|
||||
|
||||
dependencies {
|
||||
compile 'com.android.support:appcompat-v7:28.0.0'
|
||||
compile 'com.squareup.okhttp3:okhttp:4.10.0-RC1'
|
||||
compile 'com.burgstaller:okhttp-digest:2.5'
|
||||
compile 'com.squareup.okhttp3:okhttp:3.9.0'
|
||||
compile 'com.burgstaller:okhttp-digest:1.7'
|
||||
compile 'com.google.android.gms:play-services:4.0.30'
|
||||
compile 'com.google.http-client:google-http-client-gson:1.20.0'
|
||||
compile('com.google.api-client:google-api-client-android:1.16.0-rc') {
|
||||
@@ -40,8 +39,8 @@ dependencies {
|
||||
compile('com.onedrive.sdk:onedrive-sdk-android:1.2.0') {
|
||||
transitive = false
|
||||
}
|
||||
compile 'com.pcloud.sdk:java-core:1.2.0'
|
||||
compile 'com.pcloud.sdk:android:1.2.0'
|
||||
compile 'com.pcloud.sdk:java-core:1.1.0'
|
||||
compile 'com.pcloud.sdk:android:1.1.0'
|
||||
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'
|
||||
|
@@ -6,6 +6,7 @@
|
||||
android:versionName="1.0">
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="8"
|
||||
android:targetSdkVersion="14" />
|
||||
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2006-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2006-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2005-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2005-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2013-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2013-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2015-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2015-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2015-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2015-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2015-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2004-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2004-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2004-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2004-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
@@ -93,13 +93,7 @@ class IdentityFile implements Identity{
|
||||
* @return "ssh-rsa" or "ssh-dss"
|
||||
*/
|
||||
public String getAlgName(){
|
||||
byte[] name = kpair.getKeyTypeName();
|
||||
try {
|
||||
return new String(name, "UTF-8");
|
||||
}
|
||||
catch (UnsupportedEncodingException e){
|
||||
return new String(name);
|
||||
}
|
||||
return new String(kpair.getKeyTypeName());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved.
|
||||
Copyright (c) 2012-2016 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user