upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/walletcmd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/walletcmd.cpp')
-rw-r--r--src/walletcmd.cpp137
1 files changed, 137 insertions, 0 deletions
diff --git a/src/walletcmd.cpp b/src/walletcmd.cpp
index 6f8258d..265febe 100644
--- a/src/walletcmd.cpp
+++ b/src/walletcmd.cpp
@@ -13,6 +13,10 @@
13#include "bip32.h" 13#include "bip32.h"
14#include "walletcmd.h" 14#include "walletcmd.h"
15 15
16#ifndef _WIN32
17#include <dirent.h>
18#endif
19
16#undef printf 20#undef printf
17 21
18// How far ahead to look for used addresses when restoring. 22// How far ahead to look for used addresses when restoring.
@@ -658,6 +662,139 @@ static bool WriteAuditTextFile(const std::string& strPath,
658 return true; 662 return true;
659} 663}
660 664
665static bool DirectoryHasFileWithPrefixLocal(const std::string& strDir,
666 const std::string& strPrefix)
667{
668#ifdef _WIN32
669 std::string pattern = strDir + "/*";
670 WIN32_FIND_DATAA findData;
671 HANDLE hFind = FindFirstFileA(pattern.c_str(), &findData);
672 if (hFind == INVALID_HANDLE_VALUE)
673 return false;
674 bool fFound = false;
675 do
676 {
677 if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
678 {
679 std::string name = findData.cFileName;
680 if (name.compare(0, strPrefix.size(), strPrefix) == 0)
681 {
682 fFound = true;
683 break;
684 }
685 }
686 }
687 while (FindNextFileA(hFind, &findData));
688 FindClose(hFind);
689 return fFound;
690#else
691 DIR* dir = opendir(strDir.c_str());
692 if (!dir)
693 return false;
694 bool fFound = false;
695 struct dirent* ent;
696 while ((ent = readdir(dir)) != NULL)
697 {
698 std::string name = ent->d_name;
699 if (name.compare(0, strPrefix.size(), strPrefix) == 0)
700 {
701 fFound = true;
702 break;
703 }
704 }
705 closedir(dir);
706 return fFound;
707#endif
708}
709
710static void AddWalletStorageFailure(std::vector<std::string>& vFailures,
711 const std::string& strFailure)
712{
713 vFailures.push_back(strFailure);
714}
715
716static void BuildWalletStorageSanityFailures(const WalletStorageAuditCounts& counts,
717 std::vector<std::string>& vFailures)
718{
719 bool fPlainHD = counts.nPlainHDMaster > 0 || counts.nPlainHDChainCode > 0;
720 bool fCryptedHD = counts.nCryptedHDMaster > 0 || counts.nCryptedHDChainCode > 0;
721 bool fEncryptedRecords = counts.nEncryptedKeys > 0 ||
722 counts.nMasterKeys > 0 ||
723 fCryptedHD;
724
725 if (counts.nMalformed > 0)
726 AddWalletStorageFailure(vFailures, "wallet.dat contains malformed records");
727 if (counts.nUnknown > 0)
728 AddWalletStorageFailure(vFailures, "wallet.dat contains unknown records");
729 if ((counts.nPlainHDMaster > 0) != (counts.nPlainHDChainCode > 0))
730 AddWalletStorageFailure(vFailures, "plain HD seed is incomplete");
731 if ((counts.nCryptedHDMaster > 0) != (counts.nCryptedHDChainCode > 0))
732 AddWalletStorageFailure(vFailures, "encrypted HD seed is incomplete");
733 if (fPlainHD && fCryptedHD)
734 AddWalletStorageFailure(vFailures, "wallet.dat contains both plain and encrypted HD seed records");
735 if (counts.nDefaultKey > 1)
736 AddWalletStorageFailure(vFailures, "wallet.dat contains more than one default public key record");
737 if (counts.nWalletMinVersion > 1)
738 AddWalletStorageFailure(vFailures, "wallet.dat contains more than one minimum-version record");
739
740 if (fEncryptedRecords)
741 {
742 if (counts.nPlainKeys > 0)
743 AddWalletStorageFailure(vFailures, "encrypted wallet still contains plain private key records");
744 if (fPlainHD)
745 AddWalletStorageFailure(vFailures, "encrypted wallet still contains plain HD seed records");
746 if (counts.nMasterKeys == 0)
747 AddWalletStorageFailure(vFailures, "encrypted wallet has no encryption master key record");
748 if (counts.nWalletMinVersion == 0)
749 AddWalletStorageFailure(vFailures, "encrypted wallet has no minimum-version record");
750 if (DirectoryHasFileWithPrefixLocal(GetAppDir() + "/database", "log."))
751 AddWalletStorageFailure(vFailures, "Berkeley DB log files are still present for an encrypted wallet");
752 }
753}
754
755int CmdWalletStorageCheck()
756{
757 AttachTerminal();
758
759 WalletStorageAuditCounts counts;
760 std::string strError;
761 if (!ReadWalletStorageCounts(counts, strError))
762 {
763 fprintf(stderr, "Cannot check wallet storage: %s\n", strError.c_str());
764 return 1;
765 }
766
767 std::vector<std::string> vFailures;
768 BuildWalletStorageSanityFailures(counts, vFailures);
769
770 printf("Wallet storage sanity check\n");
771 printf(" records total: %u\n", counts.nTotal);
772 printf(" encrypted records: %s\n",
773 (counts.nEncryptedKeys || counts.nMasterKeys ||
774 counts.nCryptedHDMaster || counts.nCryptedHDChainCode) ? "yes" : "no");
775 printf(" plain private keys: %u\n", counts.nPlainKeys);
776 printf(" encrypted private keys: %u\n", counts.nEncryptedKeys);
777 printf(" plain HD seed: %s\n",
778 HDSeedStorageState(counts.nPlainHDMaster,
779 counts.nPlainHDChainCode).c_str());
780 printf(" encrypted HD seed: %s\n",
781 HDSeedStorageState(counts.nCryptedHDMaster,
782 counts.nCryptedHDChainCode).c_str());
783 if (vFailures.empty())
784 {
785 printf(" storage sanity: ok\n");
786 fflush(stdout);
787 return 0;
788 }
789
790 printf(" storage sanity: failed\n");
791 for (std::vector<std::string>::const_iterator it = vFailures.begin();
792 it != vFailures.end(); ++it)
793 printf(" failure: %s\n", it->c_str());
794 fflush(stdout);
795 return 2;
796}
797
661int CmdWalletStorageAudit(const std::string& strJsonOut) 798int CmdWalletStorageAudit(const std::string& strJsonOut)
662{ 799{
663 AttachTerminal(); 800 AttachTerminal();