Fix: -min parameter is sometimes ignored (Debian Bug #514414)

Fix: Cannot open DB from KeePassX 0.2.2 (Bug #2535569)

git-svn-id: https://svn.code.sf.net/p/keepassx/code/trunk@265 b624d157-de02-0410-bad0-e51aec6abb33
master
sniperbeamer 16 years ago
parent e4ae80f030
commit 5be497a26c
  1. 48
      src/Kdb3Database.cpp
  2. 4
      src/Kdb3Database.h
  3. 4
      src/main.cpp
  4. 12
      src/mainwindow.cpp

@ -52,7 +52,7 @@ bool Kdb3Database::StdEntryLessThan(const Kdb3Database::StdEntry& This,const Kdb
} }
Kdb3Database::Kdb3Database() : RawMasterKey(32), RawMasterKey_Latin1(32), MasterKey(32){ Kdb3Database::Kdb3Database() : RawMasterKey(32), RawMasterKey_Latin1(32), RawMasterKey_UTF8(32), MasterKey(32){
} }
QString Kdb3Database::getError(){ QString Kdb3Database::getError(){
@ -591,20 +591,26 @@ bool Kdb3Database::load(QString filename){
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){
if(PotentialEncodingIssue){ if(PotentialEncodingIssueLatin1){
delete[] buffer; delete[] buffer;
delete File; delete File;
File = NULL; File = NULL;
// KeePassX used Latin-1 encoding for passwords until version 0.3.1
// but KeePass/Win32 uses Windows Codepage 1252.
// Too stay compatible with databases created with KeePassX <= 0.3.1
// the loading function gives both encodings a try.
RawMasterKey.copyData(RawMasterKey_Latin1); RawMasterKey.copyData(RawMasterKey_Latin1);
PotentialEncodingIssue=false; PotentialEncodingIssueLatin1 = false;
qDebug("Decryption failed. Retrying with Latin-1."); qDebug("Decryption failed. Retrying with Latin-1.");
return load(filename); // second try return load(filename); // second try
} }
if(PotentialEncodingIssueUTF8){
delete[] buffer;
delete File;
File = NULL;
RawMasterKey.copyData(RawMasterKey_UTF8);
PotentialEncodingIssueUTF8 = false;
qDebug("Decryption failed. Retrying with UTF-8.");
return load(filename); // second/third try
}
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;
LOAD_RETURN_CLEANUP LOAD_RETURN_CLEANUP
@ -854,28 +860,40 @@ bool Kdb3Database::setKey(const QString& password,const QString& keyfile){
} }
bool Kdb3Database::setPasswordKey(const QString& Password){ bool Kdb3Database::setPasswordKey(const QString& Password){
assert(Password.size()); Q_ASSERT(Password.size());
QTextCodec* codec=QTextCodec::codecForName("Windows-1252"); QTextCodec* codec=QTextCodec::codecForName("Windows-1252");
QByteArray Password_CP1252 = codec->fromUnicode(Password); QByteArray Password_CP1252 = codec->fromUnicode(Password);
RawMasterKey.unlock(); RawMasterKey.unlock();
SHA256::hashBuffer(Password_CP1252.data(),*RawMasterKey,Password_CP1252.size()); SHA256::hashBuffer(Password_CP1252.data(),*RawMasterKey,Password_CP1252.size());
RawMasterKey.lock(); RawMasterKey.lock();
QByteArray Password_Latin1 = Password.toLatin1(); QByteArray Password_Latin1 = Password.toLatin1();
if(Password_Latin1 != Password_CP1252){ QByteArray Password_UTF8 = Password.toUtf8();
PotentialEncodingIssueLatin1 = false;
PotentialEncodingIssueUTF8 = false;
if (Password_Latin1 != Password_CP1252){
// 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 // To stay compatible with databases created with KeePassX <= 0.3.1
// the loading function gives both encodings a try. // the loading function gives both encodings a try.
PotentialEncodingIssue = true; PotentialEncodingIssueLatin1 = true;
RawMasterKey_Latin1.unlock(); RawMasterKey_Latin1.unlock();
SHA256::hashBuffer(Password_Latin1.data(),*RawMasterKey_Latin1,Password_Latin1.size()); SHA256::hashBuffer(Password_Latin1.data(),*RawMasterKey_Latin1,Password_Latin1.size());
RawMasterKey_Latin1.lock(); RawMasterKey_Latin1.lock();
} }
else {
// If the password does not contain problematic characters we don't need if (Password_UTF8 != Password_CP1252){
// to try both encodings. // KeePassX used UTF-8 encoding for passwords until version 0.2.2
PotentialEncodingIssue = false; // but KeePass/Win32 uses Windows Codepage 1252.
// To stay compatible with databases created with KeePassX <= 0.2.2
// the loading function gives both encodings a try.
PotentialEncodingIssueUTF8 = true;
RawMasterKey_UTF8.unlock();
SHA256::hashBuffer(Password_UTF8.data(),*RawMasterKey_UTF8,Password_UTF8.size());
RawMasterKey_UTF8.lock();
} }
return true; return true;
} }

@ -234,13 +234,15 @@ private:
QFile* File; QFile* File;
QString error; QString error;
bool KeyError; bool KeyError;
bool PotentialEncodingIssue; bool PotentialEncodingIssueLatin1;
bool PotentialEncodingIssueUTF8;
QList<StdEntry> UnknownMetaStreams; QList<StdEntry> UnknownMetaStreams;
QMap<quint32,bool> TreeStateMetaStream; QMap<quint32,bool> TreeStateMetaStream;
unsigned int KeyTransfRounds; unsigned int KeyTransfRounds;
CryptAlgorithm Algorithm; CryptAlgorithm Algorithm;
SecData RawMasterKey; SecData RawMasterKey;
SecData RawMasterKey_Latin1; SecData RawMasterKey_Latin1;
SecData RawMasterKey_UTF8;
SecData MasterKey; SecData MasterKey;
quint8 TransfRandomSeed[32]; quint8 TransfRandomSeed[32];
bool hasV4IconMetaStream; bool hasV4IconMetaStream;

@ -52,7 +52,7 @@ int main(int argc, char **argv)
initAppPaths(argc,argv); initAppPaths(argc,argv);
CmdLineArgs args; CmdLineArgs args;
if(!args.preparse(argc,argv)){ // searches only for the -cfg parameter if(!args.preparse(argc,argv)){ // searches only for the -cfg parameter
qCritical("%s", CSTR( args.error().append("\n") )); qCritical("%s\n", CSTR( args.error() ));
args.printHelp(); args.printHelp();
return 1; return 1;
} }
@ -128,7 +128,7 @@ int main(int argc, char **argv)
#endif #endif
} }
if ( !args.parse(QApplication::arguments()) ){ if ( !args.parse(QApplication::arguments()) ){
qCritical("%s", CSTR( args.error().append("\n") )); qCritical("%s\n", CSTR( args.error() ));
args.printHelp(); args.printHelp();
return 1; return 1;
} }

