summaryrefslogtreecommitdiffabout
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--pwmanager/pwmanager/pwmdoc.cpp65
-rw-r--r--pwmanager/pwmanager/pwmdoc.h2
-rw-r--r--pwmanager/pwmanager/pwmdocui.cpp12
3 files changed, 67 insertions, 12 deletions
diff --git a/pwmanager/pwmanager/pwmdoc.cpp b/pwmanager/pwmanager/pwmdoc.cpp
index e9906a4..f4a1636 100644
--- a/pwmanager/pwmanager/pwmdoc.cpp
+++ b/pwmanager/pwmanager/pwmdoc.cpp
@@ -1,46 +1,46 @@
/***************************************************************************
* *
* 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
+ * This file is originaly based on version 1.1 of pwmanager
* and was modified to run on embedded devices that run microkde
*
* $Id$
**************************************************************************/
#include "pwmdoc.h"
#include "pwmview.h"
#include "blowfish.h"
#include "sha1.h"
#include "globalstuff.h"
#include "gpasmanfile.h"
#include "serializer.h"
#include "compressgzip.h"
//US#include "compressbzip2.h"
#include "randomizer.h"
#include "pwminit.h"
#include "libgcryptif.h"
#ifdef PWM_EMBEDDED
#include "pwmprefs.h"
#include "kglobal.h"
#endif
#include <kmessagebox.h>
#include <libkcal/syncdefines.h>
#ifdef CONFIG_KWALLETIF
# include "kwalletemu.h"
#endif // CONFIG_KWALLETIF
#include <qdatetime.h>
#include <qsize.h>
@@ -301,144 +301,178 @@ void DocTimer::metaCheckTimeout()
PwMDocList PwMDoc::openDocList;
unsigned int PwMDocList::unnamedDocCnt = 1;
PwMDoc::PwMDoc(QObject *parent, const char *name)
: PwMDocUi(parent, name)
, dataChangedLock (0)
{
deleted = false;
unnamedNum = 0;
getOpenDocList()->add(this, getTitle().latin1());
curDocStat = 0;
setMaxNumEntries();
_timer = new DocTimer(this);
timer()->start(DocTimer::id_mpwTimer);
timer()->start(DocTimer::id_autoLockTimer);
timer()->start(DocTimer::id_metaCheckTimer);
addCategory(DEFAULT_CATEGORY, 0, false);
listView = 0;
emit docCreated(this);
}
PwMDoc::~PwMDoc()
{
emit docClosed(this);
getOpenDocList()->del(this);
delete _timer;
}
PwMerror PwMDoc::saveDoc(char compress, const QString *file)
{
PwMerror ret, e;
+ string serialized;
+ QFile f;
+ QString tmpFileMoved(QString::null);
+ bool wasDeepLocked;
+ QString savedFilename(filename);
+
if (!file) {
if (filename == "")
return e_filename;
- } else {
+ if (isDeepLocked()) {
+ /* We don't need to save any data.
+ * It's already all on disk, because
+ * we are deeplocked.
+ */
+ unsetDocStatFlag(DOC_STAT_DISK_DIRTY);
+ ret = e_success;
+ goto out;
+ }
+ } else {
if (*file == "" && filename == "")
return e_filename;
if (*file != "")
filename = *file;
}
- bool wasDeepLocked = isDeepLocked();
+ wasDeepLocked = isDeepLocked();
if (wasDeepLocked) {
- if (deepLock(false) != e_success)
- return e_noPw;
+ /* We are deeplocked. That means all data is already
+ * on disk. BUT we need to do saving procedure,
+ * because *file != savedFilename.
+ * Additionally we need to tempoarly restore
+ * the old "filename", because deepLock() references it.
+ */
+ QString newFilename(filename);
+ filename = savedFilename;
+ getDataChangedLock();
+ e = deepLock(false);
+ putDataChangedLock();
+ filename = newFilename;
+ switch (e) {
+ case e_success:
+ break;
+ case e_wrongPw:
+ case e_noPw:
+ emitDataChanged(this);
+ return e;
+ default:
+ emitDataChanged(this);
+ return e_openFile;
+ }
}
if (!isPwAvailable()) {
/* password is not available. This means, the
* document wasn't saved, yet.
*/
bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD);
QString pw(requestNewMpw(&useChipcard));
if (pw != "") {
currentPw = pw;
} else {
return e_noPw;
}
if (useChipcard) {
setDocStatFlag(DOC_STAT_USE_CHIPCARD);
} else {
unsetDocStatFlag(DOC_STAT_USE_CHIPCARD);
}
}
int _cryptAlgo = conf()->confGlobCryptAlgo();
int _hashAlgo = conf()->confGlobHashAlgo();
// sanity check for the selected algorithms
if (_cryptAlgo < PWM_CRYPT_BLOWFISH ||
_cryptAlgo > PWM_CRYPT_TWOFISH128) {
printWarn("Invalid Crypto-Algorithm selected! "
"Config-file seems to be corrupt. "
"Falling back to Blowfish.");
_cryptAlgo = PWM_CRYPT_BLOWFISH;
}
if (_hashAlgo < PWM_HASH_SHA1 ||
_hashAlgo > PWM_HASH_TIGER) {
printWarn("Invalid Hash-Algorithm selected! "
"Config-file seems to be corrupt. "
"Falling back to SHA1.");
_hashAlgo = PWM_HASH_SHA1;
}
char cryptAlgo = static_cast<char>(_cryptAlgo);
char hashAlgo = static_cast<char>(_hashAlgo);
if (conf()->confGlobMakeFileBackup()) {
if (!backupFile(filename))
return e_fileBackup;
}
- QString tmpFileMoved(QString::null);
if (QFile::exists(filename)) {
/* Move the existing file to some tmp file.
* When saving file succeeds, delete tmp file. Otherwise
* move tmp file back. See below.
*/
Randomizer *rnd = Randomizer::obj();
char rnd_buf[5];
sprintf(rnd_buf, "%X%X%X%X", rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF,
rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF);
tmpFileMoved = filename + "." + rnd_buf + ".mv";
if (!copyFile(filename, tmpFileMoved))
return e_openFile;
if (!QFile::remove(filename)) {
printWarn(string("removing orig file ")
+ filename.latin1()
+ " failed!");
}
}
- QFile f(filename);
- string serialized;
+ f.setName(filename);
if (!f.open(IO_ReadWrite)) {
ret = e_openFile;
goto out_moveback;
}
e = writeFileHeader(hashAlgo, hashAlgo,
cryptAlgo, compress,
&currentPw, &f);
if (e == e_hashNotImpl) {
printDebug("PwMDoc::saveDoc(): writeFileHeader() failed: e_hashNotImpl");
f.close();
ret = e_hashNotImpl;
goto out_moveback;
} else if (e != e_success) {
printDebug("PwMDoc::saveDoc(): writeFileHeader() failed");
f.close();
ret = e_writeHeader;
goto out_moveback;
}
if (!serializeDta(&serialized)) {
printDebug("PwMDoc::saveDoc(): serializeDta() failed");
f.close();
ret = e_serializeDta;
goto out_moveback;
}
e = writeDataHash(hashAlgo, &serialized, &f);
if (e == e_hashNotImpl) {
printDebug("PwMDoc::saveDoc(): writeDataHash() failed: e_hashNotImpl");
f.close();
ret = e_hashNotImpl;
goto out_moveback;
} else if (e != e_success) {
printDebug("PwMDoc::saveDoc(): writeDataHash() failed");
@@ -447,66 +481,74 @@ PwMerror PwMDoc::saveDoc(char compress, const QString *file)
goto out_moveback;
}
if (!compressDta(&serialized, compress)) {
printDebug("PwMDoc::saveDoc(): compressDta() failed");
f.close();
ret = e_enc;
goto out_moveback;
}
e = encrypt(&serialized, &currentPw, &f, cryptAlgo);
if (e == e_weakPw) {
printDebug("PwMDoc::saveDoc(): encrypt() failed: e_weakPw");
f.close();
ret = e_weakPw;
goto out_moveback;
} else if (e == e_cryptNotImpl) {
printDebug("PwMDoc::saveDoc(): encrypt() failed: e_cryptNotImpl");
f.close();
ret = e_cryptNotImpl;
goto out_moveback;
} else if (e != e_success) {
printDebug("PwMDoc::saveDoc(): encrypt() failed");
f.close();
ret = e_enc;
goto out_moveback;
}
unsetDocStatFlag(DOC_STAT_DISK_DIRTY);
f.close();
if (chmod(filename.latin1(),
conf()->confGlobFilePermissions())) {
printWarn(string("chmod failed: ") + strerror(errno));
}
openDocList.edit(this, getTitle().latin1());
- if (wasDeepLocked)
- deepLock(true);
+ if (wasDeepLocked) {
+ /* Do _not_ save the data with the deepLock()
+ * call, because this will recurse
+ * into saveDoc()
+ */
+ deepLock(true, false);
+ /* We don't check return value here, because
+ * it won't fail. See NOTE in deepLock()
+ */
+ }
if (tmpFileMoved != QString::null) {
// now remove the moved file.
if (!QFile::remove(tmpFileMoved)) {
printWarn(string("removing file ")
+ tmpFileMoved.latin1()
+ " failed!");
}
}
ret = e_success;
printDebug(string("writing file { name: ")
+ filename.latin1() + " compress: "
+ tostr(static_cast<int>(compress)) + " cryptAlgo: "
+ tostr(static_cast<int>(cryptAlgo)) + " hashAlgo: "
+ tostr(static_cast<int>(hashAlgo))
+ " }");
goto out;
out_moveback:
if (tmpFileMoved != QString::null) {
if (copyFile(tmpFileMoved, filename)) {
if (!QFile::remove(tmpFileMoved)) {
printWarn(string("removing tmp file ")
+ filename.latin1()
+ " failed!");
}
} else {
printWarn(string("couldn't copy file ")
+ tmpFileMoved.latin1()
+ " back to "
+ filename.latin1());
}
}
out:
@@ -1740,64 +1782,67 @@ bool PwMDoc::unlockAll_tempoary(bool revert)
oldLockStates = new vector< vector<bool> >;
vector<bool> tmp_vec;
vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(),
catEnd = dti.dta.end(),
catI = catBegin;
vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
while (catI != catEnd) {
entrBegin = catI->d.begin();
entrEnd = catI->d.end();
entrI = entrBegin;
while (entrI != entrEnd) {
if (!wasDeepLocked) {
tmp_vec.push_back(entrI->lockStat);
}
entrI->lockStat = false;
++entrI;
}
if (!wasDeepLocked) {
oldLockStates->push_back(tmp_vec);
tmp_vec.clear();
}
++catI;
}
printDebug("tempoary unlocked dta.");
}
return true;
}
PwMerror PwMDoc::deepLock(bool lock, bool saveToFile)
{
PwMerror ret;
+ /* NOTE: saveDoc() depends on this function to return
+ * e_success if saveToFile == false
+ */
if (lock) {
if (isDeepLocked())
return e_lock;
if (saveToFile) {
if (isDocEmpty())
return e_docIsEmpty;
ret = saveDoc(conf()->confGlobCompression());
if (ret == e_filename) {
/* the doc wasn't saved to a file
* by the user, yet.
*/
cantDeeplock_notSavedMsgBox();
return e_docNotSaved;
} else if (ret != e_success) {
return e_lock;
}
}
timer()->stop(DocTimer::id_autoLockTimer);
clearDoc();
PwMDataItem d;
d.desc = IS_DEEPLOCKED_SHORTMSG.latin1();
d.comment = IS_DEEPLOCKED_MSG.latin1();
d.listViewPos = 0;
addEntry(DEFAULT_CATEGORY, &d, true);
lockAt(DEFAULT_CATEGORY, 0, true);
unsetDocStatFlag(DOC_STAT_DISK_DIRTY);
setDocStatFlag(DOC_STAT_DEEPLOCKED);
} else {
if (!isDeepLocked())
return e_lock;
ret = openDoc(&filename, (conf()->confGlobUnlockOnOpen())
diff --git a/pwmanager/pwmanager/pwmdoc.h b/pwmanager/pwmanager/pwmdoc.h
index 535fb92..a6e5f58 100644
--- a/pwmanager/pwmanager/pwmdoc.h
+++ b/pwmanager/pwmanager/pwmdoc.h
@@ -1,46 +1,46 @@
/***************************************************************************
* *
* 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
+ * This file is originaly based on version 1.1 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"
diff --git a/pwmanager/pwmanager/pwmdocui.cpp b/pwmanager/pwmanager/pwmdocui.cpp
index 7b8e0ee..6ddb6f5 100644
--- a/pwmanager/pwmanager/pwmdocui.cpp
+++ b/pwmanager/pwmanager/pwmdocui.cpp
@@ -244,110 +244,120 @@ int PwMDocUi::dirtyAskSave(const QString &docTitle)
}
bool PwMDocUi::saveDocUi(PwMDoc *doc)
{
PWM_ASSERT(doc);
doc->timer()->getLock(DocTimer::id_autoLockTimer);
if (doc->isDocEmpty()) {
KMessageBox::information(currentView,
i18n
("Sorry, there's nothing to save.\n"
"Please first add some passwords."),
i18n("nothing to do"));
doc->timer()->putLock(DocTimer::id_autoLockTimer);
return true;
}
PwMerror ret = doc->saveDoc(conf()->confGlobCompression());
if (ret == e_filename) {
doc->timer()->putLock(DocTimer::id_autoLockTimer);
return saveAsDocUi(doc);
} else if (ret == e_weakPw) {
KMessageBox::error(currentView,
i18n("Error: This is a weak password.\n"
"Please select another password."),
i18n("weak password"));
doc->timer()->putLock(DocTimer::id_autoLockTimer);
return false;
} else if (ret == e_fileBackup) {
KMessageBox::error(currentView,
i18n("Error: Couldn't make backup-file!"),
i18n("backup failed"));
doc->timer()->putLock(DocTimer::id_autoLockTimer);
return false;
+ } else if (ret == e_noPw ||
+ ret == e_wrongPw ||
+ ret == e_openFile) {
+ doc->timer()->putLock(DocTimer::id_autoLockTimer);
+ return false;
} else if (ret != e_success) {
KMessageBox::error(currentView,
i18n("Error: Couldn't write to file.\n"
"Please check if you have permission to\n"
"write to the file in that directory."),
i18n("error while writing"));
doc->timer()->putLock(DocTimer::id_autoLockTimer);
return false;
}
doc->timer()->putLock(DocTimer::id_autoLockTimer);
return true;
}
bool PwMDocUi::saveAsDocUi(PwMDoc *doc)
{
PWM_ASSERT(doc);
doc->timer()->getLock(DocTimer::id_autoLockTimer);
if (doc->isDocEmpty()) {
KMessageBox::information(currentView,
i18n
("Sorry, there's nothing to save.\n"
"Please first add some passwords."),
i18n("nothing to do"));
doc->timer()->putLock(DocTimer::id_autoLockTimer);
return true;
}
#ifndef PWM_EMBEDDED
QString fn(KFileDialog::getSaveFileName(QString::null,
i18n("*.pwm|PwManager Password file"),
currentView));
#else
QString fn = locateLocal( "data", KGlobal::getAppName() + "/*.pwm" );
fn = KFileDialog::getSaveFileName(fn,
i18n("password filename(*.pwm)"),
currentView);
#endif
if (fn == "") {
doc->timer()->putLock(DocTimer::id_autoLockTimer);
return false;
}
if (fn.right(4) != ".pwm")
fn += ".pwm";
PwMerror ret = doc->saveDoc(conf()->confGlobCompression(), &fn);
- if (ret != e_success) {
+ if (ret == e_noPw ||
+ ret == e_wrongPw ||
+ ret == e_openFile) {
+ doc->timer()->putLock(DocTimer::id_autoLockTimer);
+ return false;
+ } else if (ret != e_success) {
KMessageBox::error(currentView,
i18n("Error: Couldn't write to file.\n"
"Please check if you have permission to\n"
"write to the file in that directory."),
i18n("error while writing"));
doc->timer()->putLock(DocTimer::id_autoLockTimer);
return false;
}
doc->timer()->putLock(DocTimer::id_autoLockTimer);
return true;
}
bool PwMDocUi::openDocUi(PwMDoc *doc,
QString filename,
bool openDeepLocked)
{
if (filename.isEmpty())
{
#ifndef PWM_EMBEDDED
filename = KFileDialog::getOpenFileName(QString::null,
i18n("*.pwm|PwManager Password file\n"
"*|All files"), getCurrentView());
#else
filename = locateLocal( "data", KGlobal::getAppName() + "/*.pwm");
filename = KFileDialog::getOpenFileName(filename,
i18n("password filename(*.pwm)"), getCurrentView());
#endif
}
if (filename.isEmpty())
goto cancelOpen;
PwMerror ret;
while (true) {