Kunzisoft / KeePassDX

Lightweight vault and password manager for Android, KeePassDX allows editing encrypted data in a single file in KeePass format and fill in the forms in a secure way.
https://www.keepassdx.com/
GNU General Public License v3.0
4.53k stars 267 forks source link

Can't open database from Samsung "My Files" after sync #501

Closed alexanderadam closed 4 years ago

alexanderadam commented 4 years ago

Hi @J-Jamet, I opened a new issue as you requested.

Describe the bug

To Reproduce Steps to reproduce the behavior:

  1. Have a recently opened Database
  2. Close the app / do something else
  3. Now copy another version of the database to the exact same path (or do a sync via cloud)
  4. Open KeePassDX. It will still show the path and offers to enter the password. But if you do, you will get the error Could not find file. Try reopening it from your file browser.

keepassbug

Expected behavior

The bug was introduced sometime last year. But it worked perfectly fine before. So I guess it would be nice if it would work again.

Keepass Database

KeePassDX (please complete the following information):

Android (please complete the following information):

Additional context

This happens with entries from Recent Databases too. So those entries are worthless.

keepassbug2

So the only possibility to open that database again is by going over OPEN EXISTING DATABASE again.

J-Jamet commented 4 years ago

Can you download the latest version on FDroid and retest your issue? Thank you.

alexanderadam commented 4 years ago

I just tested it and this issue is still present in the latest release 2.5beta28.

Just to be sure: can't you reproduce this on your phone as well? :thinking:

J-Jamet commented 4 years ago

Latest release is 2.5beta29 and 2.5beta28 in F-Droid. Look at your link.

alexanderadam commented 4 years ago

Sorry, I meant 2.5beta28. I don't see 2.5beta29 on F-Droid however. Latest I see is 2.5beta28:

Screenshot_20200326_165734

Can't you reproduce this issue on your phone or an emulator as well?

J-Jamet commented 4 years ago

OK, as explained in the wiki, this happens because your file manager breaks the links. By default the links detected broken are now hidden in KeePassDX (you have to activate the parameter to review them). Can you indicate the name of your file manager application and its version, if the links are always broken, I will update the wiki table with your app.

I can't reproduce the problem with your file manager because I don't know which one you are using, and I don't have a GalaxyS9. But it looks like Samsung has created its own file manager app.

alexanderadam commented 4 years ago

I have various file managers installed. "Default apps" does not show something about file managers. But as mentioned in November the manager that was installed by the vendor (Samsung) is "My Files" version 11.0.00.645. This is the version from Play Store but the preinstalled one comes from Samsung Galaxy Store.

And I guess they wouldn't care much if I tell them that everything works perfectly except KeePassDX.

J-Jamet commented 4 years ago

Just tried to install Samsung "My Files" but I can't open it on my device. So 2 solutions:

I'm adding the compatibility info in the wiki. It's not a KeePassDX bug so I can't fix it.

alexanderadam commented 4 years ago

It's not a KeePassDX bug so I can't fix it.

But wouldn't it be possible to check for file existence when the password dialogue is opened and simply show the file selection dialogue (the one that opens when clicking OPEN EXISTING DATABASE) instead (as mentioned before)? :thinking:

J-Jamet commented 4 years ago

It's already the case in the "Recent databases" list in the previous screen. "Settings -> App settings -> Hide broken database links" The password screen is displayed when a file is selected or if we are trying to open a link in the "Recent databases" list, so we know that the link exists. (unless if coming from the "recent database" and try to open a broken link (red icon), visible if the setting is disabled)

alexanderadam commented 4 years ago

The password screen is displayed when a file is selected or if we are trying to open a link in the "Recent databases" list, so we know that the link exists.

Nope. The screen is also displayed when

  1. KeePassDX was opened
  2. it naturally locked itself later on
  3. the database was copied
  4. the user opens KeePassDX

Then it's still in the password dialogue. This is also the reason why I still can reproduce it.

J-Jamet commented 4 years ago

Ha okay, I see what you mean. For me this part corresponds to the synchronization of the files, it is a feature which I have not yet developed. From a technical point of view, your solution would require filtering the opening to select only the lost file, but I don't see how to do it. Otherwise another solution would be to simply finish the password selection screen if the link is broken.

