00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <unistd.h>
00022
00023 #include <qwidget.h>
00024 #include <qlineedit.h>
00025 #include <qlabel.h>
00026 #include <qlayout.h>
00027 #include <qsize.h>
00028 #include <qevent.h>
00029 #include <qkeycode.h>
00030 #include <qcheckbox.h>
00031 #include <qregexp.h>
00032 #include <qhbox.h>
00033 #include <qwhatsthis.h>
00034 #include <qptrdict.h>
00035
00036 #include <kglobal.h>
00037 #include <kdebug.h>
00038 #include <kapplication.h>
00039 #include <klocale.h>
00040 #include <kiconloader.h>
00041 #include <kmessagebox.h>
00042 #include <kaboutdialog.h>
00043 #include <kconfig.h>
00044 #include <kstandarddirs.h>
00045 #include <kprogress.h>
00046
00047 #include <sys/time.h>
00048 #include <sys/resource.h>
00049
00050 #include "kpassdlg.h"
00051
00052
00053
00054
00055
00056
00057
00058 static QPtrDict<int>* d_ptr = 0;
00059
00060 static void cleanup_d_ptr() {
00061 delete d_ptr;
00062 }
00063
00064 static int * ourMaxLength( const KPasswordEdit* const e ) {
00065 if ( !d_ptr ) {
00066 d_ptr = new QPtrDict<int>;
00067 d_ptr->setAutoDelete(true);
00068 qAddPostRoutine( cleanup_d_ptr );
00069 }
00070 int* ret = d_ptr->find( (void*) e );
00071 if ( ! ret ) {
00072 ret = new int;
00073 d_ptr->replace( (void*) e, ret );
00074 }
00075 return ret;
00076 }
00077
00078 static void delete_d( const KPasswordEdit* const e ) {
00079 if ( d_ptr )
00080 d_ptr->remove( (void*) e );
00081 }
00082
00083 const int KPasswordEdit::PassLen = 200;
00084
00085 class KPasswordDialog::KPasswordDialogPrivate
00086 {
00087 public:
00088 KPasswordDialogPrivate()
00089 : m_MatchLabel( 0 ), iconName( 0 ), allowEmptyPasswords( false ),
00090 minimumPasswordLength(0), maximumPasswordLength(KPasswordEdit::PassLen - 1),
00091 passwordStrengthWarningLevel(1), m_strengthBar(0),
00092 reasonablePasswordLength(8)
00093 {}
00094 QLabel *m_MatchLabel;
00095 QString iconName;
00096 bool allowEmptyPasswords;
00097 int minimumPasswordLength;
00098 int maximumPasswordLength;
00099 int passwordStrengthWarningLevel;
00100 KProgress* m_strengthBar;
00101 int reasonablePasswordLength;
00102 };
00103
00104
00105 KPasswordEdit::KPasswordEdit(QWidget *parent, const char *name)
00106 : QLineEdit(parent, name)
00107 {
00108 init();
00109
00110 KConfig* const cfg = KGlobal::config();
00111 KConfigGroupSaver saver(cfg, "Passwords");
00112
00113 const QString val = cfg->readEntry("EchoMode", "OneStar");
00114 if (val == "ThreeStars")
00115 m_EchoMode = ThreeStars;
00116 else if (val == "NoEcho")
00117 m_EchoMode = NoEcho;
00118 else
00119 m_EchoMode = OneStar;
00120
00121 }
00122
00123 KPasswordEdit::KPasswordEdit(QWidget *parent, const char *name, int echoMode)
00124 : QLineEdit(parent, name), m_EchoMode(echoMode)
00125 {
00126 init();
00127 }
00128
00129 KPasswordEdit::KPasswordEdit(EchoModes echoMode, QWidget *parent, const char *name)
00130 : QLineEdit(parent, name), m_EchoMode(echoMode)
00131 {
00132 init();
00133 }
00134
00135 KPasswordEdit::KPasswordEdit(EchoMode echoMode, QWidget *parent, const char *name)
00136 : QLineEdit(parent, name)
00137 , m_EchoMode( echoMode == QLineEdit::NoEcho ? NoEcho : OneStar )
00138 {
00139 init();
00140 }
00141
00142 void KPasswordEdit::init()
00143 {
00144 setEchoMode(QLineEdit::Password);
00145 setAcceptDrops(false);
00146 int* t = ourMaxLength(this);
00147 *t = (PassLen - 1);
00148 m_Password = new char[PassLen];
00149 m_Password[0] = '\000';
00150 m_Length = 0;
00151 }
00152
00153 KPasswordEdit::~KPasswordEdit()
00154 {
00155 memset(m_Password, 0, PassLen * sizeof(char));
00156 delete[] m_Password;
00157 delete_d(this);
00158 }
00159
00160 void KPasswordEdit::insert(const QString &txt)
00161 {
00162 const QCString localTxt = txt.local8Bit();
00163 const unsigned int lim = localTxt.length();
00164 const int m_MaxLength = maxPasswordLength();
00165 for(unsigned int i=0; i < lim; ++i)
00166 {
00167 const unsigned char ke = localTxt[i];
00168 if (m_Length < m_MaxLength)
00169 {
00170 m_Password[m_Length] = ke;
00171 m_Password[++m_Length] = '\000';
00172 }
00173 }
00174 showPass();
00175 }
00176
00177 void KPasswordEdit::erase()
00178 {
00179 m_Length = 0;
00180 memset(m_Password, 0, PassLen * sizeof(char));
00181 setText("");
00182 }
00183
00184 void KPasswordEdit::focusInEvent(QFocusEvent *e)
00185 {
00186 const QString txt = text();
00187 setUpdatesEnabled(false);
00188 QLineEdit::focusInEvent(e);
00189 setUpdatesEnabled(true);
00190 setText(txt);
00191 }
00192
00193
00194 void KPasswordEdit::keyPressEvent(QKeyEvent *e)
00195 {
00196 switch (e->key()) {
00197 case Key_Return:
00198 case Key_Enter:
00199 case Key_Escape:
00200 e->ignore();
00201 break;
00202 case Key_Backspace:
00203 case Key_Delete:
00204 case 0x7f:
00205 if (e->state() & (ControlButton | AltButton))
00206 e->ignore();
00207 else if (m_Length) {
00208 m_Password[--m_Length] = '\000';
00209 showPass();
00210 }
00211 break;
00212 default:
00213 const unsigned char ke = e->text().local8Bit()[0];
00214 if (ke >= 32) {
00215 insert(e->text());
00216 } else
00217 e->ignore();
00218 break;
00219 }
00220 }
00221
00222 bool KPasswordEdit::event(QEvent *e) {
00223 switch(e->type()) {
00224
00225 case QEvent::MouseButtonPress:
00226 case QEvent::MouseButtonRelease:
00227 case QEvent::MouseButtonDblClick:
00228 case QEvent::MouseMove:
00229 case QEvent::IMStart:
00230 case QEvent::IMCompose:
00231 return true;
00232
00233 case QEvent::IMEnd:
00234 {
00235 QIMEvent* const ie = (QIMEvent*) e;
00236 insert( ie->text() );
00237 return true;
00238 }
00239
00240 case QEvent::AccelOverride:
00241 {
00242 QKeyEvent* const k = (QKeyEvent*) e;
00243 switch (k->key()) {
00244 case Key_U:
00245 if (k->state() & ControlButton) {
00246 m_Length = 0;
00247 m_Password[m_Length] = '\000';
00248 showPass();
00249 }
00250 }
00251 return true;
00252 }
00253
00254 default:
00255
00256 break;
00257 }
00258 return QLineEdit::event(e);
00259 }
00260
00261 void KPasswordEdit::showPass()
00262 {
00263 QString tmp;
00264
00265 switch (m_EchoMode) {
00266 case OneStar:
00267 tmp.fill('*', m_Length);
00268 setText(tmp);
00269 break;
00270 case ThreeStars:
00271 tmp.fill('*', m_Length*3);
00272 setText(tmp);
00273 break;
00274 case NoEcho: default:
00275 emit textChanged(QString::null);
00276 break;
00277 }
00278 }
00279
00280 void KPasswordEdit::setMaxPasswordLength(int newLength)
00281 {
00282 if (newLength >= PassLen) newLength = PassLen - 1;
00283 if (newLength < 0) newLength = 0;
00284 int* t = ourMaxLength(this);
00285 *t = newLength;
00286 while (m_Length > newLength) {
00287 m_Password[m_Length] = '\000';
00288 --m_Length;
00289 }
00290 showPass();
00291 }
00292
00293 int KPasswordEdit::maxPasswordLength() const
00294 {
00295 return *(ourMaxLength(this));
00296 }
00297
00298
00299
00300
00301 KPasswordDialog::KPasswordDialog(Types type, bool enableKeep, int extraBttn,
00302 QWidget *parent, const char *name)
00303 : KDialogBase(parent, name, true, "", Ok|Cancel|extraBttn,
00304 Ok, true), m_Keep(enableKeep? 1 : 0), m_Type(type), d(new KPasswordDialogPrivate)
00305 {
00306 d->iconName = "password";
00307 init();
00308 }
00309
00310 KPasswordDialog::KPasswordDialog(Types type, bool enableKeep, int extraBttn, const QString& icon,
00311 QWidget *parent, const char *name )
00312 : KDialogBase(parent, name, true, "", Ok|Cancel|extraBttn,
00313 Ok, true), m_Keep(enableKeep? 1 : 0), m_Type(type), d(new KPasswordDialogPrivate)
00314 {
00315 if ( icon.stripWhiteSpace().isEmpty() )
00316 d->iconName = "password";
00317 else
00318 d->iconName = icon;
00319 init();
00320 }
00321
00322 KPasswordDialog::KPasswordDialog(int type, QString prompt, bool enableKeep,
00323 int extraBttn)
00324 : KDialogBase(0L, "Password Dialog", true, "", Ok|Cancel|extraBttn,
00325 Ok, true), m_Keep(enableKeep? 1 : 0), m_Type(type), d(new KPasswordDialogPrivate)
00326 {
00327 d->iconName = "password";
00328 init();
00329 setPrompt(prompt);
00330 }
00331
00332 void KPasswordDialog::init()
00333 {
00334 m_Row = 0;
00335
00336 KConfig* const cfg = KGlobal::config();
00337 const KConfigGroupSaver saver(cfg, "Passwords");
00338 if (m_Keep && cfg->readBoolEntry("Keep", false))
00339 ++m_Keep;
00340
00341 m_pMain = new QWidget(this);
00342 setMainWidget(m_pMain);
00343 m_pGrid = new QGridLayout(m_pMain, 10, 3, 0, 0);
00344 m_pGrid->addColSpacing(1, 10);
00345
00346
00347 QLabel *lbl;
00348 const QPixmap pix( KGlobal::iconLoader()->loadIcon( d->iconName, KIcon::NoGroup, KIcon::SizeHuge, 0, 0, true));
00349 if (!pix.isNull()) {
00350 lbl = new QLabel(m_pMain);
00351 lbl->setPixmap(pix);
00352 lbl->setAlignment(AlignHCenter|AlignVCenter);
00353 lbl->setFixedSize(lbl->sizeHint());
00354 m_pGrid->addWidget(lbl, 0, 0, AlignCenter);
00355 }
00356
00357 m_pHelpLbl = new QLabel(m_pMain);
00358 m_pHelpLbl->setAlignment(AlignLeft|AlignVCenter|WordBreak);
00359 m_pGrid->addWidget(m_pHelpLbl, 0, 2, AlignLeft);
00360 m_pGrid->addRowSpacing(1, 10);
00361 m_pGrid->setRowStretch(1, 12);
00362
00363
00364 m_pGrid->addRowSpacing(6, 5);
00365 m_pGrid->setRowStretch(6, 12);
00366
00367
00368 lbl = new QLabel(m_pMain);
00369 lbl->setAlignment(AlignLeft|AlignVCenter);
00370 lbl->setText(i18n("&Password:"));
00371 lbl->setFixedSize(lbl->sizeHint());
00372 m_pGrid->addWidget(lbl, 7, 0, AlignLeft);
00373
00374 QHBoxLayout *h_lay = new QHBoxLayout();
00375 m_pGrid->addLayout(h_lay, 7, 2);
00376 m_pEdit = new KPasswordEdit(m_pMain);
00377 m_pEdit2 = 0;
00378 lbl->setBuddy(m_pEdit);
00379 QSize size = m_pEdit->sizeHint();
00380 m_pEdit->setFixedHeight(size.height());
00381 m_pEdit->setMinimumWidth(size.width());
00382 h_lay->addWidget(m_pEdit);
00383
00384
00385
00386 if ((m_Type == Password) && m_Keep) {
00387 m_pGrid->addRowSpacing(8, 10);
00388 m_pGrid->setRowStretch(8, 12);
00389 QCheckBox* const cb = new QCheckBox(i18n("&Keep password"), m_pMain);
00390 cb->setFixedSize(cb->sizeHint());
00391 if (m_Keep > 1)
00392 cb->setChecked(true);
00393 else
00394 m_Keep = 0;
00395 connect(cb, SIGNAL(toggled(bool)), SLOT(slotKeep(bool)));
00396 m_pGrid->addWidget(cb, 9, 2, AlignLeft|AlignVCenter);
00397 } else if (m_Type == NewPassword) {
00398 m_pGrid->addRowSpacing(8, 10);
00399 lbl = new QLabel(m_pMain);
00400 lbl->setAlignment(AlignLeft|AlignVCenter);
00401 lbl->setText(i18n("&Verify:"));
00402 lbl->setFixedSize(lbl->sizeHint());
00403 m_pGrid->addWidget(lbl, 9, 0, AlignLeft);
00404
00405 h_lay = new QHBoxLayout();
00406 m_pGrid->addLayout(h_lay, 9, 2);
00407 m_pEdit2 = new KPasswordEdit(m_pMain);
00408 lbl->setBuddy(m_pEdit2);
00409 size = m_pEdit2->sizeHint();
00410 m_pEdit2->setFixedHeight(size.height());
00411 m_pEdit2->setMinimumWidth(size.width());
00412 h_lay->addWidget(m_pEdit2);
00413
00414
00415 m_pGrid->addRowSpacing(10, 10);
00416 m_pGrid->setRowStretch(10, 12);
00417
00418 QHBox* const strengthBox = new QHBox(m_pMain);
00419 strengthBox->setSpacing(10);
00420 m_pGrid->addMultiCellWidget(strengthBox, 11, 11, 0, 2);
00421 QLabel* const passStrengthLabel = new QLabel(strengthBox);
00422 passStrengthLabel->setAlignment(AlignLeft|AlignVCenter);
00423 passStrengthLabel->setText(i18n("Password strength meter:"));
00424 d->m_strengthBar = new KProgress(100, strengthBox, "PasswordStrengthMeter");
00425 d->m_strengthBar->setPercentageVisible(false);
00426
00427 const QString strengthBarWhatsThis(i18n("The password strength meter gives an indication of the security "
00428 "of the password you have entered. To improve the strength of "
00429 "the password, try:\n"
00430 " - using a longer password;\n"
00431 " - using a mixture of upper- and lower-case letters;\n"
00432 " - using numbers or symbols, such as #, as well as letters."));
00433 QWhatsThis::add(passStrengthLabel, strengthBarWhatsThis);
00434 QWhatsThis::add(d->m_strengthBar, strengthBarWhatsThis);
00435
00436
00437 m_pGrid->addRowSpacing(12, 10);
00438 m_pGrid->setRowStretch(12, 12);
00439
00440 d->m_MatchLabel = new QLabel(m_pMain);
00441 d->m_MatchLabel->setAlignment(AlignLeft|AlignVCenter|WordBreak);
00442 m_pGrid->addMultiCellWidget(d->m_MatchLabel, 13, 13, 0, 2);
00443 d->m_MatchLabel->setText(i18n("Passwords do not match"));
00444
00445
00446 connect( m_pEdit, SIGNAL(textChanged(const QString&)), SLOT(enableOkBtn()) );
00447 connect( m_pEdit2, SIGNAL(textChanged(const QString&)), SLOT(enableOkBtn()) );
00448 enableOkBtn();
00449 }
00450
00451 erase();
00452 }
00453
00454
00455 KPasswordDialog::~KPasswordDialog()
00456 {
00457 delete d;
00458 }
00459
00460
00461 void KPasswordDialog::clearPassword()
00462 {
00463 m_pEdit->erase();
00464 }
00465
00466
00467 void KPasswordDialog::setPrompt(QString prompt)
00468 {
00469 m_pHelpLbl->setText(prompt);
00470 m_pHelpLbl->setFixedSize(275, m_pHelpLbl->heightForWidth(275));
00471 }
00472
00473
00474 QString KPasswordDialog::prompt() const
00475
00476 {
00477 return m_pHelpLbl->text();
00478 }
00479
00480
00481
00482 void KPasswordDialog::addLine(QString key, QString value)
00483 {
00484 if (m_Row > 3)
00485 return;
00486
00487 QLabel *lbl = new QLabel(key, m_pMain);
00488 lbl->setAlignment(AlignLeft|AlignTop);
00489 lbl->setFixedSize(lbl->sizeHint());
00490 m_pGrid->addWidget(lbl, m_Row+2, 0, AlignLeft);
00491
00492 lbl = new QLabel(value, m_pMain);
00493 lbl->setAlignment(AlignTop|WordBreak);
00494 lbl->setFixedSize(275, lbl->heightForWidth(275));
00495 m_pGrid->addWidget(lbl, m_Row+2, 2, AlignLeft);
00496 ++m_Row;
00497 }
00498
00499
00500 void KPasswordDialog::erase()
00501 {
00502 m_pEdit->erase();
00503 m_pEdit->setFocus();
00504 if (m_Type == NewPassword)
00505 m_pEdit2->erase();
00506 }
00507
00508
00509 void KPasswordDialog::slotOk()
00510 {
00511 if (m_Type == NewPassword) {
00512 if (strcmp(m_pEdit->password(), m_pEdit2->password())) {
00513 KMessageBox::sorry(this, i18n("You entered two different "
00514 "passwords. Please try again."));
00515 erase();
00516 return;
00517 }
00518 if (d->m_strengthBar && d->m_strengthBar->progress() < d->passwordStrengthWarningLevel) {
00519 int retVal = KMessageBox::warningYesNo(this,
00520 i18n( "The password you have entered has a low strength. "
00521 "To improve the strength of "
00522 "the password, try:\n"
00523 " - using a longer password;\n"
00524 " - using a mixture of upper- and lower-case letters;\n"
00525 " - using numbers or symbols as well as letters.\n"
00526 "\n"
00527 "Would you like to use this password anyway?"),
00528 i18n("Low Password Strength"));
00529 if (retVal == KMessageBox::No) return;
00530 }
00531 }
00532 if (!checkPassword(m_pEdit->password())) {
00533 erase();
00534 return;
00535 }
00536 accept();
00537 }
00538
00539
00540 void KPasswordDialog::slotCancel()
00541 {
00542 reject();
00543 }
00544
00545
00546 void KPasswordDialog::slotKeep(bool keep)
00547 {
00548 m_Keep = keep;
00549 }
00550
00551
00552
00553 int KPasswordDialog::getPassword(QCString &password, QString prompt,
00554 int *keep)
00555 {
00556 const bool enableKeep = (keep && *keep);
00557 KPasswordDialog* const dlg = new KPasswordDialog(int(Password), prompt, enableKeep);
00558 const int ret = dlg->exec();
00559 if (ret == Accepted) {
00560 password = dlg->password();
00561 if (enableKeep)
00562 *keep = dlg->keep();
00563 }
00564 delete dlg;
00565 return ret;
00566 }
00567
00568
00569
00570 int KPasswordDialog::getNewPassword(QCString &password, QString prompt)
00571 {
00572 KPasswordDialog* const dlg = new KPasswordDialog(NewPassword, prompt);
00573 const int ret = dlg->exec();
00574 if (ret == Accepted)
00575 password = dlg->password();
00576 delete dlg;
00577 return ret;
00578 }
00579
00580
00581
00582 void KPasswordDialog::disableCoreDumps()
00583 {
00584 struct rlimit rlim;
00585 rlim.rlim_cur = rlim.rlim_max = 0;
00586 setrlimit(RLIMIT_CORE, &rlim);
00587 }
00588
00589 void KPasswordDialog::virtual_hook( int id, void* data )
00590 { KDialogBase::virtual_hook( id, data ); }
00591
00592 void KPasswordDialog::enableOkBtn()
00593 {
00594 if (m_Type == NewPassword) {
00595 const bool match = strcmp(m_pEdit->password(), m_pEdit2->password()) == 0
00596 && (d->allowEmptyPasswords || m_pEdit->password()[0]);
00597
00598 const QString pass(m_pEdit->password());
00599
00600 const int minPasswordLength = minimumPasswordLength();
00601
00602 if ((int) pass.length() < minPasswordLength) {
00603 enableButtonOK(false);
00604 } else {
00605 enableButtonOK( match );
00606 }
00607
00608 if ( match && d->allowEmptyPasswords && m_pEdit->password()[0] == 0 ) {
00609 d->m_MatchLabel->setText( i18n("Password is empty") );
00610 } else {
00611 if ((int) pass.length() < minPasswordLength) {
00612 d->m_MatchLabel->setText(i18n("Password must be at least 1 character long", "Password must be at least %n characters long", minPasswordLength));
00613 } else {
00614 d->m_MatchLabel->setText( match? i18n("Passwords match")
00615 :i18n("Passwords do not match") );
00616 }
00617 }
00618
00619
00620
00621
00622
00623
00624
00625 const double lengthFactor = d->reasonablePasswordLength / 8.0;
00626
00627
00628 int pwlength = (int) (pass.length() / lengthFactor);
00629 if (pwlength > 5) pwlength = 5;
00630
00631 const QRegExp numRxp("[0-9]", true, false);
00632 int numeric = (int) (pass.contains(numRxp) / lengthFactor);
00633 if (numeric > 3) numeric = 3;
00634
00635 const QRegExp symbRxp("\\W", false, false);
00636 int numsymbols = (int) (pass.contains(symbRxp) / lengthFactor);
00637 if (numsymbols > 3) numsymbols = 3;
00638
00639 const QRegExp upperRxp("[A-Z]", true, false);
00640 int upper = (int) (pass.contains(upperRxp) / lengthFactor);
00641 if (upper > 3) upper = 3;
00642
00643 int pwstrength=((pwlength*10)-20) + (numeric*10) + (numsymbols*15) + (upper*10);
00644
00645 if ( pwstrength < 0 ) {
00646 pwstrength = 0;
00647 }
00648
00649 if ( pwstrength > 100 ) {
00650 pwstrength = 100;
00651 }
00652 d->m_strengthBar->setProgress(pwstrength);
00653
00654 }
00655 }
00656
00657
00658 void KPasswordDialog::setAllowEmptyPasswords(bool allowed) {
00659 d->allowEmptyPasswords = allowed;
00660 enableOkBtn();
00661 }
00662
00663
00664 bool KPasswordDialog::allowEmptyPasswords() const {
00665 return d->allowEmptyPasswords;
00666 }
00667
00668 void KPasswordDialog::setMinimumPasswordLength(int minLength) {
00669 d->minimumPasswordLength = minLength;
00670 enableOkBtn();
00671 }
00672
00673 int KPasswordDialog::minimumPasswordLength() const {
00674 return d->minimumPasswordLength;
00675 }
00676
00677 void KPasswordDialog::setMaximumPasswordLength(int maxLength) {
00678
00679 if (maxLength < 0) maxLength = 0;
00680 if (maxLength >= KPasswordEdit::PassLen) maxLength = KPasswordEdit::PassLen - 1;
00681
00682 d->maximumPasswordLength = maxLength;
00683
00684 m_pEdit->setMaxPasswordLength(maxLength);
00685 if (m_pEdit2) m_pEdit2->setMaxPasswordLength(maxLength);
00686
00687 }
00688
00689 int KPasswordDialog::maximumPasswordLength() const {
00690 return d->maximumPasswordLength;
00691 }
00692
00693
00694
00695 void KPasswordDialog::setReasonablePasswordLength(int reasonableLength) {
00696
00697 if (reasonableLength < 1) reasonableLength = 1;
00698 if (reasonableLength >= maximumPasswordLength()) reasonableLength = maximumPasswordLength();
00699
00700 d->reasonablePasswordLength = reasonableLength;
00701
00702 }
00703
00704 int KPasswordDialog::reasonablePasswordLength() const {
00705 return d->reasonablePasswordLength;
00706 }
00707
00708
00709 void KPasswordDialog::setPasswordStrengthWarningLevel(int warningLevel) {
00710 if (warningLevel < 0) warningLevel = 0;
00711 if (warningLevel > 99) warningLevel = 99;
00712 d->passwordStrengthWarningLevel = warningLevel;
00713 }
00714
00715 int KPasswordDialog::passwordStrengthWarningLevel() const {
00716 return d->passwordStrengthWarningLevel;
00717 }
00718
00719 #include "kpassdlg.moc"