X-Git-Url: https://vcs.maemo.org/git/?a=blobdiff_plain;f=src%2FKdb3Database.cpp;fp=src%2FKdb3Database.cpp;h=86913bcdc709de0cfefe1ebae5a1b48334f5ada8;hb=a5359e3664df4cbbafa128ae38ce243afeafa482;hp=4eb8f99c4c96d8f5aaa65b09aad1c33d81749808;hpb=87c9641f355953cd47b86c465aff503f2f7b1b86;p=keepassx diff --git a/src/Kdb3Database.cpp b/src/Kdb3Database.cpp index 4eb8f99..86913bc 100644 --- a/src/Kdb3Database.cpp +++ b/src/Kdb3Database.cpp @@ -52,7 +52,7 @@ bool Kdb3Database::StdEntryLessThan(const Kdb3Database::StdEntry& This,const Kdb } -Kdb3Database::Kdb3Database() : RawMasterKey(32), RawMasterKey_CP1252(32), +Kdb3Database::Kdb3Database() : File(NULL), RawMasterKey(32), RawMasterKey_CP1252(32), RawMasterKey_Latin1(32), RawMasterKey_UTF8(32), MasterKey(32){ } @@ -448,14 +448,28 @@ bool Kdb3Database::createGroupTree(QList& Levels){ for(int i=0;iId){ + groupIndex = g; + break; + } + } + } + + Groups[groupIndex].Entries.append(&Entries[e]); + Entries[e].Group=&Groups[groupIndex]; + Entries[e].Index=EntryIndexCounter[groupIndex]; + EntryIndexCounter[groupIndex]++; } return true; @@ -504,12 +518,6 @@ bool Kdb3Database::load(QString identifier, bool readOnly){ return false; bool Kdb3Database::loadReal(QString filename, bool readOnly, bool differentEncoding) { - unsigned long total_size,crypto_size; - quint32 Signature1,Signature2,Version,NumGroups,NumEntries,Flags; - quint8 FinalRandomSeed[16]; - quint8 ContentsHash[32]; - quint8 EncryptionIV[16]; - File = new QFile(filename); if (readOnly) { if(!File->open(QIODevice::ReadOnly)){ @@ -533,6 +541,14 @@ bool Kdb3Database::loadReal(QString filename, bool readOnly, bool differentEncod } } + openedReadOnly = readOnly; + + unsigned long total_size,crypto_size; + quint32 Signature1,Signature2,Version,NumGroups,NumEntries,Flags; + quint8 FinalRandomSeed[16]; + quint8 ContentsHash[32]; + quint8 EncryptionIV[16]; + total_size=File->size(); char* buffer = new char[total_size]; File->read(buffer,total_size); @@ -609,6 +625,7 @@ bool Kdb3Database::loadReal(QString filename, bool readOnly, bool differentEncod if ((crypto_size > 2147483446) || (!crypto_size && NumGroups)){ error=tr("Decryption failed.\nThe key is wrong or the file is damaged."); + KeyError=true; LOAD_RETURN_CLEANUP } SHA256::hashBuffer(buffer+DB_HEADER_SIZE,FinalKey,crypto_size); @@ -1104,13 +1121,16 @@ IGroupHandle* Kdb3Database::addGroup(const CGroup* group,IGroupHandle* ParentHan Groups.back().Parent->Children.append(&Groups.back()); } else{ + // Insert to root group. Try to keep Backup group at the end. Groups.back().Parent=&RootGroup; Groups.back().Index=RootGroup.Children.size(); - if (group->Title!="Backup" && RootGroup.Children.size() && RootGroup.Children.last()->Title=="Backup"){ + int position = RootGroup.Children.size(); + if (group->Title!="Backup" && !RootGroup.Children.isEmpty() && RootGroup.Children.last()->Title=="Backup"){ RootGroup.Children.last()->Index = Groups.back().Index; Groups.back().Index--; + position--; } - Groups.back().Parent->Children.append(&Groups.back()); + RootGroup.Children.insert(position, &Groups.back()); } return &GroupHandles.back(); } @@ -1135,11 +1155,25 @@ IGroupHandle* Kdb3Database::backupGroup(bool create){ return group; } +Kdb3Database::StdEntry::StdEntry(){ + Handle = NULL; + Group = NULL; +} + +Kdb3Database::StdGroup::StdGroup(){ + Index=0; + Id=0; + Parent=NULL; + Handle=NULL; +} + Kdb3Database::StdGroup::StdGroup(const CGroup& other){ Index=0; Id=other.Id; Image=other.Image; Title=other.Title; + Parent=NULL; + Handle=NULL; } void Kdb3Database::EntryHandle::setTitle(const QString& Title){Entry->Title=Title; } @@ -1225,6 +1259,7 @@ void Kdb3Database::EntryHandle::setVisualIndex(int index){ Kdb3Database::EntryHandle::EntryHandle(Kdb3Database* db){ pDB=db; valid=true; + Entry=NULL; } @@ -1319,6 +1354,18 @@ bool Kdb3Database::save(){ return false; } + if (!File->isOpen()) { + if(!File->open(QIODevice::ReadWrite)){ + error=tr("Could not open file."); + return false; + } + } + + if(!(File->openMode() & QIODevice::WriteOnly)){ + error = tr("The database has been opened read-only."); + return false; + } + //Delete old backup entries if (config->backup() && config->backupDelete() && config->backupDeleteAfter()>0 && backupGroup()){ QDateTime time = QDateTime::currentDateTime().addDays(-config->backupDeleteAfter()); @@ -1334,11 +1381,6 @@ bool Kdb3Database::save(){ quint8 ContentsHash[32]; quint8 EncryptionIV[16]; - if(!(File->openMode() & QIODevice::WriteOnly)){ - error = tr("The database has been opened read-only."); - return false; - } - unsigned int FileSize; QList MetaStreams; @@ -1455,31 +1497,53 @@ bool Kdb3Database::save(){ int size = EncryptedPartSize+DB_HEADER_SIZE; - if (!File->resize(size)){ - // only recreate file if the new database is smaller - if (File->size() > size) { - qDebug("Unable to resize, trying to recreate file"); - if (!File->remove() || !File->open(QIODevice::ReadWrite)) { - delete [] buffer; - error=decodeFileError(File->error()); - return false; - } - } - } - File->seek(0); - if (File->write(buffer,size)!=size){ - delete [] buffer; + if (!saveFileTransactional(buffer, size)) { error=decodeFileError(File->error()); + delete [] buffer; return false; } - if (!syncFile(File)) - qWarning("Unable to flush file to disk"); delete [] buffer; //if(SearchGroupID!=-1)Groups.push_back(SearchGroup); return true; } +bool Kdb3Database::saveFileTransactional(char* buffer, int size) { + QString orgFilename = File->fileName(); + QFile* tmpFile = new QFile(orgFilename + ".tmp"); + if (!tmpFile->open(QIODevice::WriteOnly|QIODevice::Truncate)) { + tmpFile->remove(); + delete tmpFile; + return false; + } + if (tmpFile->write(buffer,size) != size) { + tmpFile->remove(); + delete tmpFile; + return false; + } + if (!syncFile(tmpFile)) + qWarning("Unable to flush file to disk"); + tmpFile->close(); + if (!File->remove()) { + delete tmpFile; + return false; + } + delete File; + File = NULL; + if (!tmpFile->rename(orgFilename)) { + delete tmpFile; + File = new QFile(orgFilename); + return false; + } + File = tmpFile; + if (!tmpFile->open(QIODevice::ReadWrite)) { + delete tmpFile; + return false; + } + + return true; +} + void Kdb3Database::createCustomIconsMetaStream(StdEntry* e){ /* Rev 3 */ e->BinaryDesc="bin-stream";