alexanderadam commented 4 years ago

To be honest: I don't quite understand what

filtering the opening to select only the lost file

or

finish the password selection screen

mean. :wink:

PS: Thank you so much for your work on KeePassDX. :pray: I wish more people would use it though. It's very well done!

J-Jamet commented 4 years ago

Sorry, I'm not clear.

filtering the opening to select only the lost file

Because in the workflow, a specific file is expected when we are in the password screen, so I have to reload the file which has the same metadata, but if I cannot compare it to the metadata of the old file (whose data is no longer accessible) this is not feasible.

finish the password selection screen

I meant "finish the activity that contains the password screen". And without having tested, I do not know if there will be side effects.

PS: Thank to you for your feedback, discussions move the project forward.

alexanderadam commented 4 years ago

I cannot compare it to the metadata of the old file (whose data is no longer accessible) this is not feasible.

Why do you have to compare it? Wouldn't you just have to access it? Or call whatever leads to the error message (Could not find file. Try reopening it from your file browser.)?

J-Jamet commented 4 years ago

This error message arrives precisely because we are trying to access the URI of the file but the file manager does not give access to it (whatever the reason).

So for your solution, we must therefore recreate the URI link from the file manager's content provider (keeping the same URI) but this solution is not feasible for me because the manager's behavior is not predictable.

J-Jamet commented 4 years ago

By finishing the password selection activity, you will return to the previous workflow screen:

This would allow to reselect a file. Gain one manipulation, but I have to test the side effects.

alexanderadam commented 4 years ago

Ah, now I see. So recreating the URI would be usability-wise the best but finishing the password selection activity would be much easier to do?

J-Jamet commented 4 years ago

In the best of cases, the rights of the URI are not revoked by the file manager.

Otherwise I think it will be the only solution to finish the password selection activity. It is the responsibility of the file manager app to revoke or not a file URI. If this app decided that it is no longer valid, there is unfortunately no way to force him to reactivate a link. That's why I make a compatibility table of compatible file managers.

What I can do first is rename the error message to Access to the file has been revoked. Please reopen it from the associated file manager. Maybe it can avoid confusion.

alexanderadam commented 4 years ago

Thank you for your explanations. :+1:

That's why I make a compatibility table of compatible file managers.

Did you see the answers in the former issue? Maybe those are also giving hints regarding problematic file managers?

What I can do first is rename the error message to Access to the file has been revoked. Please reopen it from the associated file manager. Maybe it can avoid confusion.

I don't think that it would help to avoid confusion. :wink:

Maybe another approach: Can you get or store references to directories and read their content? If so: maybe a "compatibility mode solution" could be to to store that directory reference and check for *.kdbx files. If there's just one (I guess this will be the case for many users) this file could directly be opened.

Sorry for my naΓ―ve ideas. You can clearly see that I'm not an Android developer. :wink:

J-Jamet commented 4 years ago

Did you see the answers in the former issue? Maybe those are also giving hints regarding problematic file managers?

Yes, and I don't think it depends on the device but on the file manager. NextCloud, is in the table, but I haven't tested it in depth yet. It also seems that there are different behaviors depending on the versions. Otherwise need a dedicated issue for NextCoud.

Can you get or store references to directories and read their content?

KeePassDX does not access any file directly. This solution implies that KeePassDX becomes a file manager and I don't want to go in this direction for security reasons. Android's policy regarding accessing and modifying files is rather restrictive, direct access to directories requires elevating the access rights of an application, and I want to create KeePassDX as an editor (and not a file manager). Android 11 will further harden direct access to files (which I personally find very good) -> https://developer.android.com/preview/privacy/storage So to respect the conventions and the security chain, I simply let the file managers take care of providing the URIs.

setuidroot commented 4 years ago

I'm having this same issus with KeePassDX on any version above F-Droid's 2.5.0.0beta25. I tried the latest F-Droid version (didn't fix this issue) and I tried the latest github release here (still didn't fix the issue.)

The issue for me is that Version 2.5.0.0beta25 will request access to Android storage permissions (which I can then grant it access to my storage.) Versions after 2.5.0.0beta25 do not request access to my storage (and thus I cannot grant it access to my storage.) A picture is worth a thousand words:

KeePass DX Version 2.5.0.0beta25:

Screenshot_20200328-083626

Any KeePass DX above version 2.5.0.0beta25 (see how the permissions are ghosted out and thus I cannot grant it access to my storage.):

Screenshot_20200328-083807

This screenshot above was taken of a different app (because I didn't want to have to uninstall the working KeePass Version 2.5.0.0beta25 just so I could install the not working newer version for the sake of a screenshot πŸ˜’.) This is what the permission box looked like for the later versions of KeePass though.

So I'm thinking it needs to ask (in AndroidManifest.xml) for storage permission... otherwise I cannot grant it that permission. I believe even if I tried to use a root shell to grant it storage permission (pm grant) that it probably wouldn't take because it'll likely tell me that to grant the permission the app has to request it in its manifest file πŸ€”. But I didn't try this because it was easiest to revert to the older working KeePass version for me.

Anyways, this issue is long and I didn't really read it all... I think basically you took storage permission out to make KeePass compatible with later versions of iOS Android 10+ πŸ€”. Which unfortunately broke it for me (I'm on a Samsung Galaxy S5 running Lineage based custom ROM that's Android 7.1.2 based.)

For what it's worth F-Droid's latest KeePass (v28) works fine without storage permission on my OnePlus running Custom ROM of Android 9 πŸ€”. So thank you for maintaining this great app for the future; I'm cool with v25 on my old phone here anyways. I just wanted to let you know I experienced this issue as well.

To that note, I noticed the newer working KeePass on my OnePlus will only let me use one (out of the 4 or 5) of my file managers on that phone... The one file manager that works is called "Material Files" (it's on F-Droid too.) That newer KeePass that is working on my OnePlus (Android 9) has a ghosted out permissions box as well, but it'll work (though only with "Material Files".)

To OP @alexanderadam: try getting and using Material Files (file manager.) It's here: https://f-droid.org/packages/me.zhanghai.android.files/

alexanderadam commented 4 years ago

To OP @alexanderadam: try getting and using Material Files (file manager.) It's here: f-droid.org/packages/me.zhanghai.android.files

As mentioned earlier I already have a few file managers from F-Droid installed. I just don't know how I can change which one KeePassDX is using, because I don't even have a file manager option in the "Default Apps" settings (only Assist, Browser, Home, Phone and SMS app).

@J-Jamet I just reread your comment from November:

In previous versions of the app, the problem was also present but less noticeable if the database was created with the app. Before, the code included a big deprecated file creation library (which does the job of a file manager) but only for creation. The application knew the direct link of the file created (file: // ..) the first time. If the file is reopen later, the problem was present.

This cannot be possible because I never used KeePassDX to create a database so far. The bug didn't appear since the middle or end of last year though. So the reason why it worked before can not be that I created it with KeePassDX before. :wink:

setuidroot commented 4 years ago

I also wanted to add: somebody could add the storage permission to the AndroidManifest.xml (is that how it's still done? πŸ˜…) and keep a "legacy" version of this app for older Android versions πŸ€”.

Of course this is open source and anybody is free to build it with whatever added permissions they want. I'm just suggesting that if somebody does build it with the old storage permissions, they could post a binary or maybe add a note to the readme. I'm not sure how many people will have this issue... I suppose it's really an issue for the file manager apps. I'm not a fan of the over-the-top "security" (Google Lockdown of Android... the Applefication of Android: it'll kill what made Android better than iOS IMHO.) But it is what it is.

setuidroot commented 4 years ago

To OP @alexanderadam: try getting and using Material Files (file manager.) It's here: f-droid.org/packages/me.zhanghai.android.files

As mentioned earlier I already have a few file managers from F-Droid installed. I just don't know how I can change which one KeePassDX is using, because I don't even have a file manager option in the "Default Apps" settings (only Assist, Browser, Home, Phone and SMS app).

On my OnePlus phone I have 5 (or so) file managers installed. When I open the latest F-Droid KeePass (v28) and click to open database, Material Files is the only file manager KeePass gives me the option of using (probably because it sees it's the only one that'll work.) Usually an app would let me pick from my 5 different file managers, but the latest KeePass only lets me use Material Files. I don't have Material Files on my Samsung phone so I cannot say for sure that it'll work; but I highly recommend giving it a try. You might have many file managers, but they aren't compatible with the new file calling crap URI stuff.

Because the newer versions lack the storage permission, the file manager must use the right command to tell KeePass what .kdbx file to use (is how I understand this issue anyways.)

I'm not shilling for Material Files manager (it actually just came with my custom ROM or with NanoDroid Magisk module; I usually use zArchiver, but it doesn't work for the newer KeePass app versions.)

Edit: It doesn't matter what you have set for default by the way... if you have multiple compatible file managers then KeePass will ask which one you want to use.

J-Jamet commented 4 years ago

I had already tested the permissions, and sent APKs to users to test and it hadn't changed anything. I can remake a package with permissions to add manually if you want.

setuidroot commented 4 years ago

I just tested the latest KeePass release (here from github) with Material Files (from F-Droid) on my Samsung S5... I clicked "open database" in KeePass and it instantly opened Material Files (despite me having four other file managers.) I selected my kdbx file from it and KeePass worked just fine (without storage permission.)

So Material Files should fix this issue for you @alexanderadam ... it did for me anyways.

setuidroot commented 4 years ago

I had already tested the permissions, and sent APKs to users to test and it hadn't changed anything. I can remake a package with permissions to add manually if you want.

If you build the newer version with the ability to add the storage permission (like the older version has) I will test it out. I'm pretty sure that is the issue preventing newer KeePass versions from working with any old file manager app.

You don't have to build the app just for me though, but I'm happy to test it if you do. I'd build stuff myself, but I don't have a computer (just my two phones and Termux lol.)

J-Jamet commented 4 years ago

KeePassDX_2.5beta30_Test_Permission_2020_03_28_16_00.zip

Just for you (and for testers). I'm not as sure as you, I think it comes from the Android SDK used, which in any case will have to be updated regularly.

By the way, my goal is also to keep compatibility with older versions of Android.

J-Jamet commented 4 years ago

As mentioned earlier I already have a few file managers from F-Droid installed. I just don't know how I can change which one KeePassDX is using, because I don't even have a file manager option in the "Default Apps" settings (only Assist, Browser, Home, Phone and SMS app).

A URI is linked to the application that generated it, this is logical since it is the file manager that creates the links with its content-provider. So there can be several applications used, it's not a problem. For the recognition of the applications to open, it is simply by calling an Intent with ACTION_OPEN_DOCUMENT, it is the basic method to open a document, but the manager must be able to manage it. (And no permission needed for that)

Read and write permissions are only useful when using the file management API, which is not useful here.

setuidroot commented 4 years ago

KeePassDX_2.5beta30_Test_Permission_2020_03_28_16_00.zip

Just for you (and for testers). I'm not as sure as you, I think it comes from the Android SDK used, which in any case will have to be updated regularly.

By the way, my goal is also to keep compatibility with older versions of Android.

Okay, so this works 100% for me. I had to uninstall Material Files (because KeePass kept bringing it up instead of letting me pick zArchiver.) Once I uninstalled Material Files (and added the storage permission in settings) then I was able to open my kdbx file with my normal file manager just like before.

J-Jamet commented 4 years ago

OK, it's really weird. What is your file manager? I have to test too. There may be a legacy of permissions.

alexanderadam commented 4 years ago

The bug is still present for me in 2.5beta30. I gave storage permissions but it didn't change anything.

@setuidroot did you do exactly the same steps as mentioned in the first comment?

setuidroot commented 4 years ago

OK, it's really weird. What is your file manager? I have to test too. There may be a legacy of permissions.

I use zArchiver (ru.zdevs.zarchiver.) Sadly it's not open source... I get it from Aurora Store (pulled from Google play; but my phones are all de-googled πŸ˜€.)

When I don't have Material Files installed, KeePass lets me select a file manager... but when Material Files is installed, KeePass picks it (Material Files app) automatically and it works with KeePass without the storage permission.

My guess is KeePass needs the storage permission for certain file managers (that don't support the URI thing) because KeePass just takes the file path from the file manager and gets the file itself (the file manager just acts as a selection interface to tell KeePass where the kdbx file is located and KeePass grabs the kdbx file itself: which is why it would need the storage permission.) This is my thinking anyways... I don't really know much of anything 😞.

Here is a screenshot of when I click to open database in KeePass with Material Files not installed:

Screenshot_20200328-104046

J-Jamet commented 4 years ago

The bug is still present for me in 2.5beta30.

With write permission activated?

@setuidroot I understand the behavior of the app in your case, it's because the code plans to use another method (ACTION_GET_CONTENT) of opening a document when the first method (ACTION_OPEN_DOCUMENT) doesn't work (the intent cannot find a compatible app). And some managers then claim permissions with the second method (stackOverflow issue) (in any case it's URIs, it's not the problem ;)).

So what I'm going to do is ask for permissions when the second method should be used (it annoys me a little but it will keep compatibility with poorly designed file managers). Maybe I'll make a button to switch from one method to another.

Also note that you can open files from the file managers themselves.

setuidroot commented 4 years ago

The bug is still present for me in 2.5beta30. I gave storage permissions but it didn't change anything.

@setuidroot did you do exactly the same steps as mentioned in the first comment?

No, I did not do exactly those steps. I came across this bug by updating from v25 to v28 KeePassDX on F-Droid (I don't usually update apps right away in case a patch is later released and F-Droid has a lag time.) I already had my .kdbx file(s) on my phone (which I did make with KeePassDX several years ago) but the updated KeePass app from F-Droid gave the exact same error you got in your first post screenshot when I went and selected my .kdbx file (with zArchiver.) I had also noticed after I updated KeePass that my .kdbx databases were all missing... usually they're saved and I just click on it. Well when I tried to open my kdbx file, I kept getting that same error (until Material Files.) But now with the latest Beta apk (the one in the zip file posted above) I did not have this problem after I went into the app settings and checked the slider to give it access to my storage (I had to check it manually, It won't ask for it I don't think.)

I tried opening several kdbx files and I tried copying them to different locations and different file names... nothing worked, I had that same error until this latest beta allowed me to give KeePass access to my storage, now it works flawlessly and it even saved my databases like before.

Uploading your kdbx file to pcloud/mega/whatever shouldn't make any difference... I took my kdbx file, encrypted it twice (with zip and 7z AES-256) uploaded it to uploadfiles.io just so I could get it on my OnePlus phone... it worked fine.

I'm surprised you still have this issue even with the latest beta... you downloaded and unzipped the one above? Did you uninstall your other KeePass (I actually have F-Droid KeePass and github KeePass installed side-by-side it doesn't matter so long as they're signed with a different key.)

Have you tried installing Material Files? It needs storage permission as well, but then it works for me with either KeePass version. Maybe your kdbx file got corrupted... but I highly doubt it. KeePass would probably be able to tell if it was corrupt just by looking at the file headers πŸ€”.

setuidroot commented 4 years ago

I'm guessing OP has a different issue (but with the same error message) than what I had. I re-read OP post and see it's a new Samsung running Android 10... so it's likely a different issue.

@alexanderadam Does the new KeePass open your kdbx file at all (nevermind the syncing steps above... does it open them at all?) Because if you can open any of your kdbx files then we have different, yet similar issues.

I've read about problems with MIUI and OUI Android ROMs... but I have no experience with them personally.

alexanderadam commented 4 years ago

With write permission activated?

yes.

had to check it manually, It won't ask for it I don't think.

Same for me. It didn't ask in my case as well. I explicitly had to to go to app settings as well.

I tried opening several kdbx files and I tried copying them to different locations and different file names... nothing worked, I had that same error until this latest beta allowed me to give KeePass access to my storage

It looks like a similar appearing but yet different bug for me.

you downloaded and unzipped the one above?

Yes, IMHO there's no other possibility to do this beta. :wink:

Does the new KeePass open your kdbx file at all (nevermind the syncing steps above... does it open them at all?)

Yes, as mentioned in the last sentence of the first comment:

So the only possibility to open that database again is by going over OPEN EXISTING DATABASE again.

It works if I open the file via OPEN EXISTING DATABASE again.

PS: Remember there's also an edit button for GitHub comments. It also allows you to add content to an existing comment, without having the need to add another comment. :wink:

setuidroot commented 4 years ago

I don't know what you mean in the OP by "doing a sync via cloud." Are you saying you only have an issue opening the database after you've copied over it/modified it? πŸ€” That sounds to me like maybe KeePass sees the kdbx's hash changed and it rejects it... have you tried renaming that kdbx file after syncing it and then select the newly named file in KeePass?

I did file (the binary file) check on my kdbx files in Termux and they all return the same version: "Keepass password database 2.x KDBX"

So I honestly don't know about different kdbx versions... I only have phones (no x86 computers) so I'm not really familiar with different versions. If I was (and I understood exactly what you did to get your bug) I would try and reproduce it just to be helpful. I'm thinking we have different issues.

Can you tell what kdbx versions you have? I just use Termux and "file" command... it'll tell you all that good stuff:

Screenshot_20200328-112247

Like in the screenshot above (sorry I don't have any way to crop photos on this phone... I broke my Gallery by messing around with system files 😞.

Edit: yeah sorry for all the comments lol. I'm trying to type these up in a prompt that keeps crashing (2GB of RAM; actually means ~1.7GB and that's not enough when Firefox takes over 600 MB πŸ˜‘. We have different issues... I'm sorry to have crowded up your issue thread. You seem knowledgeable... I didn't mean to come off as condescending with my comments; I just wanted to make sure we were talking about the same stuff is all.

Edit 2: The crashing isn't the issue (I type in notepad and copy/paste) but I'm weary if I just edit a comment that it won't be read because somebody will think they've already read it... like I'm pretty sure you added info in the OP (either that or I didn't read it close enough.)

Anyways I will shutup now πŸ˜€. @J-Jamet I appreciate the fix for my issue and your continued work on this great app! OP I hope you find a solution, but I think I've outlived my usefulness here πŸ€”.

alexanderadam commented 4 years ago

I don't know what you mean in the OP by "doing a sync via cloud." Are you saying you only have an issue opening the database after you've copied over it/modified it?

Yes. Everything else stays exactly the same (i.e. name, file format, path). I just edit/add/remove an entry and sync the file to the Android device.

have you tried renaming that kdbx file after syncing it and then select the newly named file in KeePass?

As described earlier reselecting the file via OPEN EXISTING DATABASE works anyway for me. So renaming and reselecting would still work.

setuidroot commented 4 years ago

As described earlier reselecting the file via OPEN EXISTING DATABASE works anyway for me. So renaming and reselecting would still work.

Sorry, I didn't read this thread so well in my haste to reply that I had the "same" issue.

@J-Jamet Does KeePass DX app here check the kdbx file hashes for modification (anti-tampering mechanism?)

If so, that seems like it could be a cause for OP's issue.

Another possibly (just a thought) it could have to do with Android 10's (8+) forced data encryption. πŸ€”

Do you keep the kdbx file on /sdcard (Internal storage?) It could be SELinux interfering; I've had that issue where I modify a file and then copy it to where I want it: it'll change the SELinux context from "u:object_r:app_data_file:s0:c512,c768" to "u:object_r:app_data_file:s0" and then the intended user (KeePass app user) won't be able to read the file, despite the file being r/w and owned by the correct (KeePass) uid and gid. This only applies to a filesystem that is not /storage/emulated/0 though because all files on the internal storage are of u:object_r:sdcardfs:s0 context.

Sounds like J-Jamet has a fix. My thoughts were unlikely.

J-Jamet commented 4 years ago

@J-Jamet Does KeePass DX app here check the kdbx file hashes for modification (anti-tampering mechanism?)

Yes of course, but the problem here is that the file cannot even be recovered (so before the hashes). This is a problem in the "My Files" file manager that I will solve by checking in the activity if the file is accessible and closing it if it is not.

There is two issues in this thread. I will fix both in the next version properly. (I'm adding dynamic write permissions)

@setuidroot My solution will allow to reselect the file easily but if you have a solution to keep a valid URI provided by "My Files" after a file replacement , it is always a good information.

J-Jamet commented 4 years ago

KeePassDX-2.5beta31_Test_Only_2020_03_28_18_21.zip

contains fixes for your both issues, it's ok for you?

J-Jamet commented 4 years ago

After several tests, it seems that the finish of the password activity causes bugs in the workflow of old devices. So I cannot use this technique to return to the selection screen. I will try to find other ways.

J-Jamet commented 4 years ago

At the moment I'm only posting a message that says the link has been revoked, but that's all I can do without any other technique.

alexanderadam commented 4 years ago

Okay, let me know if you have something else to try out.