Support opening remote databases MySQL and PostgreSQL

This commit is contained in:
Christian Hohnstaedt 2017-06-26 05:32:59 +02:00
parent 2a0a4630ae
commit fc7fc357ac
19 changed files with 521 additions and 138 deletions

View File

@ -155,8 +155,7 @@ dbheaderList db_base::getHeaders()
void db_base::saveHeaderState()
{
QSqlDatabase *db = mainwin->getDb();
if (db->isOpen())
if (QSqlDatabase::database().isOpen())
mainwin->storeSetting(class_name + "_hdView",
allHeaders.toData());
}
@ -221,13 +220,13 @@ QSqlError db_base::insertPKI_noTransaction(pki_base *pki)
void db_base::insertPKI(pki_base *pki)
{
QSqlDatabase *db = mainwin->getDb();
if (db->transaction()) {
QSqlDatabase db = QSqlDatabase::database();
if (db.transaction()) {
QSqlError e = insertPKI_noTransaction(pki);
if (e.isValid())
db->rollback();
db.rollback();
else
db->commit();
db.commit();
}
emit columnsContentChanged();
}
@ -268,7 +267,7 @@ void db_base::pem2clipboard(QModelIndexList indexes) const
void db_base::deletePKI(QModelIndex idx)
{
pki_base *pki = static_cast<pki_base*>(idx.internalPointer());
QSqlDatabase *db = mainwin->getDb();
QSqlDatabase db = QSqlDatabase::database();
try {
try {
pki->deleteFromToken();
@ -276,14 +275,14 @@ void db_base::deletePKI(QModelIndex idx)
MainWindow::Error(err);
}
if (db->transaction()) {
if (db.transaction()) {
QSqlError e = pki->deleteSql();
remFromCont(idx);
mainwin->dbSqlError(e);
if (e.isValid())
db->rollback();
db.rollback();
else
db->commit();
db.commit();
mainwin->dbSqlError(e);
}
} catch (errorEx &err) {

View File

@ -72,7 +72,6 @@ void db_crl::revokeCerts(pki_crl *crl)
void db_crl::removeSigner(pki_base *signer)
{
#warning FIXME ......
FOR_ALL_pki(crl, pki_crl) {
if (crl->getIssuer() == signer) {
crl->setIssuer(NULL);
@ -248,7 +247,7 @@ void db_crl::newItem(pki_x509 *cert)
delete dlg;
return;
}
QSqlDatabase *db = mainwin->getDb();
QSqlDatabase db = QSqlDatabase::database();
try {
x509v3ext e;
X509V3_CTX ext_ctx;
@ -285,7 +284,7 @@ void db_crl::newItem(pki_x509 *cert)
crl->setLastUpdate(widget->lastUpdate->getDate());
crl->setNextUpdate(widget->nextUpdate->getDate());
crl->sign(cert->getRefKey(), widget->hashAlgo->currentHash());
if (!db->transaction())
if (!db.transaction())
throw errorEx(tr("Failed to initiate DB transaction"));
transact = true;
cert->setCrlExpire(widget->nextUpdate->getDate());
@ -306,15 +305,15 @@ void db_crl::newItem(pki_x509 *cert)
if (err.isValid())
throw errorEx(tr("Database error: ").arg(err.text()));
insertPKI_noTransaction(crl);
err = db->lastError();
err = db.lastError();
if (err.isValid())
throw errorEx(tr("Database error: ").arg(err.text()));
db->commit();
db.commit();
createSuccess((crl));
}
catch (errorEx &err) {
if (transact)
db->rollback();
db.rollback();
MainWindow::Error(err);
if (crl)
delete crl;

View File

@ -66,7 +66,7 @@ QList<pki_base *> db_key::getAllKeys()
QList<pki_base *> db_key::getUnusedKeys()
{
return sqlSELECTpki("SELECT public_keys.item FROM public_keys "
"LEFT OUTER JOIN x509super ON x509super.key = public_keys.item "
"LEFT OUTER JOIN x509super ON x509super.pkey= public_keys.item "
"WHERE x509super.item IS NULL");
}
@ -77,14 +77,14 @@ void db_key::remFromCont(QModelIndex &idx)
pki_key *pki = static_cast<pki_key*>(idx.internalPointer());
QList<pki_base*> items = sqlSELECTpki(
"SELECT item FROM x509super WHERE key=?",
"SELECT item FROM x509super WHERE pkey=?",
QList<QVariant>() << QVariant(pki->getSqlItemId()));
foreach(pki_base *b, items) {
pki_x509super *x509s = static_cast<pki_x509super*>(b);
x509s->setRefKey(NULL);
}
SQL_PREPARE(q, "UPDATE x509super SET key=NULL WHERE item=?");
SQL_PREPARE(q, "UPDATE x509super SET pkey=NULL WHERE item=?");
q.bindValue(0, pki->getSqlItemId());
q.exec();
mainwin->dbSqlError(q.lastError());
@ -96,10 +96,10 @@ void db_key::inToCont(pki_base *pki)
pki_key *key = static_cast<pki_key*>(pki);
unsigned hash = key->hash();
QList<pki_base*> items = sqlSELECTpki(
"SELECT item FROM x509super WHERE key IS NULL AND key_hash=?",
"SELECT item FROM x509super WHERE pkey IS NULL AND key_hash=?",
QList<QVariant>() << QVariant(hash));
XSqlQuery q;
SQL_PREPARE(q, "UPDATE x509super SET key=? WHERE item=?");
SQL_PREPARE(q, "UPDATE x509super SET pkey=? WHERE item=?");
q.bindValue(0, key->getSqlItemId());
foreach(pki, items) {
pki_x509super *x509s = static_cast<pki_x509super*>(pki);

View File

@ -151,12 +151,12 @@ bool db_temp::alterTemp(pki_temp *temp)
{
XSqlQuery q;
QSqlError e;
QSqlDatabase *db = mainwin->getDb();
QSqlDatabase db = QSqlDatabase::database();
if (!runTempDlg(temp))
return false;
if (!db->transaction())
if (!db.transaction())
return false;
SQL_PREPARE(q, "UPDATE templates SET version=?, template=? WHERE item=?");
q.bindValue(0, TMPL_VERSION);
@ -166,10 +166,10 @@ bool db_temp::alterTemp(pki_temp *temp)
e = q.lastError();
mainwin->dbSqlError(e);
if (e.isValid()) {
db->rollback();
db.rollback();
return false;
}
updateItem(temp, temp->getIntName(), temp->getComment());
db->commit();
db.commit();
return true;
}

View File

@ -89,7 +89,7 @@ QList<pki_base *> db_x509::getAllIssuers()
{
/* Select X509 CA certificates with available private key */
return sqlSELECTpki("SELECT x509super.item FROM x509super "
"JOIN private_keys ON x509super.key = private_keys.item "
"JOIN private_keys ON x509super.pkey = private_keys.item "
"JOIN certs ON certs.item = x509super.item "
"WHERE certs.ca=1");
}
@ -185,7 +185,7 @@ void db_x509::inToCont(pki_base *pki)
* and use its childs if we are newer */
items = sqlSELECTpki(
"SELECT x509super.item FROM x509super "
"JOIN public_keys ON x509super.key = public_keys.item "
"JOIN public_keys ON x509super.pkey = public_keys.item "
"JOIN certs ON certs.item = x509super.item "
"WHERE certs.ca=1 AND x509super.subj_hash=? "
"AND x509super.key_hash=?",
@ -782,14 +782,14 @@ void db_x509::writePKCS7(pki_x509 *cert, QString s, exportType::etype type,
void db_x509::storeRevocations(pki_x509 *cert)
{
QSqlDatabase *db = mainwin->getDb();
if (db->transaction()) {
QSqlDatabase db = QSqlDatabase::database();
if (db.transaction()) {
QSqlError e;
e = cert->revList.sqlUpdate(cert->getSqlItemId());
if (e.isValid())
db->rollback();
db.rollback();
else
db->commit();
db.commit();
}
cert->revList.merged = false;
}

View File

@ -25,7 +25,7 @@
#define SQL_PREPARE(q,cmd) do { \
(q).prepare(cmd); \
(q).location(__FILE__,__LINE__); \
} while (0);
} while (0)
enum pki_source {
unknown,

View File

@ -237,7 +237,7 @@ int pki_key::getUcount()
{
XSqlQuery q;
int size = -1;
SQL_PREPARE(q, "SELECT COUNT(*) FROM x509super WHERE key=?");
SQL_PREPARE(q, "SELECT COUNT(*) FROM x509super WHERE pkey=?");
q.bindValue(0, sqlItemId);
q.exec();
if (q.first())
@ -450,7 +450,8 @@ QSqlError pki_key::insertSqlData()
XSqlQuery q;
QList<pki_x509super*> list;
SQL_PREPARE(q, "SELECT item FROM x509super WHERE key_hash=? AND key IS NULL");
SQL_PREPARE(q, "SELECT item FROM x509super WHERE key_hash=? AND "
"pkey IS NULL");
q.bindValue(0, myhash);
q.exec();
if (q.lastError().isValid())
@ -470,7 +471,7 @@ QSqlError pki_key::insertSqlData()
}
q.finish();
SQL_PREPARE(q, "UPDATE x509super SET key=? WHERE item=?");
SQL_PREPARE(q, "UPDATE x509super SET pkey=? WHERE item=?");
q.bindValue(0, sqlItemId);
foreach(pki_x509super* x, list) {
q.bindValue(1, x->getSqlItemId());
@ -524,7 +525,7 @@ QSqlError pki_key::deleteSqlData()
e = q.lastError();
if (e.isValid())
return e;
SQL_PREPARE(q, "UPDATE x509super SET key=NULL WHERE key=?");
SQL_PREPARE(q, "UPDATE x509super SET pkey=NULL WHERE key=?");
q.bindValue(0, sqlItemId);
q.exec();
return q.lastError();

View File

@ -44,7 +44,7 @@ QSqlError pki_x509super::insertSqlData()
}
}
SQL_PREPARE(q, "INSERT INTO x509super (item, subj_hash, key, key_hash) "
SQL_PREPARE(q, "INSERT INTO x509super (item, subj_hash, pkey, key_hash) "
"VALUES (?, ?, ?, ?)");
q.bindValue(0, sqlItemId);
q.bindValue(1, (uint)getSubject().hashNum());
@ -62,7 +62,7 @@ QSqlError pki_x509super::restoreSql(QVariant sqlId)
e = pki_base::restoreSql(sqlId);
if (e.isValid())
return e;
SQL_PREPARE(q, "SELECT key FROM x509super WHERE item=?");
SQL_PREPARE(q, "SELECT pkey FROM x509super WHERE item=?");
q.bindValue(0, sqlId);
q.exec();
e = q.lastError();

View File

@ -268,5 +268,9 @@ QSqlError x509revList::sqlUpdate(QVariant caId)
for (int i=0; i<size(); i++) {
x509rev r = at(i);
r.executeQuery(q);
e = q.lastError();
if (e.isValid())
break;
}
return e;
}

View File

@ -9,7 +9,7 @@ UI_H = ui_CaProperties.h ui_CertDetail.h ui_CertExtend.h \
ui_ImportMulti.h ui_KeyDetail.h ui_MainWindow.h ui_NewCrl.h \
ui_NewKey.h ui_NewX509.h ui_Options.h ui_PwDialog.h ui_Revoke.h \
ui_SelectToken.h ui_XcaDialog.h ui_v3ext.h ui_SearchPkcs11.h \
ui_RevocationList.h ui_OidResolver.h
ui_RevocationList.h ui_OidResolver.h ui_OpenDb.h
include $(TOPDIR)/Rules.mak

217
ui/OpenDb.ui Normal file
View File

@ -0,0 +1,217 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>OpenDb</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>441</width>
<height>325</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="_2">
<property name="spacing">
<number>6</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="TextLabel6">
<property name="font">
<font>
<family>Arial</family>
<pointsize>14</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
<underline>false</underline>
<strikeout>false</strikeout>
</font>
</property>
<property name="text">
<string>Open remote database</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="image">
<property name="minimumSize">
<size>
<width>95</width>
<height>40</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>95</width>
<height>40</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Database type</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="dbType"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Hostname</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="hostName"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Username</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="userName"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Password</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="dbPassword"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Database name</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="dbName"/>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>21</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -28,7 +28,7 @@ class itemCombo : public QComboBox
void setNullItem(QString text) {
if (itemData(0).value<pki_base*>() == NULL)
removeItem(0);
insertItem(0, text, QVariant::fromValue(NULL));
insertItem(0, text, QVariant());
}
int setCurrentPkiItem(pki_base *p) {
int idx = findData(QVariant::fromValue(p));

View File

@ -19,8 +19,9 @@
#include "lib/db_base.h"
#include "lib/func.h"
#include "lib/db.h"
#include "widgets/ImportMulti.h"
#include "widgets/NewKey.h"
#include "ImportMulti.h"
#include "NewKey.h"
#include "OpenDb.h"
QSqlError MainWindow::initSqlDB()
{
@ -55,9 +56,9 @@ QSqlError MainWindow::initSqlDB()
* table column (position, sort order, visibility)
*/
<< "CREATE TABLE settings ("
"key CHAR(20) UNIQUE, "
"key_ CHAR(20) UNIQUE, " /* mySql does not like "key" or "option" */
"value VARCHAR(1024))"
<< "INSERT INTO settings (key, value) VALUES ('schema', '1')"
<< "INSERT INTO settings (key_, value) VALUES ('schema', '1')"
/*
* All items (keys, tokens, requests, certs, crls, templates)
@ -66,7 +67,7 @@ QSqlError MainWindow::initSqlDB()
* as FOREIGN KEY.
*/
<< "CREATE TABLE items("
"id SERIAL PRIMARY KEY, "
"id INTEGER PRIMARY KEY, "
"name VARCHAR(128), " /* Internal name of the item */
"type INTEGER, " /* enum pki_type */
"source INTEGER, " /* enum pki_source */
@ -124,15 +125,15 @@ QSqlError MainWindow::initSqlDB()
* - hash of the public key, used for lookups if there
* is no key to reference
* used by Requests and certificates and the use-counter of keys:
* "SELECT from x509super WHERE key=?"
* "SELECT from x509super WHERE pkey=?"
*/
<< "CREATE TABLE x509super ("
"item INTEGER, " /* reference to items(id) */
"subj_hash INTEGER, " /* 32 bit hash of the Distinguished name */
"key INTEGER, " /* reference to the key items(id) */
"pkey INTEGER, " /* reference to the key items(id) */
"key_hash INTEGER, " /* 32 bit hash of the public key */
"FOREIGN KEY (item) REFERENCES items (id), "
"FOREIGN KEY (key) REFERENCES items (id)) "
"FOREIGN KEY (pkey) REFERENCES items (id)) "
/*
* PKCS#10 Certificate request details
@ -172,7 +173,7 @@ QSqlError MainWindow::initSqlDB()
"crlExpire "DB_DATE", " /* CRL expiry date */
"crlNo INTEGER, " /* Last CRL Number */
"crlDays INTEGER, " /* CRL days until renewal */
"dnPolicy, " /* DistinguishedName policy */
"dnPolicy VARCHAR(1024), " /* DistinguishedName policy */
"FOREIGN KEY (item) REFERENCES items (id), "
"FOREIGN KEY (template) REFERENCES items (id)) "
@ -213,8 +214,15 @@ QSqlError MainWindow::initSqlDB()
;
XSqlQuery q;
QSqlDatabase db = QSqlDatabase::database();
QStringList tables = db.tables();
if (tables.contains("items")) {
return QSqlError();
}
if (!db.transaction())
return db.lastError();
foreach(QString sql, sl) {
fprintf(stderr, "EXEC: '%s'\n", CCHAR(sql));
if (!q.exec(sql)) {
@ -226,33 +234,28 @@ QSqlError MainWindow::initSqlDB()
return QSqlError();
}
QSqlError MainWindow::openSqlDB()
QString MainWindow::openSqlDB(QString dbName)
{
//#define POSTGRES 1
#ifndef POSTGRES
db.setDatabaseName(dbfile);
#else
db.setDatabaseName("xca_pg");
db.setHostName("192.168.140.7");
db.setUserName("xca");
db.setPassword("xca");
#endif
if (db.driverName() == "QSQLITE") {
// chmod 0600
if (!QFile::exists(dbfile)) {
QFile f(dbfile);
f.open(QIODevice::WriteOnly);
f.setPermissions(QFile::WriteOwner | QFile::ReadOwner);
f.close();
OpenDb *opendb = new OpenDb(this, dbName);
if (opendb->exec()) {
opendb->openDatabase();
QSqlError e = initSqlDB();
printf("DB-DESC: '%s'\n", CCHAR(opendb->getDescriptor()));
if (e.isValid()) {
dbSqlError();
dbName = QString();
} else {
dbName = opendb->getDescriptor();
}
}
if (!db.open())
return db.lastError();
QStringList tables = db.tables();
if (!tables.contains("items")) {
return initSqlDB();
}
return QSqlError();
delete opendb;
return dbName;
}
void MainWindow::openRemoteSqlDB()
{
close_database();
init_database("@/QPSQL7:");
}
void MainWindow::set_geometry(QString geo)
@ -277,7 +280,7 @@ void MainWindow::dbSqlError(QSqlError err)
}
}
bool MainWindow::checkForOldDbFormat()
bool MainWindow::checkForOldDbFormat(QString dbfile)
{
// 0x ca db 19 69
static const unsigned char magic[] = { 0xca, 0xdb, 0x19, 0x69 };
@ -304,7 +307,7 @@ int MainWindow::verifyOldDbPass(QString dbname)
if ((p = (char *)mydb.load(&head))) {
passhash = p;
free(p);
return initPass(passhash);
return initPass(dbname, passhash);
}
}
return 2;
@ -402,41 +405,43 @@ next:
}
}
int MainWindow::init_database()
int MainWindow::init_database(QString dbName)
{
int ret = 2;
QSqlError err;
QString oldDbFile;
qDebug("Opening database: %s", QString2filename(dbfile));
qDebug("Opening database: %s", QString2filename(dbName));
keys = NULL; reqs = NULL; certs = NULL; temps = NULL; crls = NULL;
if (checkForOldDbFormat()) {
QString newname = dbfile;
if (checkForOldDbFormat(dbName)) {
QString newname = dbName;
if (newname.endsWith(".xdb"))
newname = newname.left(newname.length() -4);
newname += "_backup_" + QDateTime::currentDateTime()
.toString("yyyyMMdd_hhmmss") + ".xdb";
if (!XCA_OKCANCEL(tr("Found an old version of the XCA database. I will make a backup copy called: '%1' and convert the database into the new format").arg(newname))) {
dbfile = "";
return 1;
}
if (verifyOldDbPass(dbfile) != 1)
if (verifyOldDbPass(dbName) != 1)
return 1;
if (!QFile::rename(dbfile, newname)) {
if (!QFile::rename(dbName, newname)) {
XCA_WARN(tr("Failed to rename the database file, because the target already exists"));
return 1;
}
oldDbFile = newname;
}
Entropy::seed_rng();
err = openSqlDB();
dbSqlError(err);
dbName = openSqlDB(dbName);
if (!QSqlDatabase::database().isOpen()) {
dbSqlError();
return 1;
}
certView->setRootIsDecorated(db_x509::treeview);
try {
if (pki_evp::passwd.isEmpty()) {
ret = initPass();
ret = initPass(dbName);
if (ret == 2)
return ret;
}
@ -448,7 +453,6 @@ int MainWindow::init_database()
}
catch (errorEx &err) {
Error(err);
dbfile = "";
return ret;
}
@ -492,7 +496,7 @@ int MainWindow::init_database()
if (!oldDbFile.isEmpty())
importOldDatabase(oldDbFile);
XSqlQuery query("SELECT key, value FROM settings");
XSqlQuery query("SELECT key_, value FROM settings");
while (query.next()) {
QString key = query.value(0).toString();
QString value = query.value(1).toString();
@ -523,13 +527,14 @@ int MainWindow::init_database()
if (pki_evp::passwd.isNull())
XCA_INFO(tr("Using or exporting private keys will not be possible without providing the correct password"));
dbindex->setText(tr("Database") + ": " + dbfile);
load_engine();
hashBox hb(this);
if (hb.isInsecure()) {
XCA_WARN(tr("The currently used default hash '%1' is insecure. Please select at least 'SHA 224' for security reasons.").arg(hb.currentHashName()));
setOptions();
}
dbindex->setText(tr("Database") + ": " + dbName);
currentDB = dbName;
return ret;
}
@ -608,7 +613,7 @@ void MainWindow::undelete()
int MainWindow::open_default_db()
{
if (!dbfile.isEmpty())
if (QSqlDatabase::database().isOpen())
return 0;
FILE *fp = fopen_read(getUserSettingsDir() +
QDir::separator() + "defaultdb");
@ -619,22 +624,21 @@ int MainWindow::open_default_db()
size_t len = fread(buff, 1, 255, fp);
fclose(fp);
buff[len] = 0;
dbfile = filename2QString(buff).trimmed();
QString dbfile = filename2QString(buff).trimmed();
if (QFile::exists(dbfile))
return init_database();
dbfile = QString();
return init_database(dbfile);
return 0;
}
void MainWindow::default_database()
{
QFileInfo fi(dbfile);
QFileInfo fi(currentDB);
QString dir = getUserSettingsDir();
QString file = dir +QDir::separator() +"defaultdb";
FILE *fp;
QDir d;
if (dbfile.isEmpty()) {
if (currentDB.isEmpty()) {
QFile::remove(file);
return;
}
@ -655,7 +659,7 @@ void MainWindow::default_database()
QString MainWindow::getSetting(QString key)
{
XSqlQuery q;
SQL_PREPARE(q, "SELECT value FROM settings WHERE key=?");
SQL_PREPARE(q, "SELECT value FROM settings WHERE key_=?");
q.bindValue(0, key);
q.exec();
if (q.first()) {
@ -668,16 +672,18 @@ QString MainWindow::getSetting(QString key)
void MainWindow::storeSetting(QString key, QString value)
{
XSqlQuery q;
SQL_PREPARE(q, "UPDATE settings SET value=? WHERE key=?");
q.bindValue(0, value);
q.bindValue(1, key);
QSqlError e;
SQL_PREPARE(q, "SELECT COUNT(key_) FROM settings WHERE key_=?");
q.bindValue(0, key);
q.exec();
dbSqlError(q.lastError());
if (q.numRowsAffected() == 1)
return;
SQL_PREPARE(q, "INSERT INTO settings (key, value) VALUES (?, ?)");
q.bindValue(0, key);
q.bindValue(1, value);
if (q.first() && q.value(0).toInt() == 1)
SQL_PREPARE(q, "UPDATE settings SET value=? WHERE key_=?");
else
SQL_PREPARE(q, "INSERT INTO settings (value, key_) VALUES (?,?)");
q.bindValue(0, value);
q.bindValue(1, key);
q.exec();
dbSqlError(q.lastError());
}
@ -685,10 +691,21 @@ void MainWindow::storeSetting(QString key, QString value)
void MainWindow::close_database()
{
QByteArray ba;
if (!db.isOpen())
return;
QString connName;
bool dbopen;
qDebug("Closing database: %s", QString2filename(dbfile));
{
/* Destroy "db" at the end of the block */
QSqlDatabase db = QSqlDatabase::database();
connName= db.connectionName();
dbopen = db.isOpen();
}
if (!dbopen) {
QSqlDatabase::removeDatabase(connName);
return;
}
qDebug("Closing database: %s", QString2filename(currentDB));
QString s = QString("%1,%2,%3")
.arg(size().width()).arg(size().height())
.arg(tabView->currentIndex());
@ -721,7 +738,7 @@ void MainWindow::close_database()
temps = NULL;
keys = NULL;
db.close();
QSqlDatabase::database().close();
pki_evp::passwd.cleanse();
pki_evp::passwd = QByteArray();
@ -729,10 +746,11 @@ void MainWindow::close_database()
return;
crls = NULL;
update_history(dbfile);
update_history(currentDB);
pkcs11::remove_libs();
enableTokenMenu(pkcs11::loaded());
dbfile.clear();
QSqlDatabase::removeDatabase(connName);
currentDB.clear();
}
void MainWindow::load_history()

View File

@ -93,6 +93,7 @@ void MainWindow::init_menu()
QKeySequence::New);
file->addAction(tr("&Open DataBase"), this, SLOT(load_database()),
QKeySequence::Open);
file->addAction(tr("Open Remote DataBase"), this, SLOT(openRemoteSqlDB()));
file->addMenu(historyMenu);
file->addAction(tr("Set as default DataBase"), this,
SLOT(default_database()));
@ -160,7 +161,7 @@ void MainWindow::init_menu()
wdMenuList += import;
scardList += token;
setItemEnabled(!dbfile.isEmpty());
setItemEnabled(!currentDB.isEmpty());
}
int MainWindow::changeDB(QString fname)
@ -169,8 +170,7 @@ int MainWindow::changeDB(QString fname)
return 1;
close_database();
homedir = fname.mid(0, fname.lastIndexOf(QDir::separator()));
dbfile = fname;
return init_database();
return init_database(fname);
}
void MainWindow::update_history_menu()
@ -218,7 +218,7 @@ void MainWindow::load_database()
void MainWindow::setOptions()
{
if (dbfile.isEmpty())
if (!QSqlDatabase::database().isOpen())
return;
Options *opt = new Options(this);

View File

@ -119,12 +119,6 @@ MainWindow::MainWindow(QWidget *parent)
fprintf(stderr, "DB driver: '%s'\n", CCHAR(driver));
}
//#define POSTGRES 1
#ifndef POSTGRES
db = QSqlDatabase::addDatabase("QSQLITE");
#else
db = QSqlDatabase::addDatabase("QPSQL7");
#endif
historyMenu = NULL;
init_menu();
setItemEnabled(false);
@ -649,6 +643,7 @@ void MainWindow::changeDbPass()
{
Passwd pass;
XSqlQuery q;
QSqlDatabase db = QSqlDatabase::database();
if (!checkOldGetNewPass(pass))
return;
@ -682,13 +677,13 @@ void MainWindow::changeDbPass()
pki_evp::passwd = pass;
}
int MainWindow::initPass()
int MainWindow::initPass(QString dbName)
{
QString passhash = getSetting("pwhash");
return initPass(passhash);
return initPass(dbName, passhash);
}
int MainWindow::initPass(QString passhash)
int MainWindow::initPass(QString dbName, QString passhash)
{
pki_evp::passHash = QString();
QString salt, pass;
@ -696,8 +691,8 @@ int MainWindow::initPass(QString passhash)
pass_info p(tr("New Password"), tr("Please enter a password, "
"that will be used to encrypt your private keys "
"in the database file:\n%1").
arg(compressFilename(dbfile)), this);
"in the database:\n%1").
arg(compressFilename(dbName)), this);
pki_evp::passHash = passhash;
if (pki_evp::passHash.isEmpty()) {
@ -716,7 +711,7 @@ int MainWindow::initPass(QString passhash)
XCA_WARN(
tr("Password verify error, please try again"));
p.setTitle(tr("Password"));
p.setDescription(tr("Please enter the password for unlocking the database:\n%1").arg(compressFilename(dbfile)));
p.setDescription(tr("Please enter the password for unlocking the database:\n%1").arg(compressFilename(dbName)));
ret = PwDialog::execute(&p, &pki_evp::passwd,
false, true);
if (ret != 1) {
@ -944,8 +939,8 @@ void MainWindow::changeEvent(QEvent *event)
if (model)
model->updateHeaders();
}
if (!dbfile.isEmpty())
dbindex->setText(tr("Database") + ": " + dbfile);
if (!currentDB.isEmpty())
dbindex->setText(tr("Database") + ": " + currentDB);
}
QMainWindow::changeEvent(event);
}

View File

@ -87,8 +87,8 @@ class MainWindow: public QMainWindow, public Ui::MainWindow
int exportIndex(QString fname, bool hierarchy);
void checkDB();
QSqlError initSqlDB();
QSqlError openSqlDB();
QSqlDatabase db;
QString openSqlDB(QString dbName);
QString currentDB;
protected:
void init_images();
@ -117,19 +117,14 @@ class MainWindow: public QMainWindow, public Ui::MainWindow
static QString explicit_dn;
static QString explicit_dn_default;
int exitApp;
QSqlDatabase *getDb()
{
return &db;
}
QString dbfile;
QLabel *dbindex;
MainWindow(QWidget *parent);
virtual ~MainWindow();
void loadSettings();
void saveSettings();
int initPass();
int initPass(QString passhash);
int initPass(QString dbName);
int initPass(QString dbName, QString passhash);
void read_cmdline(int argc, char *argv[]);
void load_engine();
static OidResolver *getResolver()
@ -158,11 +153,12 @@ class MainWindow: public QMainWindow, public Ui::MainWindow
void update_history(QString file);
void initResolver();
bool checkForOldDbFormat();
bool checkForOldDbFormat(QString dbfile);
int verifyOldDbPass(QString dbname);
void importOldDatabase(QString dbname);
public slots:
int init_database();
int init_database(QString dbName);
void new_database();
void load_database();
void close_database();
@ -181,6 +177,7 @@ class MainWindow: public QMainWindow, public Ui::MainWindow
void changeEvent(QEvent *event);
void exportIndex();
void exportIndexHierarchy();
void openRemoteSqlDB();
protected slots:
void closeEvent(QCloseEvent * event);

View File

@ -9,7 +9,7 @@ MOC_NAMES=MainWindow KeyDetail clicklabel XcaTreeView NewX509 \
ImportMulti CrlDetail ExportDialog hashBox Options NewKey kvView \
NewCrl SearchPkcs11 RevocationList XcaProxyModel XcaHeaderView \
KeyTreeView TempTreeView ReqTreeView X509SuperTreeView CertTreeView \
OidResolver
OidResolver OpenDb
NAMES=$(MOC_NAMES) NewX509_ext MW_menu MW_help MW_database
OBJS=$(patsubst %,moc_%.o,$(MOC_NAMES)) $(patsubst %,%.o,$(NAMES))

125
widgets/OpenDb.cpp Normal file
View File

@ -0,0 +1,125 @@
/* vi: set sw=4 ts=4:
*
* Copyright (C) 2017 Christian Hohnstaedt.
*
* All rights reserved.
*/
#include <stdio.h>
#include <QStringList>
#include <QFile>
#include "OpenDb.h"
#include "PwDialog.h"
#include "lib/base.h"
OpenDb::OpenDb(QWidget *parent, QString db)
:QDialog(parent)
{
QMap<QString, QString> databases;
QString dbTypeName;
setupUi(this);
setWindowTitle(XCA_TITLE);
QRegExp rx("(.*)@(.*)/(.*):(.*)");
int pos = rx.indexIn(db);
QStringList list = rx.capturedTexts();
foreach(QString s, list)
printf("OpenDB: '%s'\n", CCHAR(s));
if (pos != -1 && list.size() == 5) {
userName->setText(list[1]);
hostName->setText(list[2]);
dbTypeName = list[3];
dbName->setText(list[4]);
} else {
dbName->setText(db);
dbTypeName = "QSQLITE";
}
databases["QPSQL7"] = "PostgreSQL version 6 and 7";
databases["QMYSQL3"] = "MySQL 3.x and 4.x";
databases["QSQLITE" ] = "SQLite version 3 or above";
list = QSqlDatabase::drivers();
foreach (QString driver, list) {
if (!databases.contains(driver))
continue;
dbType->insertItem(0, databases[driver], driver);
if (driver == dbTypeName)
dbType->setCurrentIndex(0);
}
}
void OpenDb::openDatabase() const
{
QString type = dbType->itemData(dbType->currentIndex()).toString();
QString pass = dbPassword->text();
if (type == "QSQLITE" && !QFile::exists(dbName->text())) {
QFile f(dbName->text());
f.open(QIODevice::WriteOnly);
f.setPermissions(QFile::WriteOwner | QFile::ReadOwner);
f.close();
}
while (true) {
QString connName = QSqlDatabase::addDatabase(type).connectionName();
if (_openDatabase(connName, pass))
break;
Passwd pwd;
pass_info p(XCA_TITLE,
tr("Please enter the password to access the database server %2 as user '%1'.")
.arg(userName->text()).arg(hostName->text()));
if (PwDialog::execute(&p, &pwd) != 1)
break;
pass =QString(pwd);
QSqlDatabase::removeDatabase(connName);
}
}
bool OpenDb::_openDatabase(QString connName, QString pass) const
{
QSqlDatabase db = QSqlDatabase::database(connName, false);
QStringList hostport = hostName->text().split(":");
db.setDatabaseName(dbName->text());
printf("hostport.size(): %d\n", hostport.size());
if (hostport.size() > 0)
db.setHostName(hostport[0]);
if (hostport.size() > 1)
db.setPort(hostport[1].toInt());
db.setUserName(userName->text());
db.setPassword(pass);
db.open();
QSqlError e = db.lastError();
if (!e.isValid() || e.type() != QSqlError::ConnectionError ||
db.driverName() == "QSQLITE" || db.isOpen())
return true;
db.close();
return false;
};
QString OpenDb::getDescriptor() const
{
QString type = dbType->itemData(dbType->currentIndex()).toString();
if (type == "QSQLITE")
return dbName->text();
return QString("%1@%2/%3:%4")
.arg(userName->text())
.arg(hostName->text())
.arg(type)
.arg(dbName->text());
}
int OpenDb::exec()
{
QString type = dbType->itemData(dbType->currentIndex()).toString();
if (type != "QSQLITE")
return QDialog::exec();
return 1;
}

28
widgets/OpenDb.h Normal file
View File

@ -0,0 +1,28 @@
/* vi: set sw=4 ts=4:
*
* Copyright (C) 2017 Christian Hohnstaedt.
*
* All rights reserved.
*/
#ifndef __OPENDB_H
#define __OPENDB_H
#include "ui_OpenDb.h"
#include <QSqlDatabase>
class OpenDb: public QDialog, public Ui::OpenDb
{
Q_OBJECT
public:
OpenDb(QWidget *parent, QString db);
void openDatabase() const;
bool _openDatabase(QString connName, QString pass) const;
QString getDescriptor() const;
public slots:
int exec();
};
#endif