Menu

#2192 A way to relocate KeePass.config.xml (through Symbolic-Link?)

KeePass_2.x
closed
nobody
None
5
2016-11-01
2016-10-20
Thomas
No

To make updating KeePass portable versions easier I want to separate application files from user files (e.g. database, plugins dir, language, config). The database location is no problem, for the plugins directory I created a Symbolic-Link and for the language file I changed the path in KeePass.config.xml. So far all is good.

But when it comes to changing the location of the config file I'm out of options: it can't be supplied by commandline and a Symbolic-Link for KeePass.config.xml gets loaded on start, but gets deleted as soon as a config item is changed.

It would be great if KeePass writes the KeePass.config.xml to the location the Symbolic-Link points to.

Discussion

  • Paul

    Paul - 2016-10-20

    Have you tried the -cfg-local: command line parameter?
    http://keepass.info/help/base/cmdline.html

    cheers, Paul

     
  • Thomas

    Thomas - 2016-10-21

    Hi Paul,

    thanks for your response. I totally missed that parameter (shame), so I gave it a try. I started KeePass like this:
    KeePass.exe -cfg-local:C:\Users\someuser\Documents\KeePass.config.xml and
    KeePass.exe -cfg-local:..\KeePass.config.xml

    Configuration is loaded fine, but:

    1. KeePass.config.xml will be written in (or copied to) the application folder as soon as the program gets closed, so it doesn't get saved to the location specified in -cfg-local.
    2. The solution through command-line doesn't seem to be practical either: KeePass is often launched in ways where I can't specify a parameter (double clicking a .kdbx file or launched by the KeeFox Firefox extension). Now I can change the way .kdbx files get opened through regedit, but it will be more and more hackish...a proper solution is preferred.

    I think there are two ways to solve this:

    1. Follow symbolic links when writing/saving the config files.
    2. If the -cfg-local parameter is supplied, use that path not only for read, but also for write/save actions.

    Let me know if I'm missing something.

    Kind regards,

    Thomas

     

    Last edit: Thomas 2016-10-21
  • Paul

    Paul - 2016-10-21
    1. This is because you have not set the PreferUserConfiguration flag inb the XML. See the bottom of the Configuration help page. http://keepass.info/help/base/configuration.html
    2. If you use only the global configuration file - the one with KeePass.exe - and set the PreferUserConfiguration flag you will avoid creating a user config file, assuming the global file is writable.

    cheers, Paul

     
  • Thomas

    Thomas - 2016-10-22

    Ok, thanks for the suggestions. I started testing on a portable KeePass setup (which doesn't have a global config file yet).

    Using -cfg-local combined with PreferUserConfiguration = true in my local config, KeePass will:

    1. load the right local config
    2. upon change in options => create a full copy of the local config and save it as global config in the application folder.
    3. upon subsequent changes in options or when application closes => change PreferUserConfiguration of local config to false (doesn't seem to matter though) and save changes to the proper (local) config.

    As soon as you start KeePass without -cfg-local, the global config is used. Which is by then a copy of the local user config, possibly containing private and/or plugin settings. To prevent this behaviour (and confusion about which config is loaded), I replaced the global config file by one containing only the PreferUserConfiguration = true setting. Changes in preferences will now be written to a third location: %AppData%\KeePass\ since no other local config location is provided.

    After all this tinkering my issue still stands:
    I cannot guarantee that KeePass is always started with the -cfg-local parameter. For example when opening KeePass from the file explorer by double-clicking .kdbx files or by starting Keepass from KeeFox in Firefox. It really seems more appropriate for KeePass to just follow basic file operations instead of a harsh delete/recreate:

    • open file (doesn't matter if it's a symbolic link or not, the OS redirects you to the right file).
    • use this handle to programmatically write new content to the file.

    Looking into the source code I think this could be a fix (hopefully not missing any implications):
    // IOConnection.cs - public DeleteFile(), line 692:
    Consider not calling this from FileTransactionEx.cs line 110, or dropping it altogether (don't know if deletefile is used elsewhere):
    if(ioc.IsLocalFile()) { File.Delete(ioc.Path); return; }

    // IOConnection.cs - private OpenWriteLocal(), line 640:
    Consider dropping:
    return new FileStream(ioc.Path, FileMode.Create, FileAccess.Write, FileShare.None);
    In favor of:
    return new FileStream(ioc.Path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);

    If you want to take a harder route that involves detecting if a file is a symolic link, you can use this to detect it:

    private bool IsSymbolic(string path)
    {
        FileInfo pathInfo = new FileInfo(path);
        return pathInfo.Attributes.HasFlag(FileAttributes.ReparsePoint);
    }
    

    Kind regards,

    Thomas

     

    Last edit: Thomas 2016-10-22
  • Dominik Reichl

    Dominik Reichl - 2016-11-01
    • status: open --> closed
     
  • Dominik Reichl

    Dominik Reichl - 2016-11-01

    I've added support for this now. File transactions now are not used anymore for files that have a reparse point (e.g. symbolic links).

    Here's the latest development snapshot for testing:
    http://keepass.info/filepool/KeePass_161101c.zip

    Thanks and best regards,
    Dominik

     

Log in to post a comment.

MongoDB Logo MongoDB