25 #include <sys/resource.h>
27 #include <QtCore/QCoreApplication>
28 #include <QtCore/QRegExp>
29 #include <QtCore/QSize>
30 #include <QtCore/QString>
31 #include <QtGui/QCheckBox>
32 #include <QtGui/QLabel>
33 #include <QtGui/QLayout>
34 #include <QtGui/QKeyEvent>
35 #include <QtGui/QProgressBar>
36 #include <QtGui/QWidget>
55 static Q3PtrDict<int>*
d_ptr = 0;
63 d_ptr =
new Q3PtrDict<int>;
64 d_ptr->setAutoDelete(
true);
67 int* ret =
d_ptr->find( (
void*) e );
70 d_ptr->replace( (
void*) e, ret );
77 d_ptr->remove( (
void*) e );
82 class K3PasswordDialog::K3PasswordDialogPrivate
85 K3PasswordDialogPrivate()
97 QProgressBar* m_strengthBar;
109 if (val ==
"ThreeStars")
111 else if (val ==
"NoEcho")
119 :
QLineEdit(parent), m_EchoMode(echoMode)
126 , m_EchoMode( echoMode ==
QLineEdit::NoEcho ? NoEcho : OneStar )
131 void K3PasswordEdit::init()
133 setEchoMode(QLineEdit::Password);
134 setAcceptDrops(
false);
137 m_Password =
new char[
PassLen];
138 m_Password[0] =
'\000';
144 memset(m_Password, 0,
PassLen *
sizeof(
char));
156 const QByteArray localTxt = txt.toLocal8Bit();
157 const unsigned int lim = localTxt.length();
159 for(
unsigned int i=0; i < lim; ++i)
161 const unsigned char ke = localTxt[i];
162 if (m_Length < m_MaxLength)
164 m_Password[m_Length] = ke;
165 m_Password[++m_Length] =
'\000';
174 memset(m_Password, 0,
PassLen *
sizeof(
char));
181 setUpdatesEnabled(
false);
182 QLineEdit::focusInEvent(e);
183 setUpdatesEnabled(
true);
196 case Qt::Key_Backspace:
199 if (e->modifiers() & (Qt::ControlModifier | Qt::AltModifier))
202 m_Password[--m_Length] =
'\000';
207 const unsigned char ke = e->text().toLocal8Bit()[0];
219 case QEvent::MouseButtonPress:
220 case QEvent::MouseButtonRelease:
221 case QEvent::MouseButtonDblClick:
222 case QEvent::MouseMove:
224 case QEvent::InputMethod:
226 QInputMethodEvent*
const ie = (QInputMethodEvent*) e;
227 if (!ie->commitString().isNull())
228 insert( ie->commitString() );
232 case QEvent::ShortcutOverride:
234 QKeyEvent*
const k = (QKeyEvent*) e;
237 if (k->modifiers() & Qt::ControlModifier) {
239 m_Password[m_Length] =
'\000';
250 return QLineEdit::event(e);
253 void K3PasswordEdit::showPass()
257 switch (m_EchoMode) {
259 tmp.fill(
'*', m_Length);
263 tmp.fill(
'*', m_Length*3);
275 if (newLength < 0) newLength = 0;
278 while (m_Length > newLength) {
279 m_Password[m_Length] =
'\000';
296 , m_Keep(enableKeep? 1 : 0), m_Type(type), d(new K3PasswordDialogPrivate)
300 setDefaultButton(
Ok );
301 d->iconName =
"password";
308 , m_Keep(enableKeep? 1 : 0), m_Type(type), d(new K3PasswordDialogPrivate)
312 setDefaultButton(
Ok );
313 if ( icon.trimmed().isEmpty() )
314 d->iconName =
"password";
321 void K3PasswordDialog::init()
326 if (m_Keep && cg.readEntry(
"Keep",
false))
330 setMainWidget(m_pMain);
331 m_pGrid =
new QGridLayout(m_pMain);
332 m_pGrid->setMargin(0);
333 m_pGrid->setSpacing(0);
339 lbl =
new QLabel(m_pMain);
341 lbl->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
342 lbl->setFixedSize(lbl->sizeHint());
343 m_pGrid->addWidget(lbl, 0, 0, Qt::AlignCenter);
346 m_pHelpLbl =
new QLabel(m_pMain);
347 m_pHelpLbl->setAlignment(Qt::AlignLeft|Qt::AlignVCenter);
348 m_pHelpLbl->setWordWrap(
true);
349 m_pGrid->addWidget(m_pHelpLbl, 0, 2, Qt::AlignLeft);
350 m_pGrid->setRowStretch(1, 12);
353 m_pGrid->setRowStretch(6, 12);
356 lbl =
new QLabel(m_pMain);
357 lbl->setAlignment(Qt::AlignLeft|Qt::AlignVCenter);
358 lbl->setText(
i18n(
"&Password:"));
359 lbl->setFixedSize(lbl->sizeHint());
360 m_pGrid->addWidget(lbl, 7, 0, Qt::AlignLeft);
362 QHBoxLayout *h_lay =
new QHBoxLayout();
363 m_pGrid->addLayout(h_lay, 7, 2);
366 lbl->setBuddy(m_pEdit);
367 QSize size = m_pEdit->sizeHint();
368 m_pEdit->setFixedHeight(size.height());
369 m_pEdit->setMinimumWidth(size.width());
370 h_lay->addWidget(m_pEdit);
374 if ((m_Type ==
Password) && m_Keep) {
375 m_pGrid->setRowStretch(8, 12);
376 QCheckBox*
const cb =
new QCheckBox(
i18n(
"&Keep password"), m_pMain);
377 cb->setFixedSize(cb->sizeHint());
379 cb->setChecked(
true);
382 connect(cb, SIGNAL(toggled(
bool)), SLOT(
slotKeep(
bool)));
383 m_pGrid->addWidget(cb, 9, 2, Qt::AlignLeft|Qt::AlignVCenter);
385 lbl =
new QLabel(m_pMain);
386 lbl->setAlignment(Qt::AlignLeft|Qt::AlignVCenter);
387 lbl->setText(
i18n(
"&Verify:"));
388 lbl->setFixedSize(lbl->sizeHint());
389 m_pGrid->addWidget(lbl, 9, 0, Qt::AlignLeft);
391 h_lay =
new QHBoxLayout();
392 m_pGrid->addLayout(h_lay, 9, 2);
394 lbl->setBuddy(m_pEdit2);
395 size = m_pEdit2->sizeHint();
396 m_pEdit2->setFixedHeight(size.height());
397 m_pEdit2->setMinimumWidth(size.width());
398 h_lay->addWidget(m_pEdit2);
401 m_pGrid->setRowStretch(10, 12);
403 KHBox*
const strengthBox =
new KHBox(m_pMain);
405 m_pGrid->addWidget(strengthBox, 11, 0, 1, 3);
406 QLabel*
const passStrengthLabel =
new QLabel(strengthBox);
407 passStrengthLabel->setAlignment(Qt::AlignLeft|Qt::AlignVCenter);
408 passStrengthLabel->setText(
i18n(
"Password strength meter:"));
409 d->m_strengthBar =
new QProgressBar(strengthBox);
410 d->m_strengthBar->setObjectName(
"PasswordStrengthMeter");
411 d->m_strengthBar->setRange(0, 100);
412 d->m_strengthBar->setTextVisible(
false);
414 const QString strengthBarWhatsThis(
i18n(
"The password strength meter gives an indication of the security "
415 "of the password you have entered. To improve the strength of "
416 "the password, try:\n"
417 " - using a longer password;\n"
418 " - using a mixture of upper- and lower-case letters;\n"
419 " - using numbers or symbols, such as #, as well as letters."));
420 passStrengthLabel->setWhatsThis(strengthBarWhatsThis);
421 d->m_strengthBar->setWhatsThis(strengthBarWhatsThis);
424 m_pGrid->setRowStretch(12, 12);
426 d->m_MatchLabel =
new QLabel(m_pMain);
427 d->m_MatchLabel->setAlignment(Qt::AlignLeft|Qt::AlignVCenter);
428 d->m_MatchLabel->setWordWrap(
true);
429 m_pGrid->addWidget(d->m_MatchLabel, 13, 0, 1, 3);
430 d->m_MatchLabel->setText(
i18n(
"Passwords do not match"));
433 connect( m_pEdit, SIGNAL(textChanged(
QString)), SLOT(enableOkBtn()) );
434 connect( m_pEdit2, SIGNAL(textChanged(
QString)), SLOT(enableOkBtn()) );
455 m_pHelpLbl->setText(prompt);
456 m_pHelpLbl->setFixedSize(275, m_pHelpLbl->heightForWidth(275));
463 return m_pHelpLbl->text();
473 lbl->setAlignment(Qt::AlignLeft|Qt::AlignTop);
474 lbl->setFixedSize(lbl->sizeHint());
475 m_pGrid->addWidget(lbl, m_Row+2, 0, Qt::AlignLeft);
477 lbl =
new QLabel(value, m_pMain);
478 lbl->setAlignment(Qt::AlignTop);
479 lbl->setWordWrap(
true);
480 lbl->setFixedSize(275, lbl->heightForWidth(275));
481 m_pGrid->addWidget(lbl, m_Row+2, 2, Qt::AlignLeft);
486 void K3PasswordDialog::erase()
500 "passwords. Please try again."));
504 if (d->m_strengthBar && d->m_strengthBar->value() < d->passwordStrengthWarningLevel) {
506 i18n(
"The password you have entered has a low strength. "
507 "To improve the strength of "
508 "the password, try:\n"
509 " - using a longer password;\n"
510 " - using a mixture of upper- and lower-case letters;\n"
511 " - using numbers or symbols as well as letters.\n"
513 "Would you like to use this password anyway?"),
514 i18n(
"Low Password Strength"));
540 const QString &prompt,
bool *keep)
542 const bool enableKeep = (keep && *
keep);
544 dlg->setWindowTitle(caption);
546 const int ret = dlg->exec();
547 if (ret == Accepted) {
559 int res = K3PasswordDialog::Rejected;
561 bool boolkeep = *
keep;
562 res =
getPassword(parent, password,
i18n(
"Password Input"), prompt, &boolkeep);
576 dlg->setWindowTitle(caption);
578 const int ret = dlg->exec();
595 rlim.rlim_cur = rlim.rlim_max = 0;
596 setrlimit(RLIMIT_CORE, &rlim);
600 void K3PasswordDialog::enableOkBtn()
604 && (d->allowEmptyPasswords || m_pEdit->
password()[0]);
610 if ((
int) pass.length() < minPasswordLength) {
611 enableButtonOk(
false);
613 enableButtonOk( match );
616 if ( match && d->allowEmptyPasswords && m_pEdit->
password()[0] == 0 ) {
617 d->m_MatchLabel->setText(
i18n(
"Password is empty") );
619 if ((
int) pass.length() < minPasswordLength) {
620 d->m_MatchLabel->setText(
i18np(
"Password must be at least 1 character long",
"Password must be at least %1 characters long", minPasswordLength));
622 d->m_MatchLabel->setText( match?
i18n(
"Passwords match")
623 :
i18n(
"Passwords do not match") );
633 const double lengthFactor = d->reasonablePasswordLength / 8.0;
636 int pwlength = (int) (pass.length() / lengthFactor);
637 if (pwlength > 5) pwlength = 5;
639 const QRegExp numRxp(
"[0-9]", Qt::CaseSensitive, QRegExp::RegExp);
640 int numeric = (int) (pass.count(numRxp) / lengthFactor);
641 if (numeric > 3) numeric = 3;
643 const QRegExp symbRxp(
"\\W", Qt::CaseInsensitive, QRegExp::RegExp);
644 int numsymbols = (int) (pass.count(symbRxp) / lengthFactor);
645 if (numsymbols > 3) numsymbols = 3;
647 const QRegExp upperRxp(
"[A-Z]", Qt::CaseSensitive, QRegExp::RegExp);
648 int upper = (int) (pass.count(upperRxp) / lengthFactor);
649 if (upper > 3) upper = 3;
651 int pwstrength=((pwlength*10)-20) + (numeric*10) + (numsymbols*15) + (upper*10);
653 if ( pwstrength < 0 ) {
657 if ( pwstrength > 100 ) {
660 d->m_strengthBar->setValue(pwstrength);
667 d->allowEmptyPasswords = allowed;
673 return d->allowEmptyPasswords;
677 d->minimumPasswordLength = minLength;
682 return d->minimumPasswordLength;
687 if (maxLength < 0) maxLength = 0;
690 d->maximumPasswordLength = maxLength;
698 return d->maximumPasswordLength;
705 if (reasonableLength < 1) reasonableLength = 1;
708 d->reasonablePasswordLength = reasonableLength;
713 return d->reasonablePasswordLength;
718 if (warningLevel < 0) warningLevel = 0;
719 if (warningLevel > 99) warningLevel = 99;
720 d->passwordStrengthWarningLevel = warningLevel;
724 return d->passwordStrengthWarningLevel;
737 #include "k3passworddialog.moc"
int passwordStrengthWarningLevel() const
Password strength level below which a warning is given.
QString i18n(const char *text)
int maximumPasswordLength() const
Maximum acceptable password length.
virtual bool event(QEvent *e)
static KIconLoader * global()
A safe password input widget.
QString i18np(const char *sing, const char *plur, const A1 &a1)
static int getNewPassword(QWidget *parent, QByteArray &password, const QString &caption, const QString &prompt)
Pops up the dialog, asks the user for a password and returns it.
QString prompt() const
Returns the password prompt.
virtual void keyPressEvent(QKeyEvent *)
KSharedConfigPtr config()
void clearPassword()
Clears the password input field.
virtual ~K3PasswordDialog()
Destructs the password dialog.
void setAllowEmptyPasswords(bool allowed)
Allow empty passwords? - Default: false.
virtual bool checkPassword(const char *password)
Virtual function that can be overridden to provide password checking in derived classes.
static void sorry(QWidget *parent, const QString &text, const QString &caption=QString(), Options options=Notify)
virtual void focusInEvent(QFocusEvent *e)
static void cleanup_d_ptr()
static void disableCoreDumps()
Static helper function that disables core dumps.
void setReasonablePasswordLength(int reasonableLength)
Password length that is expected to be reasonably safe.
Types
This enum distinguishes the two operation modes of this dialog:
void setMaxPasswordLength(int newLength)
Set the current maximum password length.
~K3PasswordEdit()
Destructs the widget.
K3PasswordDialog(Types type, bool enableKeep, ButtonCodes extraBttn, QWidget *parent=0)
Constructs a password dialog.
The user is asked to enter a password and to confirm it a second time.
void erase()
Erases the current password.
static void delete_d(const K3PasswordEdit *const e)
void setPrompt(const QString &prompt)
Sets the password prompt.
bool keep() const
Returns true if the user wants to keep the password.
const char * password() const
Returns the password.
const char * password() const
Returns the password entered.
virtual void insert(const QString &)
Reimplementation.
static int getPassword(QWidget *parent, QByteArray &password, const QString &caption, const QString &prompt, bool *keep=0L)
Pops up the dialog, asks the user for a password, and returns it.
void addLine(const QString &key, const QString &value)
Adds a line of information to the dialog.
void setMinimumPasswordLength(int minLength)
Minimum acceptable password length.
void setSpacing(int space)
static Q3PtrDict< int > * d_ptr
int reasonablePasswordLength() const
Password length that is expected to be reasonably safe.
static int * ourMaxLength(const K3PasswordEdit *const e)
K3PasswordEdit(QWidget *parent=0)
Constructs a password input widget using the user's global "echo mode" setting.
void setMaximumPasswordLength(int maxLength)
Maximum acceptable password length.
bool allowEmptyPasswords() const
Allow empty passwords?
The user is asked to enter a password.
int minimumPasswordLength() const
Minimum acceptable password length.
T readEntry(const QString &key, const T &aDefault) const
void setPasswordStrengthWarningLevel(int warningLevel)
Set the password strength level below which a warning is given Value is in the range 0 to 99...
static int warningContinueCancel(QWidget *parent, const QString &text, const QString &caption=QString(), const KGuiItem &buttonContinue=KStandardGuiItem::cont(), const KGuiItem &buttonCancel=KStandardGuiItem::cancel(), const QString &dontAskAgainName=QString(), Options options=Notify)
int maxPasswordLength() const
Returns the current maximum password length.