Added 2 new password generator options
git-svn-id: https://svn.code.sf.net/p/keepassx/code/trunk@227 b624d157-de02-0410-bad0-e51aec6abb33
This commit is contained in:
parent
598d204716
commit
a5d427d262
|
@ -1,7 +1,7 @@
|
||||||
----------------------------
|
----------------------------
|
||||||
0.3.3 (2008-08-11)
|
0.3.3 (2008-08-11)
|
||||||
----------------------------
|
----------------------------
|
||||||
- fix an error when opening twofish encrypted databases
|
- fixed error when opening twofish encrypted databases (Bug #2025075)
|
||||||
|
|
||||||
----------------------------
|
----------------------------
|
||||||
0.3.2 (2008-07-20)
|
0.3.2 (2008-07-20)
|
||||||
|
|
|
@ -478,237 +478,237 @@ void Kdb3Database::restoreGroupTreeState(){
|
||||||
return false;
|
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;
|
||||||
quint8 FinalRandomSeed[16];
|
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;
|
||||||
}
|
|
||||||
}
|
|
||||||
total_size=File->size();
|
|
||||||
char* buffer = new char[total_size];
|
|
||||||
File->read(buffer,total_size);
|
|
||||||
|
|
||||||
if(total_size < DB_HEADER_SIZE){
|
|
||||||
error=tr("Unexpected file size (DB_TOTAL_SIZE < DB_HEADER_SIZE)");
|
|
||||||
LOAD_RETURN_CLEANUP
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpyFromLEnd32(&Signature1,buffer);
|
|
||||||
memcpyFromLEnd32(&Signature2,buffer+4);
|
|
||||||
memcpyFromLEnd32(&Flags,buffer+8);
|
|
||||||
memcpyFromLEnd32(&Version,buffer+12);
|
|
||||||
memcpy(FinalRandomSeed,buffer+16,16);
|
|
||||||
memcpy(EncryptionIV,buffer+32,16);
|
|
||||||
memcpyFromLEnd32(&NumGroups,buffer+48);
|
|
||||||
memcpyFromLEnd32(&NumEntries,buffer+52);
|
|
||||||
memcpy(ContentsHash,buffer+56,32);
|
|
||||||
memcpy(TransfRandomSeed,buffer+88,32);
|
|
||||||
memcpyFromLEnd32(&KeyTransfRounds,buffer+120);
|
|
||||||
|
|
||||||
if((Signature1!=PWM_DBSIG_1) || (Signature2!=PWM_DBSIG_2)){
|
|
||||||
error=tr("Wrong Signature");
|
|
||||||
LOAD_RETURN_CLEANUP
|
|
||||||
}
|
|
||||||
|
|
||||||
if((Version & 0xFFFFFF00) != (PWM_DBVER_DW & 0xFFFFFF00)){
|
|
||||||
error=tr("Unsupported File Version.");
|
|
||||||
LOAD_RETURN_CLEANUP
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Flags & PWM_FLAG_RIJNDAEL)
|
|
||||||
Algorithm = Rijndael_Cipher;
|
|
||||||
else if (Flags & PWM_FLAG_TWOFISH)
|
|
||||||
Algorithm = Twofish_Cipher;
|
|
||||||
else{
|
|
||||||
error=tr("Unknown Encryption Algorithm.");
|
|
||||||
LOAD_RETURN_CLEANUP
|
|
||||||
}
|
|
||||||
|
|
||||||
RawMasterKey.unlock();
|
|
||||||
MasterKey.unlock();
|
|
||||||
KeyTransform::transform(*RawMasterKey,*MasterKey,TransfRandomSeed,KeyTransfRounds);
|
|
||||||
|
|
||||||
quint8 FinalKey[32];
|
|
||||||
|
|
||||||
SHA256 sha;
|
|
||||||
sha.update(FinalRandomSeed,16);
|
|
||||||
sha.update(*MasterKey,32);
|
|
||||||
sha.finish(FinalKey);
|
|
||||||
|
|
||||||
RawMasterKey.lock();
|
|
||||||
MasterKey.lock();
|
|
||||||
|
|
||||||
if(Algorithm == Rijndael_Cipher){
|
|
||||||
AESdecrypt aes;
|
|
||||||
aes.key256(FinalKey);
|
|
||||||
aes.cbc_decrypt((unsigned char*)buffer+DB_HEADER_SIZE,(unsigned char*)buffer+DB_HEADER_SIZE,total_size-DB_HEADER_SIZE,(unsigned char*)EncryptionIV);
|
|
||||||
crypto_size=total_size-((quint8*)buffer)[total_size-1]-DB_HEADER_SIZE;
|
|
||||||
}
|
|
||||||
else if(Algorithm == Twofish_Cipher){
|
|
||||||
CTwofish twofish;
|
|
||||||
if (twofish.init(FinalKey, 32, EncryptionIV) != true){
|
|
||||||
error=tr("Unable to initalize the twofish algorithm.");
|
|
||||||
LOAD_RETURN_CLEANUP
|
|
||||||
}
|
|
||||||
crypto_size = (unsigned long)twofish.padDecrypt((quint8 *)buffer + DB_HEADER_SIZE,
|
|
||||||
total_size - DB_HEADER_SIZE, (quint8 *)buffer + DB_HEADER_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((crypto_size > 2147483446) || (!crypto_size && NumGroups)){
|
|
||||||
error=tr("Decryption failed.\nThe key is wrong or the file is damaged.");
|
|
||||||
LOAD_RETURN_CLEANUP
|
|
||||||
}
|
|
||||||
SHA256::hashBuffer(buffer+DB_HEADER_SIZE,FinalKey,crypto_size);
|
|
||||||
|
|
||||||
if(memcmp(ContentsHash, FinalKey, 32) != 0){
|
|
||||||
if(PotentialEncodingIssue){
|
|
||||||
delete[] buffer;
|
|
||||||
delete File;
|
|
||||||
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);
|
|
||||||
PotentialEncodingIssue=false;
|
|
||||||
qDebug("Decryption failed. Retrying with Latin-1.");
|
|
||||||
return load(filename); // second try
|
|
||||||
}
|
|
||||||
error=tr("Hash test failed.\nThe key is wrong or the file is damaged.");
|
|
||||||
KeyError=true;
|
|
||||||
LOAD_RETURN_CLEANUP
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long pos = DB_HEADER_SIZE;
|
|
||||||
quint16 FieldType;
|
|
||||||
quint32 FieldSize;
|
|
||||||
char* pField;
|
|
||||||
bool bRet;
|
|
||||||
StdGroup group;
|
|
||||||
QList<quint32> Levels;
|
|
||||||
RootGroup.Title="$ROOT$";
|
|
||||||
RootGroup.Parent=NULL;
|
|
||||||
RootGroup.Handle=NULL;
|
|
||||||
|
|
||||||
for(unsigned long CurGroup = 0; CurGroup < NumGroups; )
|
|
||||||
{
|
|
||||||
pField = buffer+pos;
|
|
||||||
|
|
||||||
memcpyFromLEnd16(&FieldType, pField);
|
|
||||||
pField += 2; pos += 2;
|
|
||||||
if (pos >= total_size){
|
|
||||||
error=tr("Unexpected error: Offset is out of range.").append(" [G1]");
|
|
||||||
LOAD_RETURN_CLEANUP
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpyFromLEnd32(&FieldSize, pField);
|
|
||||||
pField += 4; pos += 4;
|
|
||||||
if (pos >= (total_size + FieldSize)){
|
|
||||||
error=tr("Unexpected error: Offset is out of range.").append(" [G2]");
|
|
||||||
LOAD_RETURN_CLEANUP
|
|
||||||
}
|
|
||||||
|
|
||||||
bRet = readGroupField(&group,Levels, FieldType, FieldSize, (quint8 *)pField);
|
|
||||||
if ((FieldType == 0xFFFF) && (bRet == true)){
|
|
||||||
Groups << group;
|
|
||||||
CurGroup++; // Now and ONLY now the counter gets increased
|
|
||||||
}
|
|
||||||
pField += FieldSize;
|
|
||||||
pos += FieldSize;
|
|
||||||
if (pos >= total_size){
|
|
||||||
error=tr("Unexpected error: Offset is out of range.").append(" [G1]");
|
|
||||||
LOAD_RETURN_CLEANUP
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StdEntry entry;
|
|
||||||
|
|
||||||
for (unsigned long CurEntry = 0; CurEntry < NumEntries;)
|
|
||||||
{
|
|
||||||
pField = buffer+pos;
|
|
||||||
|
|
||||||
memcpyFromLEnd16(&FieldType, pField);
|
|
||||||
pField += 2; pos += 2;
|
|
||||||
if(pos >= total_size){
|
|
||||||
error=tr("Unexpected error: Offset is out of range.").append(" [E1]");
|
|
||||||
LOAD_RETURN_CLEANUP
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpyFromLEnd32(&FieldSize, pField);
|
|
||||||
pField += 4; pos += 4;
|
|
||||||
if (pos >= (total_size + FieldSize)){
|
|
||||||
error=tr("Unexpected error: Offset is out of range.").append(" [E2]");
|
|
||||||
LOAD_RETURN_CLEANUP
|
|
||||||
}
|
|
||||||
|
|
||||||
bRet = readEntryField(&entry,FieldType,FieldSize,(quint8*)pField);
|
|
||||||
|
|
||||||
if((FieldType == 0xFFFF) && (bRet == true)){
|
|
||||||
Entries << entry;
|
|
||||||
if(!entry.GroupId)
|
|
||||||
qDebug("NULL: %i, '%s'", (int)CurEntry, (char*)entry.Title.toUtf8().data());
|
|
||||||
CurEntry++;
|
|
||||||
}
|
|
||||||
|
|
||||||
pField += FieldSize;
|
|
||||||
pos += FieldSize;
|
|
||||||
if (pos >= total_size){
|
|
||||||
error=tr("Unexpected error: Offset is out of range.").append(" [E3]");
|
|
||||||
LOAD_RETURN_CLEANUP
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!createGroupTree(Levels)){
|
|
||||||
error=tr("Invalid group tree.");
|
|
||||||
LOAD_RETURN_CLEANUP
|
|
||||||
}
|
|
||||||
|
|
||||||
delete [] buffer;
|
|
||||||
|
|
||||||
hasV4IconMetaStream = false;
|
|
||||||
for(int i=0;i<Entries.size();i++){
|
|
||||||
if(isMetaStream(Entries[i]) && Entries[i].Comment=="KPX_CUSTOM_ICONS_4"){
|
|
||||||
hasV4IconMetaStream = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Remove the metastreams from the entry list
|
|
||||||
for(int i=0;i<Entries.size();i++){
|
|
||||||
if(isMetaStream(Entries[i])){
|
|
||||||
if(!parseMetaStream(Entries[i]))
|
|
||||||
UnknownMetaStreams << Entries[i];
|
|
||||||
Entries.removeAt(i);
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int* EntryIndices=new int[Groups.size()];
|
|
||||||
for(int i=0;i<Groups.size();i++)EntryIndices[i]=0;
|
|
||||||
|
|
||||||
for(int g=0;g<Groups.size();g++){
|
|
||||||
for(int e=0;e<Entries.size();e++){
|
|
||||||
if(Entries[e].GroupId==Groups[g].Id){
|
|
||||||
Entries[e].Index=EntryIndices[g];
|
|
||||||
EntryIndices[g]++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
total_size=File->size();
|
||||||
delete [] EntryIndices;
|
char* buffer = new char[total_size];
|
||||||
createHandles();
|
File->read(buffer,total_size);
|
||||||
restoreGroupTreeState();
|
|
||||||
|
|
||||||
return true;
|
if(total_size < DB_HEADER_SIZE){
|
||||||
|
error=tr("Unexpected file size (DB_TOTAL_SIZE < DB_HEADER_SIZE)");
|
||||||
|
LOAD_RETURN_CLEANUP
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpyFromLEnd32(&Signature1,buffer);
|
||||||
|
memcpyFromLEnd32(&Signature2,buffer+4);
|
||||||
|
memcpyFromLEnd32(&Flags,buffer+8);
|
||||||
|
memcpyFromLEnd32(&Version,buffer+12);
|
||||||
|
memcpy(FinalRandomSeed,buffer+16,16);
|
||||||
|
memcpy(EncryptionIV,buffer+32,16);
|
||||||
|
memcpyFromLEnd32(&NumGroups,buffer+48);
|
||||||
|
memcpyFromLEnd32(&NumEntries,buffer+52);
|
||||||
|
memcpy(ContentsHash,buffer+56,32);
|
||||||
|
memcpy(TransfRandomSeed,buffer+88,32);
|
||||||
|
memcpyFromLEnd32(&KeyTransfRounds,buffer+120);
|
||||||
|
|
||||||
|
if((Signature1!=PWM_DBSIG_1) || (Signature2!=PWM_DBSIG_2)){
|
||||||
|
error=tr("Wrong Signature");
|
||||||
|
LOAD_RETURN_CLEANUP
|
||||||
|
}
|
||||||
|
|
||||||
|
if((Version & 0xFFFFFF00) != (PWM_DBVER_DW & 0xFFFFFF00)){
|
||||||
|
error=tr("Unsupported File Version.");
|
||||||
|
LOAD_RETURN_CLEANUP
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Flags & PWM_FLAG_RIJNDAEL)
|
||||||
|
Algorithm = Rijndael_Cipher;
|
||||||
|
else if (Flags & PWM_FLAG_TWOFISH)
|
||||||
|
Algorithm = Twofish_Cipher;
|
||||||
|
else{
|
||||||
|
error=tr("Unknown Encryption Algorithm.");
|
||||||
|
LOAD_RETURN_CLEANUP
|
||||||
|
}
|
||||||
|
|
||||||
|
RawMasterKey.unlock();
|
||||||
|
MasterKey.unlock();
|
||||||
|
KeyTransform::transform(*RawMasterKey,*MasterKey,TransfRandomSeed,KeyTransfRounds);
|
||||||
|
|
||||||
|
quint8 FinalKey[32];
|
||||||
|
|
||||||
|
SHA256 sha;
|
||||||
|
sha.update(FinalRandomSeed,16);
|
||||||
|
sha.update(*MasterKey,32);
|
||||||
|
sha.finish(FinalKey);
|
||||||
|
|
||||||
|
RawMasterKey.lock();
|
||||||
|
MasterKey.lock();
|
||||||
|
|
||||||
|
if(Algorithm == Rijndael_Cipher){
|
||||||
|
AESdecrypt aes;
|
||||||
|
aes.key256(FinalKey);
|
||||||
|
aes.cbc_decrypt((unsigned char*)buffer+DB_HEADER_SIZE,(unsigned char*)buffer+DB_HEADER_SIZE,total_size-DB_HEADER_SIZE,(unsigned char*)EncryptionIV);
|
||||||
|
crypto_size=total_size-((quint8*)buffer)[total_size-1]-DB_HEADER_SIZE;
|
||||||
|
}
|
||||||
|
else if(Algorithm == Twofish_Cipher){
|
||||||
|
CTwofish twofish;
|
||||||
|
if (twofish.init(FinalKey, 32, EncryptionIV) != true){
|
||||||
|
error=tr("Unable to initalize the twofish algorithm.");
|
||||||
|
LOAD_RETURN_CLEANUP
|
||||||
|
}
|
||||||
|
crypto_size = (unsigned long)twofish.padDecrypt((quint8 *)buffer + DB_HEADER_SIZE,
|
||||||
|
total_size - DB_HEADER_SIZE, (quint8 *)buffer + DB_HEADER_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((crypto_size > 2147483446) || (!crypto_size && NumGroups)){
|
||||||
|
error=tr("Decryption failed.\nThe key is wrong or the file is damaged.");
|
||||||
|
LOAD_RETURN_CLEANUP
|
||||||
|
}
|
||||||
|
SHA256::hashBuffer(buffer+DB_HEADER_SIZE,FinalKey,crypto_size);
|
||||||
|
|
||||||
|
if(memcmp(ContentsHash, FinalKey, 32) != 0){
|
||||||
|
if(PotentialEncodingIssue){
|
||||||
|
delete[] buffer;
|
||||||
|
delete File;
|
||||||
|
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);
|
||||||
|
PotentialEncodingIssue=false;
|
||||||
|
qDebug("Decryption failed. Retrying with Latin-1.");
|
||||||
|
return load(filename); // second try
|
||||||
|
}
|
||||||
|
error=tr("Hash test failed.\nThe key is wrong or the file is damaged.");
|
||||||
|
KeyError=true;
|
||||||
|
LOAD_RETURN_CLEANUP
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long pos = DB_HEADER_SIZE;
|
||||||
|
quint16 FieldType;
|
||||||
|
quint32 FieldSize;
|
||||||
|
char* pField;
|
||||||
|
bool bRet;
|
||||||
|
StdGroup group;
|
||||||
|
QList<quint32> Levels;
|
||||||
|
RootGroup.Title="$ROOT$";
|
||||||
|
RootGroup.Parent=NULL;
|
||||||
|
RootGroup.Handle=NULL;
|
||||||
|
|
||||||
|
for(unsigned long CurGroup = 0; CurGroup < NumGroups; )
|
||||||
|
{
|
||||||
|
pField = buffer+pos;
|
||||||
|
|
||||||
|
memcpyFromLEnd16(&FieldType, pField);
|
||||||
|
pField += 2; pos += 2;
|
||||||
|
if (pos >= total_size){
|
||||||
|
error=tr("Unexpected error: Offset is out of range.").append(" [G1]");
|
||||||
|
LOAD_RETURN_CLEANUP
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpyFromLEnd32(&FieldSize, pField);
|
||||||
|
pField += 4; pos += 4;
|
||||||
|
if (pos >= (total_size + FieldSize)){
|
||||||
|
error=tr("Unexpected error: Offset is out of range.").append(" [G2]");
|
||||||
|
LOAD_RETURN_CLEANUP
|
||||||
|
}
|
||||||
|
|
||||||
|
bRet = readGroupField(&group,Levels, FieldType, FieldSize, (quint8 *)pField);
|
||||||
|
if ((FieldType == 0xFFFF) && (bRet == true)){
|
||||||
|
Groups << group;
|
||||||
|
CurGroup++; // Now and ONLY now the counter gets increased
|
||||||
|
}
|
||||||
|
pField += FieldSize;
|
||||||
|
pos += FieldSize;
|
||||||
|
if (pos >= total_size){
|
||||||
|
error=tr("Unexpected error: Offset is out of range.").append(" [G1]");
|
||||||
|
LOAD_RETURN_CLEANUP
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StdEntry entry;
|
||||||
|
|
||||||
|
for (unsigned long CurEntry = 0; CurEntry < NumEntries;)
|
||||||
|
{
|
||||||
|
pField = buffer+pos;
|
||||||
|
|
||||||
|
memcpyFromLEnd16(&FieldType, pField);
|
||||||
|
pField += 2; pos += 2;
|
||||||
|
if(pos >= total_size){
|
||||||
|
error=tr("Unexpected error: Offset is out of range.").append(" [E1]");
|
||||||
|
LOAD_RETURN_CLEANUP
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpyFromLEnd32(&FieldSize, pField);
|
||||||
|
pField += 4; pos += 4;
|
||||||
|
if (pos >= (total_size + FieldSize)){
|
||||||
|
error=tr("Unexpected error: Offset is out of range.").append(" [E2]");
|
||||||
|
LOAD_RETURN_CLEANUP
|
||||||
|
}
|
||||||
|
|
||||||
|
bRet = readEntryField(&entry,FieldType,FieldSize,(quint8*)pField);
|
||||||
|
|
||||||
|
if((FieldType == 0xFFFF) && (bRet == true)){
|
||||||
|
Entries << entry;
|
||||||
|
if(!entry.GroupId)
|
||||||
|
qDebug("NULL: %i, '%s'", (int)CurEntry, (char*)entry.Title.toUtf8().data());
|
||||||
|
CurEntry++;
|
||||||
|
}
|
||||||
|
|
||||||
|
pField += FieldSize;
|
||||||
|
pos += FieldSize;
|
||||||
|
if (pos >= total_size){
|
||||||
|
error=tr("Unexpected error: Offset is out of range.").append(" [E3]");
|
||||||
|
LOAD_RETURN_CLEANUP
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!createGroupTree(Levels)){
|
||||||
|
error=tr("Invalid group tree.");
|
||||||
|
LOAD_RETURN_CLEANUP
|
||||||
|
}
|
||||||
|
|
||||||
|
delete [] buffer;
|
||||||
|
|
||||||
|
hasV4IconMetaStream = false;
|
||||||
|
for(int i=0;i<Entries.size();i++){
|
||||||
|
if(isMetaStream(Entries[i]) && Entries[i].Comment=="KPX_CUSTOM_ICONS_4"){
|
||||||
|
hasV4IconMetaStream = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Remove the metastreams from the entry list
|
||||||
|
for(int i=0;i<Entries.size();i++){
|
||||||
|
if(isMetaStream(Entries[i])){
|
||||||
|
if(!parseMetaStream(Entries[i]))
|
||||||
|
UnknownMetaStreams << Entries[i];
|
||||||
|
Entries.removeAt(i);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int* EntryIndices=new int[Groups.size()];
|
||||||
|
for(int i=0;i<Groups.size();i++)EntryIndices[i]=0;
|
||||||
|
|
||||||
|
for(int g=0;g<Groups.size();g++){
|
||||||
|
for(int e=0;e<Entries.size();e++){
|
||||||
|
if(Entries[e].GroupId==Groups[g].Id){
|
||||||
|
Entries[e].Index=EntryIndices[g];
|
||||||
|
EntryIndices[g]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete [] EntryIndices;
|
||||||
|
createHandles();
|
||||||
|
restoreGroupTreeState();
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDateTime Kdb3Database::dateFromPackedStruct5(const unsigned char* pBytes){
|
QDateTime Kdb3Database::dateFromPackedStruct5(const unsigned char* pBytes){
|
||||||
|
@ -1614,10 +1614,7 @@ void Kdb3Database::create(){
|
||||||
RootGroup.Parent=NULL;
|
RootGroup.Parent=NULL;
|
||||||
RootGroup.Handle=NULL;
|
RootGroup.Handle=NULL;
|
||||||
Algorithm=Rijndael_Cipher;
|
Algorithm=Rijndael_Cipher;
|
||||||
quint16 ran;
|
KeyTransfRounds=50000;
|
||||||
randomize(&ran,2);
|
|
||||||
ran &= 0x03FF; // only use 10 bits -> max 1024
|
|
||||||
KeyTransfRounds=10000 + ran;
|
|
||||||
KeyError=false;
|
KeyError=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,8 @@ public:
|
||||||
bool autoSaveChange(){return settings.value("Options/AutoSaveChange",false).toBool();}
|
bool autoSaveChange(){return settings.value("Options/AutoSaveChange",false).toBool();}
|
||||||
int pwGenCategory(){return settings.value("Options/PwGenCategory",0).toInt();}
|
int pwGenCategory(){return settings.value("Options/PwGenCategory",0).toInt();}
|
||||||
QString pwGenCharList(){return settings.value("Options/PwGenCharList").toString();}
|
QString pwGenCharList(){return settings.value("Options/PwGenCharList").toString();}
|
||||||
|
bool pwGenExcludeLookAlike(){return settings.value("Options/PwGenExcludeLookAlike").toBool();}
|
||||||
|
bool pwGenEveryGroup(){return settings.value("Options/PwGenEveryGroup").toBool();}
|
||||||
int pwGenLength(){return settings.value("Options/PwGenLength",25).toInt();}
|
int pwGenLength(){return settings.value("Options/PwGenLength",25).toInt();}
|
||||||
QBitArray pwGenOptions(){return stringToBitArray(settings.value("Options/PwGenOptions","11111000011110").toString(),14);}
|
QBitArray pwGenOptions(){return stringToBitArray(settings.value("Options/PwGenOptions","11111000011110").toString(),14);}
|
||||||
bool rememberLastKey(){return settings.value("Options/RememberLastKey",true).toBool();}
|
bool rememberLastKey(){return settings.value("Options/RememberLastKey",true).toBool();}
|
||||||
|
@ -136,6 +138,8 @@ public:
|
||||||
void setAutoSaveChange(bool value){settings.setValue("Options/AutoSaveChange",value);}
|
void setAutoSaveChange(bool value){settings.setValue("Options/AutoSaveChange",value);}
|
||||||
void setPwGenCategory(int value){settings.setValue("Options/PwGenCategory",value);}
|
void setPwGenCategory(int value){settings.setValue("Options/PwGenCategory",value);}
|
||||||
void setPwGenCharList(const QString& value){settings.setValue("Options/PwGenCharList",value);}
|
void setPwGenCharList(const QString& value){settings.setValue("Options/PwGenCharList",value);}
|
||||||
|
void setPwGenExcludeLookAlike(bool value){settings.setValue("Options/PwGenExcludeLookAlike",value);}
|
||||||
|
void setPwGenEveryGroup(bool value){settings.setValue("Options/PwGenEveryGroup",value);}
|
||||||
void setPwGenLength(int value){settings.setValue("Options/PwGenLength",value);}
|
void setPwGenLength(int value){settings.setValue("Options/PwGenLength",value);}
|
||||||
void setPwGenOptions(const QBitArray& value){settings.setValue("Options/PwGenOptions",bitArrayToString(value));}
|
void setPwGenOptions(const QBitArray& value){settings.setValue("Options/PwGenOptions",bitArrayToString(value));}
|
||||||
void setRememberLastKey(bool value){settings.setValue("Options/RememberLastKey",value);}
|
void setRememberLastKey(bool value){settings.setValue("Options/RememberLastKey",value);}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#include <qstring.h>
|
#include <QString>
|
||||||
#include "twoclass.h"
|
#include "twoclass.h"
|
||||||
|
|
||||||
static bool g_bInitialized = false;
|
static bool g_bInitialized = false;
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "dialogs/PasswordGenDlg.h"
|
#include "dialogs/PasswordGenDlg.h"
|
||||||
#include "dialogs/CollectEntropyDlg.h"
|
#include "dialogs/CollectEntropyDlg.h"
|
||||||
|
|
||||||
|
#include "random.h"
|
||||||
#include "apg/randpass.h"
|
#include "apg/randpass.h"
|
||||||
#include "apg/pronpass.h"
|
#include "apg/pronpass.h"
|
||||||
|
|
||||||
|
@ -109,6 +110,8 @@ CGenPwDialog::CGenPwDialog(QWidget* parent, bool StandAloneMode,Qt::WFlags fl)
|
||||||
checkBoxPN->setChecked(true);
|
checkBoxPN->setChecked(true);
|
||||||
checkBoxPS->setChecked(false);
|
checkBoxPS->setChecked(false);
|
||||||
}
|
}
|
||||||
|
Check_ExcludeLookAlike->setChecked(config->pwGenExcludeLookAlike());
|
||||||
|
Check_EveryGroup->setChecked(config->pwGenEveryGroup());
|
||||||
Spin_Num->setValue(config->pwGenLength());
|
Spin_Num->setValue(config->pwGenLength());
|
||||||
adjustSize();
|
adjustSize();
|
||||||
setMaximumSize(size());
|
setMaximumSize(size());
|
||||||
|
@ -139,6 +142,8 @@ CGenPwDialog::~CGenPwDialog(){
|
||||||
pwGenOptions.setBit(12,checkBoxPN->isChecked());
|
pwGenOptions.setBit(12,checkBoxPN->isChecked());
|
||||||
pwGenOptions.setBit(13,checkBoxPS->isChecked());
|
pwGenOptions.setBit(13,checkBoxPS->isChecked());
|
||||||
config->setPwGenOptions(pwGenOptions);
|
config->setPwGenOptions(pwGenOptions);
|
||||||
|
config->setPwGenExcludeLookAlike(Check_ExcludeLookAlike->isChecked());
|
||||||
|
config->setPwGenEveryGroup(Check_EveryGroup->isChecked());
|
||||||
config->setPwGenLength(Spin_Num->value());
|
config->setPwGenLength(Spin_Num->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,21 +203,6 @@ void CGenPwDialog::OnGeneratePw()
|
||||||
gen_pron_pass(buffer, hyphenated_word, length, length, mode);
|
gen_pron_pass(buffer, hyphenated_word, length, length, mode);
|
||||||
delete[] hyphenated_word;
|
delete[] hyphenated_word;
|
||||||
}
|
}
|
||||||
else if (Radio_1->isChecked() && !checkBox5->isChecked() &&
|
|
||||||
!checkBox6->isChecked() && !checkBox7->isChecked())
|
|
||||||
{
|
|
||||||
unsigned int mode = 0;
|
|
||||||
if (checkBox1->isChecked())
|
|
||||||
mode |= S_CL;
|
|
||||||
if (checkBox2->isChecked())
|
|
||||||
mode |= S_SL;
|
|
||||||
if (checkBox3->isChecked())
|
|
||||||
mode |= S_NB;
|
|
||||||
if (checkBox4->isChecked())
|
|
||||||
mode |= S_SS;
|
|
||||||
|
|
||||||
gen_rand_pass(buffer, length, length, mode);
|
|
||||||
}
|
|
||||||
else{
|
else{
|
||||||
generatePasswordInternal(buffer, length);
|
generatePasswordInternal(buffer, length);
|
||||||
}
|
}
|
||||||
|
@ -221,24 +211,6 @@ void CGenPwDialog::OnGeneratePw()
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CGenPwDialog::AddToAssoctable(char* table,int start,int end,int pos){
|
|
||||||
for(int i=start;i<=end;i++){
|
|
||||||
table[pos]=i;
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
return (end-start)+1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool CGenPwDialog::trim(unsigned char &x, int r){
|
|
||||||
if(x<r)
|
|
||||||
return true;
|
|
||||||
if(256%r!=0)
|
|
||||||
return false;
|
|
||||||
x=x-(x/r)*r;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CGenPwDialog::estimateQuality(){
|
void CGenPwDialog::estimateQuality(){
|
||||||
int num=0;
|
int num=0;
|
||||||
if (tabCategory->currentIndex()==0){
|
if (tabCategory->currentIndex()==0){
|
||||||
|
@ -340,6 +312,32 @@ void CGenPwDialog::SwapEchoMode(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGenPwDialog::AddToAssoctable(char* table,int start,int end,int& pos){
|
||||||
|
for (int i=start;i<=end;i++){
|
||||||
|
if (Check_ExcludeLookAlike->isChecked()){
|
||||||
|
switch (i){
|
||||||
|
case 48: // 0
|
||||||
|
case 79: // O
|
||||||
|
case 49: // 1
|
||||||
|
case 73: // I
|
||||||
|
case 108: // l
|
||||||
|
case 124: // |
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
table[pos]=i;
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CGenPwDialog::PwGroup CGenPwDialog::AddToAssoctableGroup(char* table,int start,int end,int& pos){
|
||||||
|
PwGroup group;
|
||||||
|
group.start = pos;
|
||||||
|
AddToAssoctable(table,start,end,pos);
|
||||||
|
group.end = pos-1;
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
void CGenPwDialog::generatePasswordInternal(char* buffer, int length){
|
void CGenPwDialog::generatePasswordInternal(char* buffer, int length){
|
||||||
/*-------------------------------------------------------
|
/*-------------------------------------------------------
|
||||||
ASCII
|
ASCII
|
||||||
|
@ -355,26 +353,62 @@ void CGenPwDialog::generatePasswordInternal(char* buffer, int length){
|
||||||
|
|
||||||
int num=0;
|
int num=0;
|
||||||
char assoctable[255];
|
char assoctable[255];
|
||||||
|
int groups=0;
|
||||||
|
bool ensureEveryGroup = false;
|
||||||
|
QList<PwGroup> groupTable;
|
||||||
|
|
||||||
if(Radio_1->isChecked()){
|
if(Radio_1->isChecked()){
|
||||||
if(checkBox1->isChecked())
|
if (Check_EveryGroup->isChecked()){
|
||||||
num+=AddToAssoctable(assoctable,65,90,num);
|
if (checkBox1->isChecked()) groups++;
|
||||||
if(checkBox2->isChecked())
|
if (checkBox2->isChecked()) groups++;
|
||||||
num+=AddToAssoctable(assoctable,97,122,num);
|
if (checkBox3->isChecked()) groups++;
|
||||||
if(checkBox3->isChecked())
|
if (checkBox4->isChecked()) groups++;
|
||||||
num+=AddToAssoctable(assoctable,48,57,num);
|
if (checkBox5->isChecked()) groups++;
|
||||||
if(checkBox4->isChecked()){
|
if (checkBox6->isChecked()) groups++;
|
||||||
num+=AddToAssoctable(assoctable,33,47,num);
|
if (checkBox7->isChecked()) groups++;
|
||||||
num+=AddToAssoctable(assoctable,58,64,num);
|
if (groups<=length)
|
||||||
num+=AddToAssoctable(assoctable,91,96,num);
|
ensureEveryGroup = true;
|
||||||
num+=AddToAssoctable(assoctable,123,126,num);
|
}
|
||||||
|
|
||||||
|
if(checkBox1->isChecked()){
|
||||||
|
if (ensureEveryGroup) groupTable.append(AddToAssoctableGroup(assoctable,65,90,num));
|
||||||
|
else AddToAssoctable(assoctable,65,90,num);
|
||||||
|
}
|
||||||
|
if(checkBox2->isChecked()){
|
||||||
|
if (ensureEveryGroup) groupTable.append(AddToAssoctableGroup(assoctable,97,122,num));
|
||||||
|
else AddToAssoctable(assoctable,97,122,num);
|
||||||
|
}
|
||||||
|
if(checkBox3->isChecked()){
|
||||||
|
if (ensureEveryGroup) groupTable.append(AddToAssoctableGroup(assoctable,48,57,num));
|
||||||
|
else AddToAssoctable(assoctable,48,57,num);
|
||||||
|
}
|
||||||
|
if(checkBox4->isChecked()){
|
||||||
|
PwGroup group;
|
||||||
|
group.start = num;
|
||||||
|
AddToAssoctable(assoctable,33,44,num);
|
||||||
|
AddToAssoctable(assoctable,46,47,num);
|
||||||
|
AddToAssoctable(assoctable,58,64,num);
|
||||||
|
AddToAssoctable(assoctable,91,94,num);
|
||||||
|
AddToAssoctable(assoctable,96,96,num);
|
||||||
|
AddToAssoctable(assoctable,123,126,num);
|
||||||
|
if (ensureEveryGroup){
|
||||||
|
group.end = num-1;
|
||||||
|
groupTable.append(group);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if(checkBox5->isChecked()){
|
||||||
|
if (ensureEveryGroup) groupTable.append(AddToAssoctableGroup(assoctable,32,32,num));
|
||||||
|
else AddToAssoctable(assoctable,32,32,num);
|
||||||
|
}
|
||||||
|
if(checkBox6->isChecked()){
|
||||||
|
if (ensureEveryGroup) groupTable.append(AddToAssoctableGroup(assoctable,45,45,num));
|
||||||
|
else AddToAssoctable(assoctable,45,45,num);
|
||||||
|
}
|
||||||
|
if(checkBox7->isChecked()){
|
||||||
|
if (ensureEveryGroup) groupTable.append(AddToAssoctableGroup(assoctable,95,95,num));
|
||||||
|
else AddToAssoctable(assoctable,95,95,num);
|
||||||
}
|
}
|
||||||
if(checkBox5->isChecked())
|
|
||||||
num+=AddToAssoctable(assoctable,32,32,num);
|
|
||||||
if(checkBox6->isChecked() && !checkBox4->isChecked())
|
|
||||||
num+=AddToAssoctable(assoctable,45,45,num);
|
|
||||||
if(checkBox7->isChecked() && !checkBox4->isChecked())
|
|
||||||
num+=AddToAssoctable(assoctable,95,95,num);
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
QString str=Edit_chars->text();
|
QString str=Edit_chars->text();
|
||||||
|
@ -394,13 +428,29 @@ void CGenPwDialog::generatePasswordInternal(char* buffer, int length){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char tmp;
|
if (ensureEveryGroup){
|
||||||
for(int i=0;i<length;i++){
|
QList<int> charPos;
|
||||||
|
for (int i=0; i<length; i++)
|
||||||
|
charPos.append(i);
|
||||||
|
|
||||||
do randomize(&tmp,1);
|
for (int i=0; i<groups; i++){
|
||||||
while(!trim(tmp,num));
|
int posIndex = randintRange(0, charPos.count()-1);
|
||||||
|
int pos = charPos[posIndex];
|
||||||
|
charPos.removeAt(posIndex);
|
||||||
|
buffer[pos] = assoctable[randintRange(groupTable[i].start, groupTable[i].end)];
|
||||||
|
}
|
||||||
|
|
||||||
buffer[i]=assoctable[tmp];
|
for (int i=groups; i<length; i++){
|
||||||
|
int posIndex = randintRange(0, charPos.count()-1);
|
||||||
|
int pos = charPos[posIndex];
|
||||||
|
charPos.removeAt(posIndex);
|
||||||
|
buffer[pos] = assoctable[randint(num)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
qDebug("ja");
|
||||||
|
for (int i=0; i<length; i++)
|
||||||
|
buffer[i] = assoctable[randint(num)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,12 @@ class CGenPwDialog : public QDialog, public Ui_GenPwDlg
|
||||||
~CGenPwDialog();
|
~CGenPwDialog();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int AddToAssoctable(char* table,int start,int end,int pos);
|
struct PwGroup {
|
||||||
bool trim(unsigned char &value,int range);
|
int start;
|
||||||
|
int end;
|
||||||
|
};
|
||||||
|
void AddToAssoctable(char* table,int start,int end,int& pos);
|
||||||
|
PwGroup AddToAssoctableGroup(char* table,int start,int end,int& pos);
|
||||||
void paintEvent(QPaintEvent* event);
|
void paintEvent(QPaintEvent* event);
|
||||||
void generatePasswordInternal(char* buffer, int length);
|
void generatePasswordInternal(char* buffer, int length);
|
||||||
QPixmap BannerPixmap;
|
QPixmap BannerPixmap;
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>462</width>
|
<width>462</width>
|
||||||
<height>491</height>
|
<height>543</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle" >
|
<property name="windowTitle" >
|
||||||
|
@ -43,7 +43,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>440</width>
|
<width>440</width>
|
||||||
<height>219</height>
|
<height>271</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<attribute name="title" >
|
<attribute name="title" >
|
||||||
|
@ -102,7 +102,7 @@
|
||||||
<item row="2" column="1" >
|
<item row="2" column="1" >
|
||||||
<widget class="QCheckBox" name="checkBox7" >
|
<widget class="QCheckBox" name="checkBox7" >
|
||||||
<property name="text" >
|
<property name="text" >
|
||||||
<string>U&nderline</string>
|
<string>&Underline</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="shortcut" >
|
<property name="shortcut" >
|
||||||
<string>Alt+N</string>
|
<string>Alt+N</string>
|
||||||
|
@ -125,7 +125,7 @@
|
||||||
<item row="0" column="1" >
|
<item row="0" column="1" >
|
||||||
<widget class="QCheckBox" name="checkBox5" >
|
<widget class="QCheckBox" name="checkBox5" >
|
||||||
<property name="text" >
|
<property name="text" >
|
||||||
<string>White &Spaces</string>
|
<string>&White Spaces</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="shortcut" >
|
<property name="shortcut" >
|
||||||
<string>Alt+S</string>
|
<string>Alt+S</string>
|
||||||
|
@ -148,7 +148,7 @@
|
||||||
<item row="1" column="1" >
|
<item row="1" column="1" >
|
||||||
<widget class="QCheckBox" name="checkBox6" >
|
<widget class="QCheckBox" name="checkBox6" >
|
||||||
<property name="text" >
|
<property name="text" >
|
||||||
<string>Minus</string>
|
<string>&Minus</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -219,6 +219,20 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="Check_ExcludeLookAlike" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Exclude look-alike characters</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="Check_EveryGroup" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Ensure that password contains characters from every group</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="tabPronounceable" >
|
<widget class="QWidget" name="tabPronounceable" >
|
||||||
|
@ -227,7 +241,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>440</width>
|
<width>440</width>
|
||||||
<height>219</height>
|
<height>271</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<attribute name="title" >
|
<attribute name="title" >
|
||||||
|
@ -250,7 +264,7 @@
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout" >
|
<layout class="QHBoxLayout" name="horizontalLayout" >
|
||||||
<item>
|
<item>
|
||||||
<layout class="QGridLayout" name="gridLayout" >
|
<layout class="QGridLayout" name="gridLayout_2" >
|
||||||
<property name="spacing" >
|
<property name="spacing" >
|
||||||
<number>15</number>
|
<number>15</number>
|
||||||
</property>
|
</property>
|
||||||
|
|
|
@ -274,6 +274,7 @@ void KeepassEntryView::OnEditOpenUrl(){
|
||||||
void KeepassEntryView::OnEditCopyUrl(){
|
void KeepassEntryView::OnEditCopyUrl(){
|
||||||
if (selectedItems().size() == 0) return;
|
if (selectedItems().size() == 0) return;
|
||||||
QString url = ((EntryViewItem*)selectedItems().first())->EntryHandle->url();
|
QString url = ((EntryViewItem*)selectedItems().first())->EntryHandle->url();
|
||||||
|
if (url.trimmed().isEmpty()) return;
|
||||||
if (url.startsWith("cmd://") && url.length()>6)
|
if (url.startsWith("cmd://") && url.length()>6)
|
||||||
url = url.right(url.length()-6);
|
url = url.right(url.length()-6);
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@ void SecData::unlock(){
|
||||||
}
|
}
|
||||||
|
|
||||||
void SecData::copyData(quint8* src){
|
void SecData::copyData(quint8* src){
|
||||||
unlock();
|
locked = false;
|
||||||
memcpy(data, src, length);
|
memcpy(data, src, length);
|
||||||
lock();
|
lock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,10 +47,14 @@ void getEntropy(quint8* buffer, int length){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
quint32 randint(quint32 n){
|
quint32 randint(quint32 limit){
|
||||||
quint32 rand;
|
quint32 rand;
|
||||||
randomize(&rand, 4);
|
randomize(&rand, 4);
|
||||||
return (rand % n);
|
return (rand % limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
quint32 randintRange(quint32 min, quint32 max){
|
||||||
|
return min + randint(max-min+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(Q_WS_X11) || defined(Q_WS_MAC)
|
#if defined(Q_WS_X11) || defined(Q_WS_MAC)
|
||||||
|
|
|
@ -33,10 +33,12 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void getEntropy(quint8* buffer, int length);
|
void getEntropy(quint8* buffer, int length);
|
||||||
quint32 randint(quint32 n);
|
quint32 randint(quint32 limit); // generate random number: 0 <= n < limit
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
quint32 randintRange(quint32 min, quint32 max); // generate random number: min <= n <= max
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -354,6 +354,7 @@ void KeepassMainWindow::setupMenus(){
|
||||||
EditPasswordToClipboardAction->setShortcut(tr("Ctrl+C"));
|
EditPasswordToClipboardAction->setShortcut(tr("Ctrl+C"));
|
||||||
EditUsernameToClipboardAction->setShortcut(tr("Ctrl+B"));
|
EditUsernameToClipboardAction->setShortcut(tr("Ctrl+B"));
|
||||||
EditOpenUrlAction->setShortcut(tr("Ctrl+U"));
|
EditOpenUrlAction->setShortcut(tr("Ctrl+U"));
|
||||||
|
EditCopyUrlAction->setShortcut(tr("Ctrl+I"));
|
||||||
EditNewEntryAction->setShortcut(tr("Ctrl+Y"));
|
EditNewEntryAction->setShortcut(tr("Ctrl+Y"));
|
||||||
EditEditEntryAction->setShortcut(tr("Ctrl+E"));
|
EditEditEntryAction->setShortcut(tr("Ctrl+E"));
|
||||||
EditDeleteEntryAction->setShortcut(tr("Ctrl+D"));
|
EditDeleteEntryAction->setShortcut(tr("Ctrl+D"));
|
||||||
|
@ -630,7 +631,6 @@ void KeepassMainWindow::setStateFileOpen(bool IsOpen){
|
||||||
void KeepassMainWindow::setStateFileModified(bool mod){
|
void KeepassMainWindow::setStateFileModified(bool mod){
|
||||||
if (config->autoSaveChange() && mod && db->file()){
|
if (config->autoSaveChange() && mod && db->file()){
|
||||||
OnFileSave();
|
OnFileSave();
|
||||||
mod = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ModFlag=mod;
|
ModFlag=mod;
|
||||||
|
|
Loading…
Reference in New Issue