summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--pwmanager/pwmanager/libgcryptif.cpp420
-rw-r--r--pwmanager/pwmanager/libgcryptif.h5
-rw-r--r--pwmanager/pwmanager/pwmanagerE.pro10
-rw-r--r--pwmanager/pwmanager/pwmdoc.cpp77
4 files changed, 446 insertions, 66 deletions
diff --git a/pwmanager/pwmanager/libgcryptif.cpp b/pwmanager/pwmanager/libgcryptif.cpp
index 8e55144..6f3a994 100644
--- a/pwmanager/pwmanager/libgcryptif.cpp
+++ b/pwmanager/pwmanager/libgcryptif.cpp
@@ -340,96 +340,516 @@ bool LibGCryptIf::doHashPassphrase(DEK *dek,
340 bool ret = true; 340 bool ret = true;
341 size_t pass, i; 341 size_t pass, i;
342 size_t used = 0; 342 size_t used = 0;
343 343
344 PWM_ASSERT(s2k->hash_algo); 344 PWM_ASSERT(s2k->hash_algo);
345 BUG_ON(!(dek->keylen > 0 && dek->keylen <= array_size(dek->key))); 345 BUG_ON(!(dek->keylen > 0 && dek->keylen <= array_size(dek->key)));
346 346
347 err = gcry_md_open(&md, s2k->hash_algo, 0); 347 err = gcry_md_open(&md, s2k->hash_algo, 0);
348 if (err != GPG_ERR_NO_ERROR) { 348 if (err != GPG_ERR_NO_ERROR) {
349 ret = false; 349 ret = false;
350 goto out; 350 goto out;
351 } 351 }
352 for (pass = 0; used < dek->keylen; pass++) { 352 for (pass = 0; used < dek->keylen; pass++) {
353 if (pass) { 353 if (pass) {
354 gcry_md_reset(md); 354 gcry_md_reset(md);
355 for (i = 0; i < pass; i++) // preset the hash context 355 for (i = 0; i < pass; i++) // preset the hash context
356 gcry_md_putc(md, 0); 356 gcry_md_putc(md, 0);
357 } 357 }
358 if (s2k->mode == 1 || s2k->mode == 3) { 358 if (s2k->mode == 1 || s2k->mode == 3) {
359 size_t len2 = pwlen + 8; 359 size_t len2 = pwlen + 8;
360 size_t count = len2; 360 size_t count = len2;
361 361
362 if (create && !pass) { 362 if (create && !pass) {
363 Randomizer *rnd = Randomizer::obj(); 363 Randomizer *rnd = Randomizer::obj();
364 const unsigned int salt_len = 8; 364 const unsigned int salt_len = 8;
365 string rndBuf(rnd->genRndBuf(salt_len)); 365 string rndBuf(rnd->genRndBuf(salt_len));
366 memcpy(s2k->salt, rndBuf.c_str(), salt_len); 366 memcpy(s2k->salt, rndBuf.c_str(), salt_len);
367 if (s2k->mode == 3) 367 if (s2k->mode == 3)
368 s2k->count = 96; // 65536 iterations 368 s2k->count = 96; // 65536 iterations
369 } 369 }
370 if (s2k->mode == 3) { 370 if (s2k->mode == 3) {
371 count = (16ul + (s2k->count & 15)) << ((s2k->count >> 4) + 6); 371 count = (16ul + (s2k->count & 15)) << ((s2k->count >> 4) + 6);
372 if (count < len2) 372 if (count < len2)
373 count = len2; 373 count = len2;
374 } 374 }
375 // a little bit complicated because we need a ulong for count 375 // a little bit complicated because we need a ulong for count
376 while (count > len2) { // maybe iterated+salted 376 while (count > len2) { // maybe iterated+salted
377 gcry_md_write(md, s2k->salt, 8); 377 gcry_md_write(md, s2k->salt, 8);
378 gcry_md_write(md, pw, pwlen); 378 gcry_md_write(md, pw, pwlen);
379 count -= len2; 379 count -= len2;
380 } 380 }
381 if (count < 8) { 381 if (count < 8) {
382 gcry_md_write(md, s2k->salt, count); 382 gcry_md_write(md, s2k->salt, count);
383 } else { 383 } else {
384 gcry_md_write(md, s2k->salt, 8); 384 gcry_md_write(md, s2k->salt, 8);
385 count -= 8; 385 count -= 8;
386 gcry_md_write(md, pw, count); 386 gcry_md_write(md, pw, count);
387 } 387 }
388 } else 388 } else
389 gcry_md_write(md, pw, pwlen); 389 gcry_md_write(md, pw, pwlen);
390 gcry_md_final(md); 390 gcry_md_final(md);
391 i = gcry_md_get_algo_dlen(s2k->hash_algo); 391 i = gcry_md_get_algo_dlen(s2k->hash_algo);
392 if (i > dek->keylen - used) 392 if (i > dek->keylen - used)
393 i = dek->keylen - used; 393 i = dek->keylen - used;
394 memcpy(dek->key+used, gcry_md_read(md, s2k->hash_algo), i); 394 memcpy(dek->key+used, gcry_md_read(md, s2k->hash_algo), i);
395 used += i; 395 used += i;
396 } 396 }
397 gcry_md_close(md); 397 gcry_md_close(md);
398out: 398out:
399 return ret; 399 return ret;
400} 400}
401 401
402void LibGCryptIf::padData(unsigned char *buf, 402void LibGCryptIf::padData(unsigned char *buf,
403 size_t bufLen, 403 size_t bufLen,
404 size_t boundary) 404 size_t boundary)
405{ 405{
406 size_t numPadBytes = boundary - ((bufLen + 1) % boundary); 406 size_t numPadBytes = boundary - ((bufLen + 1) % boundary);
407 buf[bufLen] = static_cast<char>(0x01); 407 buf[bufLen] = static_cast<char>(0x01);
408 size_t i = 0; 408 size_t i = 0;
409 Randomizer *rnd = Randomizer::obj(); 409 Randomizer *rnd = Randomizer::obj();
410 char c; 410 char c;
411 unsigned char *b; 411 unsigned char *b;
412 while (i < numPadBytes) { 412 while (i < numPadBytes) {
413 c = rnd->genRndChar(); 413 c = rnd->genRndChar();
414 if (c == static_cast<char>(0x01)) 414 if (c == static_cast<char>(0x01))
415 continue; 415 continue;
416 b = buf + bufLen + 1 + i; 416 b = buf + bufLen + 1 + i;
417 *b = c; 417 *b = c;
418 ++i; 418 ++i;
419 } 419 }
420} 420}
421 421
422void LibGCryptIf::unpadData(const unsigned char *buf, 422void LibGCryptIf::unpadData(const unsigned char *buf,
423 size_t *bufLen) 423 size_t *bufLen)
424{ 424{
425 size_t pos; 425 size_t pos;
426 BUG_ON(*bufLen % 8); 426 BUG_ON(*bufLen % 8);
427 pos = *bufLen - 1; 427 pos = *bufLen - 1;
428 while (buf[pos] != static_cast<char>(0x01)) { 428 while (buf[pos] != static_cast<char>(0x01)) {
429 BUG_ON(!pos); 429 BUG_ON(!pos);
430 --pos; 430 --pos;
431 } 431 }
432 *bufLen = pos; 432 *bufLen = pos;
433} 433}
434 434
435#endif // CONFIG_PWMANAGER_GCRY 435#endif // CONFIG_PWMANAGER_GCRY
436
437#ifdef CONFIG_PWMANAGER_CRYPTO
438
439#include "pwmdoc.h"
440#include "randomizer.h"
441
442#include <openssl/crypto.h>
443
444PwMerror LibGCryptIf::encrypt(unsigned char **outBuf,
445 size_t *outBufLen,
446 unsigned char *inBuf,
447 size_t inBufLen,
448 const unsigned char *key,
449 size_t keylen,
450 char _algo)
451{
452 PwMerror ret = e_success;
453 gcry_error_t err;
454 gcry_cipher_hd_t handle;
455 size_t blklen;
456 size_t unpaddedLen = inBufLen;
457 size_t cipherKeylen;
458 unsigned char *hashedKey;
459 unsigned char salt[STRING2KEY_SALTLEN];
460 int algo = mapCipherId(_algo);
461
462 if (!inBufLen || !keylen)
463 return e_invalidArg;
464
465 // test if algo is ready for encryption
466 err = gcry_cipher_algo_info(algo,
467 GCRYCTL_TEST_ALGO,
468 0, 0);
469 if (err != GPG_ERR_NO_ERROR) {
470 printDebug(string("LibGCryptIf::doEncrypt(): GCRYCTL_TEST_ALGO failed: ")
471 + gcry_strerror(err));
472 ret = e_cryptNotImpl;
473 goto out;
474 }
475 // get the algo block length
476 err = gcry_cipher_algo_info(algo,
477 GCRYCTL_GET_BLKLEN,
478 0,
479 &blklen);
480 if (err != GPG_ERR_NO_ERROR) {
481 printDebug(string("LibGCryptIf::doEncrypt(): GCRYCTL_GET_BLKLEN failed: ")
482 + gcry_strerror(err));
483 ret = e_cryptNotImpl;
484 goto out;
485 }
486 /* double check if we have enough space.
487 * We have only 1024 extra bytes for padding and salt.
488 */
489 BUG_ON(blklen > 1024 - STRING2KEY_SALTLEN);
490 // get the algo key length
491 err = gcry_cipher_algo_info(algo,
492 GCRYCTL_GET_KEYLEN,
493 0,
494 &cipherKeylen);
495 if (err != GPG_ERR_NO_ERROR) {
496 printDebug(string("LibGCryptIf::doEncrypt(): GCRYCTL_GET_KEYLEN failed: ")
497 + gcry_strerror(err));
498 ret = e_cryptNotImpl;
499 goto out;
500 }
501 // now open the algo and get a handle
502 err = gcry_cipher_open(&handle,
503 algo,
504 GCRY_CIPHER_MODE_CBC,
505 0);
506 if (err != GPG_ERR_NO_ERROR) {
507 printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_open() failed: ")
508 + gcry_strerror(err));
509 ret = e_cryptNotImpl;
510 goto out;
511 }
512 // hash the "key" to a fixed size hash matching "cipherKeylen"
513 hashedKey = new unsigned char[cipherKeylen];
514 hashPassphrase(key, keylen, salt, hashedKey, cipherKeylen, true);
515 // so now set the hashed key
516 err = gcry_cipher_setkey(handle, hashedKey, cipherKeylen);
517 if (err != GPG_ERR_NO_ERROR) {
518 printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_setkey() failed: ")
519 + gcry_strerror(err));
520 ret = e_cryptNotImpl;
521 delete [] hashedKey;
522 goto out_close;
523 }
524 delete [] hashedKey;
525 /* allocate a buffer for the encrypted data.
526 * The size of the buffer is the inBuf length, but blklen
527 * aligned and plus the length of the salt, that is appended.
528 */
529 *outBufLen = getBufLen(unpaddedLen, blklen) + STRING2KEY_SALTLEN;
530 *outBuf = new unsigned char[*outBufLen];
531 padData(inBuf, unpaddedLen, blklen);
532 // encrypt the padded data
533 err = gcry_cipher_encrypt(handle,
534 *outBuf,
535 *outBufLen - STRING2KEY_SALTLEN,
536 inBuf,
537 *outBufLen - STRING2KEY_SALTLEN);
538 if (err != GPG_ERR_NO_ERROR) {
539 printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_encrypt() failed: ")
540 + gcry_strerror(err));
541 ret = e_cryptNotImpl;
542 goto out_delete;
543 }
544 // append the salt to the encrypted data
545 memcpy(*outBuf + *outBufLen - STRING2KEY_SALTLEN, salt, STRING2KEY_SALTLEN);
546 goto out_close;
547out_delete:
548 delete [] *outBuf;
549out_close:
550 gcry_cipher_close(handle);
551out:
552 return ret;
553}
554
555PwMerror LibGCryptIf::decrypt(unsigned char **outBuf,
556 size_t *outBufLen,
557 const unsigned char *inBuf,
558 size_t inBufLen,
559 const unsigned char *key,
560 size_t keylen,
561 char _algo)
562{
563 PwMerror ret = e_success;
564 gcry_error_t err;
565 gcry_cipher_hd_t handle;
566 size_t cipherKeylen;
567 unsigned char *hashedKey;
568 unsigned char salt[STRING2KEY_SALTLEN];
569 int algo = mapCipherId(_algo);
570
571 if (!inBufLen || !keylen)
572 return e_invalidArg;
573
574 // test if algo is ready for encryption
575 err = gcry_cipher_algo_info(algo,
576 GCRYCTL_TEST_ALGO,
577 0, 0);
578 if (err != GPG_ERR_NO_ERROR) {
579 printDebug(string("LibGCryptIf::doDecrypt(): GCRYCTL_TEST_ALGO failed: ")
580 + gcry_strerror(err));
581 ret = e_cryptNotImpl;
582 goto out;
583 }
584 // get algo key length
585 err = gcry_cipher_algo_info(algo,
586 GCRYCTL_GET_KEYLEN,
587 0,
588 &cipherKeylen);
589 if (err != GPG_ERR_NO_ERROR) {
590 printDebug(string("LibGCryptIf::doDecrypt(): GCRYCTL_GET_KEYLEN failed: ")
591 + gcry_strerror(err));
592 ret = e_cryptNotImpl;
593 goto out;
594 }
595 // extract the salt of the encrypted data buffer
596 memcpy(salt, inBuf + inBufLen - STRING2KEY_SALTLEN, STRING2KEY_SALTLEN);
597 // open the algo and get a handle
598 err = gcry_cipher_open(&handle,
599 algo,
600 GCRY_CIPHER_MODE_CBC,
601 0);
602 if (err != GPG_ERR_NO_ERROR) {
603 printDebug(string("LibGCryptIf::doDecrypt(): gcry_cipher_open() failed: ")
604 + gcry_strerror(err));
605 ret = e_cryptNotImpl;
606 goto out;
607 }
608 // hash the "key" to a fixed size hash matching "cipherKeylen"
609 hashedKey = new unsigned char[cipherKeylen];
610 hashPassphrase(key, keylen, salt, hashedKey, cipherKeylen, false);
611 // so now set the hashed key
612 err = gcry_cipher_setkey(handle, hashedKey, cipherKeylen);
613 if (err != GPG_ERR_NO_ERROR) {
614 printDebug(string("LibGCryptIf::doDecrypt(): gcry_cipher_setkey() failed: ")
615 + gcry_strerror(err));
616 ret = e_cryptNotImpl;
617 delete [] hashedKey;
618 goto out_close;
619 }
620 delete [] hashedKey;
621 *outBufLen = inBufLen - STRING2KEY_SALTLEN;
622 *outBuf = new unsigned char[*outBufLen];
623 // decrypt the data
624 err = gcry_cipher_decrypt(handle,
625 *outBuf,
626 *outBufLen,
627 inBuf,
628 *outBufLen);
629 if (err != GPG_ERR_NO_ERROR) {
630 printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_encrypt() failed: ")
631 + gcry_strerror(err));
632 ret = e_cryptNotImpl;
633 goto out_delete;
634 }
635 // remove all random padding
636 unpadData(*outBuf, outBufLen);
637 goto out_close;
638out_delete:
639 delete [] *outBuf;
640out_close:
641 gcry_cipher_close(handle);
642out:
643 return ret;
644}
645
646PwMerror LibGCryptIf::hash(unsigned char **outBuf,
647 size_t *outBufLen,
648 const unsigned char *inBuf,
649 size_t inBufLen,
650 char _algo)
651{
652 PwMerror ret = e_success;
653 unsigned int hashLen;
654 int algo = mapHashId(_algo);
655
656 hashLen = gcry_md_get_algo_dlen(algo);
657 *outBufLen = hashLen;
658 *outBuf = new unsigned char[*outBufLen];
659 gcry_md_hash_buffer(algo,
660 *outBuf,
661 inBuf,
662 inBufLen);
663 return ret;
664}
665
666unsigned int LibGCryptIf::hashLength(char _algo)
667{
668 unsigned int ret;
669 int algo = mapHashId(_algo);
670 ret = gcry_md_get_algo_dlen(algo);
671 return ret;
672}
673
674int LibGCryptIf::mapCipherId(char algo)
675{
676 switch (algo) {
677 case PWM_CRYPT_AES128:
678 return GCRY_CIPHER_AES;
679 case PWM_CRYPT_AES192:
680 return GCRY_CIPHER_AES192;
681 case PWM_CRYPT_AES256:
682 return GCRY_CIPHER_AES256;
683 case PWM_CRYPT_3DES:
684 return GCRY_CIPHER_3DES;
685 case PWM_CRYPT_TWOFISH:
686 return GCRY_CIPHER_TWOFISH;
687 case PWM_CRYPT_TWOFISH128:
688 return GCRY_CIPHER_TWOFISH128;
689 default:
690 BUG();
691 }
692 return GCRY_CIPHER_NONE;
693}
694
695int LibGCryptIf::mapHashId(char algo)
696{
697 switch (algo) {
698 case PWM_HASH_SHA1:
699 return GCRY_MD_SHA1;
700 case PWM_HASH_SHA256:
701 return GCRY_MD_SHA256;
702 case PWM_HASH_SHA384:
703 return GCRY_MD_SHA384;
704 case PWM_HASH_SHA512:
705 return GCRY_MD_SHA512;
706 case PWM_HASH_MD5:
707 return GCRY_MD_MD5;
708 case PWM_HASH_RMD160:
709 return GCRY_MD_RMD160;
710 case PWM_HASH_TIGER:
711 return GCRY_MD_TIGER;
712 default:
713 BUG();
714 }
715 return GCRY_MD_NONE;
716}
717
718bool LibGCryptIf::hashPassphrase(const unsigned char *pw,
719 size_t pwlen,
720 unsigned char *salt,
721 unsigned char *key,
722 size_t keylen,
723 bool create)
724{
725 DEK dek;
726 STRING2KEY s2k;
727 bool ret;
728
729 dek.keylen = keylen;
730 s2k.mode = 1;
731 s2k.hash_algo = mapHashId(conf()->confGlobHashAlgo());
732 s2k.count = 0;
733 if (!create)
734 memcpy(s2k.salt, salt, STRING2KEY_SALTLEN);
735 ret = doHashPassphrase(&dek,
736 pw,
737 pwlen,
738 &s2k,
739 create);
740 if (!ret)
741 goto out;
742 memcpy(key, dek.key, dek.keylen);
743 if (create)
744 memcpy(salt, s2k.salt, STRING2KEY_SALTLEN);
745out:
746 return ret;
747}
748
749
750bool LibGCryptIf::doHashPassphrase(DEK *dek,
751 const unsigned char *pw,
752 size_t pwlen,
753 STRING2KEY *s2k,
754 bool create)
755{
756 // This function is derived from GnuPG-1.2.5-rc2
757 gcry_md_hd_t md;
758 gcry_error_t err;
759 bool ret = true;
760 size_t pass, i;
761 size_t used = 0;
762
763 PWM_ASSERT(s2k->hash_algo);
764 BUG_ON(!(dek->keylen > 0 && dek->keylen <= array_size(dek->key)));
765
766 err = gcry_md_open(&md, s2k->hash_algo, 0);
767 if (err != GPG_ERR_NO_ERROR) {
768 ret = false;
769 goto out;
770 }
771 for (pass = 0; used < dek->keylen; pass++) {
772 if (pass) {
773 gcry_md_reset(md);
774 for (i = 0; i < pass; i++) // preset the hash context
775 gcry_md_putc(md, 0);
776 }
777 if (s2k->mode == 1 || s2k->mode == 3) {
778 size_t len2 = pwlen + 8;
779 size_t count = len2;
780
781 if (create && !pass) {
782 Randomizer *rnd = Randomizer::obj();
783 const unsigned int salt_len = 8;
784 string rndBuf(rnd->genRndBuf(salt_len));
785 memcpy(s2k->salt, rndBuf.c_str(), salt_len);
786 if (s2k->mode == 3)
787 s2k->count = 96; // 65536 iterations
788 }
789 if (s2k->mode == 3) {
790 count = (16ul + (s2k->count & 15)) << ((s2k->count >> 4) + 6);
791 if (count < len2)
792 count = len2;
793 }
794 // a little bit complicated because we need a ulong for count
795 while (count > len2) { // maybe iterated+salted
796 gcry_md_write(md, s2k->salt, 8);
797 gcry_md_write(md, pw, pwlen);
798 count -= len2;
799 }
800 if (count < 8) {
801 gcry_md_write(md, s2k->salt, count);
802 } else {
803 gcry_md_write(md, s2k->salt, 8);
804 count -= 8;
805 gcry_md_write(md, pw, count);
806 }
807 } else
808 gcry_md_write(md, pw, pwlen);
809 gcry_md_final(md);
810 i = gcry_md_get_algo_dlen(s2k->hash_algo);
811 if (i > dek->keylen - used)
812 i = dek->keylen - used;
813 memcpy(dek->key+used, gcry_md_read(md, s2k->hash_algo), i);
814 used += i;
815 }
816 gcry_md_close(md);
817out:
818 return ret;
819}
820
821void LibGCryptIf::padData(unsigned char *buf,
822 size_t bufLen,
823 size_t boundary)
824{
825 size_t numPadBytes = boundary - ((bufLen + 1) % boundary);
826 buf[bufLen] = static_cast<char>(0x01);
827 size_t i = 0;
828 Randomizer *rnd = Randomizer::obj();
829 char c;
830 unsigned char *b;
831 while (i < numPadBytes) {
832 c = rnd->genRndChar();
833 if (c == static_cast<char>(0x01))
834 continue;
835 b = buf + bufLen + 1 + i;
836 *b = c;
837 ++i;
838 }
839}
840
841void LibGCryptIf::unpadData(const unsigned char *buf,
842 size_t *bufLen)
843{
844 size_t pos;
845 BUG_ON(*bufLen % 8);
846 pos = *bufLen - 1;
847 while (buf[pos] != static_cast<char>(0x01)) {
848 BUG_ON(!pos);
849 --pos;
850 }
851 *bufLen = pos;
852}
853
854#endif // CONFIG_PWMANAGER_CRYPTO
855
diff --git a/pwmanager/pwmanager/libgcryptif.h b/pwmanager/pwmanager/libgcryptif.h
index e86d638..7390827 100644
--- a/pwmanager/pwmanager/libgcryptif.h
+++ b/pwmanager/pwmanager/libgcryptif.h
@@ -1,118 +1,121 @@
1/*************************************************************************** 1/***************************************************************************
2 * * 2 * *
3 * copyright (C) 2004 by Michael Buesch * 3 * copyright (C) 2004 by Michael Buesch *
4 * email: mbuesch@freenet.de * 4 * email: mbuesch@freenet.de *
5 * * 5 * *
6 * hashPassphrase() is derived from GnuPG and is * 6 * hashPassphrase() is derived from GnuPG and is *
7 * Copyright (C) 1998, 1999, 2000, 2001, 2003 * 7 * Copyright (C) 1998, 1999, 2000, 2001, 2003 *
8 * Free Software Foundation, Inc. * 8 * Free Software Foundation, Inc. *
9 * * 9 * *
10 * This program is free software; you can redistribute it and/or modify * 10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License version 2 * 11 * it under the terms of the GNU General Public License version 2 *
12 * as published by the Free Software Foundation. * 12 * as published by the Free Software Foundation. *
13 * * 13 * *
14 ***************************************************************************/ 14 ***************************************************************************/
15 15
16#ifndef __LIBGCRYPTIF_H 16#ifndef __LIBGCRYPTIF_H
17#define __LIBGCRYPTIF_H 17#define __LIBGCRYPTIF_H
18 18
19#include "pwmexception.h" 19#include "pwmexception.h"
20 20
21//US ENH: should we put this better into globalstuff.h?
22#define CONFIG_PWMANAGER_CRYPTO
23
21//#undef CONFIG_PWMANAGER_GCRY // for debugging only. 24//#undef CONFIG_PWMANAGER_GCRY // for debugging only.
22#ifdef CONFIG_PWMANAGER_GCRY 25#if defined CONFIG_PWMANAGER_GCRY || defined CONFIG_PWMANAGER_CRYPTO
23 26
24#include <stddef.h> 27#include <stddef.h>
25#include <sys/types.h> 28#include <sys/types.h>
26#include <stdint.h> 29#include <stdint.h>
27 30
28 #define STRING2KEY_SALTLEN8 31 #define STRING2KEY_SALTLEN8
29 32
30/** interface class for the libgcrypt cipher and hash algorithms 33/** interface class for the libgcrypt cipher and hash algorithms
31 * NOTE: Always allocate 1024 extra bytes for the inBuf (for padding) 34 * NOTE: Always allocate 1024 extra bytes for the inBuf (for padding)
32 */ 35 */
33class LibGCryptIf 36class LibGCryptIf
34{ 37{
35protected: 38protected:
36 struct STRING2KEY 39 struct STRING2KEY
37 { 40 {
38 int mode; 41 int mode;
39 int hash_algo; 42 int hash_algo;
40 uint8_t salt[STRING2KEY_SALTLEN]; 43 uint8_t salt[STRING2KEY_SALTLEN];
41 uint32_t count; 44 uint32_t count;
42 }; 45 };
43 struct DEK 46 struct DEK
44 { 47 {
45 size_t keylen; 48 size_t keylen;
46 uint8_t key[32]; // this is the largest used keylen (256 bit) 49 uint8_t key[32]; // this is the largest used keylen (256 bit)
47 }; 50 };
48 51
49public: 52public:
50 LibGCryptIf() { } 53 LibGCryptIf() { }
51 /** is libgcrypt available? */ 54 /** is libgcrypt available? */
52 static bool available() 55 static bool available()
53 { return true; } 56 { return true; }
54 /** encrypt data. _algo is the PWM_CRYPT_* ID 57 /** encrypt data. _algo is the PWM_CRYPT_* ID
55 * of the algorithm. 58 * of the algorithm.
56 */ 59 */
57 PwMerror encrypt(unsigned char **outBuf, 60 PwMerror encrypt(unsigned char **outBuf,
58 size_t *outBufLen, 61 size_t *outBufLen,
59 unsigned char *inBuf, 62 unsigned char *inBuf,
60 size_t inBufLen, 63 size_t inBufLen,
61 const unsigned char *key, 64 const unsigned char *key,
62 size_t keylen, 65 size_t keylen,
63 char _algo); 66 char _algo);
64 /** decrypt data. _algo is the PWM_CRYPT_* ID 67 /** decrypt data. _algo is the PWM_CRYPT_* ID
65 * of the algorithm. 68 * of the algorithm.
66 */ 69 */
67 PwMerror decrypt(unsigned char **outBuf, 70 PwMerror decrypt(unsigned char **outBuf,
68 size_t *outBufLen, 71 size_t *outBufLen,
69 const unsigned char *inBuf, 72 const unsigned char *inBuf,
70 size_t inBufLen, 73 size_t inBufLen,
71 const unsigned char *key, 74 const unsigned char *key,
72 size_t keylen, 75 size_t keylen,
73 char _algo); 76 char _algo);
74 /** hash data. _algo is the PWM_HASH_* ID of the hash */ 77 /** hash data. _algo is the PWM_HASH_* ID of the hash */
75 PwMerror hash(unsigned char **outBuf, 78 PwMerror hash(unsigned char **outBuf,
76 size_t *outBufLen, 79 size_t *outBufLen,
77 const unsigned char *inBuf, 80 const unsigned char *inBuf,
78 size_t inBufLen, 81 size_t inBufLen,
79 char _algo); 82 char _algo);
80 /** returns the length of the hash. _algo is the PWM_HASH_* 83 /** returns the length of the hash. _algo is the PWM_HASH_*
81 * id of the hash. returns 0 on error. 84 * id of the hash. returns 0 on error.
82 */ 85 */
83 unsigned int hashLength(char _algo); 86 unsigned int hashLength(char _algo);
84 87
85protected: 88protected:
86 /** returns the total buffer length */ 89 /** returns the total buffer length */
87 size_t getBufLen(size_t inBufLen, size_t boundary) 90 size_t getBufLen(size_t inBufLen, size_t boundary)
88 { 91 {
89 return ((boundary - (inBufLen % boundary)) + inBufLen); 92 return ((boundary - (inBufLen % boundary)) + inBufLen);
90 } 93 }
91 /** pad the data up to the given boundary. 94 /** pad the data up to the given boundary.
92 * "buf" has to be big enough! 95 * "buf" has to be big enough!
93 */ 96 */
94 void padData(unsigned char *buf, 97 void padData(unsigned char *buf,
95 size_t bufLen, 98 size_t bufLen,
96 size_t boundary); 99 size_t boundary);
97 /** unpad the data */ 100 /** unpad the data */
98 void unpadData(const unsigned char *buf, 101 void unpadData(const unsigned char *buf,
99 size_t *bufLen); 102 size_t *bufLen);
100 /** maps the PWM_CRYPT_* ID of an algorithm 103 /** maps the PWM_CRYPT_* ID of an algorithm
101 * to the libgcrypt GCRY_CIPHER_* ID 104 * to the libgcrypt GCRY_CIPHER_* ID
102 */ 105 */
103 int mapCipherId(char algo); 106 int mapCipherId(char algo);
104 /** maps the PWM_HASH_* ID of an algorithm 107 /** maps the PWM_HASH_* ID of an algorithm
105 * to the libgcrypt GCRY_MD_* ID 108 * to the libgcrypt GCRY_MD_* ID
106 */ 109 */
107 int mapHashId(char algo); 110 int mapHashId(char algo);
108 /** hash a passphrase to a cipher key */ 111 /** hash a passphrase to a cipher key */
109 bool hashPassphrase(const unsigned char *pw, 112 bool hashPassphrase(const unsigned char *pw,
110 size_t pwlen, 113 size_t pwlen,
111 unsigned char *salt, 114 unsigned char *salt,
112 unsigned char *key, 115 unsigned char *key,
113 size_t keylen, 116 size_t keylen,
114 bool create); 117 bool create);
115 /** hash a passphrase to a cipher key */ 118 /** hash a passphrase to a cipher key */
116 bool doHashPassphrase(DEK *dek, 119 bool doHashPassphrase(DEK *dek,
117 const unsigned char *pw, 120 const unsigned char *pw,
118 size_t pwlen, 121 size_t pwlen,
diff --git a/pwmanager/pwmanager/pwmanagerE.pro b/pwmanager/pwmanager/pwmanagerE.pro
index 52d7586..294f549 100644
--- a/pwmanager/pwmanager/pwmanagerE.pro
+++ b/pwmanager/pwmanager/pwmanagerE.pro
@@ -1,158 +1,160 @@
1 TEMPLATE= app 1 TEMPLATE= app
2 CONFIG += qt warn_on 2 CONFIG += qt warn_on
3 3
4 4
5 TARGET = pwmpi 5 TARGET = pwmpi
6OBJECTS_DIR = obj/$(PLATFORM) 6OBJECTS_DIR = obj/$(PLATFORM)
7MOC_DIR = moc/$(PLATFORM) 7MOC_DIR = moc/$(PLATFORM)
8DESTDIR=$(QPEDIR)/bin 8DESTDIR=$(QPEDIR)/bin
9 9
10INCLUDEPATH += . ../../ ../../qtcompat ../../qtcompat/xml ../../libkdepim ../../microkde ../../microkde/kdecore ../../microkde/kdeui ../../microkde/kutils $(QPEDIR)/include 10INCLUDEPATH += . ../../ ../../qtcompat ../../qtcompat/xml ../../libkdepim ../../microkde ../../microkde/kdecore ../../microkde/kdeui ../../microkde/kutils $(QPEDIR)/include
11DEFINES += PWM_EMBEDDED 11DEFINES += PWM_EMBEDDED
12#enable this setting if you want debugoutput for pwmanager 12#enable this setting if you want debugoutput for pwmanager
13#DEFINES += CONFIG_DEBUG 13DEFINES += CONFIG_DEBUG
14 14
15LIBS += -lmicrokde 15LIBS += -lmicrokde
16LIBS += -lmicroqtcompat 16LIBS += -lmicroqtcompat
17LIBS += -lmicrokdepim 17LIBS += -lmicrokdepim
18LIBS += -L$(QPEDIR)/lib 18LIBS += -L$(QPEDIR)/lib
19LIBS += -lqpe 19LIBS += -lqpe
20LIBS += -lz 20LIBS += -lz
21LIBS += -lbz2 21#LIBS += -lbz2
22LIBS += -lcrypto 22LIBS += -lcrypto
23LIBS += $(QTOPIALIB) 23LIBS += $(QTOPIALIB)
24 24
25#INTERFACES = \ 25#INTERFACES = \
26#addentrywnd.ui \ 26#addentrywnd.ui \
27#configwnd.ui \ 27#configwnd.ui \
28#findwnd.ui \ 28#findwnd.ui \
29#getmasterpwwnd.ui \ 29#getmasterpwwnd.ui \
30#pwgenwnd.ui \ 30#pwgenwnd.ui \
31#setmasterpwwnd.ui \ 31#setmasterpwwnd.ui \
32#subtbledit.ui 32#subtbledit.ui
33 33
34#INTERFACES = \ 34#INTERFACES = \
35#subtbledit.ui \ 35#subtbledit.ui \
36 36
37 37
38 38
39#HEADERS = \ 39#HEADERS = \
40#configuration_31compat.h \ 40#configuration_31compat.h \
41#configuration.h \ 41#configuration.h \
42#configwnd.h \ 42#configwnd.h \
43#configwndimpl.h \ 43#configwndimpl.h \
44#selftest.h 44#selftest.h
45#subtbledit.h \ 45#subtbledit.h \
46#subtbleditimpl.h \ 46#subtbleditimpl.h \
47#compressbzip2.h \
47 48
48HEADERS = \ 49HEADERS = \
49addentrywnd_emb.h \ 50addentrywnd_emb.h \
50addentrywndimpl.h \ 51addentrywndimpl.h \
51base64.h \ 52base64.h \
52binentrygen.h \ 53binentrygen.h \
53blowfish.h \ 54blowfish.h \
54commentbox.h \ 55commentbox.h \
55compiler.h \ 56compiler.h \
56compressbzip2.h \
57compressgzip.h \ 57compressgzip.h \
58findwnd_emb.h \ 58findwnd_emb.h \
59findwndimpl.h \ 59findwndimpl.h \
60genpasswd.h \ 60genpasswd.h \
61getkeycardwnd.h \ 61getkeycardwnd.h \
62getmasterpwwnd_emb.h \ 62getmasterpwwnd_emb.h \
63getmasterpwwndimpl.h \ 63getmasterpwwndimpl.h \
64globalstuff.h \ 64globalstuff.h \
65gpasmanfile.h \ 65gpasmanfile.h \
66htmlgen.h \ 66htmlgen.h \
67htmlparse.h \ 67htmlparse.h \
68ipc.h \ 68ipc.h \
69libgcryptif.h \
69listobjselectwnd.h \ 70listobjselectwnd.h \
70listviewpwm.h \ 71listviewpwm.h \
71printtext.h \ 72printtext.h \
72pwgenwnd_emb.h \ 73pwgenwnd_emb.h \
73pwgenwndimpl.h \ 74pwgenwndimpl.h \
74pwmdoc.h \ 75pwmdoc.h \
75pwmdocui.h \ 76pwmdocui.h \
76pwmexception.h \ 77pwmexception.h \
77pwm.h \ 78pwm.h \
78pwminit.h \ 79pwminit.h \
79pwmprefs.h \ 80pwmprefs.h \
80pwmprint.h \ 81pwmprint.h \
81pwmtray.h \ 82pwmtray.h \
82pwmview.h \ 83pwmview.h \
83pwmviewstyle_0.h \ 84pwmviewstyle_0.h \
84pwmviewstyle_1.h \ 85pwmviewstyle_1.h \
85pwmviewstyle.h \ 86pwmviewstyle.h \
86randomizer.h \ 87randomizer.h \
87rc2.h \ 88rc2.h \
88rencatwnd.h \ 89rencatwnd.h \
89serializer.h \ 90serializer.h \
90setmasterpwwnd_emb.h \ 91setmasterpwwnd_emb.h \
91setmasterpwwndimpl.h \ 92setmasterpwwndimpl.h \
92sha1.h \ 93sha1.h \
93waitwnd.h \ 94waitwnd.h \
94kcmconfigs/kcmpwmconfig.h \ 95kcmconfigs/kcmpwmconfig.h \
95kcmconfigs/pwmconfigwidget.h \ 96kcmconfigs/pwmconfigwidget.h \
96 97
97#sources that need not be build 98#sources that need not be build
98#SOURCES = \ 99#SOURCES = \
99#advcommeditimpl.cpp \ 100#advcommeditimpl.cpp \
100#configuration.cpp \ 101#configuration.cpp \
101#configwnd.cpp \ 102#configwnd.cpp \
102#configwndimpl.cpp \ 103#configwndimpl.cpp \
103#configuration_31compat.cpp \ 104#configuration_31compat.cpp \
104#htmlparse.cpp \ 105#htmlparse.cpp \
105#printtext.cpp \ 106#printtext.cpp \
106#selftest.cpp \ 107#selftest.cpp \
107#pwmprint.cpp \ 108#pwmprint.cpp \
108#spinforsignal.cpp 109#spinforsignal.cpp
109#subtbledit.cpp \ 110#subtbledit.cpp \
110#subtbleditimpl.cpp \ 111#subtbleditimpl.cpp \
112#compressbzip2.cpp \
111 113
112SOURCES = \ 114SOURCES = \
113addentrywnd_emb.cpp \ 115addentrywnd_emb.cpp \
114addentrywndimpl.cpp \ 116addentrywndimpl.cpp \
115base64.cpp \ 117base64.cpp \
116binentrygen.cpp \ 118binentrygen.cpp \
117blowfish.cpp \ 119blowfish.cpp \
118commentbox.cpp \ 120commentbox.cpp \
119compressbzip2.cpp \
120compressgzip.cpp \ 121compressgzip.cpp \
121findwnd_emb.cpp \ 122findwnd_emb.cpp \
122findwndimpl.cpp \ 123findwndimpl.cpp \
123genpasswd.cpp \ 124genpasswd.cpp \
124getkeycardwnd.cpp \ 125getkeycardwnd.cpp \
125getmasterpwwnd_emb.cpp \ 126getmasterpwwnd_emb.cpp \
126getmasterpwwndimpl.cpp \ 127getmasterpwwndimpl.cpp \
127globalstuff.cpp \ 128globalstuff.cpp \
128gpasmanfile.cpp \ 129gpasmanfile.cpp \
129htmlgen.cpp \ 130htmlgen.cpp \
130ipc.cpp \ 131ipc.cpp \
132libgcryptif.cpp \
131listobjselectwnd.cpp \ 133listobjselectwnd.cpp \
132listviewpwm.cpp \ 134listviewpwm.cpp \
133main.cpp \ 135main.cpp \
134pwgenwnd_emb.cpp \ 136pwgenwnd_emb.cpp \
135pwgenwndimpl.cpp \ 137pwgenwndimpl.cpp \
136pwm.cpp \ 138pwm.cpp \
137pwmdoc.cpp \ 139pwmdoc.cpp \
138pwmdocui.cpp \ 140pwmdocui.cpp \
139pwmexception.cpp \ 141pwmexception.cpp \
140pwminit.cpp \ 142pwminit.cpp \
141pwmprefs.cpp \ 143pwmprefs.cpp \
142pwmtray.cpp \ 144pwmtray.cpp \
143pwmview.cpp \ 145pwmview.cpp \
144pwmviewstyle_0.cpp \ 146pwmviewstyle_0.cpp \
145pwmviewstyle_1.cpp \ 147pwmviewstyle_1.cpp \
146pwmviewstyle.cpp \ 148pwmviewstyle.cpp \
147randomizer.cpp \ 149randomizer.cpp \
148rc2.cpp \ 150rc2.cpp \
149rencatwnd.cpp \ 151rencatwnd.cpp \
150serializer.cpp \ 152serializer.cpp \
151setmasterpwwnd_emb.cpp \ 153setmasterpwwnd_emb.cpp \
152setmasterpwwndimpl.cpp \ 154setmasterpwwndimpl.cpp \
153sha1.cpp \ 155sha1.cpp \
154waitwnd.cpp \ 156waitwnd.cpp \
155kcmconfigs/kcmpwmconfig.cpp \ 157kcmconfigs/kcmpwmconfig.cpp \
156kcmconfigs/pwmconfigwidget.cpp \ 158kcmconfigs/pwmconfigwidget.cpp \
157 159
158 160
diff --git a/pwmanager/pwmanager/pwmdoc.cpp b/pwmanager/pwmanager/pwmdoc.cpp
index 4ad392e..a5df8f0 100644
--- a/pwmanager/pwmanager/pwmdoc.cpp
+++ b/pwmanager/pwmanager/pwmdoc.cpp
@@ -1,157 +1,168 @@
1/*************************************************************************** 1/***************************************************************************
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 2.0 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"
27#include "compressgzip.h" 27#include "compressgzip.h"
28#include "compressbzip2.h" 28#include "compressbzip2.h"
29#include "randomizer.h" 29#include "randomizer.h"
30#include "pwminit.h" 30#include "pwminit.h"
31#ifndef PWM_EMBEDDED 31#include "libgcryptif.h"
32//US #include "libgryptif.h" 32#ifdef PWM_EMBEDDED
33#else
34#include "pwmprefs.h" 33#include "pwmprefs.h"
35#include "kglobal.h" 34#include "kglobal.h"
36#endif 35#endif
37 36
38#include <kmessagebox.h> 37#include <kmessagebox.h>
39#include <libkcal/syncdefines.h> 38#include <libkcal/syncdefines.h>
40 39
41 40
42#ifdef CONFIG_KWALLETIF 41#ifdef CONFIG_KWALLETIF
43# include "kwalletemu.h" 42# include "kwalletemu.h"
44#endif // CONFIG_KWALLETIF 43#endif // CONFIG_KWALLETIF
45 44
46#include <qdatetime.h> 45#include <qdatetime.h>
47#include <qsize.h> 46#include <qsize.h>
48#include <qfileinfo.h> 47#include <qfileinfo.h>
49#include <qfile.h> 48#include <qfile.h>
50 49
51#include <stdio.h> 50#include <stdio.h>
52#include <stdlib.h> 51#include <stdlib.h>
53#include <errno.h> 52#include <errno.h>
54#include <string.h> 53#include <string.h>
55//US#include <iostream> 54//US#include <iostream>
56#include <algorithm> 55#include <algorithm>
57#include <sys/types.h> 56#include <sys/types.h>
58#include <sys/stat.h> 57#include <sys/stat.h>
59#include <unistd.h> 58#include <unistd.h>
60#include <stdint.h> 59#include <stdint.h>
61 60
61
62#ifdef PWM_EMBEDDED
63#ifndef Q_LONG
64#define Q_LONG long
65#endif
66
67#ifndef Q_ULONG
68#define Q_ULONG unsigned long
69#endif
70#endif //PWM_EMBEDDED
71
72
62//TODO: reset to its normal value. 73//TODO: reset to its normal value.
63 #define META_CHECK_TIMER_INTERVAL10/*300*/ /* sek */ 74 #define META_CHECK_TIMER_INTERVAL10/*300*/ /* sek */
64 75
65using namespace std; 76using namespace std;
66 77
67 78
68void PwMDocList::add(PwMDoc *doc, const string &id) 79void PwMDocList::add(PwMDoc *doc, const string &id)
69{ 80{
70#ifdef PWM_DEBUG 81#ifdef PWM_DEBUG
71 // check for existance of object in debug mode only. 82 // check for existance of object in debug mode only.
72 vector<listItem>::iterator begin = docList.begin(), 83 vector<listItem>::iterator begin = docList.begin(),
73 end = docList.end(), 84 end = docList.end(),
74 i = begin; 85 i = begin;
75 while (i != end) { 86 while (i != end) {
76 if (i->doc == doc) { 87 if (i->doc == doc) {
77 BUG(); 88 BUG();
78 return; 89 return;
79 } 90 }
80 ++i; 91 ++i;
81 } 92 }
82#endif 93#endif
83 listItem newItem; 94 listItem newItem;
84 newItem.doc = doc; 95 newItem.doc = doc;
85 newItem.docId = id; 96 newItem.docId = id;
86 docList.push_back(newItem); 97 docList.push_back(newItem);
87} 98}
88 99
89void PwMDocList::edit(PwMDoc *doc, const string &newId) 100void PwMDocList::edit(PwMDoc *doc, const string &newId)
90{ 101{
91 vector<listItem>::iterator begin = docList.begin(), 102 vector<listItem>::iterator begin = docList.begin(),
92 end = docList.end(), 103 end = docList.end(),
93 i = begin; 104 i = begin;
94 while (i != end) { 105 while (i != end) {
95 if (i->doc == doc) { 106 if (i->doc == doc) {
96 i->docId = newId; 107 i->docId = newId;
97 return; 108 return;
98 } 109 }
99 ++i; 110 ++i;
100 } 111 }
101} 112}
102 113
103void PwMDocList::del(PwMDoc *doc) 114void PwMDocList::del(PwMDoc *doc)
104{ 115{
105 vector<listItem>::iterator begin = docList.begin(), 116 vector<listItem>::iterator begin = docList.begin(),
106 end = docList.end(), 117 end = docList.end(),
107 i = begin; 118 i = begin;
108 while (i != end) { 119 while (i != end) {
109 if (i->doc == doc) { 120 if (i->doc == doc) {
110 docList.erase(i); 121 docList.erase(i);
111 return; 122 return;
112 } 123 }
113 ++i; 124 ++i;
114 } 125 }
115} 126}
116 127
117bool PwMDocList::find(const string &id, listItem *ret) 128bool PwMDocList::find(const string &id, listItem *ret)
118{ 129{
119 vector<listItem>::iterator begin = docList.begin(), 130 vector<listItem>::iterator begin = docList.begin(),
120 end = docList.end(), 131 end = docList.end(),
121 i = begin; 132 i = begin;
122 while (i != end) { 133 while (i != end) {
123 if (i->docId == id) { 134 if (i->docId == id) {
124 if (ret) 135 if (ret)
125 *ret = *i; 136 *ret = *i;
126 return true; 137 return true;
127 } 138 }
128 ++i; 139 ++i;
129 } 140 }
130 return false; 141 return false;
131} 142}
132 143
133 144
134 145
135DocTimer::DocTimer(PwMDoc *_doc) 146DocTimer::DocTimer(PwMDoc *_doc)
136 : doc (_doc) 147 : doc (_doc)
137 , mpwLock (0) 148 , mpwLock (0)
138 , autoLockLock (0) 149 , autoLockLock (0)
139 , metaCheckLock (0) 150 , metaCheckLock (0)
140{ 151{
141 mpwTimer = new QTimer; 152 mpwTimer = new QTimer;
142 autoLockTimer = new QTimer; 153 autoLockTimer = new QTimer;
143 metaCheckTimer = new QTimer; 154 metaCheckTimer = new QTimer;
144 connect(mpwTimer, SIGNAL(timeout()), 155 connect(mpwTimer, SIGNAL(timeout()),
145 this, SLOT(mpwTimeout())); 156 this, SLOT(mpwTimeout()));
146 connect(autoLockTimer, SIGNAL(timeout()), 157 connect(autoLockTimer, SIGNAL(timeout()),
147 this, SLOT(autoLockTimeout())); 158 this, SLOT(autoLockTimeout()));
148 connect(metaCheckTimer, SIGNAL(timeout()), 159 connect(metaCheckTimer, SIGNAL(timeout()),
149 this, SLOT(metaCheckTimeout())); 160 this, SLOT(metaCheckTimeout()));
150} 161}
151 162
152DocTimer::~DocTimer() 163DocTimer::~DocTimer()
153{ 164{
154 delete mpwTimer; 165 delete mpwTimer;
155 delete autoLockTimer; 166 delete autoLockTimer;
156 delete metaCheckTimer; 167 delete metaCheckTimer;
157} 168}
@@ -259,199 +270,195 @@ void DocTimer::metaCheckTimeout()
259 return; 270 return;
260 } 271 }
261 if (doc->isDeepLocked()) { 272 if (doc->isDeepLocked()) {
262 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); 273 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true);
263 return; 274 return;
264 } 275 }
265 if (doc->isDocEmpty()) { 276 if (doc->isDocEmpty()) {
266 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); 277 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true);
267 return; 278 return;
268 } 279 }
269#ifdef CONFIG_KWALLETIF 280#ifdef CONFIG_KWALLETIF
270 KWalletEmu *kwlEmu = doc->init->kwalletEmu(); 281 KWalletEmu *kwlEmu = doc->init->kwalletEmu();
271 if (kwlEmu) 282 if (kwlEmu)
272 kwlEmu->suspendDocSignals(); 283 kwlEmu->suspendDocSignals();
273#endif // CONFIG_KWALLETIF 284#endif // CONFIG_KWALLETIF
274 /* We simply trigger all views to update their 285 /* We simply trigger all views to update their
275 * displayed values. This way they have a chance 286 * displayed values. This way they have a chance
276 * to get notified when some meta changes over time. 287 * to get notified when some meta changes over time.
277 * (for example an entry expired). 288 * (for example an entry expired).
278 * The _view_ is responsive for not updating its 289 * The _view_ is responsive for not updating its
279 * contents if nothing really changed! 290 * contents if nothing really changed!
280 */ 291 */
281 emit doc->dataChanged(doc); 292 emit doc->dataChanged(doc);
282#ifdef CONFIG_KWALLETIF 293#ifdef CONFIG_KWALLETIF
283 if (kwlEmu) 294 if (kwlEmu)
284 kwlEmu->resumeDocSignals(); 295 kwlEmu->resumeDocSignals();
285#endif // CONFIG_KWALLETIF 296#endif // CONFIG_KWALLETIF
286 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); 297 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true);
287} 298}
288 299
289 300
290 301
291PwMDocList PwMDoc::openDocList; 302PwMDocList PwMDoc::openDocList;
292unsigned int PwMDocList::unnamedDocCnt = 1; 303unsigned int PwMDocList::unnamedDocCnt = 1;
293 304
294PwMDoc::PwMDoc(QObject *parent, const char *name) 305PwMDoc::PwMDoc(QObject *parent, const char *name)
295 : PwMDocUi(parent, name) 306 : PwMDocUi(parent, name)
296 , dataChangedLock (0) 307 , dataChangedLock (0)
297{ 308{
298 deleted = false; 309 deleted = false;
299 unnamedNum = 0; 310 unnamedNum = 0;
300 getOpenDocList()->add(this, getTitle().latin1()); 311 getOpenDocList()->add(this, getTitle().latin1());
301 curDocStat = 0; 312 curDocStat = 0;
302 setMaxNumEntries(); 313 setMaxNumEntries();
303 _timer = new DocTimer(this); 314 _timer = new DocTimer(this);
304 timer()->start(DocTimer::id_mpwTimer); 315 timer()->start(DocTimer::id_mpwTimer);
305 timer()->start(DocTimer::id_autoLockTimer); 316 timer()->start(DocTimer::id_autoLockTimer);
306 timer()->start(DocTimer::id_metaCheckTimer); 317 timer()->start(DocTimer::id_metaCheckTimer);
307 addCategory(DEFAULT_CATEGORY, 0, false); 318 addCategory(DEFAULT_CATEGORY, 0, false);
308 listView = 0; 319 listView = 0;
309 emit docCreated(this); 320 emit docCreated(this);
310} 321}
311 322
312PwMDoc::~PwMDoc() 323PwMDoc::~PwMDoc()
313{ 324{
314 emit docClosed(this); 325 emit docClosed(this);
315 getOpenDocList()->del(this); 326 getOpenDocList()->del(this);
316 delete _timer; 327 delete _timer;
317} 328}
318 329
319PwMerror PwMDoc::saveDoc(char compress, const QString *file) 330PwMerror PwMDoc::saveDoc(char compress, const QString *file)
320{ 331{
321 PwMerror ret, e; 332 PwMerror ret, e;
322 if (!file) { 333 if (!file) {
323 if (filename == "") 334 if (filename == "")
324 return e_filename; 335 return e_filename;
325 } else { 336 } else {
326 if (*file == "" && filename == "") 337 if (*file == "" && filename == "")
327 return e_filename; 338 return e_filename;
328 if (*file != "") 339 if (*file != "")
329 filename = *file; 340 filename = *file;
330 } 341 }
331 342
332 bool wasDeepLocked = isDeepLocked(); 343 bool wasDeepLocked = isDeepLocked();
333 if (wasDeepLocked) { 344 if (wasDeepLocked) {
334 if (deepLock(false) != e_success) 345 if (deepLock(false) != e_success)
335 return e_noPw; 346 return e_noPw;
336 } 347 }
337 348
338 if (!isPwAvailable()) { 349 if (!isPwAvailable()) {
339 /* password is not available. This means, the 350 /* password is not available. This means, the
340 * document wasn't saved, yet. 351 * document wasn't saved, yet.
341 */ 352 */
342 bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD); 353 bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD);
343 QString pw(requestNewMpw(&useChipcard)); 354 QString pw(requestNewMpw(&useChipcard));
344 if (pw != "") { 355 if (pw != "") {
345 currentPw = pw; 356 currentPw = pw;
346 } else { 357 } else {
347 return e_noPw; 358 return e_noPw;
348 } 359 }
349 if (useChipcard) { 360 if (useChipcard) {
350 setDocStatFlag(DOC_STAT_USE_CHIPCARD); 361 setDocStatFlag(DOC_STAT_USE_CHIPCARD);
351 } else { 362 } else {
352 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD); 363 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD);
353 } 364 }
354 } 365 }
355#ifndef PWM_EMBEDDED 366
356 int _cryptAlgo = conf()->confGlobCryptAlgo(); 367 int _cryptAlgo = conf()->confGlobCryptAlgo();
357 int _hashAlgo = conf()->confGlobHashAlgo(); 368 int _hashAlgo = conf()->confGlobHashAlgo();
358#else
359 int _cryptAlgo = PWM_CRYPT_BLOWFISH;
360 int _hashAlgo = PWM_HASH_SHA1;
361#endif
362 369
363 // sanity check for the selected algorithms 370 // sanity check for the selected algorithms
364 if (_cryptAlgo < PWM_CRYPT_BLOWFISH || 371 if (_cryptAlgo < PWM_CRYPT_BLOWFISH ||
365 _cryptAlgo > PWM_CRYPT_TWOFISH128) { 372 _cryptAlgo > PWM_CRYPT_TWOFISH128) {
366 printWarn("Invalid Crypto-Algorithm selected! " 373 printWarn("Invalid Crypto-Algorithm selected! "
367 "Config-file seems to be corrupt. " 374 "Config-file seems to be corrupt. "
368 "Falling back to Blowfish."); 375 "Falling back to Blowfish.");
369 _cryptAlgo = PWM_CRYPT_BLOWFISH; 376 _cryptAlgo = PWM_CRYPT_BLOWFISH;
370 } 377 }
371 if (_hashAlgo < PWM_HASH_SHA1 || 378 if (_hashAlgo < PWM_HASH_SHA1 ||
372 _hashAlgo > PWM_HASH_TIGER) { 379 _hashAlgo > PWM_HASH_TIGER) {
373 printWarn("Invalid Hash-Algorithm selected! " 380 printWarn("Invalid Hash-Algorithm selected! "
374 "Config-file seems to be corrupt. " 381 "Config-file seems to be corrupt. "
375 "Falling back to SHA1."); 382 "Falling back to SHA1.");
376 _hashAlgo = PWM_HASH_SHA1; 383 _hashAlgo = PWM_HASH_SHA1;
377 } 384 }
378 char cryptAlgo = static_cast<char>(_cryptAlgo); 385 char cryptAlgo = static_cast<char>(_cryptAlgo);
379 char hashAlgo = static_cast<char>(_hashAlgo); 386 char hashAlgo = static_cast<char>(_hashAlgo);
380 387
381 if (conf()->confGlobMakeFileBackup()) { 388 if (conf()->confGlobMakeFileBackup()) {
382 if (!backupFile(filename)) 389 if (!backupFile(filename))
383 return e_fileBackup; 390 return e_fileBackup;
384 } 391 }
385 QString tmpFileMoved(QString::null); 392 QString tmpFileMoved(QString::null);
386 if (QFile::exists(filename)) { 393 if (QFile::exists(filename)) {
387 /* Move the existing file to some tmp file. 394 /* Move the existing file to some tmp file.
388 * When saving file succeeds, delete tmp file. Otherwise 395 * When saving file succeeds, delete tmp file. Otherwise
389 * move tmp file back. See below. 396 * move tmp file back. See below.
390 */ 397 */
391 Randomizer *rnd = Randomizer::obj(); 398 Randomizer *rnd = Randomizer::obj();
392 char rnd_buf[5]; 399 char rnd_buf[5];
393 sprintf(rnd_buf, "%X%X%X%X", rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF, 400 sprintf(rnd_buf, "%X%X%X%X", rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF,
394 rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF); 401 rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF);
395 tmpFileMoved = filename + "." + rnd_buf + ".mv"; 402 tmpFileMoved = filename + "." + rnd_buf + ".mv";
396 if (!copyFile(filename, tmpFileMoved)) 403 if (!copyFile(filename, tmpFileMoved))
397 return e_openFile; 404 return e_openFile;
398 if (!QFile::remove(filename)) { 405 if (!QFile::remove(filename)) {
399 printWarn(string("removing orig file ") 406 printWarn(string("removing orig file ")
400 + filename.latin1() 407 + filename.latin1()
401 + " failed!"); 408 + " failed!");
402 } 409 }
403 } 410 }
404 QFile f(filename); 411 QFile f(filename);
405 string serialized; 412 string serialized;
406 if (!f.open(IO_ReadWrite)) { 413 if (!f.open(IO_ReadWrite)) {
407 ret = e_openFile; 414 ret = e_openFile;
408 goto out_moveback; 415 goto out_moveback;
409 } 416 }
410 e = writeFileHeader(hashAlgo, hashAlgo, 417 e = writeFileHeader(hashAlgo, hashAlgo,
411 cryptAlgo, compress, 418 cryptAlgo, compress,
412 &currentPw, &f); 419 &currentPw, &f);
413 if (e == e_hashNotImpl) { 420 if (e == e_hashNotImpl) {
414 printDebug("PwMDoc::saveDoc(): writeFileHeader() failed: e_hashNotImpl"); 421 printDebug("PwMDoc::saveDoc(): writeFileHeader() failed: e_hashNotImpl");
415 f.close(); 422 f.close();
416 ret = e_hashNotImpl; 423 ret = e_hashNotImpl;
417 goto out_moveback; 424 goto out_moveback;
418 } else if (e != e_success) { 425 } else if (e != e_success) {
419 printDebug("PwMDoc::saveDoc(): writeFileHeader() failed"); 426 printDebug("PwMDoc::saveDoc(): writeFileHeader() failed");
420 f.close(); 427 f.close();
421 ret = e_writeHeader; 428 ret = e_writeHeader;
422 goto out_moveback; 429 goto out_moveback;
423 } 430 }
424 if (!serializeDta(&serialized)) { 431 if (!serializeDta(&serialized)) {
425 printDebug("PwMDoc::saveDoc(): serializeDta() failed"); 432 printDebug("PwMDoc::saveDoc(): serializeDta() failed");
426 f.close(); 433 f.close();
427 ret = e_serializeDta; 434 ret = e_serializeDta;
428 goto out_moveback; 435 goto out_moveback;
429 } 436 }
430 e = writeDataHash(hashAlgo, &serialized, &f); 437 e = writeDataHash(hashAlgo, &serialized, &f);
431 if (e == e_hashNotImpl) { 438 if (e == e_hashNotImpl) {
432 printDebug("PwMDoc::saveDoc(): writeDataHash() failed: e_hashNotImpl"); 439 printDebug("PwMDoc::saveDoc(): writeDataHash() failed: e_hashNotImpl");
433 f.close(); 440 f.close();
434 ret = e_hashNotImpl; 441 ret = e_hashNotImpl;
435 goto out_moveback; 442 goto out_moveback;
436 } else if (e != e_success) { 443 } else if (e != e_success) {
437 printDebug("PwMDoc::saveDoc(): writeDataHash() failed"); 444 printDebug("PwMDoc::saveDoc(): writeDataHash() failed");
438 f.close(); 445 f.close();
439 ret = e_writeHeader; 446 ret = e_writeHeader;
440 goto out_moveback; 447 goto out_moveback;
441 } 448 }
442 if (!compressDta(&serialized, compress)) { 449 if (!compressDta(&serialized, compress)) {
443 printDebug("PwMDoc::saveDoc(): compressDta() failed"); 450 printDebug("PwMDoc::saveDoc(): compressDta() failed");
444 f.close(); 451 f.close();
445 ret = e_enc; 452 ret = e_enc;
446 goto out_moveback; 453 goto out_moveback;
447 } 454 }
448 e = encrypt(&serialized, &currentPw, &f, cryptAlgo); 455 e = encrypt(&serialized, &currentPw, &f, cryptAlgo);
449 if (e == e_weakPw) { 456 if (e == e_weakPw) {
450 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_weakPw"); 457 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_weakPw");
451 f.close(); 458 f.close();
452 ret = e_weakPw; 459 ret = e_weakPw;
453 goto out_moveback; 460 goto out_moveback;
454 } else if (e == e_cryptNotImpl) { 461 } else if (e == e_cryptNotImpl) {
455 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_cryptNotImpl"); 462 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_cryptNotImpl");
456 f.close(); 463 f.close();
457 ret = e_cryptNotImpl; 464 ret = e_cryptNotImpl;
@@ -506,553 +513,516 @@ out:
506} 513}
507 514
508PwMerror PwMDoc::openDoc(const QString *file, int openLocked) 515PwMerror PwMDoc::openDoc(const QString *file, int openLocked)
509{ 516{
510 PWM_ASSERT(file); 517 PWM_ASSERT(file);
511 PWM_ASSERT(openLocked == 0 || openLocked == 1 || openLocked == 2); 518 PWM_ASSERT(openLocked == 0 || openLocked == 1 || openLocked == 2);
512 string decrypted, dataHash; 519 string decrypted, dataHash;
513 PwMerror ret; 520 PwMerror ret;
514 char cryptAlgo, dataHashType, compress; 521 char cryptAlgo, dataHashType, compress;
515 unsigned int headerLen; 522 unsigned int headerLen;
516 523
517 if (*file == "") 524 if (*file == "")
518 return e_readFile; 525 return e_readFile;
519 filename = *file; 526 filename = *file;
520 /* check if this file is already open. 527 /* check if this file is already open.
521 * This does not catch symlinks! 528 * This does not catch symlinks!
522 */ 529 */
523 if (!isDeepLocked()) { 530 if (!isDeepLocked()) {
524 if (getOpenDocList()->find(filename.latin1())) 531 if (getOpenDocList()->find(filename.latin1()))
525 return e_alreadyOpen; 532 return e_alreadyOpen;
526 } 533 }
527 QFile f(filename); 534 QFile f(filename);
528 535
529 if (openLocked == 2) { 536 if (openLocked == 2) {
530 // open deep-locked 537 // open deep-locked
531 if (!QFile::exists(filename)) 538 if (!QFile::exists(filename))
532 return e_openFile; 539 return e_openFile;
533 if (deepLock(true, false) != e_success) 540 if (deepLock(true, false) != e_success)
534 return e_openFile; 541 return e_openFile;
535 goto out_success; 542 goto out_success;
536 } 543 }
537 544
538 if (!f.open(IO_ReadOnly)) 545 if (!f.open(IO_ReadOnly))
539 return e_openFile; 546 return e_openFile;
540 547
541 ret = checkHeader(&cryptAlgo, &currentPw, &compress, &headerLen, 548 ret = checkHeader(&cryptAlgo, &currentPw, &compress, &headerLen,
542 &dataHashType, &dataHash, &f); 549 &dataHashType, &dataHash, &f);
543 if (ret != e_success) { 550 if (ret != e_success) {
544 printDebug("PwMDoc::openDoc(): checkHeader() failed"); 551 printDebug("PwMDoc::openDoc(): checkHeader() failed");
545 f.close(); 552 f.close();
546 if (ret == e_wrongPw) { 553 if (ret == e_wrongPw) {
547 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 554 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
548 return ret; 555 return ret;
549 } else if (ret == e_noPw || 556 } else if (ret == e_noPw ||
550 ret == e_fileVer || 557 ret == e_fileVer ||
551 ret == e_fileFormat || 558 ret == e_fileFormat ||
552 ret == e_hashNotImpl) { 559 ret == e_hashNotImpl) {
553 return ret; 560 return ret;
554 } else 561 } else
555 return e_readFile; 562 return e_readFile;
556 } 563 }
557 ret = decrypt(&decrypted, headerLen, &currentPw, cryptAlgo, &f); 564 ret = decrypt(&decrypted, headerLen, &currentPw, cryptAlgo, &f);
558 if (ret == e_cryptNotImpl) { 565 if (ret == e_cryptNotImpl) {
559 printDebug("PwMDoc::openDoc(): decrypt() failed: e_cryptNotImpl"); 566 printDebug("PwMDoc::openDoc(): decrypt() failed: e_cryptNotImpl");
560 f.close(); 567 f.close();
561 return e_cryptNotImpl; 568 return e_cryptNotImpl;
562 } else if (ret != e_success) { 569 } else if (ret != e_success) {
563 printDebug("PwMDoc::openDoc(): decrypt() failed"); 570 printDebug("PwMDoc::openDoc(): decrypt() failed");
564 f.close(); 571 f.close();
565 return e_readFile; 572 return e_readFile;
566 } 573 }
567 if (!decompressDta(&decrypted, compress)) { 574 if (!decompressDta(&decrypted, compress)) {
568 printDebug("PwMDoc::openDoc(): decompressDta() failed"); 575 printDebug("PwMDoc::openDoc(): decompressDta() failed");
569 f.close(); 576 f.close();
570 return e_fileCorrupt; 577 return e_fileCorrupt;
571 } 578 }
572 ret = checkDataHash(dataHashType, &dataHash, &decrypted); 579 ret = checkDataHash(dataHashType, &dataHash, &decrypted);
573 if (ret == e_hashNotImpl) { 580 if (ret == e_hashNotImpl) {
574 printDebug("PwMDoc::openDoc(): checkDataHash() failed: e_hashNotImpl"); 581 printDebug("PwMDoc::openDoc(): checkDataHash() failed: e_hashNotImpl");
575 f.close(); 582 f.close();
576 return e_hashNotImpl; 583 return e_hashNotImpl;
577 } else if (ret != e_success) { 584 } else if (ret != e_success) {
578 printDebug("PwMDoc::openDoc(): checkDataHash() failed"); 585 printDebug("PwMDoc::openDoc(): checkDataHash() failed");
579 f.close(); 586 f.close();
580 return e_fileCorrupt; 587 return e_fileCorrupt;
581 } 588 }
582 if (!deSerializeDta(&decrypted, openLocked == 1)) { 589 if (!deSerializeDta(&decrypted, openLocked == 1)) {
583 printDebug("PwMDoc::openDoc(): deSerializeDta() failed"); 590 printDebug("PwMDoc::openDoc(): deSerializeDta() failed");
584 f.close(); 591 f.close();
585 return e_readFile; 592 return e_readFile;
586 } 593 }
587 f.close(); 594 f.close();
588 timer()->start(DocTimer::id_mpwTimer); 595 timer()->start(DocTimer::id_mpwTimer);
589 timer()->start(DocTimer::id_autoLockTimer); 596 timer()->start(DocTimer::id_autoLockTimer);
590out_success: 597out_success:
591 openDocList.edit(this, getTitle().latin1()); 598 openDocList.edit(this, getTitle().latin1());
592 emit docOpened(this); 599 emit docOpened(this);
593 return e_success; 600 return e_success;
594} 601}
595 602
596PwMerror PwMDoc::writeFileHeader(char keyHash, char dataHash, char crypt, char compress, 603PwMerror PwMDoc::writeFileHeader(char keyHash, char dataHash, char crypt, char compress,
597 QString *pw, QFile *f) 604 QString *pw, QFile *f)
598{ 605{
599 PWM_ASSERT(pw); 606 PWM_ASSERT(pw);
600 PWM_ASSERT(f); 607 PWM_ASSERT(f);
601 PWM_ASSERT(listView); 608 PWM_ASSERT(listView);
602#ifndef PWM_EMBEDDED
603 if (f->writeBlock(FILE_ID_HEADER, strlen(FILE_ID_HEADER)) != 609 if (f->writeBlock(FILE_ID_HEADER, strlen(FILE_ID_HEADER)) !=
604 static_cast<Q_LONG>(strlen(FILE_ID_HEADER))) { 610 static_cast<Q_LONG>(strlen(FILE_ID_HEADER))) {
605 return e_writeFile; 611 return e_writeFile;
606 } 612 }
607 if (f->putch(PWM_FILE_VER) == -1 || 613 if (f->putch(PWM_FILE_VER) == -1 ||
608 f->putch(keyHash) == -1 || 614 f->putch(keyHash) == -1 ||
609 f->putch(dataHash) == -1 || 615 f->putch(dataHash) == -1 ||
610 f->putch(crypt) == -1 || 616 f->putch(crypt) == -1 ||
611 f->putch(compress) == -1 || 617 f->putch(compress) == -1 ||
612 f->putch((getDocStatFlag(DOC_STAT_USE_CHIPCARD)) ? 618 f->putch((getDocStatFlag(DOC_STAT_USE_CHIPCARD)) ?
613 (static_cast<char>(0x01)) : (static_cast<char>(0x00))) == -1) { 619 (static_cast<char>(0x01)) : (static_cast<char>(0x00))) == -1) {
614 return e_writeFile; 620 return e_writeFile;
615 } 621 }
616 622
617#else
618 if (f->writeBlock(FILE_ID_HEADER, strlen(FILE_ID_HEADER)) !=
619 (long)(strlen(FILE_ID_HEADER))) {
620 return e_writeFile;
621 }
622 if (f->putch(PWM_FILE_VER) == -1 ||
623 f->putch(keyHash) == -1 ||
624 f->putch(dataHash) == -1 ||
625 f->putch(crypt) == -1 ||
626 f->putch(compress) == -1 ||
627 f->putch((getDocStatFlag(DOC_STAT_USE_CHIPCARD)) ?
628 ((char)(0x01)) : ((char)(0x00))) == -1) {
629 return e_writeFile;
630 }
631#endif
632 // write bytes of NUL-data. These bytes are reserved for future-use. 623 // write bytes of NUL-data. These bytes are reserved for future-use.
633 const int bufSize = 64; 624 const int bufSize = 64;
634 char tmp_buf[bufSize]; 625 char tmp_buf[bufSize];
635 memset(tmp_buf, 0x00, bufSize); 626 memset(tmp_buf, 0x00, bufSize);
636 if (f->writeBlock(tmp_buf, bufSize) != bufSize) 627 if (f->writeBlock(tmp_buf, bufSize) != bufSize)
637 return e_writeFile; 628 return e_writeFile;
638 629
639 switch (keyHash) { 630 switch (keyHash) {
640 case PWM_HASH_SHA1: { 631 case PWM_HASH_SHA1: {
641 const int hashlen = SHA1_HASH_LEN_BYTE; 632 const int hashlen = SHA1_HASH_LEN_BYTE;
642 Sha1 hash; 633 Sha1 hash;
643 hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length()); 634 hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length());
644 string ret = hash.sha1_read(); 635 string ret = hash.sha1_read();
645 if (f->writeBlock(ret.c_str(), hashlen) != hashlen) 636 if (f->writeBlock(ret.c_str(), hashlen) != hashlen)
646 return e_writeFile; 637 return e_writeFile;
647 break; 638 break;
648 } 639 }
649#ifndef PWM_EMBEDDED
650 case PWM_HASH_SHA256: 640 case PWM_HASH_SHA256:
651 /*... fall through */ 641 /*... fall through */
652 case PWM_HASH_SHA384: 642 case PWM_HASH_SHA384:
653 case PWM_HASH_SHA512: 643 case PWM_HASH_SHA512:
654 case PWM_HASH_MD5: 644 case PWM_HASH_MD5:
655 case PWM_HASH_RMD160: 645 case PWM_HASH_RMD160:
656 case PWM_HASH_TIGER: 646 case PWM_HASH_TIGER:
657 { 647 {
658 if (!LibGCryptIf::available()) 648 if (!LibGCryptIf::available())
659 return e_hashNotImpl; 649 return e_hashNotImpl;
660 LibGCryptIf gc; 650 LibGCryptIf gc;
661 PwMerror err; 651 PwMerror err;
662 unsigned char *buf; 652 unsigned char *buf;
663 size_t hashLen; 653 size_t hashLen;
664 err = gc.hash(&buf, 654 err = gc.hash(&buf,
665 &hashLen, 655 &hashLen,
666 reinterpret_cast<const unsigned char *>(pw->latin1()), 656 reinterpret_cast<const unsigned char *>(pw->latin1()),
667 pw->length(), 657 pw->length(),
668 keyHash); 658 keyHash);
669 if (err != e_success) 659 if (err != e_success)
670 return e_hashNotImpl; 660 return e_hashNotImpl;
671 if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen) 661 if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen)
672 != static_cast<Q_LONG>(hashLen)) { 662 != static_cast<Q_LONG>(hashLen)) {
673 delete [] buf; 663 delete [] buf;
674 return e_hashNotImpl; 664 return e_hashNotImpl;
675 } 665 }
676 delete [] buf; 666 delete [] buf;
677 break; 667 break;
678 } 668 }
679#endif
680 default: { 669 default: {
681 return e_hashNotImpl; 670 return e_hashNotImpl;
682 } } 671 } }
683 return e_success; 672 return e_success;
684} 673}
685 674
686PwMerror PwMDoc::checkHeader(char *cryptAlgo, QString *pw, char *compress, 675PwMerror PwMDoc::checkHeader(char *cryptAlgo, QString *pw, char *compress,
687 unsigned int *headerLength, char *dataHashType, 676 unsigned int *headerLength, char *dataHashType,
688 string *dataHash, QFile *f) 677 string *dataHash, QFile *f)
689{ 678{
690 PWM_ASSERT(cryptAlgo); 679 PWM_ASSERT(cryptAlgo);
691 PWM_ASSERT(pw); 680 PWM_ASSERT(pw);
692 PWM_ASSERT(headerLength); 681 PWM_ASSERT(headerLength);
693 PWM_ASSERT(dataHashType); 682 PWM_ASSERT(dataHashType);
694 PWM_ASSERT(dataHash); 683 PWM_ASSERT(dataHash);
695 PWM_ASSERT(f); 684 PWM_ASSERT(f);
696 int tmpRet; 685 int tmpRet;
697 // check "magic" header 686 // check "magic" header
698 const char magicHdr[] = FILE_ID_HEADER; 687 const char magicHdr[] = FILE_ID_HEADER;
699 const int hdrLen = array_size(magicHdr) - 1; 688 const int hdrLen = array_size(magicHdr) - 1;
700 char tmp[hdrLen]; 689 char tmp[hdrLen];
701 if (f->readBlock(tmp, hdrLen) != hdrLen) 690 if (f->readBlock(tmp, hdrLen) != hdrLen)
702 return e_readFile; 691 return e_readFile;
703 if (memcmp(tmp, magicHdr, hdrLen) != 0) 692 if (memcmp(tmp, magicHdr, hdrLen) != 0)
704 return e_fileFormat; 693 return e_fileFormat;
705 // read and check file ver 694 // read and check file ver
706 int fileV = f->getch(); 695 int fileV = f->getch();
707 if (fileV == -1) 696 if (fileV == -1)
708 return e_fileFormat; 697 return e_fileFormat;
709 if (fileV != PWM_FILE_VER) 698 if (fileV != PWM_FILE_VER)
710 return e_fileVer; 699 return e_fileVer;
711 // read hash hash type 700 // read hash hash type
712 int keyHash = f->getch(); 701 int keyHash = f->getch();
713 if (keyHash == -1) 702 if (keyHash == -1)
714 return e_fileFormat; 703 return e_fileFormat;
715 // read data hash type 704 // read data hash type
716 tmpRet = f->getch(); 705 tmpRet = f->getch();
717 if (tmpRet == -1) 706 if (tmpRet == -1)
718 return e_fileFormat; 707 return e_fileFormat;
719 *dataHashType = tmpRet; 708 *dataHashType = tmpRet;
720 // read crypt algo 709 // read crypt algo
721 tmpRet = f->getch(); 710 tmpRet = f->getch();
722 if (tmpRet == -1) 711 if (tmpRet == -1)
723 return e_fileFormat; 712 return e_fileFormat;
724 *cryptAlgo = tmpRet; 713 *cryptAlgo = tmpRet;
725 // get compression-algo 714 // get compression-algo
726 tmpRet = f->getch(); 715 tmpRet = f->getch();
727 if (tmpRet == -1) 716 if (tmpRet == -1)
728 return e_fileFormat; 717 return e_fileFormat;
729 *compress = tmpRet; 718 *compress = tmpRet;
730 // get the MPW-flag 719 // get the MPW-flag
731 int mpw_flag = f->getch(); 720 int mpw_flag = f->getch();
732 if (mpw_flag == -1) 721 if (mpw_flag == -1)
733 return e_fileFormat; 722 return e_fileFormat;
734 if (mpw_flag == 0x01) 723 if (mpw_flag == 0x01)
735 setDocStatFlag(DOC_STAT_USE_CHIPCARD); 724 setDocStatFlag(DOC_STAT_USE_CHIPCARD);
736 else 725 else
737 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD); 726 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD);
738 // skip the "RESERVED"-bytes 727 // skip the "RESERVED"-bytes
739 if (!(f->at(f->at() + 64))) 728 if (!(f->at(f->at() + 64)))
740 return e_fileFormat; 729 return e_fileFormat;
741 730
742 *pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 731 *pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
743 if (*pw == "") { 732 if (*pw == "") {
744 /* the user didn't give a master-password 733 /* the user didn't give a master-password
745 * or didn't insert a chipcard 734 * or didn't insert a chipcard
746 */ 735 */
747 return e_noPw; 736 return e_noPw;
748 } 737 }
749 // verify key-hash 738 // verify key-hash
750 switch (keyHash) { 739 switch (keyHash) {
751 case PWM_HASH_SHA1: { 740 case PWM_HASH_SHA1: {
752 // read hash from header 741 // read hash from header
753 const int hashLen = SHA1_HASH_LEN_BYTE; 742 const int hashLen = SHA1_HASH_LEN_BYTE;
754 string readHash; 743 string readHash;
755 int i; 744 int i;
756 for (i = 0; i < hashLen; ++i) 745 for (i = 0; i < hashLen; ++i)
757 readHash.push_back(f->getch()); 746 readHash.push_back(f->getch());
758 Sha1 hash; 747 Sha1 hash;
759 hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length()); 748 hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length());
760 string ret = hash.sha1_read(); 749 string ret = hash.sha1_read();
761 if (ret != readHash) 750 if (ret != readHash)
762 return e_wrongPw;// hash doesn't match (wrong key) 751 return e_wrongPw;// hash doesn't match (wrong key)
763 break; 752 break;
764 } 753 }
765#ifndef PWM_EMBEDDED
766 case PWM_HASH_SHA256: 754 case PWM_HASH_SHA256:
767 /*... fall through */ 755 /*... fall through */
768 case PWM_HASH_SHA384: 756 case PWM_HASH_SHA384:
769 case PWM_HASH_SHA512: 757 case PWM_HASH_SHA512:
770 case PWM_HASH_MD5: 758 case PWM_HASH_MD5:
771 case PWM_HASH_RMD160: 759 case PWM_HASH_RMD160:
772 case PWM_HASH_TIGER: { 760 case PWM_HASH_TIGER: {
773 if (!LibGCryptIf::available()) 761 if (!LibGCryptIf::available())
774 return e_hashNotImpl; 762 return e_hashNotImpl;
775 LibGCryptIf gc; 763 LibGCryptIf gc;
776 PwMerror err; 764 PwMerror err;
777 unsigned char *buf; 765 unsigned char *buf;
778 size_t hashLen; 766 size_t hashLen;
779 err = gc.hash(&buf, 767 err = gc.hash(&buf,
780 &hashLen, 768 &hashLen,
781 reinterpret_cast<const unsigned char *>(pw->latin1()), 769 reinterpret_cast<const unsigned char *>(pw->latin1()),
782 pw->length(), 770 pw->length(),
783 keyHash); 771 keyHash);
784 if (err != e_success) 772 if (err != e_success)
785 return e_hashNotImpl; 773 return e_hashNotImpl;
786 string calcHash(reinterpret_cast<const char *>(buf), 774 string calcHash(reinterpret_cast<const char *>(buf),
787 static_cast<string::size_type>(hashLen)); 775 static_cast<string::size_type>(hashLen));
788 delete [] buf; 776 delete [] buf;
789 // read hash from header 777 // read hash from header
790 string readHash; 778 string readHash;
791 size_t i; 779 size_t i;
792 for (i = 0; i < hashLen; ++i) 780 for (i = 0; i < hashLen; ++i)
793 readHash.push_back(f->getch()); 781 readHash.push_back(f->getch());
794 if (calcHash != readHash) 782 if (calcHash != readHash)
795 return e_wrongPw;// hash doesn't match (wrong key) 783 return e_wrongPw;// hash doesn't match (wrong key)
796 break; 784 break;
797 } 785 }
798#endif
799 default: { 786 default: {
800 return e_hashNotImpl; 787 return e_hashNotImpl;
801 } } 788 } }
802 // read the data-hash from the file 789 // read the data-hash from the file
803 unsigned int hashLen, i; 790 unsigned int hashLen, i;
804 switch (*dataHashType) { 791 switch (*dataHashType) {
805 case PWM_HASH_SHA1: 792 case PWM_HASH_SHA1:
806 hashLen = SHA1_HASH_LEN_BYTE; 793 hashLen = SHA1_HASH_LEN_BYTE;
807 break; 794 break;
808#ifndef PWM_EMBEDDED
809 case PWM_HASH_SHA256: 795 case PWM_HASH_SHA256:
810 /*... fall through */ 796 /*... fall through */
811 case PWM_HASH_SHA384: 797 case PWM_HASH_SHA384:
812 case PWM_HASH_SHA512: 798 case PWM_HASH_SHA512:
813 case PWM_HASH_MD5: 799 case PWM_HASH_MD5:
814 case PWM_HASH_RMD160: 800 case PWM_HASH_RMD160:
815 case PWM_HASH_TIGER: { 801 case PWM_HASH_TIGER: {
816 if (!LibGCryptIf::available()) 802 if (!LibGCryptIf::available())
817 return e_hashNotImpl; 803 return e_hashNotImpl;
818 LibGCryptIf gc; 804 LibGCryptIf gc;
819 hashLen = gc.hashLength(*dataHashType); 805 hashLen = gc.hashLength(*dataHashType);
820 if (hashLen == 0) 806 if (hashLen == 0)
821 return e_hashNotImpl; 807 return e_hashNotImpl;
822 break; 808 break;
823 } 809 }
824#endif
825 default: 810 default:
826 return e_hashNotImpl; 811 return e_hashNotImpl;
827 } 812 }
828 *dataHash = ""; 813 *dataHash = "";
829 for (i = 0; i < hashLen; ++i) { 814 for (i = 0; i < hashLen; ++i) {
830 tmpRet = f->getch(); 815 tmpRet = f->getch();
831 if (tmpRet == -1) 816 if (tmpRet == -1)
832 return e_fileFormat; 817 return e_fileFormat;
833 dataHash->push_back(static_cast<char>(tmpRet)); 818 dataHash->push_back(static_cast<char>(tmpRet));
834 } 819 }
835 *headerLength = f->at(); 820 *headerLength = f->at();
836#ifndef PWM_EMBEDDED 821#ifndef PWM_EMBEDDED
837 printDebug(string("opening file { compress: ") 822 printDebug(string("opening file { compress: ")
838 + tostr(static_cast<int>(*compress)) + " cryptAlgo: " 823 + tostr(static_cast<int>(*compress)) + " cryptAlgo: "
839 + tostr(static_cast<int>(*cryptAlgo)) + " keyHashAlgo: " 824 + tostr(static_cast<int>(*cryptAlgo)) + " keyHashAlgo: "
840 + tostr(static_cast<int>(keyHash)) 825 + tostr(static_cast<int>(keyHash))
841 + " }"); 826 + " }");
842#else 827#else
843 printDebug(string("opening file { compress: ") 828 printDebug(string("opening file { compress: ")
844 + tostr((int)(*compress)) + " cryptAlgo: " 829 + tostr((int)(*compress)) + " cryptAlgo: "
845 + tostr((int)(*cryptAlgo)) + " keyHashAlgo: " 830 + tostr((int)(*cryptAlgo)) + " keyHashAlgo: "
846 + tostr((int)(keyHash)) 831 + tostr((int)(keyHash))
847 + " }"); 832 + " }");
848#endif 833#endif
849 834
850 return e_success; 835 return e_success;
851} 836}
852 837
853PwMerror PwMDoc::writeDataHash(char dataHash, string *d, QFile *f) 838PwMerror PwMDoc::writeDataHash(char dataHash, string *d, QFile *f)
854{ 839{
855 PWM_ASSERT(d); 840 PWM_ASSERT(d);
856 PWM_ASSERT(f); 841 PWM_ASSERT(f);
857 842
858 switch (dataHash) { 843 switch (dataHash) {
859 case PWM_HASH_SHA1: { 844 case PWM_HASH_SHA1: {
860 const int hashLen = SHA1_HASH_LEN_BYTE; 845 const int hashLen = SHA1_HASH_LEN_BYTE;
861 Sha1 h; 846 Sha1 h;
862 h.sha1_write(reinterpret_cast<const byte *>(d->c_str()), d->size()); 847 h.sha1_write(reinterpret_cast<const byte *>(d->c_str()), d->size());
863 string hRet = h.sha1_read(); 848 string hRet = h.sha1_read();
864 if (f->writeBlock(hRet.c_str(), hashLen) != hashLen) 849 if (f->writeBlock(hRet.c_str(), hashLen) != hashLen)
865 return e_writeFile; 850 return e_writeFile;
866 break; 851 break;
867 } 852 }
868 #ifndef PWM_EMBEDDED
869 case PWM_HASH_SHA256: 853 case PWM_HASH_SHA256:
870 /*... fall through */ 854 /*... fall through */
871 case PWM_HASH_SHA384: 855 case PWM_HASH_SHA384:
872 case PWM_HASH_SHA512: 856 case PWM_HASH_SHA512:
873 case PWM_HASH_MD5: 857 case PWM_HASH_MD5:
874 case PWM_HASH_RMD160: 858 case PWM_HASH_RMD160:
875 case PWM_HASH_TIGER: { 859 case PWM_HASH_TIGER: {
876 if (!LibGCryptIf::available()) 860 if (!LibGCryptIf::available())
877 return e_hashNotImpl; 861 return e_hashNotImpl;
878 LibGCryptIf gc; 862 LibGCryptIf gc;
879 PwMerror err; 863 PwMerror err;
880 unsigned char *buf; 864 unsigned char *buf;
881 size_t hashLen; 865 size_t hashLen;
882 err = gc.hash(&buf, 866 err = gc.hash(&buf,
883 &hashLen, 867 &hashLen,
884 reinterpret_cast<const unsigned char *>(d->c_str()), 868 reinterpret_cast<const unsigned char *>(d->c_str()),
885 d->size(), 869 d->size(),
886 dataHash); 870 dataHash);
887 if (err != e_success) 871 if (err != e_success)
888 return e_hashNotImpl; 872 return e_hashNotImpl;
889 if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen) 873 if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen)
890 != static_cast<Q_LONG>(hashLen)) { 874 != static_cast<Q_LONG>(hashLen)) {
891 delete [] buf; 875 delete [] buf;
892 return e_hashNotImpl; 876 return e_hashNotImpl;
893 } 877 }
894 delete [] buf; 878 delete [] buf;
895 break; 879 break;
896 } 880 }
897#endif
898 default: { 881 default: {
899 return e_hashNotImpl; 882 return e_hashNotImpl;
900 } } 883 } }
901 884
902 return e_success; 885 return e_success;
903} 886}
904 887
905bool PwMDoc::backupFile(const QString &filePath) 888bool PwMDoc::backupFile(const QString &filePath)
906{ 889{
907 QFileInfo fi(filePath); 890 QFileInfo fi(filePath);
908 if (!fi.exists()) 891 if (!fi.exists())
909 return true; // Yes, true is correct. 892 return true; // Yes, true is correct.
910 QString pathOnly(fi.dirPath(true)); 893 QString pathOnly(fi.dirPath(true));
911 QString nameOnly(fi.fileName()); 894 QString nameOnly(fi.fileName());
912 QString backupPath = pathOnly 895 QString backupPath = pathOnly
913 + "/~" 896 + "/~"
914 + nameOnly 897 + nameOnly
915 + ".backup"; 898 + ".backup";
916 return copyFile(filePath, backupPath); 899 return copyFile(filePath, backupPath);
917} 900}
918 901
919bool PwMDoc::copyFile(const QString &src, const QString &dst) 902bool PwMDoc::copyFile(const QString &src, const QString &dst)
920{ 903{
921 QFileInfo fi(src); 904 QFileInfo fi(src);
922 if (!fi.exists()) 905 if (!fi.exists())
923 return false; 906 return false;
924 if (QFile::exists(dst)) { 907 if (QFile::exists(dst)) {
925 if (!QFile::remove(dst)) 908 if (!QFile::remove(dst))
926 return false; 909 return false;
927 } 910 }
928 QFile srcFd(src); 911 QFile srcFd(src);
929 if (!srcFd.open(IO_ReadOnly)) 912 if (!srcFd.open(IO_ReadOnly))
930 return false; 913 return false;
931 QFile dstFd(dst); 914 QFile dstFd(dst);
932 if (!dstFd.open(IO_ReadWrite)) { 915 if (!dstFd.open(IO_ReadWrite)) {
933 srcFd.close(); 916 srcFd.close();
934 return false; 917 return false;
935 } 918 }
936 const int tmpBuf_size = 512; 919 const int tmpBuf_size = 512;
937 char tmpBuf[tmpBuf_size]; 920 char tmpBuf[tmpBuf_size];
938#ifndef PWM_EMBEDDED
939 Q_LONG bytesRead, bytesWritten; 921 Q_LONG bytesRead, bytesWritten;
940#else 922
941 long bytesRead, bytesWritten;
942#endif
943 while (!srcFd.atEnd()) { 923 while (!srcFd.atEnd()) {
944#ifndef PWM_EMBEDDED
945 bytesRead = srcFd.readBlock(tmpBuf, 924 bytesRead = srcFd.readBlock(tmpBuf,
946 static_cast<Q_ULONG>(tmpBuf_size)); 925 static_cast<Q_ULONG>(tmpBuf_size));
947#else
948 bytesRead = srcFd.readBlock(tmpBuf,
949 (unsigned long)(tmpBuf_size));
950#endif
951 if (bytesRead == -1) { 926 if (bytesRead == -1) {
952 srcFd.close(); 927 srcFd.close();
953 dstFd.close(); 928 dstFd.close();
954 return false; 929 return false;
955 } 930 }
956#ifndef PWM_EMBEDDED
957 bytesWritten = dstFd.writeBlock(tmpBuf, 931 bytesWritten = dstFd.writeBlock(tmpBuf,
958 static_cast<Q_ULONG>(bytesRead)); 932 static_cast<Q_ULONG>(bytesRead));
959#else
960 bytesWritten = dstFd.writeBlock(tmpBuf,
961 (unsigned long)(bytesRead));
962#endif
963 if (bytesWritten != bytesRead) { 933 if (bytesWritten != bytesRead) {
964 srcFd.close(); 934 srcFd.close();
965 dstFd.close(); 935 dstFd.close();
966 return false; 936 return false;
967 } 937 }
968 } 938 }
969 srcFd.close(); 939 srcFd.close();
970 dstFd.close(); 940 dstFd.close();
971 return true; 941 return true;
972} 942}
973 943
974PwMerror PwMDoc::addEntry(const QString &category, PwMDataItem *d, 944PwMerror PwMDoc::addEntry(const QString &category, PwMDataItem *d,
975 bool dontFlagDirty, bool updateMeta) 945 bool dontFlagDirty, bool updateMeta)
976{ 946{
977 PWM_ASSERT(d); 947 PWM_ASSERT(d);
978 unsigned int cat = 0; 948 unsigned int cat = 0;
979 949
980 if (isDeepLocked()) { 950 if (isDeepLocked()) {
981 PwMerror ret; 951 PwMerror ret;
982 ret = deepLock(false); 952 ret = deepLock(false);
983 if (ret != e_success) 953 if (ret != e_success)
984 return e_lock; 954 return e_lock;
985 } 955 }
986 956
987 addCategory(category, &cat); 957 addCategory(category, &cat);
988 958
989 if (numEntries(category) >= maxEntries) 959 if (numEntries(category) >= maxEntries)
990 return e_maxAllowedEntr; 960 return e_maxAllowedEntr;
991 961
992 vector<unsigned int> foundPositions; 962 vector<unsigned int> foundPositions;
993 /* historically this was: 963 /* historically this was:
994 *const int searchIn = SEARCH_IN_DESC | SEARCH_IN_NAME | 964 *const int searchIn = SEARCH_IN_DESC | SEARCH_IN_NAME |
995 * SEARCH_IN_URL | SEARCH_IN_LAUNCHER; 965 * SEARCH_IN_URL | SEARCH_IN_LAUNCHER;
996 * But for now we only search in desc. 966 * But for now we only search in desc.
997 * That's a tweak to be KWallet compatible. But it should not add 967 * That's a tweak to be KWallet compatible. But it should not add
998 * usability-drop onto PwManager, does it? 968 * usability-drop onto PwManager, does it?
999 * (And yes, "int" was a bug. Correct is "unsigned int") 969 * (And yes, "int" was a bug. Correct is "unsigned int")
1000 */ 970 */
1001 const unsigned int searchIn = SEARCH_IN_DESC; 971 const unsigned int searchIn = SEARCH_IN_DESC;
1002 findEntry(cat, *d, searchIn, &foundPositions, true); 972 findEntry(cat, *d, searchIn, &foundPositions, true);
1003 if (foundPositions.size()) { 973 if (foundPositions.size()) {
1004 // DOH! We found this entry. 974 // DOH! We found this entry.
1005 return e_entryExists; 975 return e_entryExists;
1006 } 976 }
1007 977
1008 d->listViewPos = -1; 978 d->listViewPos = -1;
1009 d->lockStat = conf()->confGlobNewEntrLockStat(); 979 d->lockStat = conf()->confGlobNewEntrLockStat();
1010 if (updateMeta) { 980 if (updateMeta) {
1011 d->meta.create = QDateTime::currentDateTime(); 981 d->meta.create = QDateTime::currentDateTime();
1012 d->meta.update = d->meta.create; 982 d->meta.update = d->meta.create;
1013 } 983 }
1014 dti.dta[cat].d.push_back(*d); 984 dti.dta[cat].d.push_back(*d);
1015 985
1016 delAllEmptyCat(true); 986 delAllEmptyCat(true);
1017 987
1018 if (!dontFlagDirty) 988 if (!dontFlagDirty)
1019 flagDirty(); 989 flagDirty();
1020 return e_success; 990 return e_success;
1021} 991}
1022 992
1023PwMerror PwMDoc::addCategory(const QString &category, unsigned int *categoryIndex, 993PwMerror PwMDoc::addCategory(const QString &category, unsigned int *categoryIndex,
1024 bool checkIfExist) 994 bool checkIfExist)
1025{ 995{
1026 if (isDeepLocked()) { 996 if (isDeepLocked()) {
1027 PwMerror ret; 997 PwMerror ret;
1028 ret = deepLock(false); 998 ret = deepLock(false);
1029 if (ret != e_success) 999 if (ret != e_success)
1030 return e_lock; 1000 return e_lock;
1031 } 1001 }
1032 if (checkIfExist) { 1002 if (checkIfExist) {
1033 if (findCategory(category, categoryIndex)) 1003 if (findCategory(category, categoryIndex))
1034 return e_categoryExists; 1004 return e_categoryExists;
1035 } 1005 }
1036 PwMCategoryItem item; 1006 PwMCategoryItem item;
1037 item.name = category.latin1(); 1007 item.name = category.latin1();
1038 dti.dta.push_back(item); 1008 dti.dta.push_back(item);
1039 if (categoryIndex) 1009 if (categoryIndex)
1040 *categoryIndex = dti.dta.size() - 1; 1010 *categoryIndex = dti.dta.size() - 1;
1041 return e_success; 1011 return e_success;
1042} 1012}
1043 1013
1044bool PwMDoc::delEntry(const QString &category, unsigned int index, bool dontFlagDirty) 1014bool PwMDoc::delEntry(const QString &category, unsigned int index, bool dontFlagDirty)
1045{ 1015{
1046 unsigned int cat = 0; 1016 unsigned int cat = 0;
1047 1017
1048 if (!findCategory(category, &cat)) { 1018 if (!findCategory(category, &cat)) {
1049 BUG(); 1019 BUG();
1050 return false; 1020 return false;
1051 } 1021 }
1052 1022
1053 return delEntry(cat, index, dontFlagDirty); 1023 return delEntry(cat, index, dontFlagDirty);
1054} 1024}
1055 1025
1056bool PwMDoc::delEntry(unsigned int category, unsigned int index, bool dontFlagDirty) 1026bool PwMDoc::delEntry(unsigned int category, unsigned int index, bool dontFlagDirty)
1057{ 1027{
1058 if (isDeepLocked()) 1028 if (isDeepLocked())
@@ -1207,373 +1177,358 @@ bool PwMDoc::getEntry(unsigned int category, unsigned int index,
1207 */ 1177 */
1208 if (unlockIfLocked) { 1178 if (unlockIfLocked) {
1209 if (!lockAt(category, index, false)) { 1179 if (!lockAt(category, index, false)) {
1210 return false; 1180 return false;
1211 } 1181 }
1212 locked = false; 1182 locked = false;
1213 } 1183 }
1214 } 1184 }
1215 1185
1216 *d = dti.dta[category].d[index]; 1186 *d = dti.dta[category].d[index];
1217 if (locked) 1187 if (locked)
1218 d->pw = LOCKED_STRING.latin1(); 1188 d->pw = LOCKED_STRING.latin1();
1219 1189
1220 return true; 1190 return true;
1221} 1191}
1222 1192
1223PwMerror PwMDoc::getCommentByLvp(const QString &category, int listViewPos, 1193PwMerror PwMDoc::getCommentByLvp(const QString &category, int listViewPos,
1224 string *foundComment) 1194 string *foundComment)
1225{ 1195{
1226 PWM_ASSERT(foundComment); 1196 PWM_ASSERT(foundComment);
1227 unsigned int cat = 0; 1197 unsigned int cat = 0;
1228 1198
1229 if (!findCategory(category, &cat)) 1199 if (!findCategory(category, &cat))
1230 return e_invalidArg; 1200 return e_invalidArg;
1231 1201
1232 unsigned int i, entries = numEntries(cat); 1202 unsigned int i, entries = numEntries(cat);
1233 for (i = 0; i < entries; ++i) { 1203 for (i = 0; i < entries; ++i) {
1234 if (dti.dta[cat].d[i].listViewPos == listViewPos) { 1204 if (dti.dta[cat].d[i].listViewPos == listViewPos) {
1235 *foundComment = dti.dta[cat].d[i].comment; 1205 *foundComment = dti.dta[cat].d[i].comment;
1236 if (dti.dta[cat].d[i].binary) 1206 if (dti.dta[cat].d[i].binary)
1237 return e_binEntry; 1207 return e_binEntry;
1238 return e_normalEntry; 1208 return e_normalEntry;
1239 } 1209 }
1240 } 1210 }
1241 BUG(); 1211 BUG();
1242 return e_generic; 1212 return e_generic;
1243} 1213}
1244 1214
1245bool PwMDoc::compressDta(string *d, char algo) 1215bool PwMDoc::compressDta(string *d, char algo)
1246{ 1216{
1247 PWM_ASSERT(d); 1217 PWM_ASSERT(d);
1248 switch (algo) { 1218 switch (algo) {
1249 case PWM_COMPRESS_GZIP: { 1219 case PWM_COMPRESS_GZIP: {
1250 CompressGzip comp; 1220 CompressGzip comp;
1251 return comp.compress(d); 1221 return comp.compress(d);
1252 } case PWM_COMPRESS_BZIP2: { 1222 } case PWM_COMPRESS_BZIP2: {
1253 CompressBzip2 comp; 1223 CompressBzip2 comp;
1254 return comp.compress(d); 1224 return comp.compress(d);
1255 } case PWM_COMPRESS_NONE: { 1225 } case PWM_COMPRESS_NONE: {
1256 return true; 1226 return true;
1257 } default: { 1227 } default: {
1258 BUG(); 1228 BUG();
1259 } 1229 }
1260 } 1230 }
1261 return false; 1231 return false;
1262} 1232}
1263 1233
1264bool PwMDoc::decompressDta(string *d, char algo) 1234bool PwMDoc::decompressDta(string *d, char algo)
1265{ 1235{
1266 PWM_ASSERT(d); 1236 PWM_ASSERT(d);
1267 switch (algo) { 1237 switch (algo) {
1268 case PWM_COMPRESS_GZIP: { 1238 case PWM_COMPRESS_GZIP: {
1269 CompressGzip comp; 1239 CompressGzip comp;
1270 return comp.decompress(d); 1240 return comp.decompress(d);
1271 } case PWM_COMPRESS_BZIP2: { 1241 } case PWM_COMPRESS_BZIP2: {
1272 CompressBzip2 comp; 1242 CompressBzip2 comp;
1273 return comp.decompress(d); 1243 return comp.decompress(d);
1274 } case PWM_COMPRESS_NONE: { 1244 } case PWM_COMPRESS_NONE: {
1275 return true; 1245 return true;
1276 } 1246 }
1277 } 1247 }
1278 return false; 1248 return false;
1279} 1249}
1280 1250
1281PwMerror PwMDoc::encrypt(string *d, const QString *pw, QFile *f, char algo) 1251PwMerror PwMDoc::encrypt(string *d, const QString *pw, QFile *f, char algo)
1282{ 1252{
1283 PWM_ASSERT(d); 1253 PWM_ASSERT(d);
1284 PWM_ASSERT(pw); 1254 PWM_ASSERT(pw);
1285 PWM_ASSERT(f); 1255 PWM_ASSERT(f);
1286 1256
1287 size_t encSize; 1257 size_t encSize;
1288 byte *encrypted = 0; 1258 byte *encrypted = 0;
1289 1259
1290 switch (algo) { 1260 switch (algo) {
1291 case PWM_CRYPT_BLOWFISH: { 1261 case PWM_CRYPT_BLOWFISH: {
1292 Blowfish::padNull(d); 1262 Blowfish::padNull(d);
1293 encSize = d->length(); 1263 encSize = d->length();
1294 encrypted = new byte[encSize]; 1264 encrypted = new byte[encSize];
1295 Blowfish bf; 1265 Blowfish bf;
1296 if (bf.bf_setkey((byte *) pw->latin1(), pw->length())) { 1266 if (bf.bf_setkey((byte *) pw->latin1(), pw->length())) {
1297 delete [] encrypted; 1267 delete [] encrypted;
1298 return e_weakPw; 1268 return e_weakPw;
1299 } 1269 }
1300 bf.bf_encrypt((byte *) encrypted, (byte *) d->c_str(), encSize); 1270 bf.bf_encrypt((byte *) encrypted, (byte *) d->c_str(), encSize);
1301 break; 1271 break;
1302 } 1272 }
1303 #ifndef PWM_EMBEDDED
1304 case PWM_CRYPT_AES128: 1273 case PWM_CRYPT_AES128:
1305 /*... fall through */ 1274 /*... fall through */
1306 case PWM_CRYPT_AES192: 1275 case PWM_CRYPT_AES192:
1307 case PWM_CRYPT_AES256: 1276 case PWM_CRYPT_AES256:
1308 case PWM_CRYPT_3DES: 1277 case PWM_CRYPT_3DES:
1309 case PWM_CRYPT_TWOFISH: 1278 case PWM_CRYPT_TWOFISH:
1310 case PWM_CRYPT_TWOFISH128: { 1279 case PWM_CRYPT_TWOFISH128: {
1311 if (!LibGCryptIf::available()) 1280 if (!LibGCryptIf::available())
1312 return e_cryptNotImpl; 1281 return e_cryptNotImpl;
1313 LibGCryptIf gc; 1282 LibGCryptIf gc;
1314 PwMerror err; 1283 PwMerror err;
1315 unsigned char *plain = new unsigned char[d->length() + 1024]; 1284 unsigned char *plain = new unsigned char[d->length() + 1024];
1316 memcpy(plain, d->c_str(), d->length()); 1285 memcpy(plain, d->c_str(), d->length());
1317 err = gc.encrypt(&encrypted, 1286 err = gc.encrypt(&encrypted,
1318 &encSize, 1287 &encSize,
1319 plain, 1288 plain,
1320 d->length(), 1289 d->length(),
1321 reinterpret_cast<const unsigned char *>(pw->latin1()), 1290 reinterpret_cast<const unsigned char *>(pw->latin1()),
1322 pw->length(), 1291 pw->length(),
1323 algo); 1292 algo);
1324 delete [] plain; 1293 delete [] plain;
1325 if (err != e_success) 1294 if (err != e_success)
1326 return e_cryptNotImpl; 1295 return e_cryptNotImpl;
1327 break; 1296 break;
1328 } 1297 }
1329#endif
1330 default: { 1298 default: {
1331 delete_ifnot_null_array(encrypted); 1299 delete_ifnot_null_array(encrypted);
1332 return e_cryptNotImpl; 1300 return e_cryptNotImpl;
1333 } } 1301 } }
1334 1302
1335 // write encrypted data to file 1303 // write encrypted data to file
1336#ifndef PWM_EMBEDDED
1337 if (f->writeBlock(reinterpret_cast<const char *>(encrypted), 1304 if (f->writeBlock(reinterpret_cast<const char *>(encrypted),
1338 static_cast<Q_ULONG>(encSize)) 1305 static_cast<Q_ULONG>(encSize))
1339 != static_cast<Q_LONG>(encSize)) { 1306 != static_cast<Q_LONG>(encSize)) {
1340 delete_ifnot_null_array(encrypted); 1307 delete_ifnot_null_array(encrypted);
1341 return e_writeFile; 1308 return e_writeFile;
1342 } 1309 }
1343#else
1344 if (f->writeBlock((const char *)(encrypted),
1345 (unsigned long)(encSize))
1346 != (long)(encSize)) {
1347 delete_ifnot_null_array(encrypted);
1348 return e_writeFile;
1349 }
1350#endif
1351 delete_ifnot_null_array(encrypted); 1310 delete_ifnot_null_array(encrypted);
1352 return e_success; 1311 return e_success;
1353} 1312}
1354 1313
1355PwMerror PwMDoc::decrypt(string *d, unsigned int pos, const QString *pw, 1314PwMerror PwMDoc::decrypt(string *d, unsigned int pos, const QString *pw,
1356 char algo, QFile *f) 1315 char algo, QFile *f)
1357{ 1316{
1358 PWM_ASSERT(d); 1317 PWM_ASSERT(d);
1359 PWM_ASSERT(pw); 1318 PWM_ASSERT(pw);
1360 PWM_ASSERT(f); 1319 PWM_ASSERT(f);
1361 1320
1362 unsigned int cryptLen = f->size() - pos; 1321 unsigned int cryptLen = f->size() - pos;
1363 byte *encrypted = new byte[cryptLen]; 1322 byte *encrypted = new byte[cryptLen];
1364 byte *decrypted = new byte[cryptLen]; 1323 byte *decrypted = new byte[cryptLen];
1365 1324
1366 f->at(pos); 1325 f->at(pos);
1367#ifndef PWM_EMBEDDED 1326#ifndef PWM_EMBEDDED
1368 if (f->readBlock(reinterpret_cast<char *>(encrypted), 1327 if (f->readBlock(reinterpret_cast<char *>(encrypted),
1369 static_cast<Q_ULONG>(cryptLen)) 1328 static_cast<Q_ULONG>(cryptLen))
1370 != static_cast<Q_LONG>(cryptLen)) { 1329 != static_cast<Q_LONG>(cryptLen)) {
1371 delete [] encrypted; 1330 delete [] encrypted;
1372 delete [] decrypted; 1331 delete [] decrypted;
1373 return e_readFile; 1332 return e_readFile;
1374 } 1333 }
1375#else 1334#else
1376 if (f->readBlock((char *)(encrypted), 1335 if (f->readBlock((char *)(encrypted),
1377 (unsigned long)(cryptLen)) 1336 (unsigned long)(cryptLen))
1378 != (long)(cryptLen)) { 1337 != (long)(cryptLen)) {
1379 delete [] encrypted; 1338 delete [] encrypted;
1380 delete [] decrypted; 1339 delete [] decrypted;
1381 return e_readFile; 1340 return e_readFile;
1382 } 1341 }
1383#endif 1342#endif
1384 switch (algo) { 1343 switch (algo) {
1385 case PWM_CRYPT_BLOWFISH: { 1344 case PWM_CRYPT_BLOWFISH: {
1386 Blowfish bf; 1345 Blowfish bf;
1387 bf.bf_setkey((byte *) pw->latin1(), pw->length()); 1346 bf.bf_setkey((byte *) pw->latin1(), pw->length());
1388 bf.bf_decrypt(decrypted, encrypted, cryptLen); 1347 bf.bf_decrypt(decrypted, encrypted, cryptLen);
1389 break; 1348 break;
1390 } 1349 }
1391#ifndef PWM_EMBEDDED
1392 case PWM_CRYPT_AES128: 1350 case PWM_CRYPT_AES128:
1393 /*... fall through */ 1351 /*... fall through */
1394 case PWM_CRYPT_AES192: 1352 case PWM_CRYPT_AES192:
1395 case PWM_CRYPT_AES256: 1353 case PWM_CRYPT_AES256:
1396 case PWM_CRYPT_3DES: 1354 case PWM_CRYPT_3DES:
1397 case PWM_CRYPT_TWOFISH: 1355 case PWM_CRYPT_TWOFISH:
1398 case PWM_CRYPT_TWOFISH128: { 1356 case PWM_CRYPT_TWOFISH128: {
1399 if (!LibGCryptIf::available()) 1357 if (!LibGCryptIf::available())
1400 return e_cryptNotImpl; 1358 return e_cryptNotImpl;
1401 LibGCryptIf gc; 1359 LibGCryptIf gc;
1402 PwMerror err; 1360 PwMerror err;
1403 err = gc.decrypt(&decrypted, 1361 err = gc.decrypt(&decrypted,
1404 &cryptLen, 1362 &cryptLen,
1405 encrypted, 1363 encrypted,
1406 cryptLen, 1364 cryptLen,
1407 reinterpret_cast<const unsigned char *>(pw->latin1()), 1365 reinterpret_cast<const unsigned char *>(pw->latin1()),
1408 pw->length(), 1366 pw->length(),
1409 algo); 1367 algo);
1410 if (err != e_success) { 1368 if (err != e_success) {
1411 delete [] encrypted; 1369 delete [] encrypted;
1412 delete [] decrypted; 1370 delete [] decrypted;
1413 return e_cryptNotImpl; 1371 return e_cryptNotImpl;
1414 } 1372 }
1415 break; 1373 break;
1416 } 1374 }
1417#endif
1418 default: { 1375 default: {
1419 delete [] encrypted; 1376 delete [] encrypted;
1420 delete [] decrypted; 1377 delete [] decrypted;
1421 return e_cryptNotImpl; 1378 return e_cryptNotImpl;
1422 } } 1379 } }
1423 delete [] encrypted; 1380 delete [] encrypted;
1424#ifndef PWM_EMBEDDED 1381#ifndef PWM_EMBEDDED
1425 d->assign(reinterpret_cast<const char *>(decrypted), 1382 d->assign(reinterpret_cast<const char *>(decrypted),
1426 static_cast<string::size_type>(cryptLen)); 1383 static_cast<string::size_type>(cryptLen));
1427#else 1384#else
1428 d->assign((const char *)(decrypted), 1385 d->assign((const char *)(decrypted),
1429 (string::size_type)(cryptLen)); 1386 (string::size_type)(cryptLen));
1430#endif 1387#endif
1431 delete [] decrypted; 1388 delete [] decrypted;
1432 if (algo == PWM_CRYPT_BLOWFISH) { 1389 if (algo == PWM_CRYPT_BLOWFISH) {
1433 if (!Blowfish::unpadNull(d)) { 1390 if (!Blowfish::unpadNull(d)) {
1434 BUG(); 1391 BUG();
1435 return e_readFile; 1392 return e_readFile;
1436 } 1393 }
1437 } 1394 }
1438 return e_success; 1395 return e_success;
1439} 1396}
1440 1397
1441PwMerror PwMDoc::checkDataHash(char dataHashType, const string *dataHash, 1398PwMerror PwMDoc::checkDataHash(char dataHashType, const string *dataHash,
1442 const string *dataStream) 1399 const string *dataStream)
1443{ 1400{
1444 PWM_ASSERT(dataHash); 1401 PWM_ASSERT(dataHash);
1445 PWM_ASSERT(dataStream); 1402 PWM_ASSERT(dataStream);
1446 switch(dataHashType) { 1403 switch(dataHashType) {
1447 case PWM_HASH_SHA1: { 1404 case PWM_HASH_SHA1: {
1448 Sha1 hash; 1405 Sha1 hash;
1449 hash.sha1_write((byte*)dataStream->c_str(), dataStream->length()); 1406 hash.sha1_write((byte*)dataStream->c_str(), dataStream->length());
1450 string ret = hash.sha1_read(); 1407 string ret = hash.sha1_read();
1451 if (ret != *dataHash) 1408 if (ret != *dataHash)
1452 return e_fileCorrupt; 1409 return e_fileCorrupt;
1453 break; 1410 break;
1454 } 1411 }
1455#ifndef PWM_EMBEDDED
1456 case PWM_HASH_SHA256: 1412 case PWM_HASH_SHA256:
1457 /*... fall through */ 1413 /*... fall through */
1458 case PWM_HASH_SHA384: 1414 case PWM_HASH_SHA384:
1459 case PWM_HASH_SHA512: 1415 case PWM_HASH_SHA512:
1460 case PWM_HASH_MD5: 1416 case PWM_HASH_MD5:
1461 case PWM_HASH_RMD160: 1417 case PWM_HASH_RMD160:
1462 case PWM_HASH_TIGER: { 1418 case PWM_HASH_TIGER: {
1463 if (!LibGCryptIf::available()) 1419 if (!LibGCryptIf::available())
1464 return e_hashNotImpl; 1420 return e_hashNotImpl;
1465 LibGCryptIf gc; 1421 LibGCryptIf gc;
1466 PwMerror err; 1422 PwMerror err;
1467 unsigned char *buf; 1423 unsigned char *buf;
1468 size_t hashLen; 1424 size_t hashLen;
1469 err = gc.hash(&buf, 1425 err = gc.hash(&buf,
1470 &hashLen, 1426 &hashLen,
1471 reinterpret_cast<const unsigned char *>(dataStream->c_str()), 1427 reinterpret_cast<const unsigned char *>(dataStream->c_str()),
1472 dataStream->length(), 1428 dataStream->length(),
1473 dataHashType); 1429 dataHashType);
1474 if (err != e_success) 1430 if (err != e_success)
1475 return e_hashNotImpl; 1431 return e_hashNotImpl;
1476 string calcHash(reinterpret_cast<const char *>(buf), 1432 string calcHash(reinterpret_cast<const char *>(buf),
1477 static_cast<string::size_type>(hashLen)); 1433 static_cast<string::size_type>(hashLen));
1478 delete [] buf; 1434 delete [] buf;
1479 if (calcHash != *dataHash) 1435 if (calcHash != *dataHash)
1480 return e_fileCorrupt; 1436 return e_fileCorrupt;
1481 break; 1437 break;
1482 } 1438 }
1483#endif
1484 default: 1439 default:
1485 return e_hashNotImpl; 1440 return e_hashNotImpl;
1486 } 1441 }
1487 return e_success; 1442 return e_success;
1488} 1443}
1489 1444
1490bool PwMDoc::lockAt(unsigned int category, unsigned int index, 1445bool PwMDoc::lockAt(unsigned int category, unsigned int index,
1491 bool lock) 1446 bool lock)
1492{ 1447{
1493 if (index >= numEntries(category)) { 1448 if (index >= numEntries(category)) {
1494 BUG(); 1449 BUG();
1495 return false; 1450 return false;
1496 } 1451 }
1497 if (lock == dti.dta[category].d[index].lockStat) 1452 if (lock == dti.dta[category].d[index].lockStat)
1498 return true; 1453 return true;
1499 1454
1500 if (!lock && currentPw != "") { 1455 if (!lock && currentPw != "") {
1501 // "unlocking" and "password is already set" 1456 // "unlocking" and "password is already set"
1502 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) { 1457 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) {
1503 // unlocking without pw not allowed 1458 // unlocking without pw not allowed
1504 QString pw; 1459 QString pw;
1505 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1460 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1506 if (pw != "") { 1461 if (pw != "") {
1507 if (pw != currentPw) { 1462 if (pw != currentPw) {
1508 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1463 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1509 return false; 1464 return false;
1510 } else { 1465 } else {
1511 timer()->start(DocTimer::id_mpwTimer); 1466 timer()->start(DocTimer::id_mpwTimer);
1512 } 1467 }
1513 } else { 1468 } else {
1514 return false; 1469 return false;
1515 } 1470 }
1516 } else { 1471 } else {
1517 timer()->start(DocTimer::id_mpwTimer); 1472 timer()->start(DocTimer::id_mpwTimer);
1518 } 1473 }
1519 } 1474 }
1520 1475
1521 dti.dta[category].d[index].lockStat = lock; 1476 dti.dta[category].d[index].lockStat = lock;
1522 dti.dta[category].d[index].rev++; // increment revision counter. 1477 dti.dta[category].d[index].rev++; // increment revision counter.
1523 1478
1524 emitDataChanged(this); 1479 emitDataChanged(this);
1525 if (!lock) 1480 if (!lock)
1526 timer()->start(DocTimer::id_autoLockTimer); 1481 timer()->start(DocTimer::id_autoLockTimer);
1527 1482
1528 return true; 1483 return true;
1529 1484
1530} 1485}
1531 1486
1532bool PwMDoc::lockAt(const QString &category,unsigned int index, 1487bool PwMDoc::lockAt(const QString &category,unsigned int index,
1533 bool lock) 1488 bool lock)
1534{ 1489{
1535 unsigned int cat = 0; 1490 unsigned int cat = 0;
1536 1491
1537 if (!findCategory(category, &cat)) { 1492 if (!findCategory(category, &cat)) {
1538 BUG(); 1493 BUG();
1539 return false; 1494 return false;
1540 } 1495 }
1541 1496
1542 return lockAt(cat, index, lock); 1497 return lockAt(cat, index, lock);
1543} 1498}
1544 1499
1545bool PwMDoc::lockAll(bool lock) 1500bool PwMDoc::lockAll(bool lock)
1546{ 1501{
1547 if (!lock && isDeepLocked()) { 1502 if (!lock && isDeepLocked()) {
1548 PwMerror ret; 1503 PwMerror ret;
1549 ret = deepLock(false); 1504 ret = deepLock(false);
1550 if (ret != e_success) 1505 if (ret != e_success)
1551 return false; 1506 return false;
1552 return true; 1507 return true;
1553 } 1508 }
1554 if (isDocEmpty()) { 1509 if (isDocEmpty()) {
1555 return true; 1510 return true;
1556 } 1511 }
1557 if (!lock && currentPw != "") { 1512 if (!lock && currentPw != "") {
1558 // unlocking and password is already set 1513 // unlocking and password is already set
1559 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) { 1514 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) {
1560 // unlocking without pw not allowed 1515 // unlocking without pw not allowed
1561 QString pw; 1516 QString pw;
1562 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1517 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1563 if (pw != "") { 1518 if (pw != "") {
1564 if (pw != currentPw) { 1519 if (pw != currentPw) {
1565 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1520 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1566 return false; 1521 return false;
1567 } else { 1522 } else {
1568 timer()->start(DocTimer::id_mpwTimer); 1523 timer()->start(DocTimer::id_mpwTimer);
1569 } 1524 }
1570 } else { 1525 } else {
1571 return false; 1526 return false;
1572 } 1527 }
1573 } else { 1528 } else {
1574 timer()->start(DocTimer::id_mpwTimer); 1529 timer()->start(DocTimer::id_mpwTimer);
1575 } 1530 }
1576 } 1531 }
1577 1532
1578 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), 1533 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(),
1579 catEnd = dti.dta.end(), 1534 catEnd = dti.dta.end(),