Compare commits

..

8 Commits

Author SHA1 Message Date
Philipp Crocoll
e2babde1fa do not reset activity state in OnNewIntent if the activity hasn't even been initialized. closes #2869, closes #2888 2025-06-17 14:04:15 +02:00
Philipp Crocoll
e1f26fb045 cleanup and improve formatting 2025-06-17 13:58:29 +02:00
Philipp Crocoll
adbbfa0ac1 add more logging to diagnose #2891 2025-06-17 08:27:13 +02:00
Philipp Crocoll
f162e868b9 link libargon2.so for x86 and x86_64 to fix #2881 2025-06-03 17:07:17 +02:00
Philipp Crocoll
e5d28f0979 only try to activate the keyboard once in password activity and entry edit activity; explain why the prompt shows up in SwitchImeActivity. closes #1400 2025-04-22 17:48:56 +02:00
Philipp Crocoll
0e581a66c5 treat server certificate failures as error by default, closes #1078 2025-04-22 16:02:02 +02:00
PhilippC
ceb31c54b1 Merge pull request #2847 from PhilippC/2430-remove-plain-storage-uri-from-logs
remove potential plain-text credentials for file storage from logs
2025-04-15 14:27:02 +02:00
Philipp Crocoll
42d8be593e remove potential plain-text credentials for file storage from logs 2025-04-15 14:00:31 +02:00
10 changed files with 305 additions and 242 deletions

View File

@@ -100,10 +100,7 @@ namespace keepass2android
if (resultCode == Result.Ok)
{
Kp2aLog.Log("FileSelection returned "+data.DataString);
//TODO: don't try to extract filename if content URI
string filename = IntentToFilename(data);
Kp2aLog.Log("FileSelection returned filename " + filename);
if (filename != null)
{
if (filename.StartsWith("file://"))

View File

@@ -331,12 +331,17 @@ namespace keepass2android
}
private bool hasRequestedKeyboardActivation = false;
protected override void OnStart()
{
base.OnStart();
if (PreferenceManager.GetDefaultSharedPreferences(this)
.GetBoolean(GetString(Resource.String.UseKp2aKeyboardInKp2a_key), false))
.GetBoolean(GetString(Resource.String.UseKp2aKeyboardInKp2a_key), false)
&& (!hasRequestedKeyboardActivation))
{
//only try this once. if the user clicks cancel, we don't want to ask again
// (it may happen that the activity is restarted because of the NewTask flag immediately after the dialog)
hasRequestedKeyboardActivation = true;
CopyToClipboardService.ActivateKeyboard(this);
}
}

View File

@@ -66,7 +66,6 @@ using Exception = System.Exception;
using String = System.String;
using Toolbar = AndroidX.AppCompat.Widget.Toolbar;
using AndroidX.Core.Content;
using Google.Android.Material.Snackbar;
namespace keepass2android
{
@@ -132,6 +131,7 @@ namespace keepass2android
ISharedPreferences _prefs;
private bool _starting;
private bool _resumeCompleted;
private OtpInfo _otpInfo;
private IOConnectionInfo _otpAuxIoc;
private ChallengeInfo _chalInfo;
@@ -801,8 +801,6 @@ namespace keepass2android
_password = i.GetStringExtra(KeyPassword) ?? "";
if (!KeyProviderTypes.Any())
{
SetKeyProviderFromString(LoadKeyProviderStringForIoc(_ioConnection.Path));
}
@@ -1570,14 +1568,20 @@ namespace keepass2android
base.OnPause();
}
private bool hasRequestedKeyboardActivation = false;
protected override void OnStart()
{
base.OnStart();
_starting = true;
if (PreferenceManager.GetDefaultSharedPreferences(this)
.GetBoolean(GetString(Resource.String.UseKp2aKeyboardInKp2a_key), false))
.GetBoolean(GetString(Resource.String.UseKp2aKeyboardInKp2a_key), false)
&& !hasRequestedKeyboardActivation)
{
hasRequestedKeyboardActivation = true;
CopyToClipboardService.ActivateKeyboard(this);
}
@@ -1687,15 +1691,20 @@ namespace keepass2android
//assume the key should be used as static password
FindViewById<EditText>(Resource.Id.password_edit).Text += otp;
}
}
else
{
// if the activity is launched twice and the first initialization hasn't even finished, we cannot
// reset the state and re-initialize the activity.
// This can happen with autofill in some cases (#2869)
if (_resumeCompleted)
{
ResetState();
GetIocFromLaunchIntent(intent);
InitializeAfterSetIoc();
OnStart();
}
}
}
@@ -1814,43 +1823,6 @@ namespace keepass2android
FindViewById(Resource.Id.otpInitView).Visibility =
_challengeSecret == null ? ViewStates.Visible : ViewStates.Gone;
}
/*
Snackbar snackbar = Snackbar
.Make(FindViewById(Resource.Id.main_content),
"snack snack snack snack snack snack snack snack snack snack snack snack snack snack snacksnack snack snacksnack snack snacksnack snack snack snack snack snack snack snack snack snack snack snack snack snack snack snacksnack snack snacksnack snack snacksnack snack snack snack snack snacksnack snack snack ",
Snackbar.LengthLong);
snackbar.SetTextMaxLines(5);
snackbar.SetBackgroundTint(GetColor(Resource.Color.md_theme_secondaryContainer));
snackbar.SetTextColor(GetColor(Resource.Color.md_theme_onSecondaryContainer));
snackbar.SetAction("dismiss",
view => snackbar.SetBackgroundTint(GetColor(Resource.Color.md_theme_surfaceContainer)));
snackbar.Show();
new Handler().PostDelayed(() =>
{
Snackbar snackbar2 = Snackbar
.Make(FindViewById(Resource.Id.main_content), "snack snack snack ",
Snackbar.LengthLong);
snackbar2.SetTextMaxLines(5);
snackbar2.SetBackgroundTint(GetColor(Resource.Color.md_theme_errorContainer));
snackbar2.SetTextColor(GetColor(Resource.Color.md_theme_onErrorContainer));
snackbar2.Show();
}, 1500);
new Handler().PostDelayed(() =>
{
Snackbar snackbar2 = Snackbar
.Make(FindViewById(Resource.Id.main_content), "snack snack warn ",
Snackbar.LengthLong);
snackbar2.SetTextMaxLines(5);
snackbar2.SetBackgroundTint(GetColor(Resource.Color.md_theme_inverseSurface));
snackbar2.SetTextColor(GetColor(Resource.Color.md_theme_inverseOnSurface));
snackbar2.Show();
}, 2500);*/
//use !IsFinishing to make sure we're not starting another activity when we're already finishing (e.g. due to TaskComplete in OnActivityResult)
//use !performingLoad to make sure we're not already loading the database (after ActivityResult from File-Prepare-Activity; this would cause _loadDbFileTask to exist when we reload later!)
@@ -1914,6 +1886,8 @@ namespace keepass2android
keyboard.HideSoftInputFromWindow(pwd.WindowToken, HideSoftInputFlags.ImplicitOnly);
}, 50);
}
_resumeCompleted = true;
}
private void TryGetOtpFromClipboard()