@ -98,11 +98,10 @@ KeepassMainWindow::KeepassMainWindow(const QString& ArgFile,bool ArgMin,bool Arg
if (config->lockOnInactivity() && config->lockAfterSec()!=0) if (config->lockOnInactivity() && config->lockAfterSec()!=0)
inactivityTimer->start(); inactivityTimer->start();
bool showWindow=true; bool showWindow = !ArgMin;
FileOpen=false; FileOpen=false;
if(!ArgFile.isEmpty()){ if(!ArgFile.isEmpty()){
QString f = QDir::cleanPath(QDir::current().absoluteFilePath(ArgFile)); QString f = QDir::cleanPath(QDir::current().absoluteFilePath(ArgFile));
showWindow = !ArgMin;
if (ArgLock) if (ArgLock)
fakeOpenDatabase(f); fakeOpenDatabase(f);
else else
@ -112,8 +111,9 @@ KeepassMainWindow::KeepassMainWindow(const QString& ArgFile,bool ArgMin,bool Arg
QFileInfo file(config->lastFile()); QFileInfo file(config->lastFile());
if(file.exists()){ if(file.exists()){
QString f = QDir::cleanPath(QDir::current().absoluteFilePath(config->lastFile())); QString f = QDir::cleanPath(QDir::current().absoluteFilePath(config->lastFile()));
showWindow = !config->startMinimized(); if (!ArgMin)
if (config->startLocked()) showWindow = !config->startMinimized();
if (ArgLock || config->startLocked())
fakeOpenDatabase(f); fakeOpenDatabase(f);
else else
openDatabase(f,true); openDatabase(f,true);
@ -121,9 +121,7 @@ KeepassMainWindow::KeepassMainWindow(const QString& ArgFile,bool ArgMin,bool Arg
else else
config->setLastFile(QString()); config->setLastFile(QString());
} }
else if (ArgLock){
showWindow = false;
}
// TODO HelpBrowser // TODO HelpBrowser
/*HelpBrowser = new QAssistantClient(QString(),this); /*HelpBrowser = new QAssistantClient(QString(),this);
HelpBrowser->setArguments(QStringList()<< "-profile" << "share/keepass/doc/keepassx.adp");*/ HelpBrowser->setArguments(QStringList()<< "-profile" << "share/keepass/doc/keepassx.adp");*/