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
This commit is contained in:
Christian Hohnstaedt 2020-02-22 09:34:24 +01:00
parent c1ea126efe
commit 176c2f8169
6 changed files with 43 additions and 58 deletions

View File

@ -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 &params, const QString &pass)
const DbMap &params, 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));

View File

@ -15,6 +15,7 @@
#include "sql.h"
#include "db_base.h"
#include "lib/Passwd.h"
typedef QMap<QString, QString> 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 &params,
const QString &pass);
const Passwd &pass);
static void openLocalDatabase(const QString &connName,
const QString &descriptor);
};

View File

@ -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();

View File

@ -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();

View File

@ -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();

View File

@ -12,7 +12,6 @@
#include "MainWindow.h"
#include "OpenDb.h"
#include "PwDialog.h"
#include "lib/base.h"
QString OpenDb::lastRemote;