View File

@@ -1,4 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
@@ -14,6 +19,7 @@
android:text="@string/switch_ime_text" />
<Button
android:id="@+id/btn_reopen"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -25,4 +31,51 @@
android:layout_height="wrap_content"
android:text="@string/cancel" />
<LinearLayout android:orientation="vertical"
android:paddingTop="64dp"
android:id="@+id/settings_notes_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:paddingTop="12dp"
android:id="@+id/note_kp2a_switch_rooted"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/autoswitch_enabled_but_not_setup"
/>
<TextView
android:paddingTop="12dp"
android:id="@+id/note_AutoFillTotp_prefs_ActivateKeyboard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/switch_keyboard_for_totp_enabled"
/>
<TextView
android:paddingTop="12dp"
android:id="@+id/note_UseKp2aKeyboardInKp2a"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/switch_keyboard_inside_kp2a_enabled"
/>
<TextView
android:id="@+id/note_OpenKp2aKeyboardAutomatically"
android:paddingTop="12dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/switch_keyboard_on_search_enabled"
/>
<Button
style="?attr/materialButtonOutlinedStyle"
android:id="@+id/btn_open_settings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/IconVisibilityInfo_Android8_btnSettings" />
</LinearLayout>
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -200,7 +200,7 @@
<item>System</item>
</string-array>
<string name="AcceptAllServerCertificates_default">WARN</string>
<string name="AcceptAllServerCertificates_default">ERROR</string>
<string-array name="AcceptAllServerCertificates_values">
<item>IGNORE</item>
<item>WARN</item>

View File

@@ -1249,5 +1249,9 @@
<string name="kp2a_switch_on_sendgodone_summary">Switch back when pressing send/go/done</string>
<string name="qr_scanning_error_no_google_play_services">QR code scanning requires Google Play Services. Please install or update Google Play Services on your device.</string>
<string name="english_ime_settings">Android keyboard settings</string>
<string name="autoswitch_enabled_but_not_setup">Note: You have enabled App - Settings - Password access - Keyboard switching - Auto-switch keyboard, but it doesn\'t seem to be configured correctly.</string>
<string name="switch_keyboard_for_totp_enabled">Note: You have enabled App - Password access - Autofill-Service - Autofill for TOTP entries. This can cause this window to show when you open an entry with a TOTP.</string>
<string name="switch_keyboard_inside_kp2a_enabled">Note: You have enabled App - Security - Use built-in keyboard inside Keepass2Android. This can cause this window to show when you open the app or edit an entry.</string>
<string name="switch_keyboard_on_search_enabled">Note: You have enabled App - Security - Password access - Keyboard switching - Switch keyboard. This can cause this window to show when you search for an entry from the browser.</string>
</resources>

View File

