-rw-r--r-- | pwmanager/pwmanager/pwmdoc.cpp | 65 | ||||
-rw-r--r-- | pwmanager/pwmanager/pwmdoc.h | 2 | ||||
-rw-r--r-- | pwmanager/pwmanager/pwmdocui.cpp | 12 |
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 | |||
@@ -2,25 +2,25 @@ | |||
2 | * * | 2 | * * |
3 | * copyright (C) 2003, 2004 by Michael Buesch * | 3 | * copyright (C) 2003, 2004 by Michael Buesch * |
4 | * email: mbuesch@freenet.de * | 4 | * email: mbuesch@freenet.de * |
5 | * * | 5 | * * |
6 | * This program is free software; you can redistribute it and/or modify * | 6 | * This program is free software; you can redistribute it and/or modify * |
7 | * it under the terms of the GNU General Public License version 2 * | 7 | * it under the terms of the GNU General Public License version 2 * |
8 | * as published by the Free Software Foundation. * | 8 | * as published by the Free Software Foundation. * |
9 | * * | 9 | * * |
10 | ***************************************************************************/ | 10 | ***************************************************************************/ |
11 | 11 | ||
12 | /*************************************************************************** | 12 | /*************************************************************************** |
13 | * copyright (C) 2004 by Ulf Schenk | 13 | * copyright (C) 2004 by Ulf Schenk |
14 | * This file is originaly based on version 2.0 of pwmanager | 14 | * This file is originaly based on version 1.1 of pwmanager |
15 | * and was modified to run on embedded devices that run microkde | 15 | * and was modified to run on embedded devices that run microkde |
16 | * | 16 | * |
17 | * $Id$ | 17 | * $Id$ |
18 | **************************************************************************/ | 18 | **************************************************************************/ |
19 | 19 | ||
20 | #include "pwmdoc.h" | 20 | #include "pwmdoc.h" |
21 | #include "pwmview.h" | 21 | #include "pwmview.h" |
22 | #include "blowfish.h" | 22 | #include "blowfish.h" |
23 | #include "sha1.h" | 23 | #include "sha1.h" |
24 | #include "globalstuff.h" | 24 | #include "globalstuff.h" |
25 | #include "gpasmanfile.h" | 25 | #include "gpasmanfile.h" |
26 | #include "serializer.h" | 26 | #include "serializer.h" |
@@ -321,38 +321,74 @@ PwMDoc::PwMDoc(QObject *parent, const char *name) | |||
321 | } | 321 | } |
322 | 322 | ||
323 | PwMDoc::~PwMDoc() | 323 | PwMDoc::~PwMDoc() |
324 | { | 324 | { |
325 | emit docClosed(this); | 325 | emit docClosed(this); |
326 | getOpenDocList()->del(this); | 326 | getOpenDocList()->del(this); |
327 | delete _timer; | 327 | delete _timer; |
328 | } | 328 | } |
329 | 329 | ||
330 | PwMerror PwMDoc::saveDoc(char compress, const QString *file) | 330 | PwMerror PwMDoc::saveDoc(char compress, const QString *file) |
331 | { | 331 | { |
332 | PwMerror ret, e; | 332 | PwMerror ret, e; |
333 | string serialized; | ||
334 | QFile f; | ||
335 | QString tmpFileMoved(QString::null); | ||
336 | bool wasDeepLocked; | ||
337 | QString savedFilename(filename); | ||
338 | |||
333 | if (!file) { | 339 | if (!file) { |
334 | if (filename == "") | 340 | if (filename == "") |
335 | return e_filename; | 341 | return e_filename; |
336 | } else { | 342 | if (isDeepLocked()) { |
343 | /* We don't need to save any data. | ||
344 | * It's already all on disk, because | ||
345 | * we are deeplocked. | ||
346 | */ | ||
347 | unsetDocStatFlag(DOC_STAT_DISK_DIRTY); | ||
348 | ret = e_success; | ||
349 | goto out; | ||
350 | } | ||
351 | } else { | ||
337 | if (*file == "" && filename == "") | 352 | if (*file == "" && filename == "") |
338 | return e_filename; | 353 | return e_filename; |
339 | if (*file != "") | 354 | if (*file != "") |
340 | filename = *file; | 355 | filename = *file; |
341 | } | 356 | } |
342 | 357 | ||
343 | bool wasDeepLocked = isDeepLocked(); | 358 | wasDeepLocked = isDeepLocked(); |
344 | if (wasDeepLocked) { | 359 | if (wasDeepLocked) { |
345 | if (deepLock(false) != e_success) | 360 | /* We are deeplocked. That means all data is already |
346 | return e_noPw; | 361 | * on disk. BUT we need to do saving procedure, |
362 | * because *file != savedFilename. | ||
363 | * Additionally we need to tempoarly restore | ||
364 | * the old "filename", because deepLock() references it. | ||
365 | */ | ||
366 | QString newFilename(filename); | ||
367 | filename = savedFilename; | ||
368 | getDataChangedLock(); | ||
369 | e = deepLock(false); | ||
370 | putDataChangedLock(); | ||
371 | filename = newFilename; | ||
372 | switch (e) { | ||
373 | case e_success: | ||
374 | break; | ||
375 | case e_wrongPw: | ||
376 | case e_noPw: | ||
377 | emitDataChanged(this); | ||
378 | return e; | ||
379 | default: | ||
380 | emitDataChanged(this); | ||
381 | return e_openFile; | ||
382 | } | ||
347 | } | 383 | } |
348 | 384 | ||
349 | if (!isPwAvailable()) { | 385 | if (!isPwAvailable()) { |
350 | /* password is not available. This means, the | 386 | /* password is not available. This means, the |
351 | * document wasn't saved, yet. | 387 | * document wasn't saved, yet. |
352 | */ | 388 | */ |
353 | bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD); | 389 | bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD); |
354 | QString pw(requestNewMpw(&useChipcard)); | 390 | QString pw(requestNewMpw(&useChipcard)); |
355 | if (pw != "") { | 391 | if (pw != "") { |
356 | currentPw = pw; | 392 | currentPw = pw; |
357 | } else { | 393 | } else { |
358 | return e_noPw; | 394 | return e_noPw; |
@@ -380,45 +416,43 @@ PwMerror PwMDoc::saveDoc(char compress, const QString *file) | |||
380 | printWarn("Invalid Hash-Algorithm selected! " | 416 | printWarn("Invalid Hash-Algorithm selected! " |
381 | "Config-file seems to be corrupt. " | 417 | "Config-file seems to be corrupt. " |
382 | "Falling back to SHA1."); | 418 | "Falling back to SHA1."); |
383 | _hashAlgo = PWM_HASH_SHA1; | 419 | _hashAlgo = PWM_HASH_SHA1; |
384 | } | 420 | } |
385 | char cryptAlgo = static_cast<char>(_cryptAlgo); | 421 | char cryptAlgo = static_cast<char>(_cryptAlgo); |
386 | char hashAlgo = static_cast<char>(_hashAlgo); | 422 | char hashAlgo = static_cast<char>(_hashAlgo); |
387 | 423 | ||
388 | if (conf()->confGlobMakeFileBackup()) { | 424 | if (conf()->confGlobMakeFileBackup()) { |
389 | if (!backupFile(filename)) | 425 | if (!backupFile(filename)) |
390 | return e_fileBackup; | 426 | return e_fileBackup; |
391 | } | 427 | } |
392 | QString tmpFileMoved(QString::null); | ||
393 | if (QFile::exists(filename)) { | 428 | if (QFile::exists(filename)) { |
394 | /* Move the existing file to some tmp file. | 429 | /* Move the existing file to some tmp file. |
395 | * When saving file succeeds, delete tmp file. Otherwise | 430 | * When saving file succeeds, delete tmp file. Otherwise |
396 | * move tmp file back. See below. | 431 | * move tmp file back. See below. |
397 | */ | 432 | */ |
398 | Randomizer *rnd = Randomizer::obj(); | 433 | Randomizer *rnd = Randomizer::obj(); |
399 | char rnd_buf[5]; | 434 | char rnd_buf[5]; |
400 | sprintf(rnd_buf, "%X%X%X%X", rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF, | 435 | sprintf(rnd_buf, "%X%X%X%X", rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF, |
401 | rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF); | 436 | rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF); |
402 | tmpFileMoved = filename + "." + rnd_buf + ".mv"; | 437 | tmpFileMoved = filename + "." + rnd_buf + ".mv"; |
403 | if (!copyFile(filename, tmpFileMoved)) | 438 | if (!copyFile(filename, tmpFileMoved)) |
404 | return e_openFile; | 439 | return e_openFile; |
405 | if (!QFile::remove(filename)) { | 440 | if (!QFile::remove(filename)) { |
406 | printWarn(string("removing orig file ") | 441 | printWarn(string("removing orig file ") |
407 | + filename.latin1() | 442 | + filename.latin1() |
408 | + " failed!"); | 443 | + " failed!"); |
409 | } | 444 | } |
410 | } | 445 | } |
411 | QFile f(filename); | 446 | f.setName(filename); |
412 | string serialized; | ||
413 | if (!f.open(IO_ReadWrite)) { | 447 | if (!f.open(IO_ReadWrite)) { |
414 | ret = e_openFile; | 448 | ret = e_openFile; |
415 | goto out_moveback; | 449 | goto out_moveback; |
416 | } | 450 | } |
417 | e = writeFileHeader(hashAlgo, hashAlgo, | 451 | e = writeFileHeader(hashAlgo, hashAlgo, |
418 | cryptAlgo, compress, | 452 | cryptAlgo, compress, |
419 | ¤tPw, &f); | 453 | ¤tPw, &f); |
420 | if (e == e_hashNotImpl) { | 454 | if (e == e_hashNotImpl) { |
421 | printDebug("PwMDoc::saveDoc(): writeFileHeader() failed: e_hashNotImpl"); | 455 | printDebug("PwMDoc::saveDoc(): writeFileHeader() failed: e_hashNotImpl"); |
422 | f.close(); | 456 | f.close(); |
423 | ret = e_hashNotImpl; | 457 | ret = e_hashNotImpl; |
424 | goto out_moveback; | 458 | goto out_moveback; |
@@ -467,26 +501,34 @@ PwMerror PwMDoc::saveDoc(char compress, const QString *file) | |||
467 | printDebug("PwMDoc::saveDoc(): encrypt() failed"); | 501 | printDebug("PwMDoc::saveDoc(): encrypt() failed"); |
468 | f.close(); | 502 | f.close(); |
469 | ret = e_enc; | 503 | ret = e_enc; |
470 | goto out_moveback; | 504 | goto out_moveback; |
471 | } | 505 | } |
472 | unsetDocStatFlag(DOC_STAT_DISK_DIRTY); | 506 | unsetDocStatFlag(DOC_STAT_DISK_DIRTY); |
473 | f.close(); | 507 | f.close(); |
474 | if (chmod(filename.latin1(), | 508 | if (chmod(filename.latin1(), |
475 | conf()->confGlobFilePermissions())) { | 509 | conf()->confGlobFilePermissions())) { |
476 | printWarn(string("chmod failed: ") + strerror(errno)); | 510 | printWarn(string("chmod failed: ") + strerror(errno)); |
477 | } | 511 | } |
478 | openDocList.edit(this, getTitle().latin1()); | 512 | openDocList.edit(this, getTitle().latin1()); |
479 | if (wasDeepLocked) | 513 | if (wasDeepLocked) { |
480 | deepLock(true); | 514 | /* Do _not_ save the data with the deepLock() |
515 | * call, because this will recurse | ||
516 | * into saveDoc() | ||
517 | */ | ||
518 | deepLock(true, false); | ||
519 | /* We don't check return value here, because | ||
520 | * it won't fail. See NOTE in deepLock() | ||
521 | */ | ||
522 | } | ||
481 | if (tmpFileMoved != QString::null) { | 523 | if (tmpFileMoved != QString::null) { |
482 | // now remove the moved file. | 524 | // now remove the moved file. |
483 | if (!QFile::remove(tmpFileMoved)) { | 525 | if (!QFile::remove(tmpFileMoved)) { |
484 | printWarn(string("removing file ") | 526 | printWarn(string("removing file ") |
485 | + tmpFileMoved.latin1() | 527 | + tmpFileMoved.latin1() |
486 | + " failed!"); | 528 | + " failed!"); |
487 | } | 529 | } |
488 | } | 530 | } |
489 | ret = e_success; | 531 | ret = e_success; |
490 | printDebug(string("writing file { name: ") | 532 | printDebug(string("writing file { name: ") |
491 | + filename.latin1() + " compress: " | 533 | + filename.latin1() + " compress: " |
492 | + tostr(static_cast<int>(compress)) + " cryptAlgo: " | 534 | + tostr(static_cast<int>(compress)) + " cryptAlgo: " |
@@ -1760,24 +1802,27 @@ bool PwMDoc::unlockAll_tempoary(bool revert) | |||
1760 | } | 1802 | } |
1761 | ++catI; | 1803 | ++catI; |
1762 | } | 1804 | } |
1763 | printDebug("tempoary unlocked dta."); | 1805 | printDebug("tempoary unlocked dta."); |
1764 | } | 1806 | } |
1765 | 1807 | ||
1766 | return true; | 1808 | return true; |
1767 | } | 1809 | } |
1768 | 1810 | ||
1769 | PwMerror PwMDoc::deepLock(bool lock, bool saveToFile) | 1811 | PwMerror PwMDoc::deepLock(bool lock, bool saveToFile) |
1770 | { | 1812 | { |
1771 | PwMerror ret; | 1813 | PwMerror ret; |
1814 | /* NOTE: saveDoc() depends on this function to return | ||
1815 | * e_success if saveToFile == false | ||
1816 | */ | ||
1772 | 1817 | ||
1773 | if (lock) { | 1818 | if (lock) { |
1774 | if (isDeepLocked()) | 1819 | if (isDeepLocked()) |
1775 | return e_lock; | 1820 | return e_lock; |
1776 | if (saveToFile) { | 1821 | if (saveToFile) { |
1777 | if (isDocEmpty()) | 1822 | if (isDocEmpty()) |
1778 | return e_docIsEmpty; | 1823 | return e_docIsEmpty; |
1779 | ret = saveDoc(conf()->confGlobCompression()); | 1824 | ret = saveDoc(conf()->confGlobCompression()); |
1780 | if (ret == e_filename) { | 1825 | if (ret == e_filename) { |
1781 | /* the doc wasn't saved to a file | 1826 | /* the doc wasn't saved to a file |
1782 | * by the user, yet. | 1827 | * by the user, yet. |
1783 | */ | 1828 | */ |
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 | |||
@@ -2,25 +2,25 @@ | |||
2 | * * | 2 | * * |
3 | * copyright (C) 2003, 2004 by Michael Buesch * | 3 | * copyright (C) 2003, 2004 by Michael Buesch * |
4 | * email: mbuesch@freenet.de * | 4 | * email: mbuesch@freenet.de * |
5 | * * | 5 | * * |
6 | * This program is free software; you can redistribute it and/or modify * | 6 | * This program is free software; you can redistribute it and/or modify * |
7 | * it under the terms of the GNU General Public License version 2 * | 7 | * it under the terms of the GNU General Public License version 2 * |
8 | * as published by the Free Software Foundation. * | 8 | * as published by the Free Software Foundation. * |
9 | * * | 9 | * * |
10 | ***************************************************************************/ | 10 | ***************************************************************************/ |
11 | 11 | ||
12 | /*************************************************************************** | 12 | /*************************************************************************** |
13 | * copyright (C) 2004 by Ulf Schenk | 13 | * copyright (C) 2004 by Ulf Schenk |
14 | * This file is originaly based on version 2.0 of pwmanager | 14 | * This file is originaly based on version 1.1 of pwmanager |
15 | * and was modified to run on embedded devices that run microkde | 15 | * and was modified to run on embedded devices that run microkde |
16 | * | 16 | * |
17 | * $Id$ | 17 | * $Id$ |
18 | **************************************************************************/ | 18 | **************************************************************************/ |
19 | 19 | ||
20 | #ifndef __PWMDOC_H | 20 | #ifndef __PWMDOC_H |
21 | #define __PWMDOC_H | 21 | #define __PWMDOC_H |
22 | 22 | ||
23 | #define PWM_FILE_VER (static_cast<char>(0x05)) | 23 | #define PWM_FILE_VER (static_cast<char>(0x05)) |
24 | 24 | ||
25 | #define PWM_HASH_SHA1 (static_cast<char>(0x01)) | 25 | #define PWM_HASH_SHA1 (static_cast<char>(0x01)) |
26 | #define PWM_HASH_SHA256 (static_cast<char>(0x02)) | 26 | #define PWM_HASH_SHA256 (static_cast<char>(0x02)) |
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 | |||
@@ -264,24 +264,29 @@ bool PwMDocUi::saveDocUi(PwMDoc *doc) | |||
264 | KMessageBox::error(currentView, | 264 | KMessageBox::error(currentView, |
265 | i18n("Error: This is a weak password.\n" | 265 | i18n("Error: This is a weak password.\n" |
266 | "Please select another password."), | 266 | "Please select another password."), |
267 | i18n("weak password")); | 267 | i18n("weak password")); |
268 | doc->timer()->putLock(DocTimer::id_autoLockTimer); | 268 | doc->timer()->putLock(DocTimer::id_autoLockTimer); |
269 | return false; | 269 | return false; |
270 | } else if (ret == e_fileBackup) { | 270 | } else if (ret == e_fileBackup) { |
271 | KMessageBox::error(currentView, | 271 | KMessageBox::error(currentView, |
272 | i18n("Error: Couldn't make backup-file!"), | 272 | i18n("Error: Couldn't make backup-file!"), |
273 | i18n("backup failed")); | 273 | i18n("backup failed")); |
274 | doc->timer()->putLock(DocTimer::id_autoLockTimer); | 274 | doc->timer()->putLock(DocTimer::id_autoLockTimer); |
275 | return false; | 275 | return false; |
276 | } else if (ret == e_noPw || | ||
277 | ret == e_wrongPw || | ||
278 | ret == e_openFile) { | ||
279 | doc->timer()->putLock(DocTimer::id_autoLockTimer); | ||
280 | return false; | ||
276 | } else if (ret != e_success) { | 281 | } else if (ret != e_success) { |
277 | KMessageBox::error(currentView, | 282 | KMessageBox::error(currentView, |
278 | i18n("Error: Couldn't write to file.\n" | 283 | i18n("Error: Couldn't write to file.\n" |
279 | "Please check if you have permission to\n" | 284 | "Please check if you have permission to\n" |
280 | "write to the file in that directory."), | 285 | "write to the file in that directory."), |
281 | i18n("error while writing")); | 286 | i18n("error while writing")); |
282 | doc->timer()->putLock(DocTimer::id_autoLockTimer); | 287 | doc->timer()->putLock(DocTimer::id_autoLockTimer); |
283 | return false; | 288 | return false; |
284 | } | 289 | } |
285 | doc->timer()->putLock(DocTimer::id_autoLockTimer); | 290 | doc->timer()->putLock(DocTimer::id_autoLockTimer); |
286 | return true; | 291 | return true; |
287 | } | 292 | } |
@@ -309,25 +314,30 @@ bool PwMDocUi::saveAsDocUi(PwMDoc *doc) | |||
309 | i18n("password filename(*.pwm)"), | 314 | i18n("password filename(*.pwm)"), |
310 | currentView); | 315 | currentView); |
311 | 316 | ||
312 | #endif | 317 | #endif |
313 | if (fn == "") { | 318 | if (fn == "") { |
314 | doc->timer()->putLock(DocTimer::id_autoLockTimer); | 319 | doc->timer()->putLock(DocTimer::id_autoLockTimer); |
315 | return false; | 320 | return false; |
316 | } | 321 | } |
317 | if (fn.right(4) != ".pwm") | 322 | if (fn.right(4) != ".pwm") |
318 | fn += ".pwm"; | 323 | fn += ".pwm"; |
319 | 324 | ||
320 | PwMerror ret = doc->saveDoc(conf()->confGlobCompression(), &fn); | 325 | PwMerror ret = doc->saveDoc(conf()->confGlobCompression(), &fn); |
321 | if (ret != e_success) { | 326 | if (ret == e_noPw || |
327 | ret == e_wrongPw || | ||
328 | ret == e_openFile) { | ||
329 | doc->timer()->putLock(DocTimer::id_autoLockTimer); | ||
330 | return false; | ||
331 | } else if (ret != e_success) { | ||
322 | KMessageBox::error(currentView, | 332 | KMessageBox::error(currentView, |
323 | i18n("Error: Couldn't write to file.\n" | 333 | i18n("Error: Couldn't write to file.\n" |
324 | "Please check if you have permission to\n" | 334 | "Please check if you have permission to\n" |
325 | "write to the file in that directory."), | 335 | "write to the file in that directory."), |
326 | i18n("error while writing")); | 336 | i18n("error while writing")); |
327 | doc->timer()->putLock(DocTimer::id_autoLockTimer); | 337 | doc->timer()->putLock(DocTimer::id_autoLockTimer); |
328 | return false; | 338 | return false; |
329 | } | 339 | } |
330 | doc->timer()->putLock(DocTimer::id_autoLockTimer); | 340 | doc->timer()->putLock(DocTimer::id_autoLockTimer); |
331 | return true; | 341 | return true; |
332 | } | 342 | } |
333 | 343 | ||