Fixed #2230887: No password generated using list of very special characters

git-svn-id: https://svn.code.sf.net/p/keepassx/code/trunk@243 b624d157-de02-0410-bad0-e51aec6abb33
master
sniperbeamer 16 years ago
parent ff58631a2c
commit 56d9acef43
  1. 114
      src/dialogs/PasswordGenDlg.cpp
  2. 16
      src/dialogs/PasswordGenDlg.h

@ -53,8 +53,8 @@ CGenPwDialog::CGenPwDialog(QWidget* parent, bool StandAloneMode,Qt::WFlags fl)
connect(checkBoxPN, SIGNAL(toggled(bool)), SLOT(estimateQuality())); connect(checkBoxPN, SIGNAL(toggled(bool)), SLOT(estimateQuality()));
connect(checkBoxPS, SIGNAL(toggled(bool)), SLOT(estimateQuality())); connect(checkBoxPS, SIGNAL(toggled(bool)), SLOT(estimateQuality()));
connect(Spin_Num, SIGNAL(valueChanged(int)), SLOT(estimateQuality())); connect(Spin_Num, SIGNAL(valueChanged(int)), SLOT(estimateQuality()));
connect(Check_ExcludeLookAlike, SIGNAL(toggled(bool)), SLOT(estimateQuality()));
connect(Check_CollectEntropy, SIGNAL(stateChanged(int)), SLOT(OnCollectEntropyChanged(int))); connect(Check_CollectEntropy, SIGNAL(stateChanged(int)), SLOT(OnCollectEntropyChanged(int)));
connect(Edit_chars, SIGNAL(textEdited(const QString&)), SLOT(OnCharsChanged(const QString&)));
connect(ButtonChangeEchoMode, SIGNAL(clicked()), SLOT(SwapEchoMode())); connect(ButtonChangeEchoMode, SIGNAL(clicked()), SLOT(SwapEchoMode()));
connect(tabCategory, SIGNAL(currentChanged(int)), SLOT(setGenerateEnabled())); connect(tabCategory, SIGNAL(currentChanged(int)), SLOT(setGenerateEnabled()));
connect(Radio_1, SIGNAL(toggled(bool)), SLOT(setGenerateEnabled())); connect(Radio_1, SIGNAL(toggled(bool)), SLOT(setGenerateEnabled()));
@ -83,6 +83,8 @@ CGenPwDialog::CGenPwDialog(QWidget* parent, bool StandAloneMode,Qt::WFlags fl)
AcceptButton=NULL; AcceptButton=NULL;
} }
Edit_chars->setValidator(new PassCharValidator(this));
tabCategory->setCurrentIndex(config->pwGenCategory()); tabCategory->setCurrentIndex(config->pwGenCategory());
QBitArray pwGenOptions=config->pwGenOptions(); QBitArray pwGenOptions=config->pwGenOptions();
Radio_1->setChecked(pwGenOptions.at(0)); Radio_1->setChecked(pwGenOptions.at(0));
@ -184,7 +186,7 @@ void CGenPwDialog::OnRadio2StateChanged(bool state){
void CGenPwDialog::OnGeneratePw() void CGenPwDialog::OnGeneratePw()
{ {
int length = Spin_Num->value(); int length = Spin_Num->value();
char* buffer = new char[length+1]; QString password;
if (tabCategory->currentIndex()==1) if (tabCategory->currentIndex()==1)
{ {
@ -198,35 +200,49 @@ void CGenPwDialog::OnGeneratePw()
if (checkBoxPS->isChecked()) if (checkBoxPS->isChecked())
mode |= S_SS; mode |= S_SS;
char* buffer = new char[length+1];
char* hyphenated_word = new char[length*18+1]; char* hyphenated_word = new char[length*18+1];
gen_pron_pass(buffer, hyphenated_word, length, length, mode); gen_pron_pass(buffer, hyphenated_word, length, length, mode);
password = buffer;
delete[] hyphenated_word; delete[] hyphenated_word;
delete[] buffer;
} }
else{ else{
generatePasswordInternal(buffer, length); password = generatePasswordInternal(length);
} }
Edit_dest->setText(buffer); Edit_dest->setText(password);
delete[] buffer;
} }
void CGenPwDialog::estimateQuality(){ void CGenPwDialog::estimateQuality(){
int num=0; int num=0;
if (tabCategory->currentIndex()==0){ if (tabCategory->currentIndex()==0){
if(Radio_1->isChecked()){ if(Radio_1->isChecked()){
if(checkBox1->isChecked()) if(checkBox1->isChecked()) {
num+=26; num+=26;
if(checkBox2->isChecked()) if (Check_ExcludeLookAlike->isChecked())
num -= 2;
}
if(checkBox2->isChecked()) {
num+=26; num+=26;
if(checkBox3->isChecked()) if (Check_ExcludeLookAlike->isChecked())
num -= 1;
}
if(checkBox3->isChecked()) {
num+=10; num+=10;
if(checkBox4->isChecked()) if (Check_ExcludeLookAlike->isChecked())
num -= 2;
}
if(checkBox4->isChecked()) {
num+=32; num+=32;
if (Check_ExcludeLookAlike->isChecked())
num -= 1;
}
if(checkBox5->isChecked()) if(checkBox5->isChecked())
num++; num++;
if(checkBox6->isChecked() && !checkBox4->isChecked()) if(checkBox6->isChecked())
num++; num++;
if(checkBox7->isChecked() && !checkBox4->isChecked()) if(checkBox7->isChecked())
num++; num++;
} }
else else
@ -247,39 +263,11 @@ void CGenPwDialog::estimateQuality(){
if (num) if (num)
bits = log((float)num) / log(2.0f); bits = log((float)num) / log(2.0f);
bits = bits * ((float)Spin_Num->value()); bits = bits * ((float)Spin_Num->value());
Progress_Quali->setFormat(tr("%1 Bits").arg((int)bits)); int bitsNum = (int) (bits+0.5);
Progress_Quali->update();
if(bits>128)bits=128;
Progress_Quali->setValue((int)bits);
}
void CGenPwDialog::OnCharsChanged(const QString& str){
bool multiple=false;
for(int i=0;i<str.size();i++){
int count=0;
for(int j=0;j<str.size();j++){
if(str[i]==str[j]){
if(count){
multiple=true;
break;
}
else {
count++;
}
}
}
if(multiple)break;
}
if(!multiple)return;
QString newstr;
for(int i=0;i<str.size();i++){
if(!newstr.count(str[i])){
newstr+=str[i];
}
}
Edit_chars->setText(newstr);
Progress_Quali->setFormat(tr("%1 Bits").arg(bitsNum));
Progress_Quali->update();
Progress_Quali->setValue((bitsNum > 128) ? 128 : bitsNum);
} }
void CGenPwDialog::OnAccept() void CGenPwDialog::OnAccept()
@ -311,7 +299,7 @@ void CGenPwDialog::SwapEchoMode(){
} }
} }
void CGenPwDialog::AddToAssoctable(char* table,int start,int end,int& pos){ void CGenPwDialog::AddToAssoctable(QList<QChar>& table,int start,int end,int& pos){
for (int i=start;i<=end;i++){ for (int i=start;i<=end;i++){
if (Check_ExcludeLookAlike->isChecked()){ if (Check_ExcludeLookAlike->isChecked()){
switch (i){ switch (i){
@ -324,12 +312,12 @@ void CGenPwDialog::AddToAssoctable(char* table,int start,int end,int& pos){
continue; continue;
} }
} }
table[pos]=i; table.append(QChar(i));
pos++; pos++;
} }
} }
CGenPwDialog::PwGroup CGenPwDialog::AddToAssoctableGroup(char* table,int start,int end,int& pos){ CGenPwDialog::PwGroup CGenPwDialog::AddToAssoctableGroup(QList<QChar>& table,int start,int end,int& pos){
PwGroup group; PwGroup group;
group.start = pos; group.start = pos;
AddToAssoctable(table,start,end,pos); AddToAssoctable(table,start,end,pos);
@ -337,7 +325,7 @@ CGenPwDialog::PwGroup CGenPwDialog::AddToAssoctableGroup(char* table,int start,i
return group; return group;
} }
void CGenPwDialog::generatePasswordInternal(char* buffer, int length){ QString CGenPwDialog::generatePasswordInternal(int length){
/*------------------------------------------------------- /*-------------------------------------------------------
ASCII ASCII
------------------------------------------------------- -------------------------------------------------------
@ -351,7 +339,7 @@ void CGenPwDialog::generatePasswordInternal(char* buffer, int length){
*/ */
int num=0; int num=0;
char assoctable[255]; QList<QChar> assoctable;
int groups=0; int groups=0;
bool ensureEveryGroup = false; bool ensureEveryGroup = false;
QList<PwGroup> groupTable; QList<PwGroup> groupTable;
@ -412,13 +400,11 @@ void CGenPwDialog::generatePasswordInternal(char* buffer, int length){
else{ else{
QString str=Edit_chars->text(); QString str=Edit_chars->text();
for(int i=0;i<str.length();i++){ for(int i=0;i<str.length();i++){
assoctable[i]=str[i].toAscii(); assoctable.append(str[i]);
num++; num++;
} }
} }
buffer[length]=0;
if(Check_CollectEntropy->isChecked()){ if(Check_CollectEntropy->isChecked()){
if((Check_CollectOncePerSession->isChecked() && !EntropyCollected) || !Check_CollectOncePerSession->isChecked()){ if((Check_CollectOncePerSession->isChecked() && !EntropyCollected) || !Check_CollectOncePerSession->isChecked()){
CollectEntropyDlg dlg(this); CollectEntropyDlg dlg(this);
@ -427,6 +413,8 @@ void CGenPwDialog::generatePasswordInternal(char* buffer, int length){
} }
} }
QString password(length, '\0');
if (ensureEveryGroup){ if (ensureEveryGroup){
QList<int> charPos; QList<int> charPos;
for (int i=0; i<length; i++) for (int i=0; i<length; i++)
@ -436,20 +424,22 @@ void CGenPwDialog::generatePasswordInternal(char* buffer, int length){
int posIndex = randintRange(0, charPos.count()-1); int posIndex = randintRange(0, charPos.count()-1);
int pos = charPos[posIndex]; int pos = charPos[posIndex];
charPos.removeAt(posIndex); charPos.removeAt(posIndex);
buffer[pos] = assoctable[randintRange(groupTable[i].start, groupTable[i].end)]; password[pos] = assoctable[randintRange(groupTable[i].start, groupTable[i].end)];
} }
for (int i=groups; i<length; i++){ for (int i=groups; i<length; i++){
int posIndex = randintRange(0, charPos.count()-1); int posIndex = randintRange(0, charPos.count()-1);
int pos = charPos[posIndex]; int pos = charPos[posIndex];
charPos.removeAt(posIndex); charPos.removeAt(posIndex);
buffer[pos] = assoctable[randint(num)]; password[pos] = assoctable[randint(num)];
} }
} }
else{ else{
for (int i=0; i<length; i++) for (int i=0; i<length; i++)
buffer[i] = assoctable[randint(num)]; password[i] = assoctable[randint(num)];
} }
return password;
} }
void CGenPwDialog::setGenerateEnabled(){ void CGenPwDialog::setGenerateEnabled(){
@ -476,3 +466,19 @@ void CGenPwDialog::setGenerateEnabled(){
void CGenPwDialog::setAcceptEnabled(const QString& str){ void CGenPwDialog::setAcceptEnabled(const QString& str){
AcceptButton->setEnabled(!str.isEmpty()); AcceptButton->setEnabled(!str.isEmpty());
} }
PassCharValidator::PassCharValidator(QObject* parent) : QValidator(parent) {
}
QValidator::State PassCharValidator::validate(QString& input, int& pos) const {
QSet<QChar> chars;
for (int i=0; i<input.size(); i++) {
if (chars.contains(input[i]))
return QValidator::Invalid;
else
chars.insert(input[i]);
}
return QValidator::Acceptable;
}

@ -36,10 +36,10 @@ class CGenPwDialog : public QDialog, public Ui_GenPwDlg
int start; int start;
int end; int end;
}; };
void AddToAssoctable(char* table,int start,int end,int& pos); void AddToAssoctable(QList<QChar>& table,int start,int end,int& pos);
PwGroup AddToAssoctableGroup(char* table,int start,int end,int& pos); PwGroup AddToAssoctableGroup(QList<QChar>& table,int start,int end,int& pos);
void paintEvent(QPaintEvent* event); void paintEvent(QPaintEvent* event);
void generatePasswordInternal(char* buffer, int length); QString generatePasswordInternal(int length);
QPixmap BannerPixmap; QPixmap BannerPixmap;
static bool EntropyCollected; static bool EntropyCollected;
QPushButton* AcceptButton; QPushButton* AcceptButton;
@ -52,11 +52,19 @@ class CGenPwDialog : public QDialog, public Ui_GenPwDlg
void OnAccept(); void OnAccept();
void estimateQuality(); void estimateQuality();
void OnCollectEntropyChanged(int); void OnCollectEntropyChanged(int);
void OnCharsChanged(const QString& str);
void SwapEchoMode(); void SwapEchoMode();
void setGenerateEnabled(); void setGenerateEnabled();
void setAcceptEnabled(const QString& str); void setAcceptEnabled(const QString& str);
}; };
class PassCharValidator : public QValidator
{
Q_OBJECT
public:
PassCharValidator(QObject* parent);
State validate(QString& input, int& pos) const;
};
#endif #endif