@@ -6,6 +6,7 @@ using System.Threading;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Preferences;
using Android.Runtime;
using Android.Util;
using Android.Views;
@@ -15,8 +16,8 @@ using keepass2android;
namespace keepass2android
{
[Activity(Label = AppNames.AppName, TaskAffinity = "", NoHistory = true)]
public class SwitchImeActivity : Activity
[Activity(Label = AppNames.AppName, Theme = "@style/Kp2aTheme_BlueActionBar")]
public class SwitchImeActivity : AndroidX.AppCompat.App.AppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
@@ -24,7 +25,26 @@ namespace keepass2android
SetContentView(Resource.Layout.switch_ime_activity_layout);
FindViewById<Button>(Resource.Id.btn_reopen).Click += (sender, args) => TrySwitchKeyboard();
FindViewById<Button>(Resource.Id.btn_cancel).Click += (sender, args) => Finish();
FindViewById<Button>(Resource.Id.btn_open_settings).Click += (sender, args) => AppSettingsActivity.Launch(this);
var prefs = PreferenceManager.GetDefaultSharedPreferences(LocaleManager.LocalizedAppContext);
bool useKp2aKeyboardInKp2a = prefs.GetBoolean(GetString(Resource.String.UseKp2aKeyboardInKp2a_key), false);
bool kp2a_switch_rooted = prefs.GetBoolean("kp2a_switch_rooted", false);
bool AutoFillTotp_prefs_ActivateKeyboard = prefs.GetBoolean("AutoFillTotp_prefs_ActivateKeyboard_key", false);
bool OpenKp2aKeyboardAutomatically = prefs.GetBoolean(GetString(Resource.String.OpenKp2aKeyboardAutomatically_key), Resources.GetBoolean(Resource.Boolean.OpenKp2aKeyboardAutomatically_default));
FindViewById(Resource.Id.note_UseKp2aKeyboardInKp2a).Visibility = useKp2aKeyboardInKp2a ? ViewStates.Visible : ViewStates.Gone;
FindViewById(Resource.Id.note_kp2a_switch_rooted).Visibility = kp2a_switch_rooted ? ViewStates.Visible : ViewStates.Gone;
FindViewById(Resource.Id.note_AutoFillTotp_prefs_ActivateKeyboard).Visibility = AutoFillTotp_prefs_ActivateKeyboard ? ViewStates.Visible : ViewStates.Gone;
FindViewById(Resource.Id.note_OpenKp2aKeyboardAutomatically).Visibility = OpenKp2aKeyboardAutomatically ? ViewStates.Visible : ViewStates.Gone;
bool hasNote = useKp2aKeyboardInKp2a || kp2a_switch_rooted || AutoFillTotp_prefs_ActivateKeyboard || OpenKp2aKeyboardAutomatically;
((LinearLayout)FindViewById(Resource.Id.settings_notes_container)).Visibility = hasNote ? ViewStates.Visible : ViewStates.Gone;
}
private string Kp2aInputMethodName
{
get { return PackageName + "/keepass2android.softkeyboard.KP2AKeyboard"; }

View File

@@ -803,13 +803,15 @@ namespace keepass2android
var hasUnsecureDisplay = HasUnsecureDisplay(context);
if (hasUnsecureDisplay)
{
Kp2aLog.Log("Display is not secure");
var intent = new Intent(context, typeof(NoSecureDisplayActivity));
intent.AddFlags(ActivityFlags.SingleTop | ActivityFlags.ClearTop);
context.StartActivityForResult(intent, 9999);
}
Kp2aLog.Log("Setting FLAG_SECURE.");
context.Window.SetFlags(WindowManagerFlags.Secure, WindowManagerFlags.Secure);
}
else Kp2aLog.Log("Secure display disabled by user preference.");
}
public static bool SecureDisplayConfigured(Activity context)

View File

@@ -918,13 +918,15 @@ namespace keepass2android
{
var prefs = PreferenceManager.GetDefaultSharedPreferences(LocaleManager.LocalizedAppContext);
ValidationMode validationMode = ValidationMode.Warn;
ValidationMode validationMode = ValidationMode.Error;
string strValMode = prefs.GetString(LocaleManager.LocalizedAppContext.Resources.GetString(Resource.String.AcceptAllServerCertificates_key),
LocaleManager.LocalizedAppContext.Resources.GetString(Resource.String.AcceptAllServerCertificates_default));
if (strValMode == "IGNORE")
validationMode = ValidationMode.Ignore;
else if (strValMode == "WARN")
validationMode = ValidationMode.Warn;
else if (strValMode == "ERROR")
validationMode = ValidationMode.Error;
return validationMode;

View File

@@ -732,6 +732,12 @@
<ItemGroup>
<AndroidNativeLibrary Include="..\java\argon2\libs\armeabi-v7a\libargon2.so" Link="armeabi-v7a\libargon2.so" />
</ItemGroup>
<ItemGroup>
<AndroidNativeLibrary Include="..\java\argon2\libs\x86\libargon2.so" Link="x86\libargon2.so" />
</ItemGroup>
<ItemGroup>
<AndroidNativeLibrary Include="..\java\argon2\libs\x86_64\libargon2.so" Link="x86_64\libargon2.so" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Xamarin.AndroidX.AppCompat" Version="1.7.0.5" />
<PackageReference Include="Xamarin.AndroidX.AppCompat.AppCompatResources" Version="1.7.0.5" />