Menu ▾ ▴

#2321 Keepass 2 linux client unable to save/sync properly via gio/gvfs mounts

KeePass_2.x
closed
nobody
None
5
2024-05-09
2024-04-24
ghjebus
No

KeePass2 Linux client does properly save or synchronize database files mounted via gio/gfvs. When attempting to save a database that's mounted via gvfs a .kdbx.tmp file will be created that is valid, however the associated .kdbx file is 0 size. When attempting to synchronize with a database via gvfs no .kdbx.tmp file is created and the existing .kdbx file becomes 0 size.

If, however, the same share is mounted via "mount -t cifs" with the same uid and gid as the user who mounted via gio everything works as expected.

Windows does not have this issue when synchronizing or saving to the same SMB shared database.

2 Attachments

Discussion

  • Paul

    Paul - 2024-04-25

    KeePass is using "file transactions" to write the database (write temp, delete orig, rename temp) but the delete step fails for some reason. It may be permission related or a bug in gvfs.
    Try Tools > Options > Advanced, File Input/Output Connections, Use file transaction for writing databases.

    cheers, Paul

    p.s. what version of KeePass?

     
  • Dominik Reichl

    Dominik Reichl - 2024-04-25
    • status: open --> closed
     
  • Dominik Reichl

    Dominik Reichl - 2024-04-25

    The error message mentions "Operation not supported". Most likely one of the operations involved in the file transaction (deletion, rename, ...) failed (KeePass cannot predict this).

    In such a case, disable file transactions, like Paul mentioned (and of course make backups regularly).

    Best regards,
    Dominik

     
  • ghjebus

    ghjebus - 2024-04-25

    I'm using KeePass 2.47, the latest available via the default linux mint's package manager.

    Disabling file transactions make no difference when attempting to synchronize the database via a gvfs mount. It does resolve the saving to a gvfs location however.

    When mounting with the elevated mount -t cifs //smb_location /local_location -o creds,uid=user,gid=user everything works, but when using 'gio mount smb://workgroup;user@location' saving does not. This is the same user, uid, and gid as specified with mount. I can also drop into a shell as the same user and manually mv the .tmp over the .kdbx file. So there shouldn't be any user/group permission issues with the share. The issue seems to be with keepass, and I'd really prefer not to have to mount the share with elevated permissions.

    The only difference between the gvfs and "traditional" mount I can find are the local permissions. 700 for gvfs and 755 for mount. Though that shouldn't cause a problem here as the uid running KeePass is the owner of the smb mount.

    Can this bug please be reopened for investigation?

    Thanks.

     
  • Paul

    Paul - 2024-04-25

    KeePass does nothing different when using different mount types - all saves to drives are the same - so it's unlikely to be KeePass at fault. This is shown as the save works without transactions.

    What happens when you perform a sync with transactions off?
    Do you still get a TMP file and zero byte database?

    cheers, Paul

     
  • Dominik Reichl

    Dominik Reichl - 2024-04-25

    When file transactions are disabled, KeePass simply writes directly to the file. If this fails, the problem lies outside of KeePass.

    If you still see a '.tmp' file, file transactions are not disabled.

    You could try the latest KeePass version (2.56), but I don't think this will change anything in this case here.

    Best regards,
    Dominik

     
  • ghjebus

    ghjebus - 2024-04-25

    Hi Paul,

    Yes, the same behavior with synchronizing. No .tmp file, and a 0 sized .kdbx file.

    Perhaps it's something with how fuse operates where it's not supporting the specific file ops KeePass is using? It shouldn't be related to the user 'sandboxing' as the user launching keepass and mounting the share is the owner of said share. If that is the case, I can try to find a workaround. I guess I was hopeful it's something that could be addressed on the application side.

     
  • ghjebus

    ghjebus - 2024-04-25

    Interestingly enough, it appears if I add an 'Export active database' action to the 'Saved database file' event I can save and overwrite a .kdbx file at the same network location/mount with no errors (even with transactions enabled).

    I'm guessing 'Export active database' operates differently than traditional saving/saving a copy?

     

    Last edit: ghjebus 2024-04-25
  • Dominik Reichl

    Dominik Reichl - 2024-04-25

    It would be interesting which operation fails exactly. If you run the following development snapshot (with mono KeePass.exe), you should see a more detailed error message:
    https://keepass.info/filepool/KeePass_240425.zip

    Best regards,
    Dominik

     
  • ghjebus

    ghjebus - 2024-04-25

    Just ran that executable and both synchronization and saving to a gvfs location still fails. I'm attaching the errors reported.
    One difference though is that when synchronization fails the .kdbx file on the smb share is not 0 size. It remains unchanged. The save behavior is the same as reported, 0 size .kdbx with a .tmp file that can be renamed to a valid .kdbx file. And saving a copy to the location with a different file name still works.

    The trigger still works to export a copy on save as well.

    Let me know if there's any other information I can provide that might help!

     

    Last edit: ghjebus 2024-04-25
  • Dominik Reichl

    Dominik Reichl - 2024-04-25

    These are different errors now; I've extended only the error message containing "Synchronization failed"... I'll try to also extend the new ones and will post a development snapshot here (might take a few days).

    Thanks and best regards,
    Dominik

     
  • ghjebus

    ghjebus - 2024-04-25

    All good, thanks for looking in to this!

     
  • Dominik Reichl

    Dominik Reichl - 2024-04-28

    Here's a new development snapshot:
    https://keepass.info/filepool/KeePass_240428.zip

    If you run it as follows, you should see a more detailed error message:
    mono KeePass.exe -debug

    Thanks and best regards,
    Dominik

     
  • ghjebus

    ghjebus - 2024-04-28

    Thanks for the quick turnaround! I'm attaching the results of the operations (sync and save-over-existing kdbx) on gvfs mounts. Sync does not end up changing the gvfs mounted version, and attempting to save over an existing file has the same reult with 0 file .kdbx and .kdbx.tmp file that can be renamed to a proper keepass database. Though that's probably expected if the only changes are for the error messages =)

    If you need me to test anything else or gather more data, please let me know!

     
  • Dominik Reichl

    Dominik Reichl - 2024-04-29

    On '240428_SaveOverwrite_error.png': here, file transactions are enabled and renaming the temporary file to the database file fails. Like I wrote previously, KeePass cannot predict this and my recommendation is to disable file transactions in this case (if you have unpacked the development snapshot to a new folder, it runs as portable version, i.e. it saves/loads configuration settings to/from the new folder and thus you need to disable file transactions again). If GVfs would add support for moving/renaming files, this would of course be better.

    On '240428_Synchronize_error.png': for synchronizing database files, KeePass must first read the ones from disk that are not in the process memory already. This is what fails in this case; KeePass cannot read the database file from '/home/run/...'. The exception is of type 'DirectoryNotFoundException'. Are you sure that the path is correct (and that the file exists)? If so, it might be that Mono has problems with the path; maybe Mono is confused by the ':' (which is often used as path separator on Linux). Maybe try adding a backslash before the ':'.

    Thanks and best regards,
    Dominik

     
  • ghjebus

    ghjebus - 2024-04-29

    Hi Dominik,

    Oops, that's my fault. I didn't realize I had to disable file transactions again!

    gvfs does support rename, I tested this with success (see attached). Do you know if, when transactions are disabled, a temp file is still created and renamed on save? Rename is atomic so it should be pretty much as safe as file transactions in this case.

    As for the synchronizing, that is the correct path and the database does exist. KeePass is able to open the .kdbx file via File -> Open -> Open File and browsing to that location. Is the synchronize logic acting in a different fashion than the file browsing logic?

    I've also tried symlinking that mount point to another location without a ':' which fails to synchronize as well. Though, under the hood, something in mono/KeePass has to evaluate the path with a ':' in it (probably Mono).

    Unfortunately that path is autogenerated via the 'gio mount' command so it isn't changeable without using the elevated 'mount' command or adding a mount point via fstab which is what I'm hoping to avoid, to keep the mount point and database in 'user space' for credential management.

    I'm assuming the problem is Mono complaining about the ':' in the path, since that's one of the forbidden characters in windows filepaths. And, without knowing the complexity of the KeePass source, is it possible to escape those verboten characters as a test?

    I realize that's kind of a weird thing to ask considering KeePass is a windows exe and ':' is purely a problem for the non-default target =)

    Thanks for all the help in trying to get to the bottom of this!

    John

     
  • ghjebus

    ghjebus - 2024-04-30

    Forgot to upload the sync failure on the symlink directory without a ":" in it. While it still fails, it does emit a different error than attempting to synchronize to the 'long form' directory. The result of the sync operation is a 0 size destination file.

     

    Last edit: ghjebus 2024-04-30
  • Dominik Reichl

    Dominik Reichl - 2024-05-01

    When the file transactions option is deactivated, KeePass writes directly to the target file, without creating any temporary file and without renaming any file.

    The 'File' → 'Open' → 'Open File' command and the synchronization feature are opening files in the same way (both use the IOConnection.OpenRead method for obtaining a Stream object). I don't see how one could succeed but not the other one, except if the paths are different.

    Mono didn't explicitly complain about the ':' character in the path; this was just my guess what might be the reason. I've just experimented a bit on a Linux system; loading, saving and synchronizing database files whose path contains ':', '=' and ',' characters (regular directory, not GVfs) works perfectly fine. So, these characters actually are no problem (at least in this specific case and on the system where I tested it).

    On 'Sync_on_symlink.png': after the synchronization feature has merged two (or more) databases in the process memory, it first writes the resulting database to a file and then copies this file to the other locations. In your screenshot, we see that copying the first file to the second file fails. I've just tested this with a regular file as source and a symlink as target (both in a regular directory, not GVfs); it worked fine.

    As everything seems to work without GVfs, the problem probably is in Mono (or GVfs). As you can program, maybe you could write a minimal application for reproducing the problems (e.g. File.Copy where the target is in GVfs) and create an item in Mono's issues tracker?

    Thanks and best regards,
    Dominik

     
  • ghjebus

    ghjebus - 2024-05-01

    Looks like I'll have to find a workaround for this as it definitely seems to be an issue with Mono, gvfs/fuse, or the combination of the two. I sincerely appreciate all the help with trying to track this down!

    I should be able to get creative with fstab mounting only the KeePass dir and since those databases are owned by a specific user and password protected it should be safe enough. And that should allow transactions again.

    I might try to figure out how to compile C#/mono apps in linux or track down a windows machine to install dev tools on and check it out. Though for the mean time, I'll move forward with creative/alternative methods of mounting the network share holding the database.

    Thank you, again, for all your help with this one!

     
  • Dominik Reichl

    Dominik Reichl - 2024-05-04

    To make sure that there are no side conditions, I've now written a small test application; you can find it attached. When running 'Test.sh', it compiles a small C# application (Mono's 'mcs' compiler is required), mounts an FTP server using 'gio', copies a file using 'cp' (to ensure that the connection works), tries to copy the file using Mono, and copies the file using 'cp' again (to ensure that the connection still works). Mono throws the exception that we've seen before. I've tested it on Ubuntu 24.04 (Mono 6.8.0.105) and Fedora 40 (6.12.0.199).

    As the exception message is 'Operation not supported', I'm not sure whether this is something that the Mono developers want to implement. You could report it to the Mono developers [1], if you wish (feel free to use/modify the small test application).

    In any case, I'm glad that the issue is clearer now. Many thanks for your help!

    Best regards,
    Dominik

    [1] https://github.com/mono/mono/issues/

     
  • ghjebus

    ghjebus - 2024-05-09

    Thanks for putting that test case together! I can confirm that just running the CopyFile.exe fails when trying to copy to the gvfs mount but not to a direct smb mount or local file system. Even if the destination path contains a comma or colon.

    I'll throw a bug over in mono's court.

    Thanks for all the help!

    Edit: There was an eerily similar bug already in the mono github, so I added details from this test case to it. (https://github.com/dotnet/runtime/issues/96503).

     

    Last edit: ghjebus 2024-05-09

Log in to post a comment.