From 176c2f81695bdb5797e6265020e1f8bf422e97ce Mon Sep 17 00:00:00 2001 From: Christian Hohnstaedt Date: Sat, 22 Feb 2020 09:34:24 +0100 Subject: [PATCH] Improve password input and handling Use the Passwd class instead of QString Move password input into the database model to be available for commandline use. Repeat in case of wrong password --- lib/database_model.cpp | 54 ++++++++++++++++++++++++------------------ lib/database_model.h | 7 +++--- lib/main.cpp | 5 ++-- widgets/MainWindow.cpp | 32 ++++--------------------- widgets/MainWindow.h | 2 +- widgets/OpenDb.cpp | 1 - 6 files changed, 43 insertions(+), 58 deletions(-) diff --git a/lib/database_model.cpp b/lib/database_model.cpp index 10265160..d61c702e 100644 --- a/lib/database_model.cpp +++ b/lib/database_model.cpp @@ -225,7 +225,7 @@ next: } } -database_model::database_model(const QString &name, const QString &pass) +database_model::database_model(const QString &name, const Passwd &pass) { int ret = 2; QSqlError err; @@ -245,7 +245,23 @@ database_model::database_model(const QString &name, const QString &pass) if (!isRemoteDB(dbName)) oldDbFile = checkPre2Xdatabase(); - openDatabase(dbName, pass); + Passwd passwd(pass); + do { + try { + openDatabase(dbName, passwd); + break; + } catch (errorEx &err) { + if (!isRemoteDB(dbName)) + throw err; + XCA_ERROR(err); + 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); + } + } while (1); + Entropy::seed_rng(); initSqlDB(); @@ -253,11 +269,6 @@ database_model::database_model(const QString &name, const QString &pass) /* Error already printed */ throw errorEx(1); } - if (!QSqlDatabase::database().isOpen()) { - /* Error already printed */ - throw errorEx(1); - } - if (oldDbFile.isEmpty()) { ret = initPass(dbName, Settings["pwhash"]); if (ret == 2) @@ -454,9 +465,9 @@ bool database_model::isRemoteDB(const QString &db) } void database_model::openRemoteDatabase(const QString &connName, - const DbMap ¶ms, const QString &pass) + const DbMap ¶ms, const Passwd &pass) { - QSqlDatabase db = QSqlDatabase::database(connName); + QSqlDatabase db = QSqlDatabase::database(connName, false); db.setDatabaseName(params["dbname"]); QStringList hostport = params["host"].split(":"); @@ -468,22 +479,18 @@ void database_model::openRemoteDatabase(const QString &connName, db.setPassword(pass); XSqlQuery::setTablePrefix(params["prefix"]); - db.open(); QSqlError e = db.lastError(); -#warning HANDLE wrong password - if (!e.isValid() || e.type() != QSqlError::ConnectionError || - db.isOpen()) - { - /* This is MySQL specific. Execute it always, because - * dbType() could return "ODBC" but connect to MariaDB - */ - XSqlQuery q("SET SESSION SQL_MODE='ANSI'"); - return; + if (e.isValid() || !db.isOpen()) { + XSqlQuery::clearTablePrefix(); + db.close(); + throw errorEx(e.text()); } - XSqlQuery::clearTablePrefix(); - db.close(); + /* This is MySQL specific. Execute it always, because + * dbType() could return "ODBC" but connect to MariaDB + */ + XSqlQuery q("SET SESSION SQL_MODE='ANSI'"); } void database_model::openLocalDatabase(const QString &connName, @@ -517,7 +524,7 @@ void database_model::openLocalDatabase(const QString &connName, } } -void database_model::openDatabase(const QString &descriptor, const QString &pass) +void database_model::openDatabase(const QString &descriptor, const Passwd &pass) { DbMap params = splitRemoteDbName(descriptor); bool isRemote = params.size() == NUM_PARAM; @@ -525,6 +532,7 @@ void database_model::openDatabase(const QString &descriptor, const QString &pass qDebug() << "IS REMOTE?" << params.size() << NUM_PARAM << type << params; try { + Passwd pwd(pass); QSqlDatabase db = QSqlDatabase::addDatabase(type); connName = db.connectionName(); if (!isRemote) { @@ -532,7 +540,7 @@ void database_model::openDatabase(const QString &descriptor, const QString &pass throw errorEx(tr("No SqLite3 driver available. Please install the qt-sqlite package of your distribution")); openLocalDatabase(connName, descriptor); } else { - openRemoteDatabase(connName, params, pass); + openRemoteDatabase(connName, params, pwd); } DbTransaction::setHasTransaction( db.driver()->hasFeature(QSqlDriver::Transactions)); diff --git a/lib/database_model.h b/lib/database_model.h index 2467ca08..c647a062 100644 --- a/lib/database_model.h +++ b/lib/database_model.h @@ -15,6 +15,7 @@ #include "sql.h" #include "db_base.h" +#include "lib/Passwd.h" typedef QMap DbMap; @@ -38,7 +39,7 @@ class database_model: public QObject public: database_model(const QString &dbName, - const QString &pass = QString()); + const Passwd &pass = Passwd()); ~database_model(); void restart_timer(); const QString &dbname() const @@ -65,10 +66,10 @@ class database_model: public QObject static DbMap splitRemoteDbName(const QString &db); static bool isRemoteDB(const QString &db); static void openDatabase(const QString &descriptor, - const QString &pass); + const Passwd &pass); static void openRemoteDatabase(const QString &connName, const DbMap ¶ms, - const QString &pass); + const Passwd &pass); static void openLocalDatabase(const QString &connName, const QString &descriptor); }; diff --git a/lib/main.cpp b/lib/main.cpp index 2fdd6e4c..95a4be81 100644 --- a/lib/main.cpp +++ b/lib/main.cpp @@ -144,7 +144,7 @@ static database_model* read_cmdline(int argc, char *argv[]) arguments cmd_opts(argc, argv); database_model *models = NULL; pki_evp::passwd = acquire_password(cmd_opts["password"]); - + Passwd sqlpw = acquire_password(cmd_opts["sqlpass"]); if (cmd_opts.has("verbose")) debug = 1; @@ -152,8 +152,7 @@ static database_model* read_cmdline(int argc, char *argv[]) cmd_help(EXIT_FAILURE); if (cmd_opts.has("database")) - models = new database_model(cmd_opts["database"], - cmd_opts["sqlpass"]); + models = new database_model(cmd_opts["database"], sqlpw); imported_items = new pki_multi(); diff --git a/widgets/MainWindow.cpp b/widgets/MainWindow.cpp index 8cedb859..5271d3db 100644 --- a/widgets/MainWindow.cpp +++ b/widgets/MainWindow.cpp @@ -586,13 +586,13 @@ void MainWindow::importMulti(pki_multi *multi, int force) void MainWindow::openRemoteSqlDB() { OpenDb *opendb = new OpenDb(this, currentDB); - QString descriptor, pass; - int round; + QString descriptor; + Passwd pass; DbMap params; if (opendb->exec()) { descriptor = opendb->getDescriptor(); - pass = opendb->dbPassword->text(); + pass = opendb->dbPassword->text().toLatin1(); params = database_model::splitRemoteDbName(descriptor); } delete opendb; @@ -600,32 +600,10 @@ void MainWindow::openRemoteSqlDB() if (descriptor.isEmpty()) return; - for (round=0; ; round++) { - try { - if (init_database(descriptor, pass) == 1) - break; - if (QSqlDatabase::database().driver()->hasFeature( - QSqlDriver::Transactions)) - XCA_WARN(tr("The database driver does not support transactions. This may happen if the client and server have different versions. Continue with care.")); - break; - } catch (errorEx &err) { - if (pass.size() > 0 || round > 0) - XCA_ERROR(err); - } - - Passwd pwd; - 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, &pwd) != 1) - break; - pass = QString(pwd); - - qDebug() << "DB-DESC:" << descriptor; - } + init_database(descriptor, pass); } -int MainWindow::init_database(const QString &name, const QString &pass) +int MainWindow::init_database(const QString &name, const Passwd &pass) { try { close_database(); diff --git a/widgets/MainWindow.h b/widgets/MainWindow.h index 78ce2780..ad3f5723 100644 --- a/widgets/MainWindow.h +++ b/widgets/MainWindow.h @@ -126,7 +126,7 @@ class MainWindow: public QMainWindow, public Ui::MainWindow public slots: int init_database(const QString &dbName, - const QString &pass = QString()); + const Passwd &pass = Passwd()); int init_database(database_model *m); void new_database(); void load_database(); diff --git a/widgets/OpenDb.cpp b/widgets/OpenDb.cpp index e25ac94f..b8d72228 100644 --- a/widgets/OpenDb.cpp +++ b/widgets/OpenDb.cpp @@ -12,7 +12,6 @@ #include "MainWindow.h" #include "OpenDb.h" -#include "PwDialog.h" #include "lib/base.h" QString OpenDb::lastRemote;