📄 pwmanager.cpp
字号:
if(!id)continue; //darf nicht 0 sein (KDB-Format v3) for(int j=0;j<Groups.size();j++){ if(Groups[j].ID==id)used=true;}if(used==false)break;}return id;}quint32 PwDatabase::getNewEntrySid(){quint32 sid;while(1){getRandomBytes(&sid,4,1,false);if(!sid)continue;if(!isEntrySidInUse(sid))break;}return sid;}bool PwDatabase::convHexToBinaryKey(char* HexKey, char* dst){QString hex=QString::fromAscii(HexKey,64);for(int i=0; i<64; i+=2){ bool err; quint8 bin; bin=hex.mid(i,2).toUInt(&err,16); if(!err){ qWarning("Invalid Hex Key\n"); return false;} memcpy(dst+(i/2),&bin,1);}return true;}void PwDatabase::moveGroup(CGroup* group, CGroup* DstGroup, int pos){int NumSubGroups=0;int GroupIndex=Groups.indexOf(*group);int DstIndex;int i;for(i=GroupIndex+1; i<Groups.size(); i++){ if(Groups[i].Level <= group->Level) break;}NumSubGroups=i-GroupIndex-1;int LevelDiff;QList<CGroup> tmp;if(DstGroup) LevelDiff=DstGroup->Level - group->Level +1;else LevelDiff=-group->Level;for(i=GroupIndex; i<=GroupIndex+NumSubGroups; i++){ tmp << Groups[i]; tmp.back().Level+=LevelDiff;}for(i=0; i<=NumSubGroups; i++) Groups.removeAt(GroupIndex);int NumParentSubGroups;if(DstGroup){ DstIndex=Groups.indexOf(*DstGroup); NumParentSubGroups=getNumberOfChilds(DstGroup);}else{ DstIndex=0; NumParentSubGroups=Groups.size();}if(pos==-1)DstIndex+=(NumParentSubGroups+1);else{ int n=0; //counter for direct (first-level) childs for(i=0; i<NumParentSubGroups;i++){ if(n==pos)break; if(Groups[DstIndex+1+i].Level==DstGroup->Level+1)n++; } DstIndex+=(n+1);}for(i=NumSubGroups; i>=0; i--) Groups.insert(DstIndex,tmp[i]);}void PwDatabase::moveGroupDirectly(CGroup* group, CGroup* DstGroup){int NumSubGroups=getNumberOfChilds(group);int GroupIndex=Groups.indexOf(*group);int DstIndex, LevelDiff, i;QList<CGroup> tmp;if(DstGroup) LevelDiff=DstGroup->Level - group->Level;else LevelDiff=-group->Level;for(i=GroupIndex; i<=GroupIndex+NumSubGroups; i++){ tmp << Groups[i]; tmp.back().Level+=LevelDiff;}for(i=0; i<=NumSubGroups; i++) Groups.removeAt(GroupIndex);if(DstGroup) DstIndex=Groups.indexOf(*DstGroup)+1;else DstIndex=0;for(i=NumSubGroups; i>=0; i--) Groups.insert(DstIndex,tmp[i]);}bool PwDatabase::createKeyFile(const QString& filename){QFile file(filename);if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate)){ Errors << tr("Could not open key file."); return false;}char* pKeyData=new char[32];getRandomBytes(pKeyData,32);if(file.write(pKeyData,32)!=32){ Errors << tr("Key file could not be written."); file.close(); return false;}file.close();return true;}int PwDatabase::getNumberOfChilds(CGroup* group){if(!group)return Groups.size();int GroupIndex=Groups.indexOf(*group);int i;for(i=GroupIndex+1; i<Groups.size(); i++){ if(Groups[i].Level <= group->Level) break;}return (i-GroupIndex-1);}CGroup& PwDatabase::group(unsigned long index){ return Groups[index];}void PwDatabase::setGroup(unsigned long index,CGroup& group){ Groups[index]=group;}int PwDatabase::numGroups(){ return Groups.size();}CEntry& PwDatabase::entry(unsigned long index){ return Entries[index];}void PwDatabase::setEntry(unsigned long index,CEntry& entry){ Entries[index]=entry;}int PwDatabase::numEntries(){ return Entries.size();}void memcpyFromLEnd32(quint32* dst,const char* src){if(QSysInfo::ByteOrder==QSysInfo::BigEndian){ memcpy(((char*)dst)+3,src+0,1); memcpy(((char*)dst)+2,src+1,1); memcpy(((char*)dst)+1,src+2,1); memcpy(((char*)dst)+0,src+3,1);}else memcpy(dst,src,4);}void memcpyFromLEnd16(quint16* dst,const char* src){if(QSysInfo::ByteOrder==QSysInfo::BigEndian){ memcpy(((char*)dst)+1,src+0,1); memcpy(((char*)dst)+0,src+1,1);}else memcpy(dst,src,2);}void memcpyToLEnd32(char* dst,const quint32* src){if(QSysInfo::ByteOrder==QSysInfo::BigEndian){ memcpy(dst+0,((char*)src)+3,1); memcpy(dst+1,((char*)src)+2,1); memcpy(dst+2,((char*)src)+1,1); memcpy(dst+3,((char*)src)+0,1);}else memcpy(dst,src,4);}void memcpyToLEnd16(char* dst,const quint16* src){if(QSysInfo::ByteOrder==QSysInfo::BigEndian){ memcpy(dst+0,((char*)src)+1,1); memcpy(dst+1,((char*)src)+0,1);}else memcpy(dst,src,2);}const QDateTime Date_Never(QDate(2999,12,28),QTime(23,59,59));QDateTime dateFromPackedStruct5(const unsigned char* pBytes){quint32 dw1, dw2, dw3, dw4, dw5;dw1 = (quint32)pBytes[0]; dw2 = (quint32)pBytes[1]; dw3 = (quint32)pBytes[2];dw4 = (quint32)pBytes[3]; dw5 = (quint32)pBytes[4];int y = (dw1 << 6) | (dw2 >> 2);int mon = ((dw2 & 0x00000003) << 2) | (dw3 >> 6);int d = (dw3 >> 1) & 0x0000001F;int h = ((dw3 & 0x00000001) << 4) | (dw4 >> 4);int min = ((dw4 & 0x0000000F) << 2) | (dw5 >> 6);int s = dw5 & 0x0000003F;return QDateTime(QDate(y,mon,d),QTime(h,min,s));}void dateToPackedStruct5(const QDateTime& d,unsigned char* pBytes){pBytes[0] = (quint8)(((quint32)d.date().year() >> 6) & 0x0000003F);pBytes[1] = (quint8)((((quint32)d.date().year() & 0x0000003F) << 2) | (((quint32)d.date().month() >> 2) & 0x00000003));pBytes[2] = (quint8)((((quint32)d.date().month() & 0x00000003) << 6) | (((quint32)d.date().day() & 0x0000001F) << 1) | (((quint32)d.time().hour() >> 4) & 0x00000001));pBytes[3] = (quint8)((((quint32)d.time().hour() & 0x0000000F) << 4) | (((quint32)d.time().minute() >> 2) & 0x0000000F));pBytes[4] = (quint8)((((quint32)d.time().minute() & 0x00000003) << 6) | ((quint32)d.time().second() & 0x0000003F));}class KPTestResults{public: KPTestResults(){passed=failed=0;} int passed, failed;};/* assumes context of failed/passed variables */#define kp_assert(results, x) \ do {\ if (x){\ (results).passed++;\ }else{\ (results).failed++;\ cout << __FILE__ << ":" << __LINE__ << ": assert failed: " << #x << endl; \ }\ } while(0)void testDateConv(KPTestResults& results, const QDateTime& d){ unsigned char binDate[5]; dateToPackedStruct5(d, binDate); kp_assert(results, d.toTime_t() == dateFromPackedStruct5(binDate).toTime_t());}void assertGroupsEq(KPTestResults& results, CGroup* left, CGroup* right){ unsigned long size = 0; kp_assert(results, left->ID == right->ID); size += sizeof(left->ID); kp_assert(results, left->ImageID == right->ImageID); size += sizeof(left->ImageID); kp_assert(results, left->Name == right->Name); size += sizeof(left->Name); kp_assert(results, left->Creation.toTime_t() == right->Creation.toTime_t()); size += sizeof(left->Creation); kp_assert(results, left->LastMod.toTime_t() == right->LastMod.toTime_t()); size += sizeof(left->LastMod); kp_assert(results, left->LastAccess.toTime_t() == right->LastAccess.toTime_t()); size += sizeof(left->LastAccess); kp_assert(results, left->Expire.toTime_t() == right->Expire.toTime_t()); size += sizeof(left->Expire); kp_assert(results, left->Level == right->Level); size += sizeof(left->Level); kp_assert(results, left->Flags == right->Flags); size += sizeof(left->Flags); /* ignore expansion */ size += sizeof(left->UI_ItemIsExpanded); /* make sure that all members were checked */ /* CGroup is padded with two additional bytes */ kp_assert(results, size + 2 == sizeof(CGroup)); kp_assert(results, 40 == sizeof(CGroup));}void assertEntriesEq(KPTestResults& results, CEntry* left, CEntry* right){ unsigned long size = 0; kp_assert(results, left->Uuid==right->Uuid); size += sizeof(left->Uuid); kp_assert(results, left->sID == right->sID); size += sizeof(left->sID); kp_assert(results, left->GroupID == right->GroupID); size += sizeof(left->GroupID); kp_assert(results, left->ImageID == right->ImageID); size += sizeof(left->ImageID); kp_assert(results, left->Title == right->Title); size += sizeof(left->Title); kp_assert(results, left->URL == right->URL); size += sizeof(left->URL); kp_assert(results, left->UserName == right->UserName); size += sizeof(left->UserName); left->Password.unlock(); right->Password.unlock(); kp_assert(results, left->Password.string() == right->Password.string()); size += sizeof(left->Password); left->Password.lock(); right->Password.lock(); kp_assert(results, left->Additional == right->Additional); size += sizeof(left->Additional); kp_assert(results, left->BinaryDesc == right->BinaryDesc); size += sizeof(left->BinaryDesc); kp_assert(results, left->Creation.toTime_t() == right->Creation.toTime_t()); size += sizeof(left->Creation); kp_assert(results, left->LastMod.toTime_t() == right->LastMod.toTime_t()); size += sizeof(left->LastMod); kp_assert(results, left->LastAccess.toTime_t() == right->LastAccess.toTime_t()); size += sizeof(left->LastAccess); kp_assert(results, left->Expire.toTime_t() == right->Expire.toTime_t()); size += sizeof(left->Expire); kp_assert(results, left->BinaryData.length() == right->BinaryData.length()); kp_assert(results, (left->BinaryData.isNull() && right->BinaryData.isNull()) || memcmp(left->BinaryData.data(), right->BinaryData.data(), left->BinaryData.length()) == 0); size += left->BinaryData.length(); size += sizeof(left->BinaryData.length()); kp_assert(results, size == sizeof(CEntry));}void assertDatabasesEq(KPTestResults& results, PwDatabase* left, PwDatabase* right){ /* check groups */ kp_assert(results, left->Groups.size() == right->Groups.size()); int numGroups = min(left->Groups.size(), right->Groups.size()); for(int i=0;i<numGroups;i++) assertGroupsEq(results, &left->Groups[i], &right->Groups[i]); /* check entries */ kp_assert(results, left->Entries.size() == right->Entries.size()); int numEntries = min(left->Entries.size(), right->Entries.size()); for(int j=0;j<numEntries;j++) assertEntriesEq(results, &left->Entries[j], &right->Entries[j]);}bool testDatabase(){ KPTestResults results; /* test the date/time serialization */ QDateTime now = QDateTime::currentDateTime(); testDateConv(results, now); testDateConv(results, Date_Never); QString dbPassword("keepass-db-test"); const QString dbPath("/tmp/keepass-db-test"); /* create a test database */ PwDatabase database; kp_assert(results, database.CalcMasterKeyByPassword(dbPassword)); database.file = new QFile(dbPath); database.CryptoAlgorithmus = ALGO_TWOFISH; CGroup* main = database.addGroup(NULL); CGroup* child = database.addGroup(main); child->Name = "<Subgroup>"; QString entry1pw("password"); CEntry* entry1 = database.addEntry(); database.moveEntry(entry1, main); entry1->Title = "title"; entry1->URL = "http://keepass.berlios.de/"; entry1->UserName = "username"; entry1->Password.setString(entry1pw); entry1->Additional = "additional"; entry1->BinaryDesc = "binarydesc"; QString entry2pw("password"); CEntry* entry2 = database.addEntry(); database.moveEntry(entry2, child); entry2->Title = "TITLE"; entry2->URL = "http://keepass.berlios.de/"; entry2->UserName = "USERNAME"; entry2->Password.setString(entry2pw); entry2->Additional = "ADDITIONAL"; entry2->BinaryDesc = "BINARYDESC"; /* save the database */ kp_assert(results, database.saveDatabase()); /* reload the database */ PwDatabase cloneDatabase; kp_assert(results, cloneDatabase.CalcMasterKeyByPassword(dbPassword)); QString err; bool loadedDB = cloneDatabase.openDatabase(dbPath, err); if (!loadedDB){ kp_assert(results, loadedDB); qWarning((err+QString('\n')).toAscii()); } assertDatabasesEq(results, &database, &cloneDatabase); /* compare the databases */ cout << results.passed << "/" << (results.passed+results.failed) << " ok" << endl; return results.failed == 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -