Create default groups when creating new database
Increase and randomize default key transformation number Better cleanup when loading database fails git-svn-id: https://svn.code.sf.net/p/keepassx/code/trunk@196 b624d157-de02-0410-bad0-e51aec6abb33
This commit is contained in:
parent
1905150642
commit
7c34d2010a
|
@ -414,6 +414,12 @@ void Kdb3Database::restoreGroupTreeState(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define LOAD_RETURN_CLEANUP \
|
||||||
|
delete File; \
|
||||||
|
File = NULL; \
|
||||||
|
delete[] buffer; \
|
||||||
|
return false;
|
||||||
|
|
||||||
bool Kdb3Database::load(QString filename){
|
bool Kdb3Database::load(QString filename){
|
||||||
unsigned long total_size,crypto_size;
|
unsigned long total_size,crypto_size;
|
||||||
quint32 Signature1,Signature2,Version,NumGroups,NumEntries,Flags;
|
quint32 Signature1,Signature2,Version,NumGroups,NumEntries,Flags;
|
||||||
|
@ -422,12 +428,12 @@ quint8 FinalRandomSeed[16];
|
||||||
quint8 ContentsHash[32];
|
quint8 ContentsHash[32];
|
||||||
quint8 EncryptionIV[16];
|
quint8 EncryptionIV[16];
|
||||||
|
|
||||||
File=new QFile(filename);
|
File = new QFile(filename);
|
||||||
if(!File->open(QIODevice::ReadWrite)){
|
if(!File->open(QIODevice::ReadWrite)){
|
||||||
if(!File->open(QIODevice::ReadOnly)){
|
if(!File->open(QIODevice::ReadOnly)){
|
||||||
error=tr("Could not open file.");
|
error=tr("Could not open file.");
|
||||||
delete File;
|
delete File;
|
||||||
File=NULL;
|
File = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -437,7 +443,7 @@ File->read(buffer,total_size);
|
||||||
|
|
||||||
if(total_size < DB_HEADER_SIZE){
|
if(total_size < DB_HEADER_SIZE){
|
||||||
error=tr("Unexpected file size (DB_TOTAL_SIZE < DB_HEADER_SIZE)");
|
error=tr("Unexpected file size (DB_TOTAL_SIZE < DB_HEADER_SIZE)");
|
||||||
return false;
|
LOAD_RETURN_CLEANUP
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpyFromLEnd32(&Signature1,buffer);
|
memcpyFromLEnd32(&Signature1,buffer);
|
||||||
|
@ -454,12 +460,12 @@ memcpyFromLEnd32(&KeyTransfRounds,buffer+120);
|
||||||
|
|
||||||
if((Signature1!=PWM_DBSIG_1) || (Signature2!=PWM_DBSIG_2)){
|
if((Signature1!=PWM_DBSIG_1) || (Signature2!=PWM_DBSIG_2)){
|
||||||
error=tr("Wrong Signature");
|
error=tr("Wrong Signature");
|
||||||
return false;
|
LOAD_RETURN_CLEANUP
|
||||||
}
|
}
|
||||||
|
|
||||||
if((Version & 0xFFFFFF00) != (PWM_DBVER_DW & 0xFFFFFF00)){
|
if((Version & 0xFFFFFF00) != (PWM_DBVER_DW & 0xFFFFFF00)){
|
||||||
error=tr("Unsupported File Version.");
|
error=tr("Unsupported File Version.");
|
||||||
return false;
|
LOAD_RETURN_CLEANUP
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Flags & PWM_FLAG_RIJNDAEL)
|
if (Flags & PWM_FLAG_RIJNDAEL)
|
||||||
|
@ -468,7 +474,7 @@ else if (Flags & PWM_FLAG_TWOFISH)
|
||||||
Algorithm = Twofish_Cipher;
|
Algorithm = Twofish_Cipher;
|
||||||
else{
|
else{
|
||||||
error=tr("Unknown Encryption Algorithm.");
|
error=tr("Unknown Encryption Algorithm.");
|
||||||
return false;
|
LOAD_RETURN_CLEANUP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -490,20 +496,22 @@ if(Algorithm == Rijndael_Cipher){
|
||||||
else if(Algorithm == Twofish_Cipher){
|
else if(Algorithm == Twofish_Cipher){
|
||||||
CTwofish twofish;
|
CTwofish twofish;
|
||||||
if (twofish.init(FinalKey, 32, EncryptionIV) != true)
|
if (twofish.init(FinalKey, 32, EncryptionIV) != true)
|
||||||
return false;
|
LOAD_RETURN_CLEANUP
|
||||||
crypto_size = (unsigned long)twofish.padDecrypt((quint8 *)buffer + DB_HEADER_SIZE,
|
crypto_size = (unsigned long)twofish.padDecrypt((quint8 *)buffer + DB_HEADER_SIZE,
|
||||||
total_size - DB_HEADER_SIZE, (quint8 *)buffer + DB_HEADER_SIZE);
|
total_size - DB_HEADER_SIZE, (quint8 *)buffer + DB_HEADER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((crypto_size > 2147483446) || (!crypto_size && NumGroups)){
|
if ((crypto_size > 2147483446) || (!crypto_size && NumGroups)){
|
||||||
error=tr("Decryption failed.\nThe key is wrong or the file is damaged.");
|
error=tr("Decryption failed.\nThe key is wrong or the file is damaged.");
|
||||||
return false;
|
LOAD_RETURN_CLEANUP
|
||||||
}
|
}
|
||||||
SHA256::hashBuffer(buffer+DB_HEADER_SIZE,FinalKey,crypto_size);
|
SHA256::hashBuffer(buffer+DB_HEADER_SIZE,FinalKey,crypto_size);
|
||||||
|
|
||||||
if(memcmp(ContentsHash, FinalKey, 32) != 0){
|
if(memcmp(ContentsHash, FinalKey, 32) != 0){
|
||||||
delete buffer;
|
|
||||||
if(PotentialEncodingIssue){
|
if(PotentialEncodingIssue){
|
||||||
|
delete[] buffer;
|
||||||
|
delete File;
|
||||||
|
File = NULL;
|
||||||
// KeePassX used Latin-1 encoding for passwords until version 0.3.1
|
// KeePassX used Latin-1 encoding for passwords until version 0.3.1
|
||||||
// but KeePass/Win32 uses Windows Codepage 1252.
|
// but KeePass/Win32 uses Windows Codepage 1252.
|
||||||
// Too stay compatible with databases created with KeePassX <= 0.3.1
|
// Too stay compatible with databases created with KeePassX <= 0.3.1
|
||||||
|
@ -515,7 +523,7 @@ if(memcmp(ContentsHash, FinalKey, 32) != 0){
|
||||||
}
|
}
|
||||||
error=tr("Hash test failed.\nThe key is wrong or the file is damaged.");
|
error=tr("Hash test failed.\nThe key is wrong or the file is damaged.");
|
||||||
KeyError=true;
|
KeyError=true;
|
||||||
return false;
|
LOAD_RETURN_CLEANUP
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long pos = DB_HEADER_SIZE;
|
unsigned long pos = DB_HEADER_SIZE;
|
||||||
|
@ -537,14 +545,14 @@ for(unsigned long CurGroup = 0; CurGroup < NumGroups; )
|
||||||
pField += 2; pos += 2;
|
pField += 2; pos += 2;
|
||||||
if (pos >= total_size){
|
if (pos >= total_size){
|
||||||
error=tr("Unexpected error: Offset is out of range.").append(" [G1]");
|
error=tr("Unexpected error: Offset is out of range.").append(" [G1]");
|
||||||
return false;
|
LOAD_RETURN_CLEANUP
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpyFromLEnd32(&FieldSize, pField);
|
memcpyFromLEnd32(&FieldSize, pField);
|
||||||
pField += 4; pos += 4;
|
pField += 4; pos += 4;
|
||||||
if (pos >= (total_size + FieldSize)){
|
if (pos >= (total_size + FieldSize)){
|
||||||
error=tr("Unexpected error: Offset is out of range.").append(" [G2]");
|
error=tr("Unexpected error: Offset is out of range.").append(" [G2]");
|
||||||
return false;
|
LOAD_RETURN_CLEANUP
|
||||||
}
|
}
|
||||||
|
|
||||||
bRet = readGroupField(&group,Levels, FieldType, FieldSize, (quint8 *)pField);
|
bRet = readGroupField(&group,Levels, FieldType, FieldSize, (quint8 *)pField);
|
||||||
|
@ -556,7 +564,7 @@ for(unsigned long CurGroup = 0; CurGroup < NumGroups; )
|
||||||
pos += FieldSize;
|
pos += FieldSize;
|
||||||
if (pos >= total_size){
|
if (pos >= total_size){
|
||||||
error=tr("Unexpected error: Offset is out of range.").append(" [G1]");
|
error=tr("Unexpected error: Offset is out of range.").append(" [G1]");
|
||||||
return false;
|
LOAD_RETURN_CLEANUP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -570,14 +578,14 @@ for (unsigned long CurEntry = 0; CurEntry < NumEntries;)
|
||||||
pField += 2; pos += 2;
|
pField += 2; pos += 2;
|
||||||
if(pos >= total_size){
|
if(pos >= total_size){
|
||||||
error=tr("Unexpected error: Offset is out of range.").append(" [E1]");
|
error=tr("Unexpected error: Offset is out of range.").append(" [E1]");
|
||||||
return false;
|
LOAD_RETURN_CLEANUP
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpyFromLEnd32(&FieldSize, pField);
|
memcpyFromLEnd32(&FieldSize, pField);
|
||||||
pField += 4; pos += 4;
|
pField += 4; pos += 4;
|
||||||
if (pos >= (total_size + FieldSize)){
|
if (pos >= (total_size + FieldSize)){
|
||||||
error=tr("Unexpected error: Offset is out of range.").append(" [E2]");
|
error=tr("Unexpected error: Offset is out of range.").append(" [E2]");
|
||||||
return false;
|
LOAD_RETURN_CLEANUP
|
||||||
}
|
}
|
||||||
|
|
||||||
bRet = readEntryField(&entry,FieldType,FieldSize,(quint8*)pField);
|
bRet = readEntryField(&entry,FieldType,FieldSize,(quint8*)pField);
|
||||||
|
@ -593,13 +601,13 @@ for (unsigned long CurEntry = 0; CurEntry < NumEntries;)
|
||||||
pos += FieldSize;
|
pos += FieldSize;
|
||||||
if (pos >= total_size){
|
if (pos >= total_size){
|
||||||
error=tr("Unexpected error: Offset is out of range.").append(" [E3]");
|
error=tr("Unexpected error: Offset is out of range.").append(" [E3]");
|
||||||
return false;
|
LOAD_RETURN_CLEANUP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!createGroupTree(Levels)){
|
if(!createGroupTree(Levels)){
|
||||||
error=tr("Invalid group tree.");
|
error=tr("Invalid group tree.");
|
||||||
return false;
|
LOAD_RETURN_CLEANUP
|
||||||
}
|
}
|
||||||
|
|
||||||
delete [] buffer;
|
delete [] buffer;
|
||||||
|
@ -1258,7 +1266,8 @@ bool Kdb3Database::save(){
|
||||||
if(twofish.init(FinalKey, 32, EncryptionIV) == false){
|
if(twofish.init(FinalKey, 32, EncryptionIV) == false){
|
||||||
UNEXP_ERROR
|
UNEXP_ERROR
|
||||||
delete [] buffer;
|
delete [] buffer;
|
||||||
return false;}
|
return false;
|
||||||
|
}
|
||||||
EncryptedPartSize = (unsigned long)twofish.padEncrypt((quint8*)buffer+DB_HEADER_SIZE,
|
EncryptedPartSize = (unsigned long)twofish.padEncrypt((quint8*)buffer+DB_HEADER_SIZE,
|
||||||
pos - DB_HEADER_SIZE,(quint8*)buffer+DB_HEADER_SIZE);
|
pos - DB_HEADER_SIZE,(quint8*)buffer+DB_HEADER_SIZE);
|
||||||
}
|
}
|
||||||
|
@ -1523,6 +1532,8 @@ void Kdb3Database::serializeEntries(QList<StdEntry>& EntryList,char* buffer,unsi
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Kdb3Database::close(){
|
bool Kdb3Database::close(){
|
||||||
|
if (File!=NULL)
|
||||||
|
delete File;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1532,7 +1543,9 @@ void Kdb3Database::create(){
|
||||||
RootGroup.Parent=NULL;
|
RootGroup.Parent=NULL;
|
||||||
RootGroup.Handle=NULL;
|
RootGroup.Handle=NULL;
|
||||||
Algorithm=Rijndael_Cipher;
|
Algorithm=Rijndael_Cipher;
|
||||||
KeyTransfRounds=6000;
|
quint8 ran;
|
||||||
|
randomize(&ran,1);
|
||||||
|
KeyTransfRounds=10000 + 3*ran;
|
||||||
KeyError=false;
|
KeyError=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -484,14 +484,12 @@
|
||||||
</widget>
|
</widget>
|
||||||
<layoutdefault spacing="6" margin="11" />
|
<layoutdefault spacing="6" margin="11" />
|
||||||
<tabstops>
|
<tabstops>
|
||||||
<tabstop>Combo_Group</tabstop>
|
|
||||||
<tabstop>Button_Icons</tabstop>
|
|
||||||
<tabstop>Edit_Title</tabstop>
|
<tabstop>Edit_Title</tabstop>
|
||||||
<tabstop>Edit_UserName</tabstop>
|
<tabstop>Edit_UserName</tabstop>
|
||||||
<tabstop>Edit_URL</tabstop>
|
<tabstop>Edit_URL</tabstop>
|
||||||
<tabstop>Edit_Password</tabstop>
|
<tabstop>Edit_Password</tabstop>
|
||||||
<tabstop>ButtonEchoMode</tabstop>
|
|
||||||
<tabstop>Edit_Password_w</tabstop>
|
<tabstop>Edit_Password_w</tabstop>
|
||||||
|
<tabstop>ButtonEchoMode</tabstop>
|
||||||
<tabstop>ButtonGenPw</tabstop>
|
<tabstop>ButtonGenPw</tabstop>
|
||||||
<tabstop>Edit_Comment</tabstop>
|
<tabstop>Edit_Comment</tabstop>
|
||||||
<tabstop>DateTime_Expire</tabstop>
|
<tabstop>DateTime_Expire</tabstop>
|
||||||
|
@ -501,6 +499,8 @@
|
||||||
<tabstop>ButtonOpenAttachment</tabstop>
|
<tabstop>ButtonOpenAttachment</tabstop>
|
||||||
<tabstop>ButtonSaveAttachment</tabstop>
|
<tabstop>ButtonSaveAttachment</tabstop>
|
||||||
<tabstop>ButtonDeleteAttachment</tabstop>
|
<tabstop>ButtonDeleteAttachment</tabstop>
|
||||||
|
<tabstop>Combo_Group</tabstop>
|
||||||
|
<tabstop>Button_Icons</tabstop>
|
||||||
<tabstop>buttonBox</tabstop>
|
<tabstop>buttonBox</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
<resources/>
|
<resources/>
|
||||||
|
|
|
@ -127,6 +127,28 @@ void KeepassGroupView::OnNewGroup(){
|
||||||
emit fileModified();
|
emit fileModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KeepassGroupView::createGroup(const QString& title, quint32 image){
|
||||||
|
CGroup NewGroup;
|
||||||
|
NewGroup.Title = title;
|
||||||
|
NewGroup.Image = image;
|
||||||
|
|
||||||
|
IGroupHandle* group;
|
||||||
|
if(topLevelItemCount()){
|
||||||
|
if(topLevelItem(topLevelItemCount()-1)==SearchResultItem)
|
||||||
|
Items.append(new GroupViewItem(this,topLevelItem(topLevelItemCount()-2)));
|
||||||
|
else
|
||||||
|
Items.append(new GroupViewItem(this,topLevelItem(topLevelItemCount()-1)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Items.append(new GroupViewItem(this));
|
||||||
|
|
||||||
|
group = db->addGroup(&NewGroup,NULL);
|
||||||
|
|
||||||
|
Items.back()->GroupHandle = group;
|
||||||
|
Items.back()->setText(0, group->title());
|
||||||
|
Items.back()->setIcon(0, db->icon(group->image()));
|
||||||
|
}
|
||||||
|
|
||||||
void KeepassGroupView::OnEditGroup(){
|
void KeepassGroupView::OnEditGroup(){
|
||||||
GroupViewItem* item=(GroupViewItem*)currentItem();
|
GroupViewItem* item=(GroupViewItem*)currentItem();
|
||||||
CEditGroupDialog dlg(db,item->GroupHandle,parentWidget(),true);
|
CEditGroupDialog dlg(db,item->GroupHandle,parentWidget(),true);
|
||||||
|
|
|
@ -36,6 +36,7 @@ class KeepassGroupView:public QTreeWidget{
|
||||||
void createItems();
|
void createItems();
|
||||||
void showSearchResults();
|
void showSearchResults();
|
||||||
void setCurrentGroup(IGroupHandle* group);
|
void setCurrentGroup(IGroupHandle* group);
|
||||||
|
void createGroup(const QString& title, quint32 image);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void dragEnterEvent(QDragEnterEvent* event);
|
virtual void dragEnterEvent(QDragEnterEvent* event);
|
||||||
|
|
|
@ -519,6 +519,8 @@ void KeepassMainWindow::OnFileNewKdb(){
|
||||||
setupDatabaseConnections(db);
|
setupDatabaseConnections(db);
|
||||||
setStateGroupSelected(NONE);
|
setStateGroupSelected(NONE);
|
||||||
setStateEntrySelected(NONE);
|
setStateEntrySelected(NONE);
|
||||||
|
GroupView->createGroup("Internet", 1);
|
||||||
|
GroupView->createGroup("eMail", 19);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
delete db_new;
|
delete db_new;
|
||||||
|
|
Loading…
Reference in New Issue