diff --git a/lib/database_model.cpp b/lib/database_model.cpp index d61c702e..4dfa591e 100644 --- a/lib/database_model.cpp +++ b/lib/database_model.cpp @@ -85,7 +85,7 @@ bool database_model::checkForOldDbFormat(const QString &dbfile) const return !memcmp(head, magic, sizeof head); } -int database_model::verifyOldDbPass(const QString &dbname) const +enum open_result database_model::verifyOldDbPass(const QString &dbname) const { // look for the password QString passhash; @@ -101,11 +101,12 @@ int database_model::verifyOldDbPass(const QString &dbname) const return initPass(dbname, passhash); } } - return 2; + return open_abort; } QString database_model::checkPre2Xdatabase() const { + enum open_result result; if (!checkForOldDbFormat(dbName)) return QString(); @@ -115,14 +116,16 @@ QString database_model::checkPre2Xdatabase() const newname += "_backup_" + QDateTime::currentDateTime() .toString("yyyyMMdd_hhmmss") + ".xdb"; if (!XCA_OKCANCEL(tr("Legacy database format detected. Creating a backup copy called: '%1' and converting the database to the new format").arg(newname))) { - throw 1; + throw open_abort; } - if (verifyOldDbPass(dbName) != 1) - throw 1; + + result = verifyOldDbPass(dbName); + if (result != pw_ok) + throw result; if (!QFile::rename(dbName, newname)) { XCA_WARN(tr("Failed to rename the database file, because the target already exists")); - throw 1; + throw open_abort; } return newname; } @@ -227,7 +230,7 @@ next: database_model::database_model(const QString &name, const Passwd &pass) { - int ret = 2; + enum open_result result; QSqlError err; QString oldDbFile; @@ -238,7 +241,7 @@ database_model::database_model(const QString &name, const Passwd &pass) dbName = get_default_db(); if (dbName.isEmpty()) - throw errorEx(1); + throw open_abort; qDebug("Opening database: %s", QString2filename(dbName)); @@ -257,24 +260,21 @@ database_model::database_model(const QString &name, const Passwd &pass) DbMap params = splitRemoteDbName(dbName); pass_info p(XCA_TITLE, tr("Please enter the password to access the database server %2 as user '%1'.") .arg(params["user"]).arg(params["host"])); - if (PwDialog::execute(&p, &passwd) != 1) - throw errorEx(1); + result = PwDialog::execute(&p, &passwd); + if (result != pw_ok) + throw result; } } while (1); Entropy::seed_rng(); initSqlDB(); - if (dbName.isEmpty()) { - /* Error already printed */ - throw errorEx(1); - } if (oldDbFile.isEmpty()) { - ret = initPass(dbName, Settings["pwhash"]); - if (ret == 2) - throw errorEx(ret); - if (ret == 0 && Settings["pwhash"].empty()) - throw errorEx(2); + result = initPass(dbName, Settings["pwhash"]); + if (result == pw_exit) + throw pw_exit; + if (result != pw_ok && Settings["pwhash"].empty()) + throw open_abort; } /* Assure initialisation order: * keys first, followed by x509[req], and crls last. @@ -485,7 +485,7 @@ void database_model::openRemoteDatabase(const QString &connName, if (e.isValid() || !db.isOpen()) { XSqlQuery::clearTablePrefix(); db.close(); - throw errorEx(e.text()); + throw errorEx(e); } /* This is MySQL specific. Execute it always, because * dbType() could return "ODBC" but connect to MariaDB @@ -520,7 +520,7 @@ void database_model::openLocalDatabase(const QString &connName, QSqlError e = db.lastError(); if (e.isValid()) { db.close(); - throw errorEx(e.text()); + throw errorEx(e); } } @@ -573,10 +573,10 @@ static void pwhash_upgrade() } } -int database_model::initPass(const QString &dbName, const QString &passhash) const +enum open_result database_model::initPass(const QString &dbName, const QString &passhash) const { QString salt, pass; - int ret; + enum open_result result = pw_cancel; pass_info p(tr("New Password"), tr("Please enter a password, " "that will be used to encrypt your private keys " @@ -585,33 +585,31 @@ int database_model::initPass(const QString &dbName, const QString &passhash) con pki_evp::passHash = passhash; if (pki_evp::passHash.isEmpty()) { - ret = PwDialog::execute(&p, &pki_evp::passwd, true, true); - if (ret != 1) - return ret; + result = PwDialog::execute(&p, &pki_evp::passwd, true, true); + if (result != pw_ok) + return result; salt = Entropy::makeSalt(); pki_evp::passHash =pki_evp::sha512passwT(pki_evp::passwd,salt); Settings["pwhash"] = pki_evp::passHash; } else { pwhash_upgrade(); - ret = 0; while (pki_evp::sha512passwT(pki_evp::passwd, pki_evp::passHash) != pki_evp::passHash) { - if (ret) - XCA_WARN( - tr("Password verify error, please try again")); + if (result == pw_ok) + XCA_PASSWD_ERROR(); p.setTitle(tr("Password")); p.setDescription(tr("Please enter the password for unlocking the database:\n%1").arg(compressFilename(dbName))); - ret = PwDialog::execute(&p, &pki_evp::passwd, + result = PwDialog::execute(&p, &pki_evp::passwd, false, true); - if (ret != 1) { + if (result != pw_ok) { pki_evp::passwd = QByteArray(); - return ret; + return result; } pwhash_upgrade(); } } if (pki_evp::passwd.isNull()) pki_evp::passwd = ""; - return 1; + return pw_ok; } diff --git a/lib/database_model.h b/lib/database_model.h index c647a062..5af63c2e 100644 --- a/lib/database_model.h +++ b/lib/database_model.h @@ -30,11 +30,11 @@ class database_model: public QObject QSqlError initSqlDB(); QString dbName; bool checkForOldDbFormat(const QString &dbfile) const; - int verifyOldDbPass(const QString &dbname) const; + enum open_result verifyOldDbPass(const QString &dbname) const; void importOldDatabase(const QString &dbfile); QString get_default_db() const; QString checkPre2Xdatabase() const; - int initPass(const QString &dbName, + enum open_result initPass(const QString &dbName, const QString &passhash) const; public: diff --git a/lib/exception.h b/lib/exception.h index c83bc154..264f17c8 100644 --- a/lib/exception.h +++ b/lib/exception.h @@ -10,38 +10,32 @@ #include #include +#include + #include "base.h" -#define E_PASSWD 1 +enum open_result { + pw_cancel, + pw_ok, + pw_exit, + open_abort +}; class errorEx { - private: + protected: QString msg; + public: - int info; - errorEx(QString txt = "", QString className = "", int inf = 0) + errorEx(QString txt = "", QString className = "") { msg = txt; if (!className.isEmpty()) msg += " (" + className + ")"; - info = inf; } - errorEx(int inf) + errorEx(const QSqlError &e) { - info = inf; - msg.clear(); - } - errorEx(const errorEx &e) - { - msg = e.msg; - info = e.info; - } - errorEx &operator = (const errorEx &e) - { - msg = e.msg; - info = e.info; - return *this; + msg = e.text(); } void appendString(QString s) { diff --git a/lib/func.h b/lib/func.h index 1eec3a3f..073bb43c 100644 --- a/lib/func.h +++ b/lib/func.h @@ -25,7 +25,8 @@ #define COL_CYAN "\x1b[0;36m" #define COL_BLUE "\x1b[0;94m" -#define COL_LRED "\x1b[0;92m" +#define COL_GREEN "\x1b[0;92m" +#define COL_LRED "\x1b[0;91m" #define COL_YELL "\x1b[0;33m" #define COL_RED "\x1b[0;31m" #define COL_RESET "\x1b[0m" diff --git a/lib/main.cpp b/lib/main.cpp index 95a4be81..227c58b5 100644 --- a/lib/main.cpp +++ b/lib/main.cpp @@ -7,7 +7,7 @@ #include -#include +//#include #include #include //#include @@ -105,14 +105,16 @@ QCoreApplication *createApplication(int &argc, char *argv[]) static void cmd_version(FILE *fp) { - fprintf(fp, XCA_TITLE " Version %s\n", version_str(false)); + fprintf(fp, XCA_TITLE "\nVersion %s\n", version_str(false)); } +const char *xca_name = "xca"; static void cmd_help(int exitcode = EXIT_SUCCESS, const char *msg = NULL) { FILE *fp = exitcode == EXIT_SUCCESS ? stdout : stderr; cmd_version(fp); + fprintf(fp, "\nUsage %s ...\n\n", xca_name); fputs(CCHAR(arguments::help()), fp); if (msg) @@ -192,8 +194,8 @@ static database_model* read_cmdline(int argc, char *argv[]) int main(int argc, char *argv[]) { - int ret = 0; - QDir d; + if (argc > 0) + xca_name = argv[0]; #if defined(Q_OS_WIN32) SetUnhandledExceptionFilter(w32_segfault); @@ -201,7 +203,7 @@ int main(int argc, char *argv[]) signal(SIGSEGV, segv_handler_gui); #endif - d.mkpath(getUserSettingsDir()); + QDir().mkpath(getUserSettingsDir()); #if QT_VERSION < 0x050000 qInstallMsgHandler(myMsgOutput); @@ -216,8 +218,8 @@ int main(int argc, char *argv[]) XcaApplication *gui = qobject_cast(core); try { -#warning FIXME cmdline database_model *models = read_cmdline(argc, argv); + TRACE if (gui) { OpenDb::checkSqLite(); mainwin = new MainWindow(models); @@ -228,10 +230,16 @@ int main(int argc, char *argv[]) gui->exec(); } } catch (errorEx &ex) { + TRACE XCA_ERROR(ex); + } catch (enum open_result r) { + XCA_ERROR(QObject::tr("DB Open failed: %1").arg(r)); + TRACE } delete mainwin; + TRACE delete gui; + TRACE - return ret; + return EXIT_SUCCESS; } diff --git a/lib/pass_info.cpp b/lib/pass_info.cpp index 57e25e80..884f3ddf 100644 --- a/lib/pass_info.cpp +++ b/lib/pass_info.cpp @@ -14,6 +14,7 @@ pass_info::pass_info(const QString &t, const QString &d, QWidget *w) widget = w; type = tr("Password"); pixmap = QString(":keyImg"); + result = pw_ok; } void pass_info::setPin() diff --git a/lib/pass_info.h b/lib/pass_info.h index 76f1f3fd..9be3008a 100644 --- a/lib/pass_info.h +++ b/lib/pass_info.h @@ -12,25 +12,29 @@ #include #include +#include "lib/exception.h" + class QWidget; class pass_info: public QObject { - Q_OBJECT + Q_OBJECT + private: QString title; QString description; QWidget *widget; QString type; QString pixmap; + enum open_result result; public: pass_info(const QString &t, const QString &d, QWidget *w = NULL); - QString getTitle() + QString getTitle() const { return title; } - QString getDescription() + QString getDescription() const { return description; } @@ -40,14 +44,18 @@ class pass_info: public QObject widget = qApp->activeWindow(); return widget; } - QString getType() + QString getType() const { return type; } - QString getImage() + QString getImage() const { return pixmap; } + enum open_result getResult() const + { + return result; + } void setTitle(QString t) { title = t; @@ -60,6 +68,10 @@ class pass_info: public QObject { widget = w; } + void setResult(enum open_result r) + { + result = r; + } void setPin(); }; diff --git a/lib/pkcs11.cpp b/lib/pkcs11.cpp index 7c722ef0..5e3eac73 100644 --- a/lib/pkcs11.cpp +++ b/lib/pkcs11.cpp @@ -297,14 +297,15 @@ bool pkcs11::selectToken(slotid *slot, QWidget *w) for (int i = 0; i < p11_slots.count(); i++) { try { - tkInfo info = tokenInfo(p11_slots[i]); + tkInfo info; + CK_RV rv = tokenInfo(p11_slots[i], &info); + if (rv == CKR_TOKEN_NOT_PRESENT) + continue; slotsWithToken.append(i); slotnames << QString("%1 (#%2)"). arg(info.label()).arg(info.serial()); } catch (errorEx &e) { - if (e.info != CKR_TOKEN_NOT_PRESENT) { - XCA_WARN(QString("Error: %1").arg(e.getString())); - } + XCA_WARN(QString("Error: %1").arg(e.getString())); } } switch (slotnames.count()) { @@ -423,15 +424,25 @@ void pkcs11::initToken(slotid slot, unsigned char *pin, int pinlen, } tkInfo pkcs11::tokenInfo(slotid slot) +{ + tkInfo ti; + CK_RV rv = tokenInfo(slot, &ti); + + if (rv != CKR_OK) { + pk11error(slot, "C_GetTokenInfo", rv); + } + return ti; +} + +CK_RV pkcs11::tokenInfo(slotid slot, tkInfo *tkinfo) { CK_TOKEN_INFO token_info; CK_RV rv; CALL_P11_C(slot.lib, C_GetTokenInfo, slot.id, &token_info); - if (rv != CKR_OK) { - pk11error(slot, "C_GetTokenInfo", rv); - } - return tkInfo(&token_info); + if (rv == CKR_OK) + tkinfo->set(&token_info); + return rv; } void pkcs11::loadAttribute(pk11_attribute &attribute, CK_OBJECT_HANDLE object) diff --git a/lib/pkcs11.h b/lib/pkcs11.h index 7824b326..f9abae52 100644 --- a/lib/pkcs11.h +++ b/lib/pkcs11.h @@ -42,6 +42,10 @@ class tkInfo private: CK_TOKEN_INFO token_info; public: + tkInfo() + { + memset(&token_info, 0, sizeof token_info); + } tkInfo(const CK_TOKEN_INFO *ti) { set(ti); @@ -143,6 +147,7 @@ class pkcs11 return libs; } + CK_RV tokenInfo(slotid slot, tkInfo *tkinfo); tkInfo tokenInfo(slotid slot); tkInfo tokenInfo() { diff --git a/lib/pkcs11_lib.cpp b/lib/pkcs11_lib.cpp index 9bee0ce2..1fbef1a5 100644 --- a/lib/pkcs11_lib.cpp +++ b/lib/pkcs11_lib.cpp @@ -319,6 +319,6 @@ void pk11error(slotid slot, const QString &func, int rv) WAITCURSOR_END errorEx err(QObject::tr("PKCS#11 function '%1' failed: %2\nIn library %3\n%4"). arg(func).arg(pk11errorString(rv)).arg(slot.lib->filename()). - arg(slot.lib->driverInfo()), "", rv); + arg(slot.lib->driverInfo())); throw err; } diff --git a/lib/pki_base.cpp b/lib/pki_base.cpp index fb1cfd0d..fba717fd 100644 --- a/lib/pki_base.cpp +++ b/lib/pki_base.cpp @@ -350,7 +350,7 @@ bool pki_base::compare(const pki_base *ref) const } /* Unsigned 32 bit integer */ -unsigned pki_base::hash(QByteArray ba) +unsigned pki_base::hash(const QByteArray &ba) { unsigned char md[EVP_MAX_MD_SIZE]; diff --git a/lib/pki_base.h b/lib/pki_base.h index 9fe40857..7ba2283c 100644 --- a/lib/pki_base.h +++ b/lib/pki_base.h @@ -10,7 +10,7 @@ #include #include -#include +//#include #include "asn1time.h" #include "pkcs11_lib.h" #include "db.h" @@ -51,7 +51,7 @@ class pki_base : public QObject public: /* static */ static QRegExp limitPattern; static QString rmslashdot(const QString &fname); - static unsigned hash(QByteArray ba); + static unsigned hash(const QByteArray &ba); static bool pem_comment; protected: diff --git a/lib/pki_evp.cpp b/lib/pki_evp.cpp index c4143ed6..b43be43c 100644 --- a/lib/pki_evp.cpp +++ b/lib/pki_evp.cpp @@ -12,6 +12,7 @@ #include "db.h" #include "entropy.h" #include "widgets/PwDialog.h" +#include "widgets/XcaWarning.h" #include #include @@ -228,16 +229,16 @@ pki_evp::pki_evp(EVP_PKEY *pkey) set_EVP_PKEY(pkey); } -void pki_evp::openssl_pw_error(QString fname) +bool pki_evp::openssl_pw_error() const { switch (ERR_peek_error() & 0xff000fff) { case ERR_PACK(ERR_LIB_PEM, 0, PEM_R_BAD_DECRYPT): case ERR_PACK(ERR_LIB_PEM, 0, PEM_R_BAD_PASSWORD_READ): case ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BAD_DECRYPT): pki_ign_openssl_error(); - throw errorEx(tr("Failed to decrypt the key (bad password) %1") - .arg(fname), getClassName(), E_PASSWD); + return true; } + return false; } void pki_evp::fromPEMbyteArray(const QByteArray &ba, const QString &name) @@ -245,15 +246,24 @@ void pki_evp::fromPEMbyteArray(const QByteArray &ba, const QString &name) BIO *bio = BIO_from_QByteArray(ba); EVP_PKEY *pkey; pass_info p(XCA_TITLE, - tr("Please enter the password to decrypt the private key.") + - " " + name); - pkey = PEM_read_bio_PrivateKey(bio, NULL, PwDialog::pwCallback, &p); - openssl_pw_error(name); + tr("Please enter the password to decrypt the private key %1.") + .arg(name)); + do { + pkey = PEM_read_bio_PrivateKey(bio, NULL, + PwDialog::pwCallback, &p); + if (openssl_pw_error()) + XCA_PASSWD_ERROR(); + if (p.getResult() != pw_ok) + throw p.getResult(); + if (pki_ign_openssl_error()) + break; + } while (!pkey); + if (!pkey) { pki_ign_openssl_error(); BIO_free(bio); bio = BIO_from_QByteArray(ba); - pkey = PEM_read_bio_PUBKEY(bio, NULL, PwDialog::pwCallback, &p); + pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, 0); } BIO_free(bio); pki_openssl_error(); @@ -326,8 +336,17 @@ void pki_evp::fload(const QString &fname) pki_ign_openssl_error(); XFile file(fname); file.open_read(); - EVP_PKEY *pkey = PEM_read_PrivateKey(file.fp(), NULL, cb, &p); - openssl_pw_error(fname); + EVP_PKEY *pkey; + do { + pkey = PEM_read_PrivateKey(file.fp(), NULL, cb, &p); + if (openssl_pw_error()) + XCA_PASSWD_ERROR(); + if (p.getResult() != pw_ok) + throw p.getResult(); + if (pki_ign_openssl_error()) + break; + file.retry_read(); + } while (!pkey); if (!pkey) { pki_ign_openssl_error(); file.retry_read(); diff --git a/lib/pki_evp.h b/lib/pki_evp.h index 4d3dbe33..1d7e881c 100644 --- a/lib/pki_evp.h +++ b/lib/pki_evp.h @@ -34,7 +34,7 @@ class pki_evp: public pki_key void set_EVP_PKEY(EVP_PKEY *pkey, QString name = QString()); protected: - void openssl_pw_error(QString fname); + bool openssl_pw_error() const; public: static QString passHash; static Passwd passwd; diff --git a/lib/pki_multi.cpp b/lib/pki_multi.cpp index 29fc35eb..f09e2023 100644 --- a/lib/pki_multi.cpp +++ b/lib/pki_multi.cpp @@ -153,10 +153,10 @@ void pki_multi::probeAnything(const QString &fname) break; } } catch (errorEx &err) { - if (err.info == E_PASSWD) { - XCA_ERROR(err); + XCA_ERROR(err); + } catch (enum open_result r) { + if (r == pw_cancel) break; - } } } if (count() == old_count && !fname.isEmpty()) diff --git a/lib/pki_pkcs12.cpp b/lib/pki_pkcs12.cpp index 85b65537..cdd48740 100644 --- a/lib/pki_pkcs12.cpp +++ b/lib/pki_pkcs12.cpp @@ -11,6 +11,7 @@ #include "exception.h" #include "func.h" #include "widgets/PwDialog.h" +#include "widgets/XcaWarning.h" #include #include @@ -42,14 +43,18 @@ pki_pkcs12::pki_pkcs12(const QString &fname) if (pki_ign_openssl_error()) { if (pkcs12) PKCS12_free(pkcs12); - throw errorEx(tr("Unable to load the PKCS#12 (pfx) file %1.").arg(fname)); + throw errorEx(tr("Unable to load the PKCS#12 (pfx) file %1.") + .arg(fname)); } - if (PKCS12_verify_mac(pkcs12, "", 0) || PKCS12_verify_mac(pkcs12, NULL, 0)) - pass.clear(); - else if (PwDialog::execute(&p, &pass) != 1) { - /* cancel pressed */ - PKCS12_free(pkcs12); - throw errorEx("","", E_PASSWD); + while (!PKCS12_verify_mac(pkcs12, pass.constData(), 0)) { + if (pass.size() > 0) + XCA_PASSWD_ERROR(); + enum open_result result = PwDialog::execute(&p, &pass); + if (result != pw_ok) { + /* cancel pressed */ + PKCS12_free(pkcs12); + throw result; + } } PKCS12_parse(pkcs12, pass.constData(), &mykey, &mycert, &certstack); int error = ERR_peek_error(); @@ -58,7 +63,7 @@ pki_pkcs12::pki_pkcs12(const QString &fname) PKCS12_free(pkcs12); throw errorEx(getClassName(), tr("The supplied password was wrong (%1)") - .arg(ERR_reason_error_string(error)), E_PASSWD); + .arg(ERR_reason_error_string(error))); } pki_ign_openssl_error(); if (mycert) { diff --git a/widgets/MainWindow.cpp b/widgets/MainWindow.cpp index 5271d3db..c87c5017 100644 --- a/widgets/MainWindow.cpp +++ b/widgets/MainWindow.cpp @@ -141,9 +141,10 @@ MainWindow::MainWindow(database_model *m) dhgenBar->setMaximum(0); models = NULL; - int ret = m ? init_database(m) : init_database(QString()); - if (ret == 2) - throw errorEx(2); + enum open_result result = m ? init_database(m) : + init_database(QString()); + if (result == pw_exit) + throw pw_exit; } void MainWindow::dropEvent(QDropEvent *event) @@ -603,26 +604,28 @@ void MainWindow::openRemoteSqlDB() init_database(descriptor, pass); } -int MainWindow::init_database(const QString &name, const Passwd &pass) +enum open_result MainWindow::init_database(const QString &name, + const Passwd &pass) { try { close_database(); +TRACE return init_database(new database_model(name, pass)); } catch (errorEx &err) { - if (err.info == 0 && !err.isEmpty()) { - XCA_ERROR(err); - return 1; - } else { - return err.info; - } +TRACE + XCA_ERROR(err); + return open_abort; + } catch (enum open_result r) { +TRACE + return r; } - return 1; + return pw_ok; } -int MainWindow::init_database(database_model *m) +enum open_result MainWindow::init_database(database_model *m) { if (!m) - return 1; + return open_abort; models = m; setItemEnabled(true); m->restart_timer(); @@ -664,7 +667,8 @@ int MainWindow::init_database(database_model *m) certs, SLOT(newCert(pki_temp *)) ); connect(tempView, SIGNAL(newReq(pki_temp *)), reqs, SLOT(newItem(pki_temp *)) ); - return 0; + + return pw_ok; } void MainWindow::set_geometry(QString geo) diff --git a/widgets/MainWindow.h b/widgets/MainWindow.h index ad3f5723..169ba5f9 100644 --- a/widgets/MainWindow.h +++ b/widgets/MainWindow.h @@ -125,9 +125,9 @@ class MainWindow: public QMainWindow, public Ui::MainWindow void initResolver(); public slots: - int init_database(const QString &dbName, + enum open_result init_database(const QString &dbName, const Passwd &pass = Passwd()); - int init_database(database_model *m); + enum open_result init_database(database_model *m); void new_database(); void load_database(); void close_database(); diff --git a/widgets/PwDialog.cpp b/widgets/PwDialog.cpp index 715e5416..b81127bf 100644 --- a/widgets/PwDialog.cpp +++ b/widgets/PwDialog.cpp @@ -5,15 +5,15 @@ * All rights reserved. */ - -#include "PwDialog.h" #include "lib/func.h" #include "lib/base.h" #include "lib/Passwd.h" -#include "widgets/MainWindow.h" +#include "lib/exception.h" +#include "XcaWarning.h" +#include "PwDialog.h" #include #include -#include +//#include static int hex2bin(QString &x, Passwd *final) { @@ -34,34 +34,38 @@ static int hex2bin(QString &x, Passwd *final) return len; } -int PwDialog::execute(pass_info *p, Passwd *passwd, bool write, bool abort) +enum open_result PwDialog::execute(pass_info *p, Passwd *passwd, + bool write, bool abort) { if (IS_GUI_APP) { PwDialog *dlg = new PwDialog(p, write); if (abort) dlg->addAbortButton(); - int ret = dlg->exec(); + enum open_result result = (enum open_result)dlg->exec(); *passwd = dlg->getPass(); delete dlg; - return ret; + if (result == pw_exit) + throw pw_exit; + return result; } printf(COL_CYAN "%s" COL_LRED "\n%s:" COL_RESET, CCHAR(p->getDescription()), CCHAR(tr("Password"))); *passwd = readPass(); - return 1; + return pw_ok; } int PwDialog::pwCallback(char *buf, int size, int rwflag, void *userdata) { Passwd passwd; + enum open_result result; pass_info *p = static_cast(userdata); - int ret = PwDialog::execute(p, &passwd, rwflag, false); + result = PwDialog::execute(p, &passwd, rwflag, false); size = MIN(size, passwd.size()); memcpy(buf, passwd.constData(), size); - - return ret == 1 ? size : 0; + p->setResult(result); + return result == pw_ok ? size : 0; } PwDialog::PwDialog(pass_info *p, bool write) @@ -117,20 +121,23 @@ void PwDialog::accept() void PwDialog::buttonPress(QAbstractButton *but) { - switch (buttonBox->standardButton(but)) { - case QDialogButtonBox::Ok: + qDebug() << "buttonBox->standardButton(but)" << buttonBox->buttonRole(but) << QDialogButtonBox::DestructiveRole; + switch (buttonBox->buttonRole(but)) { + case QDialogButtonBox::AcceptRole: accept(); break; - case QDialogButtonBox::Cancel: + case QDialogButtonBox::RejectRole: reject(); break; - case QDialogButtonBox::Abort: + case QDialogButtonBox::ResetRole: + done(pw_exit); + break; default: - done(2); + break; } } void PwDialog::addAbortButton() { - buttonBox->addButton(tr("E&xit"), QDialogButtonBox::ResetRole); + buttonBox->addButton(tr("Exit"), QDialogButtonBox::ResetRole); } diff --git a/widgets/PwDialog.h b/widgets/PwDialog.h index 3c4ae06c..7e91a196 100644 --- a/widgets/PwDialog.h +++ b/widgets/PwDialog.h @@ -31,7 +31,7 @@ class PwDialog: public QDialog, public Ui::PwDialog void addAbortButton(); void setRW(bool write); - static int execute(pass_info *p, Passwd *passwd, + static enum open_result execute(pass_info *p, Passwd *passwd, bool write = false, bool abort = false); static int pwCallback(char *buf, int size, int rwflag, void *userdata); diff --git a/widgets/XcaWarning.h b/widgets/XcaWarning.h index 55efe17e..c60a8604 100644 --- a/widgets/XcaWarning.h +++ b/widgets/XcaWarning.h @@ -20,6 +20,7 @@ #define XCA_OKCANCEL(msg) xcaWarning::okcancel(msg) #define XCA_ERROR(err) xcaWarning::error(err) #define XCA_SQLERROR(err) xcaWarning::sqlerror(err) +#define XCA_PASSWD_ERROR() XCA_WARN(QObject::tr("Password verify error, please try again")) class xcaWarning: public QObject {