Re: [Passwordsafe-devel] PasswordSafe merge functionality
Popular easy-to-use and secure password manager
Brought to you by:
ronys
From: Wolfgang K. <91...@gm...> - 2004-11-05 16:09:56
|
> > >Since this has been added, this is probably a good >time to start a discussion on merge functionality. > > > Probably a good open-source logic! ;) Both cases 1 and 2 are convincing in my eyes. (In case 1 the socalled "default" scheme should in any case be made explicit.) Please always keep in mind that you have to explain all this to the (always stupid) user! So if even experts have a hard time following your methods, you are going to have a hard time with regular users. I would suggest to stay with as few visible "solutions" as possible. Perhaps for some problems some users can be expected to use their hands to post-edit merged files. Some other problems might be detected automatically (e.g. when V1 files come into play). Other possibility: you create some "10 questions to guide me through the merge function" wizard and let the program set various settings. If that is really desirable? Regards, - Wolfgang Victor Myne wrote: >Since this has been added, this is probably a good >time to start a discussion on merge functionality. > >As I see it there's more than one kind of merge >functionality required, because there's more than one >"use-case" for merging. I see at least the following >cases and types of merge: > >1. Merging two branches of one safe >Case: I have a safe, and I made copies on home (A) and >work (B) machines. Now I need to get them back in sync >because they may have been independently modified. >Proposed Solution: Both safes started from the same >set and so we should compare based on GUID's. Where a >GUID exists in one but not the otherm simply add. >Where it exists in both, compare and if different, >offer the usual merge options, namely use A, use B, >split into two entries, skip/ignore (default will be >use newer assuming timestamps are implemented). This >allows me to correctly merge entries even where the >title/group has changed as GUID will not have changed. > >2. Merging two potentially overlapping (non-branch) >safes >Case: Since there was no merge feature yet I did >things manually. I created a safe at home (A) and at >work (B) and tried to keep them sync-ed by making >entries in both, but I wasn't perfect at that. Now I >want to combine them both. >Proposed Solution: If I created the same entry in both >manually, they will exist with different GUID's but I >want them treated as the same entry during merging. >Therefore GUID's should be ignored and the check >should be based on the same uniqueness criteria >currently used, i.e. group+title+username. Thus the >same entry in both A and B will be identified as such >even if GUID's differ. Merging options will be as in >case 1. > >These are the absolute basic ones that we need, as I >see it. Additional ones could be possible but less >required may be: > >3. Same as #2 but ignore group in the comparison. This >will also help with any pre-V2 safes out there that >people want to merge with more updated safes. This >will also help handle merging after any major re-org >has been done with items moving around groups etc. > >Note that either #2 and #3 will also come into play >when importing. I may have a safe from another app >that I want to import into a safe I created when I >started using pwsafe. Therefore either of case 2 or >case 3 will apply, depending whether the other app had >groups or not. > >These are just the initial cases that strike me. I >would love to hear more from everyone on whether they >agree/disagree and especially if they see a flaw in my >logic that combines the various cases into a single >merging logic. > >- Vic > > > --- Justin Forrester ><for...@us...> wrote: > > >>Hi, >> >>I've created a simple db merge option for Password >>Safe. It allows you to >>merge another pws database into your currently open >>database. I'm not sure >>how code submissions are handled for PWS, but I've >>included a description >>and a patch of my changes below. >> >>-j >> >> >> >> >> >>Code changes: >> >>DBoxMain - added code to handle merging. Open >>another core & process >>entries. If entry is missing, add it. If entry >>differs, add it with a >>"-merged-datestamp" suffix for the user to figure >>out. This could be >>enhanced with more sophisticated merge logic, but a >>simple merge is better >>than no merge capability at all :) >> >>PasswordSafe.rc/resource.h - add Merge Database menu >>option in the File menu >> >>PWScore - current session key initialization >>prevents creation of more than >>one core. Made the session key static and added a >>static flag indicating >>whether it was initialized or not. >> >> >>Patch: >> >>--- pwsafe.test/corelib/PWScore.cpp Wed Sep 15 >>01:20:19 2004 >>+++ pwsafe-2.06-src-withmerge/corelib/PWScore.cpp >>Thu Oct 28 10:20:58 >>2004 >>@@ -12,6 +12,10 @@ >> #include "PWScore.h" >> #include "BlowFish.h" >> #include "PWSprefs.h" >>+ >>+unsigned char PWScore::m_session_key[20]; >>+unsigned char PWScore::m_session_salt[20]; >>+unsigned char PWScore::m_session_initialized = >>false; >> >> PWScore::PWScore() : m_currfile(_T("")), >>m_changed(false), >> m_usedefuser(false), m_defusername(_T("")), >>@@ -19,13 +23,17 @@ >> m_passkey(NULL), m_passkey_len(0) >> { >> int i; >>- >>- srand((unsigned)time(NULL)); >>- CItemData::SetSessionKey(); // per-session >>initialization >>- for (i = 0; i < sizeof(m_session_key); i++) >>- m_session_key[i] = newrand(); >>- for (i = 0; i < sizeof(m_session_salt); i++) >>- m_session_salt[i] = newrand(); >>+ >>+ if (!m_session_initialized) >>+ { >>+ srand((unsigned)time(NULL)); >>+ CItemData::SetSessionKey(); // per-session >>initialization >>+ for (i = 0; i < sizeof(m_session_key); i++) >>+ m_session_key[i] = newrand(); >>+ for (i = 0; i < sizeof(m_session_salt); i++) >>+ m_session_salt[i] = newrand(); >>+ m_session_initialized = true; >>+ } >> >> } >> >>--- pwsafe.test/corelib/PWScore.h Fri Sep 3 >>06:06:31 2004 >>+++ pwsafe-2.06-src-withmerge/corelib/PWScore.h Thu >>Oct 28 10:20:02 2004 >>@@ -79,8 +79,9 @@ >> CMyString m_currfile; // current pw db filespec >> unsigned char *m_passkey; // encrypted by session >>key >> unsigned int m_passkey_len; // Length of >>cleartext passkey >>- unsigned char m_session_key[20]; >>- unsigned char m_session_salt[20]; >>+ static unsigned char m_session_key[20]; >>+ static unsigned char m_session_salt[20]; >>+ static unsigned char m_session_initialized; >> CMyString GetPassKey() const; // returns >>cleartext - USE WITH CARE >> // Following used by SetPassKey >> void EncryptPassword(const unsigned char >>*plaintext, int len, >>--- pwsafe.test/DboxMain.cpp Mon Oct 11 22:17:33 >>2004 >>+++ pwsafe-2.06-src-withmerge/DboxMain.cpp Thu Oct >>28 10:58:28 2004 >>@@ -155,6 +155,7 @@ >> ON_COMMAND(ID_MENUITEM_COPYPASSWORD, >>OnCopyPassword) >> ON_COMMAND(ID_MENUITEM_NEW, OnNew) >> ON_COMMAND(ID_MENUITEM_OPEN, OnOpen) >>+ ON_COMMAND(ID_MENUITEM_MERGE, OnMerge) >> ON_COMMAND(ID_MENUITEM_RESTORE, OnRestore) >> ON_COMMAND(ID_MENUTIME_SAVEAS, OnSaveAs) >> ON_COMMAND(ID_MENUITEM_BACKUPSAFE, OnBackupSafe) >>@@ -1070,6 +1071,179 @@ >> return PWScore::SUCCESS; >> } >> >>+int >>+DboxMain::Merge() >>+{ >>+ int rc = PWScore::SUCCESS; >>+ CMyString newfile; >>+ >>+ //Open-type dialog box >>+ while (1) >>+ { >>+ CFileDialog fd(TRUE, >>+ _T("dat"), >>+ NULL, >>+ >>OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_LONGNAMES, >>+ _T("Password Safe Databases >>(*.dat)|*.dat|") >>+ _T("Password Safe Backups >>(*.bak)|*.bak|") >>+ _T("All files (*.*)|*.*|") >>+ _T("|"), >>+ this); >>+ fd.m_ofn.lpstrTitle = _T("Please Choose a >>Database to Merge:"); >>+ rc = fd.DoModal(); >>+ if (rc == IDOK) >>+ { >>+ newfile = (CMyString)fd.GetPathName(); >>+ >>+ rc = Merge( newfile ); >>+ >>+ if ( rc == PWScore::SUCCESS ) >>+ break; >>+ } >>+ else >>+ return PWScore::USER_CANCEL; >>+ } >>+ >>+ return rc; >>+} >>+ >>+int >>+DboxMain::Merge(const CMyString &pszFilename) >>+{ >>+ /* open file they want to merge */ >>+ int rc = PWScore::SUCCESS; >>+ CMyString passkey, temp; >>+ >>+ //Check that this file isn't already open >>+ if (pszFilename == m_core.GetCurFile()) >>+ { >>+ //It is the same damn file >>+ MessageBox(_T("That file is already open."), >>+ _T("Oops!"), >>+ MB_OK|MB_ICONWARNING); >>+ return PWScore::ALREADY_OPEN; >>+ } >>+ >>+ rc = GetAndCheckPassword(pszFilename, passkey); >>+ switch (rc) >>+ { >>+ case PWScore::SUCCESS: >>+ app.GetMRU()->Add(pszFilename); >>+ break; // Keep going... >>+ case PWScore::CANT_OPEN_FILE: >>+ temp = m_core.GetCurFile() >>+ + "\n\nCan't open file. Please choose >>another."; >>+ MessageBox(temp, _T("File open error."), >>MB_OK|MB_ICONWARNING); >>+ case TAR_OPEN: >>+ return Open(); >>+ case TAR_NEW: >>+ return New(); >>+ case PWScore::WRONG_PASSWORD: >>+ /* >>+ If the user just cancelled out of the password >>dialog, >>+ assume they want to return to where they were >>before... >>+ */ >>+ return PWScore::USER_CANCEL; >>+ } >>+ >>+ PWScore otherCore; >>+ otherCore.ReadFile(pszFilename, passkey); >>+ >>+ if (rc == PWScore::CANT_OPEN_FILE) >>+ { >>+ temp = pszFilename; >>+ temp += _T("\n\nCould not open file for >>reading!"); >>+ MessageBox(temp, _T("File read error."), >>MB_OK|MB_ICONWARNING); >>+ /* >>+ Everything stays as is... Worst case, >>+ they saved their file.... >>+ */ >>+ return PWScore::CANT_OPEN_FILE; >>+ } >>+ >>+ otherCore.SetCurFile(pszFilename); >>+ >>+ /* >>+ Purpose: >>+ Merge entries from otherCore to m_core >>+ >>+ Algorithm: >>+ Foreach entry in otherCore >>+ Find in m_core >>+ if find a match >>+ if pw, notes, & group also matches >>+ no merge >>+ else >>+ add to m_core with new title suffixed with >>-merged-HHMMSS-DDMMYY >>+ else >>+ add to m_core directly >>+ */ >>+ POSITION otherPos = >>otherCore.GetFirstEntryPosition(); >>+ while (otherPos) >>+ { >>+ CItemData otherItem = >>otherCore.GetEntryAt(otherPos); >>+ CMyString otherGroup = otherItem.GetGroup(); >>+ CMyString otherTitle = otherItem.GetTitle(); >>+ CMyString otherUser = otherItem.GetUser(); >>+ >>+ POSITION foundPos = m_core.Find(otherGroup, >>otherTitle, >>otherUser); >>+ if (foundPos) >>+ { >>+ /* found a match, see if the pw & notes also >>match >>*/ >>+ CItemData curItem = m_core.GetEntryAt(foundPos); >>+ if (otherItem.GetPassword() != >>curItem.GetPassword() >>|| >>+ otherItem.GetNotes() != curItem.GetNotes()) >>+ { >>+ /* have a match on title/user, but not on >>pw/notes >>+ add an entry suffixed with >>-merged-HHMMSS-DDMMYY */ >>+ CTime curTime = CTime::GetCurrentTime(); >>+ CMyString newTitle = otherItem.GetTitle(); >>+ newTitle += _T("-merged-"); >>+ CMyString timeStr = >>curTime.Format("%H%M%S-%m%d%y"); >>+ newTitle = newTitle + timeStr; >>+ >>+ /* note it as an issue for the user */ >>+ CMyString warnMsg; >>+ warnMsg = _T("Conflicting entries for ") + >>otherItem.GetTitle() + "," + otherItem.GetUser() + >>"\n"; >>+ warnMsg += _T("Adding new entry as ") + >>newTitle + "," + otherItem.GetUser() + "\n"; >>+ >>+ /* tell the user the bad news */ >>+ MessageBox(warnMsg, >>+ _T("Attention"), >>+ >>MB_OK|MB_ICONWARNING); >>+ >>+ /* do it */ >>+ otherItem.SetTitle(newTitle); >>+ m_core.AddEntryToTail(otherItem); >>+ } >>+ } >>+ else >>+ { >>+ /* didn't find any match...add it directly */ >>+ m_core.AddEntryToTail(otherItem); >>+ } >>+ >>+ otherCore.GetNextEntry(otherPos); >>+ } >>+ >>+ MessageBox(_T("Merge Complete"), _T("Merge >>Complete"), MB_OK); >>+ >>+ ChangeOkUpdate(); >>+ RefreshList(); >>+ >>+ return rc; >>+} >>+ >>+ >>+void >>+DboxMain::OnMerge() >>+{ >>+ m_LockDisabled = true; >>+ Merge(); >>+ m_LockDisabled = false; >>+} >>+ >>+ >> void >> DboxMain::OnNew() >> { >>@@ -1793,19 +1967,7 @@ >> >> LRESULT DboxMain::WindowProc(UINT message, WPARAM >>wParam, LPARAM lParam) >> { >>- // list of all the events that signify actual >>user activity, as opposed >>- // to Windows internal events... >>- if (message == WM_KEYDOWN || >>- message == WM_COMMAND || >>- message == WM_SYSCOMMAND || >>- message == WM_MOUSEMOVE || >>- message == WM_MOVE || >>- message == WM_LBUTTONDOWN || >>- message == WM_LBUTTONDBLCLK || >>- message == WM_CONTEXTMENU || >>- message == WM_MENUSELECT || >>- message == WM_VSCROLL >>- ) >>+ if (message != WM_TIMER) >> ResetIdleLockCounter(); >> return CDialog::WindowProc(message, wParam, >>lParam); >> } >>--- pwsafe.test/DboxMain.h Tue Oct 5 00:59:02 2004 >>+++ pwsafe-2.06-src-withmerge/DboxMain.h Thu Oct 28 >>00:01:56 2004 >>@@ -161,6 +161,9 @@ >> int SaveAs(void); >> int Open(void); >> int Open( const CMyString &pszFilename ); >>+ int Merge(void); >>+ int Merge( const CMyString &pszFilename ); >>+ >> int BackupSafe(void); >> int New(void); >> int Restore(void); >>@@ -181,6 +184,7 @@ >> afx_msg void OnCopyPassword(); >> afx_msg void OnNew(); >> afx_msg void OnOpen(); >>+ afx_msg void OnMerge(); >> afx_msg void OnRestore(); >> afx_msg void OnSaveAs(); >> afx_msg void OnListView(); >>--- pwsafe.test/PasswordSafe.rc Thu Oct 7 23:38:27 >>2004 >>+++ pwsafe-2.06-src-withmerge/PasswordSafe.rc Thu >>Oct 28 13:05:30 2004 >>@@ -771,6 +771,7 @@ >> MENUITEM "&XML format...", >>ID_FILE_IMPORT_XML >> , GRAYED >> END >>+ MENUITEM "Merge Database...", >>ID_MENUITEM_MERGE >> MENUITEM SEPARATOR >> MENUITEM "E&xit\tCtrl+Q", >>ID_MENUITEM_EXIT >> END >>--- pwsafe.test/resource.h Thu Oct 7 23:38:27 2004 >>+++ pwsafe-2.06-src-withmerge/resource.h Tue Oct 26 >>17:47:08 2004 >>@@ -181,6 +181,7 @@ >> #define ID_FILE_EXPORTTO_XML 32839 >> #define ID_FILE_IMPORT_XML 32840 >> #define ID_FILE_IMPORT_PLAINTEXT 32841 >>+#define ID_MENUITEM_MERGE 32842 >> #define ID_FILE_MRU_ENTRY1 40001 >> #define ID_FILE_MRU_ENTRY20 40020 >> >>@@ -189,7 +190,7 @@ >> #ifdef APSTUDIO_INVOKED >> #ifndef APSTUDIO_READONLY_SYMBOLS >> #define _APS_NEXT_RESOURCE_VALUE 225 >>-#define _APS_NEXT_COMMAND_VALUE 32842 >>+#define _APS_NEXT_COMMAND_VALUE 32843 >> #define _APS_NEXT_CONTROL_VALUE 1089 >> #define _APS_NEXT_SYMED_VALUE 105 >> #endif >> >> >> >> >> >> >> >------------------------------------------------------- > > >>This Newsletter Sponsored by: Macrovision >>For reliable Linux application installations, use >>the industry's leading >>setup authoring tool, InstallShield X. Learn more >>and evaluate >>today. >> >> >> >http://clk.atdmt.com/MSI/go/ins0030000001msi/direct/01/ > > >>_______________________________________________ >>Passwordsafe-devel mailing list >>Pas...@li... >> >> >> >https://lists.sourceforge.net/lists/listinfo/passwordsafe-devel > > >> >> >> > >________________________________________________________________________ >Yahoo! India Matrimony: Find your life partner online >Go to: http://yahoo.shaadi.com/india-matrimony > > >------------------------------------------------------- >This SF.Net email is sponsored by: >Sybase ASE Linux Express Edition - download now for FREE >LinuxWorld Reader's Choice Award Winner for best database on Linux. >http://ads.osdn.com/?ad_id=5588&alloc_id=12065&op=click >_______________________________________________ >Passwordsafe-devel mailing list >Pas...@li... >https://lists.sourceforge.net/lists/listinfo/passwordsafe-devel > > > > |