1 /***************************************************************************
2 * Copyright (C) 2005 by Tarek Saidi *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; version 2 of the License. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
22 #include "dialogs/PasswordGenDlg.h"
23 #include "dialogs/CollectEntropyDlg.h"
26 #include "apg/randpass.h"
27 #include "apg/pronpass.h"
29 bool CGenPwDialog::EntropyCollected=false;
31 CGenPwDialog::CGenPwDialog(QWidget* parent, bool StandAloneMode,Qt::WFlags fl)
35 connect(ButtonGenerate, SIGNAL(clicked()), SLOT(OnGeneratePw()));
36 connect(DialogButtons, SIGNAL(rejected()), SLOT(OnCancel()));
37 connect(DialogButtons, SIGNAL(accepted()), SLOT(OnAccept()));
38 connect(tabCategory, SIGNAL(currentChanged(int)), SLOT(estimateQuality()));
39 connect(checkBox1, SIGNAL(toggled(bool)), SLOT(estimateQuality()));
40 connect(checkBox2, SIGNAL(toggled(bool)), SLOT(estimateQuality()));
41 connect(checkBox3, SIGNAL(toggled(bool)), SLOT(estimateQuality()));
42 connect(checkBox4, SIGNAL(toggled(bool)), SLOT(estimateQuality()));
43 connect(checkBox5, SIGNAL(toggled(bool)), SLOT(estimateQuality()));
44 connect(checkBox6, SIGNAL(toggled(bool)), SLOT(estimateQuality()));
45 connect(checkBox7, SIGNAL(toggled(bool)), SLOT(estimateQuality()));
46 connect(Edit_chars, SIGNAL(textChanged(const QString&)), SLOT(estimateQuality()));
47 connect(checkBoxPU, SIGNAL(toggled(bool)), SLOT(estimateQuality()));
48 connect(checkBoxPL, SIGNAL(toggled(bool)), SLOT(estimateQuality()));
49 connect(checkBoxPN, SIGNAL(toggled(bool)), SLOT(estimateQuality()));
50 connect(checkBoxPS, SIGNAL(toggled(bool)), SLOT(estimateQuality()));
51 connect(Spin_Num, SIGNAL(valueChanged(int)), SLOT(estimateQuality()));
52 connect(Check_ExcludeLookAlike, SIGNAL(toggled(bool)), SLOT(estimateQuality()));
53 connect(Check_CollectEntropy, SIGNAL(stateChanged(int)), SLOT(OnCollectEntropyChanged(int)));
54 connect(ButtonChangeEchoMode, SIGNAL(clicked()), SLOT(SwapEchoMode()));
55 connect(tabCategory, SIGNAL(currentChanged(int)), SLOT(setGenerateEnabled()));
56 connect(checkBox1, SIGNAL(toggled(bool)), SLOT(setGenerateEnabled()));
57 connect(checkBox2, SIGNAL(toggled(bool)), SLOT(setGenerateEnabled()));
58 connect(checkBox3, SIGNAL(toggled(bool)), SLOT(setGenerateEnabled()));
59 connect(checkBox4, SIGNAL(toggled(bool)), SLOT(setGenerateEnabled()));
60 connect(checkBox5, SIGNAL(toggled(bool)), SLOT(setGenerateEnabled()));
61 connect(checkBox6, SIGNAL(toggled(bool)), SLOT(setGenerateEnabled()));
62 connect(checkBox7, SIGNAL(toggled(bool)), SLOT(setGenerateEnabled()));
63 connect(Edit_chars, SIGNAL(textChanged(const QString&)), SLOT(setGenerateEnabled()));
64 connect(checkBoxPU, SIGNAL(toggled(bool)), SLOT(setGenerateEnabled()));
65 connect(checkBoxPL, SIGNAL(toggled(bool)), SLOT(setGenerateEnabled()));
66 connect(checkBoxPN, SIGNAL(toggled(bool)), SLOT(setGenerateEnabled()));
67 connect(checkBoxPS, SIGNAL(toggled(bool)), SLOT(setGenerateEnabled()));
70 AcceptButton=DialogButtons->addButton(QDialogButtonBox::Ok);
71 AcceptButton->setEnabled(false);
72 DialogButtons->addButton(QDialogButtonBox::Cancel);
73 connect(Edit_dest, SIGNAL(textChanged(const QString&)), SLOT(setAcceptEnabled(const QString&)));
76 DialogButtons->addButton(QDialogButtonBox::Close);
80 Edit_chars->setValidator(new PassCharValidator(this));
82 tabCategory->setCurrentIndex(config->pwGenCategory());
83 QBitArray pwGenOptions=config->pwGenOptions();
84 //Radio_1->setChecked(pwGenOptions.at(0));
85 //Radio_2->setChecked(!pwGenOptions.at(0));
86 checkBox1->setChecked(pwGenOptions.at(1));
87 checkBox2->setChecked(pwGenOptions.at(2));
88 checkBox3->setChecked(pwGenOptions.at(3));
89 checkBox4->setChecked(pwGenOptions.at(4));
90 checkBox5->setChecked(pwGenOptions.at(5));
91 checkBox6->setChecked(pwGenOptions.at(6));
92 checkBox7->setChecked(pwGenOptions.at(7));
93 Check_CollectEntropy->setChecked(pwGenOptions.at(8));
94 Check_CollectOncePerSession->setChecked(pwGenOptions.at(9));
95 //OnRadio1StateChanged(pwGenOptions.at(0));
96 //OnRadio2StateChanged(!pwGenOptions.at(0));
97 if (pwGenOptions.size()>=14){
98 checkBoxPU->setChecked(pwGenOptions.at(10));
99 checkBoxPL->setChecked(pwGenOptions.at(11));
100 checkBoxPN->setChecked(pwGenOptions.at(12));
101 checkBoxPS->setChecked(pwGenOptions.at(13));
104 checkBoxPU->setChecked(true);
105 checkBoxPL->setChecked(true);
106 checkBoxPN->setChecked(true);
107 checkBoxPS->setChecked(false);
109 Edit_chars->setText(config->pwGenCharList());
110 Check_ExcludeLookAlike->setChecked(config->pwGenExcludeLookAlike());
111 Check_EveryGroup->setChecked(config->pwGenEveryGroup());
112 Spin_Num->setValue(config->pwGenLength());
114 resize(size() + QSize(5, 10));
115 createBanner(&BannerPixmap,getPixmap("dice"),tr("Password Generator"),width());
117 if(!config->showPasswords())
120 ButtonChangeEchoMode->setIcon(getIcon("pwd_show"));
123 CGenPwDialog::~CGenPwDialog(){
124 config->setPwGenCategory(tabCategory->currentIndex());
125 QBitArray pwGenOptions(14);
126 //pwGenOptions.setBit(0,Radio_1->isChecked());
127 pwGenOptions.setBit(1,checkBox1->isChecked());
128 pwGenOptions.setBit(2,checkBox2->isChecked());
129 pwGenOptions.setBit(3,checkBox3->isChecked());
130 pwGenOptions.setBit(4,checkBox4->isChecked());
131 pwGenOptions.setBit(5,checkBox5->isChecked());
132 pwGenOptions.setBit(6,checkBox6->isChecked());
133 pwGenOptions.setBit(7,checkBox7->isChecked());
134 pwGenOptions.setBit(8,Check_CollectEntropy->isChecked());
135 pwGenOptions.setBit(9,Check_CollectOncePerSession->isChecked());
136 pwGenOptions.setBit(10,checkBoxPU->isChecked());
137 pwGenOptions.setBit(11,checkBoxPL->isChecked());
138 pwGenOptions.setBit(12,checkBoxPN->isChecked());
139 pwGenOptions.setBit(13,checkBoxPS->isChecked());
140 config->setPwGenOptions(pwGenOptions);
141 config->setPwGenCharList(Edit_chars->text());
142 config->setPwGenExcludeLookAlike(Check_ExcludeLookAlike->isChecked());
143 config->setPwGenEveryGroup(Check_EveryGroup->isChecked());
144 config->setPwGenLength(Spin_Num->value());
147 void CGenPwDialog::paintEvent(QPaintEvent *event){
148 QDialog::paintEvent(event);
149 QPainter painter(this);
150 painter.setClipRegion(event->region());
151 painter.drawPixmap(QPoint(0,0),BannerPixmap);
154 void CGenPwDialog::OnGeneratePw()
156 if(Check_CollectEntropy->isChecked()){
157 if((Check_CollectOncePerSession->isChecked() && !EntropyCollected) || !Check_CollectOncePerSession->isChecked()){
158 CollectEntropyDlg dlg(this);
160 EntropyCollected=true;
164 int length = Spin_Num->value();
167 if (tabCategory->currentIndex() == 1)
169 unsigned int mode = 0;
170 if (checkBoxPU->isChecked())
172 if (checkBoxPL->isChecked())
174 if (checkBoxPN->isChecked())
176 if (checkBoxPS->isChecked())
179 char* buffer = new char[length+1];
180 char* hyphenated_word = new char[length*18+1];
181 gen_pron_pass(buffer, hyphenated_word, length, length, mode);
183 delete[] hyphenated_word;
187 password = generatePasswordInternal(length);
190 Edit_dest->setText(password);
193 void CGenPwDialog::estimateQuality(){
195 int index = tabCategory->currentIndex();
197 if (checkBox1->isChecked()) {
199 if (Check_ExcludeLookAlike->isChecked())
202 if (checkBox2->isChecked()) {
204 if (Check_ExcludeLookAlike->isChecked())
207 if (checkBox3->isChecked()) {
209 if (Check_ExcludeLookAlike->isChecked())
212 if (checkBox4->isChecked()) {
214 if (Check_ExcludeLookAlike->isChecked())
217 if (checkBox5->isChecked())
219 if (checkBox6->isChecked())
221 if (checkBox7->isChecked())
224 else if (index == 1) {
225 if (checkBoxPU->isChecked())
227 if (checkBoxPL->isChecked())
229 if (checkBoxPN->isChecked())
231 if (checkBoxPS->isChecked())
235 num=Edit_chars->text().length();
240 bits = log((float)num) / log(2.0f);
241 bits = bits * ((float)Spin_Num->value());
242 int bitsNum = (int) (bits+0.5);
244 Progress_Quali->setFormat(tr("%1 Bits").arg(bitsNum));
245 Progress_Quali->update();
246 Progress_Quali->setValue((bitsNum > 128) ? 128 : bitsNum);
249 void CGenPwDialog::OnAccept()
254 void CGenPwDialog::OnCancel()
259 void CGenPwDialog::OnCollectEntropyChanged(int state){
260 if(state==Qt::Checked)
261 Check_CollectOncePerSession->setDisabled(false);
263 Check_CollectOncePerSession->setDisabled(true);
267 void CGenPwDialog::SwapEchoMode(){
268 if(Edit_dest->echoMode()==QLineEdit::Normal){
269 Edit_dest->setEchoMode(QLineEdit::Password);
270 ButtonChangeEchoMode->setIcon(getIcon("pwd_hide"));
273 Edit_dest->setEchoMode(QLineEdit::Normal);
274 ButtonChangeEchoMode->setIcon(getIcon("pwd_show"));
278 void CGenPwDialog::AddToAssoctable(QList<QChar>& table,int start,int end,int& pos){
279 for (int i=start;i<=end;i++){
280 if (Check_ExcludeLookAlike->isChecked()){
291 table.append(QChar(i));
296 CGenPwDialog::PwGroup CGenPwDialog::AddToAssoctableGroup(QList<QChar>& table,int start,int end,int& pos){
299 AddToAssoctable(table,start,end,pos);
304 QString CGenPwDialog::generatePasswordInternal(int length){
305 /*-------------------------------------------------------
307 -------------------------------------------------------
311 Special Characters 33...47; 58...64; 91...96; 123...126
314 -------------------------------------------------------
318 QList<QChar> assoctable;
320 bool ensureEveryGroup = false;
321 QList<PwGroup> groupTable;
323 if (tabCategory->currentIndex() == 0) {
324 if (Check_EveryGroup->isChecked()){
325 if (checkBox1->isChecked()) groups++;
326 if (checkBox2->isChecked()) groups++;
327 if (checkBox3->isChecked()) groups++;
328 if (checkBox4->isChecked()) groups++;
329 if (checkBox5->isChecked()) groups++;
330 if (checkBox6->isChecked()) groups++;
331 if (checkBox7->isChecked()) groups++;
333 ensureEveryGroup = true;
336 if(checkBox1->isChecked()){
337 if (ensureEveryGroup) groupTable.append(AddToAssoctableGroup(assoctable,65,90,num));
338 else AddToAssoctable(assoctable,65,90,num);
340 if(checkBox2->isChecked()){
341 if (ensureEveryGroup) groupTable.append(AddToAssoctableGroup(assoctable,97,122,num));
342 else AddToAssoctable(assoctable,97,122,num);
344 if(checkBox3->isChecked()){
345 if (ensureEveryGroup) groupTable.append(AddToAssoctableGroup(assoctable,48,57,num));
346 else AddToAssoctable(assoctable,48,57,num);
348 if(checkBox4->isChecked()){
351 AddToAssoctable(assoctable,33,44,num);
352 AddToAssoctable(assoctable,46,47,num);
353 AddToAssoctable(assoctable,58,64,num);
354 AddToAssoctable(assoctable,91,94,num);
355 AddToAssoctable(assoctable,96,96,num);
356 AddToAssoctable(assoctable,123,126,num);
357 if (ensureEveryGroup){
359 groupTable.append(group);
363 if(checkBox5->isChecked()){
364 if (ensureEveryGroup) groupTable.append(AddToAssoctableGroup(assoctable,32,32,num));
365 else AddToAssoctable(assoctable,32,32,num);
367 if(checkBox6->isChecked()){
368 if (ensureEveryGroup) groupTable.append(AddToAssoctableGroup(assoctable,45,45,num));
369 else AddToAssoctable(assoctable,45,45,num);
371 if(checkBox7->isChecked()){
372 if (ensureEveryGroup) groupTable.append(AddToAssoctableGroup(assoctable,95,95,num));
373 else AddToAssoctable(assoctable,95,95,num);
377 QString str=Edit_chars->text();
378 for(int i=0;i<str.length();i++){
379 assoctable.append(str[i]);
384 QString password(length, '\0');
386 if (ensureEveryGroup){
388 for (int i=0; i<length; i++)
391 for (int i=0; i<groups; i++){
392 int posIndex = randintRange(0, charPos.count()-1);
393 int pos = charPos[posIndex];
394 charPos.removeAt(posIndex);
395 password[pos] = assoctable[randintRange(groupTable[i].start, groupTable[i].end)];
398 for (int i=groups; i<length; i++){
399 int posIndex = randintRange(0, charPos.count()-1);
400 int pos = charPos[posIndex];
401 charPos.removeAt(posIndex);
402 password[pos] = assoctable[randint(num)];
406 for (int i=0; i<length; i++)
407 password[i] = assoctable[randint(num)];
413 void CGenPwDialog::setGenerateEnabled(){
415 int index = tabCategory->currentIndex();
418 enable = checkBox1->isChecked() || checkBox2->isChecked() || checkBox3->isChecked() ||
419 checkBox4->isChecked() || checkBox5->isChecked() || checkBox6->isChecked() ||
420 checkBox7->isChecked();
422 else if (index == 1) {
423 enable = checkBoxPU->isChecked() || checkBoxPL->isChecked() ||
424 checkBoxPN->isChecked() || checkBoxPS->isChecked();
427 enable = !Edit_chars->text().isEmpty();
430 ButtonGenerate->setEnabled(enable);
433 void CGenPwDialog::setAcceptEnabled(const QString& str){
434 AcceptButton->setEnabled(!str.isEmpty());
437 PassCharValidator::PassCharValidator(QObject* parent) : QValidator(parent) {
440 QValidator::State PassCharValidator::validate(QString& input, int& pos) const {
444 for (int i=0; i<input.size(); i++) {
445 if (chars.contains(input[i]))
446 return QValidator::Invalid;
448 chars.insert(input[i]);
451 return QValidator::Acceptable;