Architecture of PuttyAgent plugin for KeePass (c) 2011 Nikolaus Hammler PuttyAgent: KeePass Plugin. Instantiates plugin, does menu creation, KeePass specific stuff, ... The constructor queries for a window "Pageant". If it does not exist, the member variable CPageantThread starts a new thread by CreateThread() In the destructor, the thread is first tried to be stopped gracefully (StopThread); if it does not work, KillThread In OnMessage, the plugin waits for the events KPM_SAVEDB_POST and KPM_OPENDB_POST. In both cases, UpdateKeys() is called, which queries the database, and copies all keys into the CKeyHandler (singleton). This happens only when workspace is open and the thread is running. The database in CKeyHandler is first cleared, and then refilled. A keys gets added, if it has an attachmed file with ending ".ppk". If it is protected by password, the password field is taken to decrypt the private key. CKeyHandler: singleton database containg the loaded keys Encapsulates the Pageant functionality. The actual keys are stored in member variables of type "tree234" - taken from Pageant. + DeleteKeys(): Delete all keys + AddKey(): Add a key by char*, len and password + ListKeys(): returns keys as CArray + MessageHandler(): called when an agent query is received This class calls original pageant code (found in subfolder putty/) and functions modified to load keys from char*-array, rather than from files in putty_additional.c The class is thread-safe; access to key arrays is protected by CCriticalSection. CPageantThread: Pageant thread This is only an empty UI-thread which created a CPageantWnd which does the main work. The window is created in InitInstance The thread is stopped by StopThread() which sends WM_CLOSE() to the window, which in turn calls PostQuitMessage, exiting the thread CPageantWnd: Window doing the main work Implements a message handler for WM_COPYDATA (OnCopyData). This function first checks if workspace is locked by calling UnlockKeePass() and afterwards - replies to message by calling MessageHandler from CKeyHandler. UnlockKeePass() shows a balloon that a authentication is requested if the workspace is open. If workspace is locked, ShowBalloonAndWaitForAnswer() from CKeePassExtensions is called, which shows a balloon and waits until the user clicks on it (or it times out) - see below. If the result was an unlocking request, UnlockKeepass() is called which shows the unlocking dialog from KeePass; afterwards, the function tries to restore the previously foreground window (e.g. PuTTY). CKeePassExtensions: Encapsulates KeePass calls Instantiated by HWND of KeePass. This class is similar to CWnd: It maintains a list of HWND/instance pairs, (c_mapWindows) because data is needed in instances as well as in a static function. This list is thread-safe by c_mapProtection. + ShowBalloon(): Shows a balloon message + UnlockKeepass(): Sends an unlocking request to KeePass window; before it sets the KeePass window to foreground. + Hook/Unhook(): Subclasses the KeePass window in order to intercept messages. Until now, only messages from the balloon are intercepted + ShowBalloonAndWaitForAnswer: Shows a balloon but waits until user clicks on it, discards it or a timeout occurs. The latter method first subclasses the window, calls ShowBalloo() and waits until an event (CBalloonEvent) is signaled. Then, KeePass is unsubclassed and the functions returns either TRUE if the user actively clicked on the balloon or FALSE otherweise. The window messages are handled by KeePassWinProc. Should be thread-safe. CBalloonEvent: Encapsulates the balloon event This class encapsulates a CEvent which is signaled in the KeePass WndProc when user reacts on balloon. Additionally it includes a flag whether the user clicked or dimissed the ballon which is protected by a CCriticalSection. CInfoDlg: Standarddialog (Info) putty_additional.c: PuTTYs sources only allow to load keys from files. These function are derivates which allow to load keys from char arrays. CPuttyAgentApp: Dummy class to satisfy MFC framework CViewKeysDlg: Standard dialog for displaying the list of active keys Utils: helper class