xca/widgets/Options.cpp
Christian Hohnstaedt ced0995862 Close #91: Change order of "PKCS#11 provider"
With this commit PKCS#11 libraries may be reordered
and enabled or disabled.

The slot selection dialog iterates over all enabled and successfully
loaded libraries in the configured order and collects the slots
of each of them.

In the options dialog the library info is shown in the tool-tip
2019-03-21 06:12:51 +01:00

279 lines
6.8 KiB
C++

/* vi: set sw=4 ts=4:
*
* Copyright (C) 2001 - 2012 Christian Hohnstaedt.
*
* All rights reserved.
*/
#include "lib/func.h"
#include "Options.h"
#include "SearchPkcs11.h"
#include "lib/pki_scard.h"
#include <openssl/objects.h>
#include <QMessageBox>
#include <QToolTip>
Options::Options(MainWindow *parent)
:QDialog(parent)
{
mw = parent;
setWindowTitle(XCA_TITLE);
setupUi(this);
foreach(int nid, *MainWindow::dn_nid) {
QString n = OBJ_nid2ln(nid);
extDNobj->addItem(n);
expDNobj->addItem(n);
}
string_opts << "MASK:0x2002" << "pkix" << "nombstr" <<
"utf8only" << "default";
QStringList s;
s << tr("Printable string or UTF8 (default)")
<< tr("PKIX recommendation in RFC2459")
<< tr("No BMP strings, only printable and T61")
<< tr("UTF8 strings only (RFC2459)")
<< tr("All strings");
mbstring->addItems(s);
mbstring->setCurrentIndex(string_opts.indexOf(Settings["string_opt"]));
searchP11 = NULL;
transDnEntries->setText(transDnEntries->text()
.arg(OBJ_nid2ln(NID_commonName))
.arg(dn_translations[NID_commonName]));
setDnString(Settings["mandatory_dn"], extDNlist);
setDnString(Settings["explicit_dn"], expDNlist);
setupPkcs11Provider(Settings["pkcs11path"]);
suppress->setCheckState(Settings["suppress_messages"]);
noColorize->setCheckState(Settings["no_expire_colors"]);
transDnEntries->setCheckState(Settings["translate_dn"]);
onlyTokenHashes->setCheckState(Settings["only_token_hashes"]);
disableNetscape->setCheckState(Settings["disable_netscape"]);
adapt_explicit_subject->setCheckState(Settings["adapt_explicit_subject"]);
QStringList units;
QString x = Settings["ical_expiry"];
units << tr("Days") << "D" << tr("Weeks") << "W";
ical_expiry_unit->addItemsData(units, x.right(1));
x.chop(1);
ical_expiry_num->setText(x);
units << "%" << "%";
x = QString(Settings["cert_expiry"]);
cert_expiry_unit->addItemsData(units, x.right(1));
x.chop(1);
cert_expiry_num->setText(x);
serial_len->setValue(Settings["serial_len"]);
connect(pkcs11List, SIGNAL(itemClicked(QListWidgetItem *)),
this, SLOT(Pkcs11ItemChanged(QListWidgetItem *)));
}
Options::~Options()
{
if (searchP11)
delete searchP11;
}
void Options::on_extDNadd_clicked()
{
extDNlist->addItem(extDNobj->currentText());
}
void Options::on_extDNdel_clicked()
{
extDNlist->takeItem(extDNlist->currentRow());
}
void Options::on_expDNadd_clicked()
{
expDNlist->addItem(expDNobj->currentText());
}
void Options::on_expDNdel_clicked()
{
expDNlist->takeItem(expDNlist->currentRow());
}
void Options::on_expDNdefault_clicked()
{
setDnString(Settings.defaults("explicit_dn"), expDNlist);
}
void Options::setDnString(QString dn, QListWidget *w)
{
QStringList dnl;
if (!dn.isEmpty())
dnl = dn.split(",");
w->clear();
for (int i=0; i < dnl.count(); i++) {
int nid = OBJ_sn2nid(CCHAR(dnl[i]));
w->addItem(OBJ_nid2ln(nid));
}
}
QString Options::getDnString(QListWidget *w)
{
QStringList dn;
for (int j=0; j<w->count(); j++) {
int nid = OBJ_ln2nid(CCHAR(w->item(j)->text()));
dn << QString(OBJ_nid2sn(nid));
}
return dn.join(",");
}
int Options::exec()
{
if (QDialog::exec() == QDialog::Rejected)
return QDialog::Rejected;
Transaction;
if (!TransBegin())
return QDialog::Rejected;
Settings["suppress_messages"] = suppress->checkState();
Settings["no_expire_colors"] = noColorize->checkState();
Settings["translate_dn"] = transDnEntries->checkState();
Settings["only_token_hashes"] = onlyTokenHashes->checkState();
Settings["disable_netscape"] = disableNetscape->checkState();
Settings["default_hash"] = hashAlgo->currentHashName();
Settings["mandatory_dn"] = getDnString(extDNlist);
Settings["explicit_dn"] = getDnString(expDNlist);
Settings["string_opt"] = string_opts[mbstring->currentIndex()];
Settings["pkcs11path"] = getPkcs11Provider();
Settings["cert_expiry"] = cert_expiry_num->text() +
cert_expiry_unit->currentItemData().toString();
Settings["ical_expiry"] = ical_expiry_num->text() +
ical_expiry_unit->currentItemData().toString();
Settings["serial_len"] = serial_len->value();
Settings["adapt_explicit_subject"] = adapt_explicit_subject->checkState();
return TransCommit() ? QDialog::Accepted : QDialog::Rejected;
}
void Options::on_addButton_clicked(void)
{
load_pkcs11 l;
QString fname;
fname = QFileDialog::getOpenFileName(this, l.caption,
getLibDir(), l.filter);
addLib(fname);
}
void Options::addLib(QString fname)
{
QString status;
fname = QFileInfo(fname).canonicalFilePath();
if (fname.isEmpty() || pkcs11::get_lib(fname))
return;
pkcs11_lib *l = pkcs11::load_lib(fname);
addLibItem(fname);
if (searchP11 && l)
QToolTip::showText(searchP11->mapToGlobal(
QPoint(0,0)), l->driverInfo().trimmed());
}
void Options::on_removeButton_clicked(void)
{
QListWidgetItem *item = pkcs11List->takeItem(pkcs11List->currentRow());
if (!item)
return;
try {
pkcs11::remove_lib(item->text());
} catch (errorEx &err) {
mw->Error(err);
}
}
void Options::on_searchPkcs11_clicked(void)
{
if (!searchP11) {
searchP11 = new SearchPkcs11(this, QString());
connect(searchP11, SIGNAL(addLib(QString)),
this, SLOT(addLib(QString)));
}
searchP11->show();
}
void Options::Pkcs11ItemChanged(QListWidgetItem *item)
{
TRACE
pkcs11List->blockSignals(true);
pkcs11_lib *l = pkcs11::get_libs().get_lib(item->text());
qDebug() << item->text() << item->checkState() << l->isEnabled() << l->isLoaded();
if ((item->checkState() == Qt::Checked) != l->isEnabled()) {
QString file = listItem2Name(item);
pkcs11::remove_lib(file);
pkcs11::load_lib(file);
updatePkcs11Item(item);
}
pkcs11List->blockSignals(false);
}
void Options::updatePkcs11Item(QListWidgetItem *item) const
{
pkcs11_lib *l = pkcs11::get_libs().get_lib(item->text());
if (!l)
return;
if (l->isEnabled()) {
item->setIcon(l->isLoaded() ?
*MainWindow::doneIco : *MainWindow::warnIco);
} else {
QPixmap m(QSize(20,20));
m.fill(Qt::transparent);
item->setIcon(QIcon(m));
}
item->setToolTip(l->driverInfo().trimmed());
}
QListWidgetItem *Options::addLibItem(const QString &lib) const
{
pkcs11_lib *l = pkcs11::get_libs().get_lib(lib);
if (!l)
return NULL;
QListWidgetItem *item = new QListWidgetItem(lib);
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
updatePkcs11Item(item);
item->setText(l->filename());
item->setCheckState(l->isEnabled() ? Qt::Checked : Qt::Unchecked);
pkcs11List->addItem(item);
return item;
}
void Options::setupPkcs11Provider(QString list)
{
foreach(QString libname, list.split('\n')) {
addLibItem(libname);
}
}
QString Options::listItem2Name(const QListWidgetItem *item) const
{
return QString("%1:%2").arg(item->checkState() == Qt::Checked)
.arg(item->text());
}
QString Options::getPkcs11Provider()
{
QStringList prov;
for (int j=0; j<pkcs11List->count(); j++) {
prov << listItem2Name(pkcs11List->item(j));
}
if (prov.count() == 0)
return QString("");
return prov.join("\n");
}