summaryrefslogtreecommitdiffabout
Side-by-side diff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--pwmanager/pwmanager/pwmdoc.cpp36
-rw-r--r--pwmanager/pwmanager/pwmdoc.h34
-rw-r--r--pwmanager/pwmanager/serializer.cpp2
3 files changed, 56 insertions, 16 deletions
diff --git a/pwmanager/pwmanager/pwmdoc.cpp b/pwmanager/pwmanager/pwmdoc.cpp
index 76a45f4..ab3238a 100644
--- a/pwmanager/pwmanager/pwmdoc.cpp
+++ b/pwmanager/pwmanager/pwmdoc.cpp
@@ -2674,444 +2674,456 @@ PwMerror PwMDoc::importFromGpasman(const QString *file)
if (ret != 1)
return e_accessFile;
do {
ret = gp.load_entry(entry);
if(ret != 1)
break;
tmpData.desc = entry[0];
tmpData.name = entry[1];
tmpData.pw = entry[2];
tmpData.comment = entry[3];
tmpData.lockStat = true;
tmpData.listViewPos = -1;
ret2 = addEntry(DEFAULT_CATEGORY, &tmpData, true);
for (i = 0; i < 4; ++i)
free(entry[i]);
if (ret2 == e_maxAllowedEntr) {
gp.load_finalize();
return e_maxAllowedEntr;
}
} while (1);
gp.load_finalize();
if (isDocEmpty())
return e_wrongPw; // we assume this.
flagDirty();
return e_success;
}
void PwMDoc::ensureLvp()
{
if (isDocEmpty())
return;
vector< vector<PwMDataItem>::iterator > undefined;
vector< vector<PwMDataItem>::iterator >::iterator undefBegin,
undefEnd,
undefI;
vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(),
catEnd = dti.dta.end(),
catI = catBegin;
vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
int lvpTop, tmpLvp;
while (catI != catEnd) {
lvpTop = -1;
undefined.clear();
entrBegin = catI->d.begin();
entrEnd = catI->d.end();
entrI = entrBegin;
while (entrI != entrEnd) {
tmpLvp = entrI->listViewPos;
if (tmpLvp == -1)
undefined.push_back(entrI);
else if (tmpLvp > lvpTop)
lvpTop = tmpLvp;
++entrI;
}
undefBegin = undefined.begin();
undefEnd = undefined.end();
undefI = undefBegin;
while (undefI != undefEnd) {
(*undefI)->listViewPos = ++lvpTop;
++undefI;
}
++catI;
}
}
QString PwMDoc::getTitle()
{
/* NOTE: We have to ensure, that the returned title
* is unique and not reused somewhere else while
* this document is valid (open).
*/
QString title(getFilename());
if (title.isEmpty()) {
if (unnamedNum == 0) {
unnamedNum = PwMDocList::getNewUnnamedNumber();
PWM_ASSERT(unnamedNum != 0);
}
title = DEFAULT_TITLE;
title += " ";
title += tostr(unnamedNum).c_str();
}
return title;
}
bool PwMDoc::tryDelete()
{
if (deleted)
return true;
int ret;
if (isDirty()) {
ret = dirtyAskSave(getTitle());
if (ret == 0) { // save to disk
if (!saveDocUi(this))
goto out_ignore;
} else if (ret == 1) { // don't save and delete
goto out_accept;
} else { // cancel operation
goto out_ignore;
}
}
out_accept:
deleted = true;
delete this;
return true;
out_ignore:
return false;
}
#ifdef PWM_EMBEDDED
//US ENH: this is the magic function that syncronizes the this doc with the remote doc
//US it could have been defined as static, but I did not want to.
PwMerror PwMDoc::syncronize(KSyncManager* manager, PwMDoc* syncLocal , PwMDoc* syncRemote, int mode )
{
int addedPasswordsLocal = 0;
int addedPasswordsRemote = 0;
int deletedPasswordsRemote = 0;
int deletedPasswordsLocal = 0;
int changedLocal = 0;
int changedRemote = 0;
- PwMSyncItem* syncItemLocal;
- PwMSyncItem* syncItemRemote;
+ PwMSyncItem syncItemLocal;
+ PwMSyncItem syncItemRemote;
QString mCurrentSyncName = manager->getCurrentSyncName();
QString mCurrentSyncDevice = manager->getCurrentSyncDevice();
bool fullDateRange = false;
int take;
// local->resetTempSyncStat();
QDateTime mLastSync = QDateTime::currentDateTime();
QDateTime modifiedSync = mLastSync;
unsigned int index;
//Step 1. Find syncinfo in Local file and create if not existent.
bool found = syncLocal->findSyncData(mCurrentSyncDevice, &index);
if (found == false)
{
PwMSyncItem newSyncItemLocal;
newSyncItemLocal.syncName = mCurrentSyncDevice;
newSyncItemLocal.lastSyncDate = mLastSync;
syncLocal->addSyncDataEntry(&newSyncItemLocal, true);
found = syncLocal->findSyncData(mCurrentSyncDevice, &index);
if (found == false) {
qDebug("PwMDoc::syncronize : newly created local sync data could not be found");
return e_syncError;
}
}
syncItemLocal = syncLocal->getSyncDataEntry(index);
- qDebug("Last Sync %s ", syncItemLocal->lastSyncDate.toString().latin1());
+ qDebug("Last Sync %s ", syncItemLocal.lastSyncDate.toString().latin1());
//Step 2. Find syncinfo in remote file and create if not existent.
found = syncRemote->findSyncData(mCurrentSyncName, &index);
if (found == false)
{
qDebug("FULLDATE 1");
fullDateRange = true;
PwMSyncItem newSyncItemRemote;
newSyncItemRemote.syncName = mCurrentSyncName;
newSyncItemRemote.lastSyncDate = mLastSync;
syncRemote->addSyncDataEntry(&newSyncItemRemote, true);
found = syncRemote->findSyncData(mCurrentSyncName, &index);
if (found == false) {
qDebug("PwMDoc::syncronize : newly created remote sync data could not be found");
return e_syncError;
}
}
syncItemRemote = syncRemote->getSyncDataEntry(index);
//and remove the found entry here. We will reenter it later again.
syncRemote->delSyncDataEntry(index, true);
- if ( syncItemLocal->lastSyncDate == mLastSync ) {
+ if ( syncItemLocal.lastSyncDate == mLastSync ) {
qDebug("FULLDATE 2");
fullDateRange = true;
}
if ( ! fullDateRange ) {
- if ( syncItemLocal->lastSyncDate != syncItemRemote->lastSyncDate ) {
+ if ( syncItemLocal.lastSyncDate != syncItemRemote->lastSyncDate ) {
// qDebug("set fulldate to true %s %s" ,addresseeLSync->dtStart().toString().latin1(), addresseeRSync->dtStart().toString().latin1() );
//qDebug("%d %d %d %d ", addresseeLSync->dtStart().time().second(), addresseeLSync->dtStart().time().msec() , addresseeRSync->dtStart().time().second(), addresseeRSync->dtStart().time().msec());
fullDateRange = true;
- qDebug("FULLDATE 3 %s %s", syncItemLocal->lastSyncDate.toString().latin1() , syncItemRemote->lastSyncDate.toString().latin1() );
+ qDebug("FULLDATE 3 %s %s", syncItemLocal.lastSyncDate.toString().latin1() , syncItemRemote.lastSyncDate.toString().latin1() );
}
}
// fullDateRange = true; // debug only!
if ( fullDateRange )
mLastSync = QDateTime::currentDateTime().addDays( -100*365);
else
mLastSync = syncItemLocal->lastSyncDate;
qDebug("*************************** ");
// qDebug("mLastAddressbookSync %s ",mLastAddressbookSync.toString().latin1() );
QStringList er = syncRemote->getIDEntryList();
PwMDataItem* inRemote ;//= er.first();
PwMDataItem* inLocal;
unsigned int catLocal, indexLocal;
unsigned int catRemote, indexRemote;
QString uid;
manager->showProgressBar(0, i18n("Syncing - close to abort!"), er.count());
int modulo = (er.count()/10)+1;
unsigned int incCounter = 0;
while ( incCounter < er.count()) {
if (manager->isProgressBarCanceled())
return e_syncError;
if ( incCounter % modulo == 0 )
manager->showProgressBar(incCounter);
uid = er[ incCounter ];
qDebug("sync uid %s from remote file", uid.latin1());
qApp->processEvents();
inLocal = syncLocal->findEntryByID( uid, &catLocal, &indexLocal );
inRemote = syncRemote->findEntryByID( uid, &catRemote, &indexRemote );
PWM_ASSERT(inRemote);
if ( inLocal != 0 ) { // maybe conflict - same uid in both files
if ( (take = takePwMDataItem( inLocal, inRemote, mLastSync, mode, fullDateRange) ) ) {
//qDebug("take %d %s ", take, inL.summary().latin1());
if ( take == 3 )
return e_syncError;
if ( take == 1 ) {// take local
//US syncRemote->removeAddressee( inRemote );
(*inRemote) = (*inLocal);
//US syncRemote->insertAddressee( inRemote , false);
++changedRemote;
} else { // take == 2 take remote
//US syncLocal->removeAddressee( inLocal );
(*inLocal) = (*inRemote);
//US syncLocal->insertAddressee( inLocal , false );
++changedLocal;
}
}
} else { // no conflict
if ( inRemote->meta.update > mLastSync || mode == 5 ) {
inRemote->meta.update = modifiedSync;
+
+ //first check if we have a matching category in the local file
+ const string* remotecat = syncRemote->getCategory(catRemote);
//US syncRemote->insertAddressee( inRemote, false );
//US syncLocal->insertAddressee( inRemote, false );
- syncLocal->addEntry("newcategory", inRemote, true, false);
+ syncLocal->addEntry(remotecat->c_str(), inRemote, true, false);
++addedPasswordsLocal;
} else {
// pending checkExternSyncAddressee(addresseeRSyncSharp, inR);
syncRemote->delEntry(catRemote, indexRemote, true);
//USsyncRemote->removeAddressee( inRemote );
++deletedPasswordsRemote;
}
}
++incCounter;
}
er.clear();
QStringList el = syncLocal->getIDEntryList();
modulo = (el.count()/10)+1;
manager->showProgressBar(0, i18n("Add / remove addressees"), el.count());
incCounter = 0;
while ( incCounter < el.count()) {
qApp->processEvents();
if (manager->isProgressBarCanceled())
return e_syncError;
if ( incCounter % modulo == 0 )
manager->showProgressBar(incCounter);
uid = el[ incCounter ];
inLocal = syncLocal->findEntryByID( uid, &catLocal, &indexLocal );
inRemote = syncRemote->findEntryByID( uid, &catRemote, &indexRemote );
+ PWM_ASSERT(inLocal);
+
if ( inRemote == 0 ) {
if ( inLocal->meta.update < mLastSync && mode != 4 ) {
// pending checkExternSyncAddressee(addresseeLSyncSharp, inL);
syncLocal->delEntry(catLocal, indexLocal, true);
//USsyncLocal->removeAddressee( inLocal );
++deletedPasswordsLocal;
} else {
if ( ! manager->mWriteBackExistingOnly ) {
++addedPasswordsRemote;
inLocal->meta.update = modifiedSync;
+
+ //first check if we have a matching category in the remote file
+ const string* localcat = syncLocal->getCategory(catLocal);
+
//USsyncLocal->insertAddressee( inLocal, false );
- (*inRemote) = (*inLocal);
+ PwMDataItem newEntry;
+ newEntry = *inLocal;
+ inRemote = &newEntry;
+
//USsyncRemote->insertAddressee( inRemote, false );
- syncRemote->addEntry("newcategory", inRemote, true, false);
+ syncRemote->addEntry(localcat->c_str(), inRemote, true, false);
}
}
}
++incCounter;
}
el.clear();
manager->hideProgressBar();
// Now write the info back into the sync data space of the files
mLastSync = QDateTime::currentDateTime().addSecs( 1 );
// get rid of micro seconds
QTime t = mLastSync.time();
mLastSync.setTime( QTime (t.hour (), t.minute (), t.second () ) );
- syncItemLocal->lastSyncDate = mLastSync;
- syncItemRemote->lastSyncDate = mLastSync;
+ syncItemLocal.lastSyncDate = mLastSync;
+ syncItemRemote.lastSyncDate = mLastSync;
// addresseeRSync.setRole( i18n("!Remote from: ")+mCurrentSyncName ) ;
// addresseeLSync.setRole(i18n("!Local from: ") + mCurrentSyncName );
syncRemote->addSyncDataEntry( syncItemRemote, false );
syncLocal->addSyncDataEntry( syncItemLocal, false );
QString mes;
mes .sprintf( i18n("Synchronization summary:\n\n %d items added to local\n %d items added to remote\n %d items updated on local\n %d items updated on remote\n %d items deleted on local\n %d items deleted on remote\n"),addedPasswordsLocal, addedPasswordsRemote, changedLocal, changedRemote, deletedPasswordsLocal, deletedPasswordsRemote );
if ( manager->mShowSyncSummary ) {
KMessageBox::information(0, mes, i18n("PWM/Pi Synchronization") );
}
qDebug( mes );
return e_success;
}
int PwMDoc::takePwMDataItem( PwMDataItem* local, PwMDataItem* remote, QDateTime lastSync, int mode , bool full )
{
// 0 equal
// 1 take local
// 2 take remote
// 3 cancel
QDateTime localMod = local->meta.update;
QDateTime remoteMod = remote->meta.update;
//US QString mCurrentSyncDevice = syncManager->getCurrentSyncDevice();
if ( localMod == remoteMod )
return 0;
qDebug(" %d %d conflict on %s %s ", mode, full, local->desc.c_str(), remote->desc.c_str() );
//qDebug("%s %d %s %d", local->lastModified().toString().latin1() , localMod, remote->lastModified().toString().latin1(), remoteMod);
//qDebug("%d %d %d %d ", local->lastModified().time().second(), local->lastModified().time().msec(), remote->lastModified().time().second(), remote->lastModified().time().msec() );
//full = true; //debug only
if ( full ) {
bool equ = true;//US ( (*local) == (*remote) );
if ( equ ) {
//qDebug("equal ");
if ( mode < SYNC_PREF_FORCE_LOCAL )
return 0;
}//else //debug only
//qDebug("not equal %s %s ", local->summary().latin1(), remote->summary().latin1());
}
int result;
bool localIsNew;
//qDebug("%s -- %s mLastCalendarSync %s lastsync %s --- local %s remote %s ",local->summary().latin1(), remote->summary().latin1(),mLastCalendarSync.toString().latin1() ,lastSync.toString().latin1() , local->lastModified().toString().latin1() , remote->lastModified().toString().latin1() );
if ( full && mode < SYNC_PREF_NEWEST )
mode = SYNC_PREF_ASK;
switch( mode ) {
case SYNC_PREF_LOCAL:
if ( lastSync > remoteMod )
return 1;
if ( lastSync > localMod )
return 2;
return 1;
break;
case SYNC_PREF_REMOTE:
if ( lastSync > remoteMod )
return 1;
if ( lastSync > localMod )
return 2;
return 2;
break;
case SYNC_PREF_NEWEST:
if ( localMod > remoteMod )
return 1;
else
return 2;
break;
case SYNC_PREF_ASK:
//qDebug("lsy %s --- lo %s --- re %s ", lastSync.toString().latin1(), localMod.toString().latin1(), remoteMod.toString().latin1() );
if ( lastSync > remoteMod )
return 1;
if ( lastSync > localMod )
return 2;
localIsNew = localMod >= remoteMod;
//qDebug("conflict! ************************************** ");
{
PwMDataItemChooser acd ( *local,*remote, localIsNew , 0/*this*/ );
result = acd.executeD(localIsNew);
return result;
}
break;
case SYNC_PREF_FORCE_LOCAL:
return 1;
break;
case SYNC_PREF_FORCE_REMOTE:
return 2;
break;
default:
// SYNC_PREF_TAKE_BOTH not implemented
break;
}
return 0;
}
//this are the overwritten callbackmethods from the syncinterface
bool PwMDoc::sync(KSyncManager* manager, QString filename, int mode)
{
QString mCurrentSyncDevice = manager->getCurrentSyncDevice();
//1) unlock local file first if necessary (ask for password)
if (this->isDeepLocked()) {
PwMerror ret = this->deepLock(false);
if (ret != e_success)
return false;
}
//2) construct and open a new doc on the stack(automatic cleanup) for remote file.
PwMDoc syncTarget(this, "synctarget");
PwMDoc* pSyncTarget = &syncTarget;
PwMerror err = pSyncTarget->openDoc(&filename, 1 /*== open with all entries locked*/);
if (err == e_alreadyOpen) {
PwMDocList::listItem li;
if (getOpenDocList()->find(filename.latin1(), &li))
pSyncTarget = li.doc;
@@ -3157,144 +3169,144 @@ bool PwMDoc::sync(KSyncManager* manager, QString filename, int mode)
}
//called by the syncmanager to indicate that the work has to marked as dirty.
void PwMDoc::sync_setModified()
{
flagDirty();
}
//called by the syncmanager to ask if the dirty flag is set.
bool PwMDoc::sync_isModified()
{
return isDirty();
}
//called by the syncmanager to indicate that the work has to be saved.
void PwMDoc::sync_save()
{
saveDoc(conf()->confGlobCompression());
}
#endif
bool PwMDoc::findSyncData(const QString &syncname, unsigned int *index)
{
vector<PwMSyncItem>::iterator i = dti.syncDta.begin(),
end = dti.syncDta.end();
while (i != end) {
if ((*i).syncName == syncname.latin1()) {
if (index) {
*index = i - dti.syncDta.begin();
}
return true;
}
++i;
}
return false;
};
/** add new syncdataentry */
PwMerror PwMDoc::addSyncDataEntry(PwMSyncItem *d, bool dontFlagDirty)
{
PWM_ASSERT(d);
if (isDeepLocked()) {
PwMerror ret;
ret = deepLock(false);
if (ret != e_success)
return e_lock;
}
unsigned int index;
const QString tmp = d->syncName.c_str();
bool exists = findSyncData(d->syncName.c_str(), &index);
if (exists == true) {
// DOH! We found this entry.
return e_entryExists;
}
dti.syncDta.push_back(*d);
if (!dontFlagDirty)
flagDirty();
return e_success;
}
/** delete syncdata entry */
bool PwMDoc::delSyncDataEntry(unsigned int index, bool dontFlagDirty)
{
if (isDeepLocked())
return false;
if (index > dti.syncDta.size() - 1)
return false;
// delete entry
dti.syncDta.erase(dti.syncDta.begin() + index);
if (!dontFlagDirty)
flagDirty();
return true;
}
PwMDataItem* PwMDoc::findEntryByID(const QString &uid, unsigned int *category, unsigned int *index)
{
vector<PwMCategoryItem>::iterator catcounter = dti.dta.begin(),
catend = dti.dta.end();
vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
while (catcounter != catend) {
entrBegin = catcounter->d.begin();
entrEnd = catcounter->d.end();
entrI = entrBegin;
while (entrI != entrEnd) {
if ((*entrI).meta.uniqueid == uid.latin1()) {
if (category)
*category = catcounter - dti.dta.begin();
if (index)
*index = entrI - entrBegin;
return &(*entrI);
}
++entrI;
}
++catcounter;
}
return 0;
}
QStringList PwMDoc::getIDEntryList()
{
QStringList results;
vector<PwMCategoryItem>::iterator catcounter = dti.dta.begin(),
catend = dti.dta.end();
vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
while (catcounter != catend) {
entrBegin = catcounter->d.begin();
entrEnd = catcounter->d.end();
entrI = entrBegin;
while (entrI != entrEnd) {
- results.append( (*entrI).meta.uniqueid );
+ results.append( (*entrI).meta.uniqueid.c_str() );
++entrI;
}
++catcounter;
}
return results;
}
#ifndef PWM_EMBEDDED
#include "pwmdoc.moc"
#endif
diff --git a/pwmanager/pwmanager/pwmdoc.h b/pwmanager/pwmanager/pwmdoc.h
index 91277f6..ddab7f3 100644
--- a/pwmanager/pwmanager/pwmdoc.h
+++ b/pwmanager/pwmanager/pwmdoc.h
@@ -1,337 +1,365 @@
/***************************************************************************
* *
* copyright (C) 2003, 2004 by Michael Buesch *
* email: mbuesch@freenet.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 *
* as published by the Free Software Foundation. *
* *
***************************************************************************/
/***************************************************************************
* copyright (C) 2004 by Ulf Schenk
* This file is originaly based on version 2.0 of pwmanager
* and was modified to run on embedded devices that run microkde
*
* $Id$
**************************************************************************/
#ifndef __PWMDOC_H
#define __PWMDOC_H
#define PWM_FILE_VER (static_cast<char>(0x05))
#define PWM_HASH_SHA1 (static_cast<char>(0x01))
#define PWM_HASH_SHA256 (static_cast<char>(0x02))
#define PWM_HASH_SHA384 (static_cast<char>(0x03))
#define PWM_HASH_SHA512 (static_cast<char>(0x04))
#define PWM_HASH_MD5 (static_cast<char>(0x05))
#define PWM_HASH_RMD160 (static_cast<char>(0x06))
#define PWM_HASH_TIGER (static_cast<char>(0x07))
#define PWM_CRYPT_BLOWFISH (static_cast<char>(0x01))
#define PWM_CRYPT_AES128 (static_cast<char>(0x02))
#define PWM_CRYPT_AES192 (static_cast<char>(0x03))
#define PWM_CRYPT_AES256 (static_cast<char>(0x04))
#define PWM_CRYPT_3DES (static_cast<char>(0x05))
#define PWM_CRYPT_TWOFISH (static_cast<char>(0x06))
#define PWM_CRYPT_TWOFISH128 (static_cast<char>(0x07))
#define PWM_COMPRESS_NONE (static_cast<char>(0x00))
#define PWM_COMPRESS_GZIP (static_cast<char>(0x01))
#define PWM_COMPRESS_BZIP2 (static_cast<char>(0x02))
#define DEFAULT_MAX_ENTRIES (~(static_cast<unsigned int>(0)))
#define FILE_ID_HEADER "PWM_PASSWORD_FILE"
#include "pwmexception.h"
#include "pwmdocui.h"
#include <qobject.h>
#include <qtimer.h>
#include <qdatetime.h>
#include <kprocess.h>
#ifndef PWM_EMBEDDED
#include "configuration.h"
#else
#include <kapplication.h>
#include <ksyncmanager.h>
#endif
#include <string>
#include <vector>
#include <utility>
using std::vector;
using std::string;
using std::pair;
/* used in findEntry() function */
#define SEARCH_IN_DESC (1)
#define SEARCH_IN_NAME (1 << 1)
#define SEARCH_IN_PW (1 << 2)
#define SEARCH_IN_COMMENT (1 << 3)
#define SEARCH_IN_URL (1 << 4)
#define SEARCH_IN_LAUNCHER (1 << 5)
#define SEARCH_IN_ALL (SEARCH_IN_DESC | SEARCH_IN_NAME | \
SEARCH_IN_PW | SEARCH_IN_COMMENT | \
SEARCH_IN_URL | SEARCH_IN_LAUNCHER)
/** document deeplocked. Data is out for lunch to disk */
#define DOC_STAT_DEEPLOCKED (1)
/** encrypted document on disk is dirty. data has to go to disk. */
#define DOC_STAT_DISK_DIRTY (1 << 1)
/** we are using a chipcard to encrypt the data */
#define DOC_STAT_USE_CHIPCARD (1 << 2)
/** use "currentPw" to unlock. (This flag is set/unset by a timer) */
#define DOC_STAT_UNLOCK_WITHOUT_PW (1 << 3)
class PwMDoc;
class PwMView;
class QFile;
/* meta data for a PwMDataItem */
struct PwMMetaData
{
PwMMetaData()
: updateInt (0)
{ }
/** creation date of the PwMDataItem to which
* this meta data belongs.
*/
QDateTime create;
/** becomes valid on this date */
QDateTime valid;
/** expire date */
QDateTime expire;
/** update date (last updated at this date) */
QDateTime update;
/** update interval (in minutes). Time since the
* last update to remind the user to update the item.
* 0 disables.
*/
unsigned long updateInt;
//US ENH: enhancements of the filestructure
/* each entry gets a unique id assigned */
- QString uniqueid;
+ string uniqueid;
void clear()
{
create = QDateTime();
expire = QDateTime();
update = QDateTime();
updateInt = 0;
uniqueid = KApplication::randomString(8);
}
+
+ PwMMetaData& operator = (const PwMMetaData& x)
+ {
+ create = x.create;
+ expire = x.expire;
+ update = x.update;
+ updateInt = x.updateInt;
+ uniqueid = x.uniqueid;
+ return *this;
+ }
+
inline bool isValid() const
{
if (valid.isNull())
return true;
return (valid < QDateTime::currentDateTime());
}
inline bool isExpired() const
{
if (expire.isNull())
return false;
return (expire < QDateTime::currentDateTime());
}
inline bool isUpdateIntOver() const
{
if (updateInt == 0 ||
update.isNull())
return false;
QDateTime d(update);
return (d.addSecs(updateInt * 60) < QDateTime::currentDateTime());
}
};
struct PwMDataItem
{
PwMDataItem()
: lockStat (true)
, listViewPos (-1)
, binary (false)
, rev (0)
{ }
/** password description */
string desc;
/** user-name */
string name;
/** the password itself */
string pw;
/** some comment */
string comment;
/** an URL string */
string url;
/** launcher. Can be executed as a system() command */
string launcher;
/** locking status. If locked (true), pw is not emitted through getEntry() */
bool lockStat;
/** position of this item in main "list-view"
* If -1, the position is not yet specified and should be appended to the list
*/
int listViewPos;
/** does this entry contain binary data? */
bool binary;
/** meta data for this data item. */
PwMMetaData meta;
/** data revision counter. This counter can be used
* to easily, efficiently determine if this data item
* has changed since some time.
* This counter is incremented on every update.
*/
unsigned int rev;
void clear(bool clearMeta = true)
{
/* NOTE: Don't use .clear() here to be
* backward compatible with gcc-2 (Debian Woody)
*/
desc = "";
name = "";
pw = "";
comment = "";
url = "";
launcher = "";
lockStat = true;
listViewPos = -1;
binary = false;
if (clearMeta)
meta.clear();
}
+ PwMDataItem& operator = (const PwMDataItem& x)
+ {
+ qDebug("oper=%s", x.desc.c_str());
+ desc = x.desc;
+ name = x.name;
+ pw = x.pw;
+ comment = x.comment;
+ url = x.url;
+ launcher = x.launcher;
+ lockStat = x.lockStat;
+ listViewPos = x.listViewPos;
+ binary = x.binary;
+ meta = x.meta;
+ rev = x.rev;
+ return *this;
+ }
+
};
struct PwMCategoryItem
{
/** all PwMDataItems (all passwords) within this category */
vector<PwMDataItem> d;
/** category name/description */
string name;
void clear()
{
d.clear();
name = "";
}
};
struct PwMSyncItem
{
string syncName;
QDateTime lastSyncDate;
void clear()
{
lastSyncDate = QDateTime();
syncName = "";
}
};
struct PwMItem
{
vector<PwMCategoryItem> dta;
vector<PwMSyncItem> syncDta;
void clear()
{
dta.clear();
syncDta.clear();
}
};
/** "Function Object" for sort()ing PwMDataItem::listViewPos */
class dta_lvp_greater
{
public:
bool operator() (const pair<unsigned int, unsigned int> &d1,
const pair<unsigned int, unsigned int> &d2)
{
return d1.second > d2.second;
}
};
/** list of PwMDoc documents and it's IDs */
class PwMDocList
{
public:
struct listItem
{
/** document filename (known as ID, here) */
string docId;
/** pointer to the document class */
PwMDoc *doc;
};
PwMDocList() {}
/** add a new item to the list */
void add(PwMDoc *doc, const string &id);
/** changes the contents of an existing item */
void edit(PwMDoc *doc, const string &newId);
/** remove the given item */
void del(PwMDoc *doc);
/** get the item at index */
listItem getAt(int index)
{ return docList[index]; }
/** find an entry with this id */
bool find(const string &id, listItem *ret = 0);
/** returns a copy of the list */
const vector<listItem>* getList() const
{ return &docList; }
/** returns a new unique number to extend the name of
* an unnamed document.
*/
static unsigned int getNewUnnamedNumber()
{ return unnamedDocCnt++; }
protected:
/* Hm, I think we shouldn't really use a "list" here, should we?
* So I decided to actually use a vector.
*/
vector<listItem> docList;
/** This value is used to get a new number for yet unnamed
* documents. It is incremented on every request. So it's
* theoretically possible to overflow it, but... :)
*/
static unsigned int unnamedDocCnt;
};
/** implements timers for the document */
class DocTimer : public QObject
{
Q_OBJECT
public:
enum TimerIDs
{
id_mpwTimer,
id_autoLockTimer,
id_metaCheckTimer
};
public:
DocTimer(PwMDoc *_doc);
~DocTimer();
/** start the timer */
void start(TimerIDs timer);
/** stop the timer */
void stop(TimerIDs timer);
/** get the lock for a timer.
* This lock is a recursive lock. When a lock is
* held, the timer will be stopped and timeout is
* guaranteed to not happen
*/
void getLock(TimerIDs timer);
/** put a recursive timer lock */
void putLock(TimerIDs timer);
@@ -638,141 +666,141 @@ public:
}
protected:
/** current file for this doc */
QString filename;
//US ENH: we need a place where we keep the syncentries. So I invented
// struct PwMItem, that has a vector of PwMCategoryItem and vector of PwMSyncItem
/** holds all data */
PwMItem dti;
/** maximum number of entries */
unsigned int maxEntries;
/** currently used password to encrypt data */
QString currentPw;
/** current global document status flags */
unsigned int curDocStat;
/** browser process for goToURL() */
KProcess browserProc;
/** pointer to the list-view, using this document.
* As there can only be one list-view per doc, we
* don't need a list here.
*/
PwMView *listView;
/** unnamedNum is used to store the "unnamed counter"
* for this document, while it's unnamed. If it's 0,
* we have to get a new unique one.
*/
unsigned int unnamedNum;
/** is this doc going to be deleted (executing in destructor context) */
bool deleted;
/** document timer */
DocTimer *_timer;
/** lock counter for the "dataChanged" signal */
unsigned int dataChangedLock;
/** list of all open documents */
static PwMDocList openDocList;
protected:
/** serialize "dta" and return it in "d". */
bool serializeDta(string *d);
/** de-serialize "d" and overwrite "dta" */
bool deSerializeDta(const string *d, bool entriesLocked);
/** write header to file */
PwMerror writeFileHeader(char keyHash, char dataHash, char crypt, char compress,
QString *pw, QFile *f);
/** write data-hash to file */
PwMerror writeDataHash(char dataHash, string *d, QFile *f);
/** check header. Read header info and verify key-hash and filever.
* returns length of header in "headerLength" */
PwMerror checkHeader(char *cryptAlgo, QString *pw, char *compress,
unsigned int *headerLength, char *dataHashType,
string *dataHash, QFile *f);
/** check the data-hash */
PwMerror checkDataHash(char dataHashType, const string *dataHash, const string *dataStream);
/** encrypt data "d" and write to "filename" */
PwMerror encrypt(string *d, const QString *pw, QFile *f, char algo);
/** read data from file beginning at "pos", decrypt and return it */
PwMerror decrypt(string *d, unsigned int pos, const QString *pw, char algo, QFile *f);
/** compress the data */
bool compressDta(string *d, char algo);
/** uncompress the data */
bool decompressDta(string *d, char algo);
/** internal import function for a text-file generated by PwM.
* If this is not a valid PwM-exported file, it returns e_fileFormat */
PwMerror importText_PwM(const QString *file);
/** PwM-text-import helper function to extract the name/pw/comment out
* of one entry-line */
bool textExtractEntry_PwM(const char *in, ssize_t in_size, string *out);
/** compare two strings */
bool compareString(const string &s1, const string &s2, bool caseSensitive,
bool exactWordMatch);
/** clears all document-data */
void clearDoc();
/** delete all empty categories */
void delAllEmptyCat(bool dontFlagDirty);
/** set a document status flag */
void setDocStatFlag(unsigned int statFlag)
{ curDocStat |= statFlag; }
/** unset a document status flag */
void unsetDocStatFlag(unsigned int statFlag)
{ curDocStat &= ~statFlag; }
/** get a document status flag */
bool getDocStatFlag(unsigned int statFlag) const
{ return (curDocStat & statFlag); }
/** set the "currentPassword" */
void setCurrentPw(const QString &pw)
{
currentPw = pw;
setDocStatFlag(DOC_STAT_DISK_DIRTY);
}
/** make a backup-copy of the given file */
bool backupFile(const QString &filePath);
/** copy a file from src to dst */
bool copyFile(const QString &src, const QString &dst);
public:
#ifdef PWM_EMBEDDED
//US ENH: this is the magic function that syncronizes the local doc with the remote doc.
PwMerror syncronize(KSyncManager* manager, PwMDoc* syncLocal, PwMDoc* syncRemote, int mode );
//takePwMDataItem returns the following values
// 0 equal
// 1 take local
// 2 take remote
// 3 cancel
int takePwMDataItem( PwMDataItem* local, PwMDataItem* remote, QDateTime lastSync, int mode , bool full );
//the following methods are the overwritten callbackmethods from the syncinterface
virtual bool sync(KSyncManager* manager, QString filename, int mode);
//called by the syncmanager to indicate that the work has to be marked as dirty.
virtual void sync_setModified();
//called by the syncmanager to ask if the dirty flag is set.
virtual bool sync_isModified();
//called by the syncmanager to indicate that the work has to be saved.
virtual void sync_save();
#endif
private:
//US ENH: helpermethods to access the sync data for a certain syncname.
// It returns the syncdatas index
bool findSyncData(const QString &syncname, unsigned int *index);
/** add new syncdataentry */
PwMerror addSyncDataEntry(PwMSyncItem *d, bool dontFlagDirty = false);
/** returns a pointer to the syncdata */
- PwMSyncItem* getSyncDataEntry(unsigned int index)
- { return &(dti.syncDta[index]); }
+ PwMSyncItem getSyncDataEntry(unsigned int index)
+ { return *(dti.syncDta[index]); }
/** delete entry */
bool delSyncDataEntry(unsigned int index, bool dontFlagDirty = false);
PwMDataItem* findEntryByID(const QString &uid, unsigned int *category, unsigned int *index);
QStringList getIDEntryList();
};
#endif
diff --git a/pwmanager/pwmanager/serializer.cpp b/pwmanager/pwmanager/serializer.cpp
index f615082..74b3354 100644
--- a/pwmanager/pwmanager/serializer.cpp
+++ b/pwmanager/pwmanager/serializer.cpp
@@ -521,236 +521,236 @@ bool Serializer::writeEntry(QDomElement *e,
{
#if WRITE_CDATA_SEC != 0
# define new_text(x) domDoc->createCDATASection(x)
QDomCDATASection curText;
#else
# define new_text(x) domDoc->createTextNode(x)
QDomText curText;
#endif
QDomText plainText;
QDomElement tag;
// begin -- This is for compatibility with the old serializer
PwMDataItem dta = _dta;
if (!dta.desc.size())
dta.desc = " ";
if (!dta.name.size())
dta.name = " ";
if (!dta.pw.size())
dta.pw = " ";
if (!dta.comment.size())
dta.comment = " ";
if (!dta.url.size())
dta.url = " ";
if (!dta.launcher.size())
dta.launcher = " ";
// end -- This is for compatibility with the old serializer
tag = domDoc->createElement(ENTRY_DESC_WR);
curText = new_text(escapeEntryData(dta.desc.c_str()));
tag.appendChild(curText);
e->appendChild(tag);
tag = domDoc->createElement(ENTRY_NAME_WR);
curText = new_text(escapeEntryData(dta.name.c_str()));
tag.appendChild(curText);
e->appendChild(tag);
tag = domDoc->createElement(ENTRY_PW_WR);
curText = new_text(escapeEntryData(dta.pw.c_str()));
tag.appendChild(curText);
e->appendChild(tag);
tag = domDoc->createElement(ENTRY_COMMENT_WR);
curText = new_text(escapeEntryData(dta.comment.c_str()));
tag.appendChild(curText);
e->appendChild(tag);
tag = domDoc->createElement(ENTRY_URL_WR);
curText = new_text(escapeEntryData(dta.url.c_str()));
tag.appendChild(curText);
e->appendChild(tag);
tag = domDoc->createElement(ENTRY_LAUNCHER_WR);
curText = new_text(escapeEntryData(dta.launcher.c_str()));
tag.appendChild(curText);
e->appendChild(tag);
tag = domDoc->createElement(ENTRY_LVP_WR);
plainText = domDoc->createTextNode(tostr(dta.listViewPos).c_str());
tag.appendChild(plainText);
e->appendChild(tag);
tag = domDoc->createElement(ENTRY_BIN_WR);
if (dta.binary)
plainText = domDoc->createTextNode("1");
else
plainText = domDoc->createTextNode("0");
tag.appendChild(plainText);
e->appendChild(tag);
tag = domDoc->createElement(ENTRY_META_WR);
if (!writeMeta(&tag, dta.meta))
return false;
e->appendChild(tag);
#undef new_text
return true;
}
bool Serializer::writeMeta(QDomElement *e,
const PwMMetaData &dta)
{
QDomText text;
QDomElement tag;
tag = domDoc->createElement(META_CREATE_DATE);
#ifndef PWM_EMBEDDED
text = domDoc->createTextNode(dta.create.toString(Qt::ISODate));
#else
text = domDoc->createTextNode(KGlobal::locale()->formatDateTime(dta.create, KLocale::ISODate));
#endif
tag.appendChild(text);
e->appendChild(tag);
tag = domDoc->createElement(META_VALID_DATE);
#ifndef PWM_EMBEDDED
text = domDoc->createTextNode(dta.valid.toString(Qt::ISODate));
#else
text = domDoc->createTextNode(KGlobal::locale()->formatDateTime(dta.valid, KLocale::ISODate));
#endif
tag.appendChild(text);
e->appendChild(tag);
tag = domDoc->createElement(META_EXPIRE_DATE);
#ifndef PWM_EMBEDDED
text = domDoc->createTextNode(dta.expire.toString(Qt::ISODate));
#else
text = domDoc->createTextNode(KGlobal::locale()->formatDateTime(dta.expire, KLocale::ISODate));
#endif
tag.appendChild(text);
e->appendChild(tag);
tag = domDoc->createElement(META_UPDATE_DATE);
#ifndef PWM_EMBEDDED
text = domDoc->createTextNode(dta.update.toString(Qt::ISODate));
#else
text = domDoc->createTextNode(KGlobal::locale()->formatDateTime(dta.update, KLocale::ISODate));
#endif
tag.appendChild(text);
e->appendChild(tag);
tag = domDoc->createElement(META_UPDATE_INT);
text = domDoc->createTextNode(tostr(dta.updateInt).c_str());
tag.appendChild(text);
e->appendChild(tag);
tag = domDoc->createElement(META_UNIQUEID);
- text = domDoc->createTextNode(escapeEntryData(dta.uniqueid));
+ text = domDoc->createTextNode(escapeEntryData(dta.uniqueid.c_str()));
tag.appendChild(text);
e->appendChild(tag);
#undef new_text
return true;
}
QString Serializer::escapeEntryData(QString dta)
{
#ifndef PWM_EMBEDDED
dta.replace('\n', "$>--endl--<$");
dta.replace("]]>", "||>");
#else
dta.replace(QRegExp("\n"), "$>--endl--<$");
dta.replace(QRegExp("]]>"), "||>");
#endif
return dta;
}
QString Serializer::unescapeEntryData(QString dta)
{
#ifndef PWM_EMBEDDED
dta.replace("$>--endl--<$", "\n");
dta.replace("||>", "]]>");
#else
dta.replace(QRegExp("$>--endl--<$"), "\n");
dta.replace(QRegExp("||>"), "]]>");
#endif
return dta;
}
//US ENH: the following methods are getting used to write/read sync entries
/** read the syncentries in the node "n" */
bool Serializer::readSyncData(const QDomNode &n, vector<PwMSyncItem> *dta)
{
QDomNodeList nl(n.childNodes());
QDomNode cur;
QString devicename, val;
unsigned int numSync = nl.count(), i;
PwMSyncItem curSync;
bool ok = true;
if (!numSync) {
//no sync entries is a possible result
printDebug("Serializer::readSyncData(): empty");
return true;
}
for (i = 0; i < numSync; ++i) {
cur = nl.item(i);
if (cur.nodeName().left(1) == SYNC_TARGET_PREFIX) {
devicename = cur.toElement().attribute(SYNC_TARGET_NAME);
val = cur.toElement().text();
if ((val == "") || (devicename == QString::null)) {
printDebug("Serializer::readSyncData(): empty synctarget name or syncdate");
continue;
}
curSync.syncName = devicename;
#ifndef PWM_EMBEDDED
curSync.lastSyncDate = QDateTime::fromString(val, Qt::ISODate);
#else
curSync.lastSyncDate = KGlobal::locale()->readDateTime(val, KLocale::ISODate, &ok);
if (ok == false)
qDebug("Serializer::readSyncData(): could not parse syncdate:%s",val.latin1());
#endif
dta->push_back(curSync);
}
}
return true;
}
bool Serializer::addSyncData(QDomElement *e,
const vector<PwMSyncItem> &dta)
{
unsigned int numSync = dta.size(), i;
QString curId, curDeviceName;
QDomElement curSync, curSyncDate;
QDomText text;
for (i = 0; i < numSync; ++i) {
curId = SYNC_TARGET_PREFIX;
curId += tostr(i).c_str();
curDeviceName = dta[i].syncName.c_str();
curSync = domDoc->createElement(curId);
curSync.setAttribute(SYNC_TARGET_NAME, curDeviceName);
#ifndef PWM_EMBEDDED
text = domDoc->createTextNode(dta[i].lastSyncDate.toString(Qt::ISODate));
#else
text = domDoc->createTextNode(KGlobal::locale()->formatDateTime(dta[i].lastSyncDate, KLocale::ISODate));
#endif
curSyncDate.appendChild(text);
curSync.appendChild(curSyncDate);
e->appendChild(curSync);
}
return true;
}