Monthly Archives: August 2016

KeePassX – Part 1: Introduction

I have been using KeePass (on windows) and KeePassX (on linux) as my main password manager tool for some years now. It’s simple to use and does the job well. However, there does not seem to be a version for Meego/Harmattan. I would think that porting the tool to N9 would not be too difficult. The source code for KeePassX is available and it is based on version 4.8 of the Qt libraries which are also included in the Nokia QtSDK. Basically we would just need to replace the Qt widget based user interface with a QML based one.

Getting the source code

The source code for KeePassX can be downloaded from the official KeePassX website: https://www.keepassx.org/. I will use the v0.4.4 code base as my starting point because I’m currently using v1 database format on other platforms. The source code is provided as a gzipped tar file (keepassx-0.4.4.tar.gz).

Building the KeePassX with QtCreator

After unzipping and untaring I can open the project in QtCreator.

Keepassx-04

Let’s try to build the tool right away by clicking the build button. Seems there are some issues:

Keepassx-05

The error is related to the SetDllDirectoryA function call in the beginning of the main function:

int main(int argc, char **argv)
{
#ifdef Q_WS_WIN
	// Make sure Windows doesn't load DLLs from the current working directory
	SetDllDirectoryA("");
	SetSearchPathMode(BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE);
#endif

Probably some header file is missing. Because we just want to get the tool compiled to be used as a reference and debugging target I guess I will just ignore those lines for now:

int main(int argc, char **argv)
{
#if 0 //#ifdef Q_WS_WIN
	// Make sure Windows doesn't load DLLs from the current working directory
	SetDllDirectoryA("");
	SetSearchPathMode(BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE);
#endif

New try and voilá! Seems we have successfully build the tool with just 4 warnings:
Keepassx-06

Let’s run the tool by clicking the play button. Seems there are some additonal issues:

Keepassx-07

Some path is probably not set correctly (maybe due to the shadow building method). To find out we can rebuild the debug version (select Build>Clean All & click Start Debugging). After build finishes we get a greeting message from QtCreator:

Keepassx-08

Looks like the tool hasn’t been developed with QtCreator in mind and hence the debug/release selection does not work. To force the debug build we can always edit the src.pro file and add one line:

DEBUG = 1
CONFIG = qt uic resources thread stl warn_on
QT += xml

*-g++ : QMAKE_CXXFLAGS_WARN_ON += -Wno-sign-compare

DEPENDPATH += crypto dialogs export forms import lib translations res
INCLUDEPATH += . lib crypto plugins/interfaces export import dialogs

After this change we can set a break point to the main function and start stepping through the code to see what actually happens. To step one line forward just press F10.
Keepassx-09
It is also useful to see the variable values. Just select Windows>Views>Locals and Expressions.
Keepassx-10
Now when stepping through the code we can see the local variables and their values. Looks like there are also some global variables, e.g. variables called AppDir and DataDir look interesting. Let’s also include those to the variable list. This can be done be right clicking the variable name and selecting: Add to Watch Window.
Keepassx-11
The variables point to the shadow build folder:

  • DataDir = <shadow build folder>/bin/share
  • AppDir = <shadow build folder>/bin

After some intensive F10, F11 (step into) and shift-F11 (step out) clicking I can see that the issue is in the file tools.cpp:

QString getImageFile(const QString& name){
	if (QFile::exists(DataDir+"/icons/"+name))
		return DataDir+"/icons/"+name;
	else{
		QString errMsg = QApplication::translate("Main","File '%1' could not be found.").arg(name);
		showErrMsg(errMsg);
		qFatal("File '%s' could not be found.", CSTR(errMsg));
		return QString();
	}
}

So the program is trying to load the clientic.png file from the /icons folder which does not exist as the DataDir points to the shadow build folder and the icons folder is actually under the source code root folder in the sub-folder share/keepassx/icons. A quick and dirty fix:

QString getImageFile(const QString& name){
    if (QFile::exists(DataDir+"/../../../keepassx-0.4.4/share/keepassx/icons/"+name))
        return DataDir+"/../../../keepassx-0.4.4/share/keepassx/icons/"+name;
	else{
		QString errMsg = QApplication::translate("Main","File '%1' could not be found.").arg(name);
		showErrMsg(errMsg);
		qFatal("File '%s' could not be found.", CSTR(errMsg));
		return QString();
	}
}

After one more try I can successfully get KeePassX running. 🙂
Keepassx-12

So now I can go on and start exploring the existing source code. I can put break points to the code and step through the code to see how it works.