Password Safe v3.57 64-bit does not load config file correctly from UNC path. (It worked OK in v3.55)
Can be reproduced on all of :
Create a portable instance (using v3.55 first, to prove it works), thus:
On a new machine, extract all the Password Safe v3.55 files into a new directory (call it the "portable directory")
In that directory run
pwsafe -u mitch -h portable -g pwsafe.cfg
at the prompt, click "yes" to create the .cfg file, then create a new database pwsafe.psafe3 in the portable directory.
Change the configuration so that it is easily distinguished from the defaults. I used
Note that the PWS_PREFSDIR environment variable is not set.
To make it easy to run from anywhere, add portable.cmd to the portable directory, containing this line:
start "(title)" "%~dp0pwsafe.exe" "%~dp0pwsafe.psafe3" -u mitch -h portable -g pwsafe.cfg
"(title)" is a placeholder, required because I need quotes around the .exe to allow for spaces in the directory name, but "start" assumes that the first thing in quotes is a title. "%~dp0" is the directory containing portable.cmd
Put this portable directory onto a shared network location, with write access.
Now I can run portable.cmd from anywhere, including without it being the current directory, which is useful when I don't want to map the network directory to a drive letter. It works perfectly at v3.55.
But when I update to v3.57 it does not work properly if run from a network, eg
\\VBOXSVR\Temp\password-safe-portable-357\portable.cmd
it ignores pwsafe.cfg in the portable directory and uses the default configuration, creating and using %localappdata%\PasswordSafe\pwsafe.cfg
This is the case even when I run portable.cmd from a shortcut that specifies the "start in" directory as the portable directory, or if I specify that directory as the start directory in the command script:
start "(title)" /d "%~dp0" "%~dp0pwsafe.exe" "%~dp0pwsafe.psafe3" -u mitch -h portable -g pwsafe.cfg
I thought perhaps the default directory for "-g pwsafe.cfg" had changed, so I updated my cmd script to specify it:
start "(title)" "%~dp0pwsafe.exe" "%~dp0pwsafe.psafe3" -u mitch -h portable -g "%~dp0pwsafe.cfg"
but this does not make any difference to the behaviour.
If I specify PWS_PREFSDIR in the script, it does work:
set PWS_PREFSDIR=%~dp0
start "(title)" "%~dp0pwsafe.exe" "%~dp0pwsafe.psafe3" -u mitch -h portable -g pwsafe.cfg
Also - presumably related - with the original script (and no PWS_PREFSDIR), if I put the portable directory into a local drive or map a drive letter for the network drive, then run it from a different location, it creates %localappdata%\PasswordSafe\ but does not use it. (Whereas v3.55 did not, in these scenarios.) Eg from a command prompt in C:\
c:\password-safe-portable-357\portable.cmd
z:\password-safe-portable-357\portable.cmd
I couldn't reproduce this problem using the Visual Studio debugger.
The relevant code hasn't changed since 2017, though, so perhaps the problem is in the Windows environment?
Can you (or anyone else) reproduce the problem with the standalone release build?
v3.56 includes bug fix SF1542 "UNC paths now accepted as backup directory", which might possibly be related.
That being said, I just tested 3.56 and it appears to work OK. My problem only appears in 3.57.
I can reproduce the problem, in a variety of different environments. In the case of the original 3 scenarios, the two Win7 machines were both home machines created and configured by me, so could possibly have the same oddity that caused the problem, but the Win10 machines were created and configured by someone else, in a corporate network environment.
Adding to the list of other environments in which I can reproduce the problem:
In all cases, v3.55 and 3.56 work as expected, 3.57 fails, with no changes to the environment, only to the pwsafe binaries.
I'm happy to do some more testing to try to track down the problem, so let me know if there's something specific I can check.
I tried specifying a UNC path for a file to encrypt, and that works OK:
However it looks like the UNC path to config file does not work correctly in earlier versions for all scenarios. Eg 3.55
creates and uses C:\temp\password-safe-portable-355\pwsafe.cfg (which did not exist beforehand, for this test) instead of \\VBOXSVR\Temp\config-only\pwsafe.cfg (which did exist)
3.56 behaves the same. However in the same scenario 3.57 creates and uses %localappdata%\PasswordSafe\pwsafe.cfg (which did not previously exist) instead of \\VBOXSVR\Temp\config-only\pwsafe.cfg (which did exist)
If I specify the UNC directory in PWS_PREFSDIR I get the same results in 3.55:
creates and uses C:\temp\password-safe-portable-355\pwsafe.cfg (which did not exist beforehand, for this test) instead of \\VBOXSVR\Temp\config-only\pwsafe.cfg (which did exist)
3.56 behaves the same.
However in this scenario, 3.57 works correctly, using \\VBOXSVR\Temp\config-only\pwsafe.cfg
If I specify the directory in PWS_PREFSDIR but do not specify the config file name at all it works correctly for all of 3.55, 3.56, 3.57, eg
correctly uses \\VBOXSVR\Temp\config-only\pwsafe.cfg for all three versions.
In case it matters, in all tests in today's post I was running from a command line z:\pwsafe, where z:\ is a network drive that does not contain any of the password safe files (binary or config)
All of today's tests are on a Windows 7 SP1 64-bit VirtualBox VM, running on a Windows 7 SP1 64-bit host, and \\VBOXSVR is created by VirtualBox "shared folders".
I just downloaded the source code for v3.56 and 3.57 and compared them. PWSprefs::FindConfigFile() has changed, in particular from:
to
This is probably (part of?) the problem.
Note that IsWindows && sDrive.empty might be assuming that Windows paths always have drive letters - but UNC paths do not have drive letters.
It's possible that the Help file needs updating regarding
Password Safe Preferences, in particular the location of pwsafe.cfg.
Is the statement "By default, pwsafe.cfg is kept in the same directory as the pwsafe.exe
executable program" necessarily true now? I suspect that (even if the directory is writeable) the software will read the file from the exe directory only if it already exists, but if it does not already exist it is created in %localappdata%\PasswordSafe by default.
Also in pwsafe-3.57.0-src\src\core\PWSprefs.cpp I see
However that does not look right. Should it be
sDrive.empty && sDir.emptyand a comment of "if filename only...", rather than "filename is relative"?
The code as it stands (on a Windows machine) will not use sDrive if sDir is empty, and not use sDir if sDrive is empty. Eg given either "test\pwsafe.cfg" or "d:pwsafe.cfg" (or in my case, "\\server\share\path\pwsafe.cfg") the code will apparently use sCnfDir\pwsafe.cfg
Note that the help file says, for -g config_file "If just a filename is given, without a path, ..." If a relative path were given, I would expect it to be relative to the current directory (as per normal conventions) not the preferences directory, unless you explicitly stated otherwise in the help file.
Right. The confusion arose in part because in the distant past PasswordSafe stored the config file in the same directory as the executable file.
Fixed the code by cleaning it up - the relative path was already made absolute for Windows, so the entire if statement was wrong. Also updated the help file - thanks for pointing it out.
Commit c99b3a494 - will be in next release.
OK thanks
Remember to search the entire help file for references to pwsafe.cfg and updated them if necessary - I just noticed one in the Filter section: "... autoload_filters.xml in the same
directory as the pwsafe.cfg file (by default the directory where Password
Safe is installed)"
Right. The confusion arose in part because in the distant past PasswordSafe stored the config file in the same directory as the executable file.
Fixed the code by cleaning it up - the relative path was already made absolute for Windows, so the entire if statement was wrong. Also updated the help file - thanks for pointing it out.
Commit c99b3a494 - will be in next release.