QCA

pkcs11configdlg.cpp
1 /*
2  Copyright (C) 2007 Justin Karneges <[email protected]>
3 
4  Permission is hereby granted, free of charge, to any person obtaining a copy
5  of this software and associated documentation files (the "Software"), to deal
6  in the Software without restriction, including without limitation the rights
7  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  copies of the Software, and to permit persons to whom the Software is
9  furnished to do so, subject to the following conditions:
10 
11  The above copyright notice and this permission notice shall be included in
12  all copies or substantial portions of the Software.
13 
14  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18  AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 */
21 
22 #include "pkcs11configdlg.h"
23 
24 #include "ui_pkcs11config.h"
25 #include <QFileDialog>
26 #include <QMessageBox>
27 #include <QtCore>
28 #include <QtCrypto>
29 #include <QtGui>
30 
31 //----------------------------------------------------------------------------
32 // Pkcs11ProviderConfig
33 //----------------------------------------------------------------------------
34 class Pkcs11ProviderConfig
35 {
36 public:
37  bool allow_protected_authentication;
38  bool cert_private;
39  bool enabled;
40  QString library;
41  QString name;
42  int private_mask;
43  QString slotevent_method;
44  int slotevent_timeout;
45 
46  Pkcs11ProviderConfig()
47  : allow_protected_authentication(true)
48  , cert_private(false)
49  , enabled(false)
50  , private_mask(0)
51  , slotevent_method("auto")
52  , slotevent_timeout(0)
53  {
54  }
55 
56  QVariantMap toVariantMap() const
57  {
58  QVariantMap out;
59  out["allow_protected_authentication"] = allow_protected_authentication;
60  out["cert_private"] = cert_private;
61  out["enabled"] = enabled;
62  out["library"] = library;
63  out["name"] = name;
64  out["private_mask"] = private_mask;
65  out["slotevent_method"] = slotevent_method;
66  out["slotevent_timeout"] = slotevent_timeout;
67  return out;
68  }
69 
70  bool fromVariantMap(const QVariantMap &in)
71  {
72  allow_protected_authentication = in["allow_protected_authentication"].toBool();
73  cert_private = in["cert_private"].toBool();
74  enabled = in["enabled"].toBool();
75  library = in["library"].toString();
76  name = in["name"].toString();
77  private_mask = in["private_mask"].toInt();
78  slotevent_method = in["slotevent_method"].toString();
79  slotevent_timeout = in["slotevent_timeout"].toInt();
80  return true;
81  }
82 };
83 
84 //----------------------------------------------------------------------------
85 // Pkcs11Config
86 //----------------------------------------------------------------------------
87 class Pkcs11Config
88 {
89 public:
90  bool allow_load_rootca;
91  bool allow_protected_authentication;
92  int log_level;
93  int pin_cache;
95 
96  QVariantMap orig_config;
97 
98  Pkcs11Config()
99  : allow_load_rootca(false)
100  , allow_protected_authentication(true)
101  , log_level(0)
102  , pin_cache(-1)
103  {
104  }
105 
106  QVariantMap toVariantMap() const
107  {
108  QVariantMap out = orig_config;
109 
110  // form type
111  out["formtype"] = "http://affinix.com/qca/forms/qca-pkcs11#1.0";
112 
113  // base settings
114  out["allow_load_rootca"] = allow_load_rootca;
115  out["allow_protected_authentication"] = allow_protected_authentication;
116  out["log_level"] = log_level;
117  out["pin_cache"] = pin_cache;
118 
119  // provider settings (always write at least 10 providers)
120  for (int n = 0; n < 10 || n < providers.count(); ++n) {
121  QString prefix = QString().sprintf("provider_%02d_", n);
122 
123  Pkcs11ProviderConfig provider;
124  if (n < providers.count())
125  provider = providers[n];
126 
127  QVariantMap subconfig = provider.toVariantMap();
128  QMapIterator<QString, QVariant> it(subconfig);
129  while (it.hasNext()) {
130  it.next();
131  out.insert(prefix + it.key(), it.value());
132  }
133  }
134 
135  return out;
136  }
137 
138  bool fromVariantMap(const QVariantMap &in)
139  {
140  if (in["formtype"] != "http://affinix.com/qca/forms/qca-pkcs11#1.0")
141  return false;
142 
143  allow_load_rootca = in["allow_load_rootca"].toBool();
144  allow_protected_authentication = in["allow_protected_authentication"].toBool();
145  log_level = in["log_level"].toInt();
146  pin_cache = in["pin_cache"].toInt();
147 
148  for (int n = 0;; ++n) {
149  QString prefix = QString().sprintf("provider_%02d_", n);
150 
151  // collect all key/values with this prefix into a
152  // a separate container, leaving out the prefix
153  // from the keys.
154  QVariantMap subconfig;
156  while (it.hasNext()) {
157  it.next();
158  if (it.key().startsWith(prefix))
159  subconfig.insert(it.key().mid(prefix.length()), it.value());
160  }
161 
162  // if there are no config items with this prefix, we're done
163  if (subconfig.isEmpty())
164  break;
165 
166  Pkcs11ProviderConfig provider;
167  if (!provider.fromVariantMap(subconfig))
168  return false;
169 
170  // skip unnamed entries
171  if (provider.name.isEmpty())
172  continue;
173 
174  // skip duplicate entries
175  bool have_name_already = false;
176  foreach (const Pkcs11ProviderConfig &i, providers) {
177  if (i.name == provider.name) {
178  have_name_already = true;
179  break;
180  }
181  }
182  if (have_name_already)
183  continue;
184 
185  providers += provider;
186  }
187 
188  orig_config = in;
189  return true;
190  }
191 };
192 
193 //----------------------------------------------------------------------------
194 // ModuleListModel
195 //----------------------------------------------------------------------------
196 class ModuleListModel : public QAbstractListModel
197 {
198  Q_OBJECT
199 public:
201 
202  ModuleListModel(QObject *parent = 0)
203  : QAbstractListModel(parent)
204  {
205  }
206 
207  int rowCount(const QModelIndex &parent = QModelIndex()) const
208  {
209  Q_UNUSED(parent);
210  return list.count();
211  }
212 
213  QVariant data(const QModelIndex &index, int role) const
214  {
215  if (!index.isValid())
216  return QVariant();
217 
218  if (index.row() >= list.count())
219  return QVariant();
220 
221  if (role == Qt::DisplayRole)
222  return list[index.row()].name;
223  else if (role == Qt::EditRole)
224  return list[index.row()].name;
225  else
226  return QVariant();
227  }
228 
229  Qt::ItemFlags flags(const QModelIndex &index) const
230  {
231  if (!index.isValid())
232  return Qt::ItemIsEnabled;
233 
235  }
236 
237  bool setData(const QModelIndex &index, const QVariant &value, int role)
238  {
239  if (index.isValid() && role == Qt::EditRole) {
240  QString str = value.toString();
241 
242  if (str.isEmpty()) {
243  emit editFailed(index, tr("Module name cannot be blank."));
244  return false;
245  }
246 
247  bool have_name_already = false;
248  int at = index.row();
249  for (int n = 0; n < list.count(); ++n) {
250  const Pkcs11ProviderConfig &i = list[n];
251 
252  // skip self
253  if (n == at)
254  continue;
255 
256  if (i.name == str) {
257  have_name_already = true;
258  break;
259  }
260  }
261  if (have_name_already) {
262  emit editFailed(index, tr("There is already a module with this name."));
263  return false;
264  }
265 
266  list[index.row()].name = str;
267  emit dataChanged(index, index);
268  return true;
269  }
270  return false;
271  }
272 
273  void addItems(const QList<Pkcs11ProviderConfig> &items)
274  {
275  if (items.isEmpty())
276  return;
277 
278  beginInsertRows(QModelIndex(), list.size(), list.size() + items.count() - 1);
279  list += items;
280  endInsertRows();
281  }
282 
283  void addItem(const Pkcs11ProviderConfig &i)
284  {
285  beginInsertRows(QModelIndex(), list.size(), list.size());
286  list += i;
287  endInsertRows();
288  }
289 
290  void removeItem(int at)
291  {
292  beginRemoveRows(QModelIndex(), at, at);
293  list.removeAt(at);
294  endRemoveRows();
295  }
296 
297 Q_SIGNALS:
298  void editFailed(const QModelIndex &index, const QString &reasonString);
299 };
300 
301 //----------------------------------------------------------------------------
302 // Pkcs11ConfigDlg
303 //----------------------------------------------------------------------------
304 static QCA::Provider *get_pkcs11_provider(QVariantMap *_config = 0)
305 {
306  QCA::ProviderList providers = QCA::providers();
307  providers += QCA::defaultProvider();
308 
309  QCA::Provider *provider = 0;
310  QVariantMap config;
311  foreach (QCA::Provider *p, providers) {
312  config = QCA::getProviderConfig(p->name());
313  if (!config.isEmpty() && config["formtype"] == "http://affinix.com/qca/forms/qca-pkcs11#1.0") {
314  provider = p;
315  break;
316  }
317  }
318 
319  if (provider && _config)
320  *_config = config;
321 
322  return provider;
323 }
324 
325 class Pkcs11ConfigDlg::Private : public QObject
326 {
327  Q_OBJECT
328 public:
329  Pkcs11ConfigDlg *q;
330  Ui_Pkcs11Config ui;
331  QString providerName;
332  ModuleListModel *model;
333  Pkcs11Config config;
334  bool dirty;
335 
336  // for safe dialog closing behavior during QListView editing
337  bool allow_close;
338  bool done;
339 
340  // for ignoring modifications that we cause when populating fields
341  bool ignore_dataChanged;
342 
343  Private(Pkcs11ConfigDlg *_q, const QString &_providerName, const QVariantMap &configmap)
344  : QObject(_q)
345  , q(_q)
346  , providerName(_providerName)
347  , dirty(false)
348  , allow_close(true)
349  , done(false)
350  , ignore_dataChanged(true)
351  {
352  ui.setupUi(q);
353  q->resize(q->minimumSize());
354 
355  model = new ModuleListModel(this);
356  qRegisterMetaType<QModelIndex>("QModelIndex");
357  // do this queued for two reasons:
358  // 1) if we throw an error dialog, it will occur after the
359  // row text has reverted, and the call stack completed
360  // (the latter may not be required, but it helps me
361  // sleep).
362  // 2) if the user accepts/rejects the dialog while editing,
363  // it is easy to ensure that the signal is not processed
364  // (if it gets delivered at all).
365  connect(model,
366  SIGNAL(editFailed(const QModelIndex &, const QString &)),
367  SLOT(model_editFailed(const QModelIndex &, const QString &)),
369 
370  // set up widgets
371  ui.rb_pincache_nolimit->setChecked(true);
372  ui.sb_pincache_time->setEnabled(false);
373  ui.sb_pincache_time->setValue(300);
374  ui.lv_modules->setModel(model);
377  ui.pb_remove->setEnabled(false);
378  ui.tb_details->setEnabled(false);
379  ui.gb_poll->setEnabled(false);
380  ui.rb_polldefault->setChecked(true);
381  ui.sb_pollcustom->setEnabled(false);
382  ui.sb_pollcustom->setValue(5);
383  ui.ck_modeauto->setChecked(true);
384 
385  // disable this by default, enable on dataChanged
386  ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
387 
388  // general
389  connect(ui.ck_allowroot, SIGNAL(toggled(bool)), SLOT(dataChanged()));
390  connect(ui.ck_allowprotected, SIGNAL(toggled(bool)), SLOT(dataChanged()));
391  connect(ui.sb_loglevel, SIGNAL(valueChanged(int)), SLOT(dataChanged()));
392  connect(ui.gb_pincache, SIGNAL(toggled(bool)), SLOT(dataChanged()));
393  connect(ui.rb_pincache_nolimit, SIGNAL(toggled(bool)), SLOT(dataChanged()));
394  connect(ui.rb_pincache_time, SIGNAL(toggled(bool)), ui.sb_pincache_time, SLOT(setEnabled(bool)));
395  connect(ui.rb_pincache_time, SIGNAL(toggled(bool)), SLOT(dataChanged()));
396  connect(ui.sb_pincache_time, SIGNAL(valueChanged(int)), SLOT(dataChanged()));
397 
398  // modules
399  connect(model, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), SLOT(dataChanged()));
400  connect(ui.lv_modules->selectionModel(),
401  SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
402  SLOT(module_selectionChanged(const QItemSelection &, const QItemSelection &)));
403  connect(ui.pb_add, SIGNAL(clicked()), SLOT(module_add()));
404  connect(ui.pb_remove, SIGNAL(clicked()), SLOT(module_remove()));
405  connect(ui.le_library, SIGNAL(textChanged(const QString &)), SLOT(dataChanged()));
406  connect(ui.pb_browse, SIGNAL(clicked()), SLOT(library_browse()));
407  connect(ui.cb_slotmethod, SIGNAL(currentIndexChanged(int)), SLOT(slotmethod_currentIndexChanged(int)));
408  connect(ui.rb_polldefault, SIGNAL(toggled(bool)), SLOT(dataChanged()));
409  connect(ui.rb_pollcustom, SIGNAL(toggled(bool)), ui.sb_pollcustom, SLOT(setEnabled(bool)));
410  connect(ui.rb_pollcustom, SIGNAL(toggled(bool)), SLOT(dataChanged()));
411  connect(ui.sb_pollcustom, SIGNAL(valueChanged(int)), SLOT(dataChanged()));
412  connect(ui.ck_modallowprotected, SIGNAL(toggled(bool)), SLOT(dataChanged()));
413  connect(ui.ck_certprivate, SIGNAL(toggled(bool)), SLOT(dataChanged()));
414  connect(ui.ck_modeauto, SIGNAL(toggled(bool)), SLOT(modeauto_toggled(bool)));
415  connect(ui.ck_modesign, SIGNAL(toggled(bool)), SLOT(modenonauto_toggled(bool)));
416  connect(ui.ck_modesignrecover, SIGNAL(toggled(bool)), SLOT(modenonauto_toggled(bool)));
417  connect(ui.ck_modedecrypt, SIGNAL(toggled(bool)), SLOT(modenonauto_toggled(bool)));
418  connect(ui.ck_modeunwrap, SIGNAL(toggled(bool)), SLOT(modenonauto_toggled(bool)));
419 
420  // is this a valid config?
421  if (!providerName.isEmpty() && config.fromVariantMap(configmap)) {
422  // if so, load everything up
423  ui.ck_allowroot->setChecked(config.allow_load_rootca);
424  ui.ck_allowprotected->setChecked(config.allow_protected_authentication);
425  ui.sb_loglevel->setValue(config.log_level);
426  if (config.pin_cache != 0) {
427  ui.gb_pincache->setChecked(true);
428  if (config.pin_cache <= -1)
429  ui.rb_pincache_nolimit->setChecked(true);
430  else {
431  ui.rb_pincache_time->setChecked(true);
432  ui.sb_pincache_time->setValue(config.pin_cache);
433  }
434  }
435 
436  model->addItems(config.providers);
437  if (!model->list.isEmpty()) {
438  QModelIndex index = model->index(0);
439  ui.lv_modules->setCurrentIndex(index);
440  ui.lv_modules->selectionModel()->select(
442  }
443  ui.buttonBox->setFocus();
444  ui.buttonBox->button(QDialogButtonBox::Cancel)->setFocus();
445  } else {
446  // otherwise, disable everything
447  ui.gb_general->setEnabled(false);
448  ui.gb_modules->setEnabled(false);
449  ui.buttonBox->setFocus();
450  ui.buttonBox->button(QDialogButtonBox::Cancel)->setFocus();
451  }
452 
453  ignore_dataChanged = false;
454  }
455 
456  void save_module(int at)
457  {
458  // save all options (except the name, which is handled by the model)
459  Pkcs11ProviderConfig &i = model->list[at];
460 
461  i.library = ui.le_library->text();
462  i.enabled = true;
463 
464  int x = ui.cb_slotmethod->currentIndex();
465  if (x == 0)
466  i.slotevent_method = "auto";
467  else if (x == 1)
468  i.slotevent_method = "trigger";
469  else // 2
470  i.slotevent_method = "poll";
471  if (x == 2) {
472  if (ui.rb_polldefault->isChecked())
473  i.slotevent_timeout = 0;
474  else
475  i.slotevent_timeout = ui.sb_pollcustom->value();
476  } else
477  i.slotevent_timeout = 0;
478 
479  i.allow_protected_authentication = ui.ck_modallowprotected->isChecked();
480  i.cert_private = ui.ck_certprivate->isChecked();
481 
482  i.private_mask = 0;
483  if (ui.ck_modesign->isChecked())
484  i.private_mask |= 1;
485  if (ui.ck_modesignrecover->isChecked())
486  i.private_mask |= 2;
487  if (ui.ck_modedecrypt->isChecked())
488  i.private_mask |= 4;
489  if (ui.ck_modeunwrap->isChecked())
490  i.private_mask |= 8;
491  }
492 
493  void save()
494  {
495  // save currently selected module, which may not be saved yet
496  QItemSelection selection = ui.lv_modules->selectionModel()->selection();
497  if (!selection.indexes().isEmpty()) {
498  QModelIndex index = selection.indexes().first();
499  save_module(index.row());
500  }
501 
502  config.allow_load_rootca = ui.ck_allowroot->isChecked();
503  config.allow_protected_authentication = ui.ck_allowprotected->isChecked();
504  config.log_level = ui.sb_loglevel->value();
505  if (ui.gb_pincache->isChecked()) {
506  if (ui.rb_pincache_nolimit->isChecked())
507  config.pin_cache = -1;
508  else
509  config.pin_cache = ui.sb_pincache_time->value();
510  } else
511  config.pin_cache = 0;
512 
513  config.providers = model->list;
514 
515  QVariantMap configmap = config.toVariantMap();
516  QCA::setProviderConfig(providerName, configmap);
517  QCA::saveProviderConfig(providerName);
518  }
519 
520 private Q_SLOTS:
521  void model_editFailed(const QModelIndex &index, const QString &reasonString)
522  {
523  // if the dialog has already been dismissed, then don't
524  // bother with handling the editing failure
525  if (done)
526  return;
527 
528  // show error dialog, and don't allow dimissing the dialog
529  // during. we need this, because the dismiss request
530  // can be queued, and end up being invoked during the
531  // QMessageBox nested eventloop.
532  allow_close = false;
533  QMessageBox::information(q, tr("Module Configuration"), reasonString);
534  allow_close = true;
535 
536  // return to edit mode for the item
537  ui.lv_modules->setFocus();
538  ui.lv_modules->setCurrentIndex(index);
539  ui.lv_modules->selectionModel()->select(
541  ui.lv_modules->edit(index);
542  }
543 
544  void dataChanged()
545  {
546  if (ignore_dataChanged)
547  return;
548 
549  if (dirty)
550  return;
551 
552  dirty = true;
553  ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
554  }
555 
556  void module_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
557  {
558  if (!deselected.indexes().isEmpty()) {
559  QModelIndex index = deselected.indexes().first();
560  save_module(index.row());
561  }
562 
563  ignore_dataChanged = true;
564 
565  if (!selected.indexes().isEmpty()) {
566  if (deselected.indexes().isEmpty()) {
567  ui.pb_remove->setEnabled(true);
568  ui.tb_details->setEnabled(true);
569  }
570 
571  QModelIndex index = selected.indexes().first();
572  const Pkcs11ProviderConfig &i = model->list[index.row()];
573 
574  ui.le_library->setText(i.library);
575 
576  if (i.slotevent_method == "trigger")
577  ui.cb_slotmethod->setCurrentIndex(1);
578  else if (i.slotevent_method == "poll") {
579  ui.cb_slotmethod->setCurrentIndex(2);
580  if (i.slotevent_timeout <= 0)
581  ui.rb_polldefault->setChecked(true);
582  else {
583  ui.rb_pollcustom->setChecked(true);
584  ui.sb_pollcustom->setValue(i.slotevent_timeout);
585  }
586  } else // auto
587  ui.cb_slotmethod->setCurrentIndex(0);
588  if (i.slotevent_method != "poll") {
589  ui.rb_polldefault->setChecked(true);
590  ui.sb_pollcustom->setValue(5);
591  }
592 
593  ui.ck_modallowprotected->setChecked(i.allow_protected_authentication);
594  ui.ck_certprivate->setChecked(i.cert_private);
595 
596  if (i.private_mask == 0)
597  ui.ck_modeauto->setChecked(true);
598  else {
599  ui.ck_modesign->setChecked(i.private_mask & 1);
600  ui.ck_modesignrecover->setChecked(i.private_mask & 2);
601  ui.ck_modedecrypt->setChecked(i.private_mask & 4);
602  ui.ck_modeunwrap->setChecked(i.private_mask & 8);
603  }
604  } else if (selected.indexes().isEmpty() && !deselected.indexes().isEmpty()) {
605  // restore defaults for all details widgets
606  ui.le_library->setText(QString());
607  ui.cb_slotmethod->setCurrentIndex(0);
608  ui.rb_polldefault->setChecked(true);
609  ui.sb_pollcustom->setValue(5);
610  ui.ck_modallowprotected->setChecked(false);
611  ui.ck_certprivate->setChecked(false);
612  ui.ck_modeauto->setChecked(true);
613 
614  // flip to first page, disable
615  ui.tb_details->setCurrentIndex(0);
616  ui.pb_remove->setEnabled(false);
617  ui.tb_details->setEnabled(false);
618  }
619 
620  ignore_dataChanged = false;
621  }
622 
623  void module_add()
624  {
625  // find unused default name
626  QString name;
627  for (int n = 1;; ++n) {
628  if (n == 1)
629  name = tr("New Module");
630  else
631  name = tr("New Module (%1)").arg(n);
632 
633  bool have_name_already = false;
634  for (int n = 0; n < model->list.count(); ++n) {
635  const Pkcs11ProviderConfig &i = model->list[n];
636  if (i.name == name) {
637  have_name_already = true;
638  break;
639  }
640  }
641  if (!have_name_already)
642  break;
643  }
644 
645  Pkcs11ProviderConfig i;
646  i.name = name;
647  i.enabled = true;
648  model->addItem(i);
649 
650  dataChanged();
651 
652  QModelIndex index = model->index(model->list.count() - 1);
653 
654  // flip to first page
655  ui.tb_details->setCurrentIndex(0);
656 
657  // edit this item
658  ui.lv_modules->setFocus();
659  ui.lv_modules->setCurrentIndex(index);
660  ui.lv_modules->selectionModel()->select(
662  ui.lv_modules->edit(index);
663  }
664 
665  void module_remove()
666  {
667  QItemSelection selection = ui.lv_modules->selectionModel()->selection();
668  if (selection.indexes().isEmpty())
669  return;
670  QModelIndex index = selection.indexes().first();
671  model->removeItem(index.row());
672 
673  dataChanged();
674  }
675 
676  void library_browse()
677  {
678  QString fileName =
679  QFileDialog::getOpenFileName(q, tr("Select PKCS#11 Module"), QString(), tr("PKCS#11 Modules (*.*)"));
680  if (fileName.isEmpty())
681  return;
682 
683  ui.le_library->setText(fileName);
684  }
685 
686  void slotmethod_currentIndexChanged(int index)
687  {
688  if (index == 2) // Polling
689  ui.gb_poll->setEnabled(true);
690  else
691  ui.gb_poll->setEnabled(false);
692 
693  dataChanged();
694  }
695 
696  void modeauto_toggled(bool checked)
697  {
698  if (checked) {
699  if (ui.ck_modesign->isChecked())
700  ui.ck_modesign->setChecked(false);
701  if (ui.ck_modesignrecover->isChecked())
702  ui.ck_modesignrecover->setChecked(false);
703  if (ui.ck_modedecrypt->isChecked())
704  ui.ck_modedecrypt->setChecked(false);
705  if (ui.ck_modeunwrap->isChecked())
706  ui.ck_modeunwrap->setChecked(false);
707  } else {
708  if (!ui.ck_modesign->isChecked() && !ui.ck_modesignrecover->isChecked() &&
709  !ui.ck_modedecrypt->isChecked() && !ui.ck_modeunwrap->isChecked()) {
710  ui.ck_modesign->setChecked(true);
711  ui.ck_modesignrecover->setChecked(true);
712  ui.ck_modedecrypt->setChecked(true);
713  ui.ck_modeunwrap->setChecked(true);
714  }
715  }
716 
717  dataChanged();
718  }
719 
720  void modenonauto_toggled(bool checked)
721  {
722  if (checked) {
723  if (ui.ck_modeauto->isChecked())
724  ui.ck_modeauto->setChecked(false);
725  } else {
726  if (!ui.ck_modesign->isChecked() && !ui.ck_modesignrecover->isChecked() &&
727  !ui.ck_modedecrypt->isChecked() && !ui.ck_modeunwrap->isChecked()) {
728  ui.ck_modeauto->setChecked(true);
729  }
730  }
731 
732  dataChanged();
733  }
734 };
735 
736 Pkcs11ConfigDlg::Pkcs11ConfigDlg(QWidget *parent)
737  : QDialog(parent)
738 {
739  QVariantMap config;
740  QCA::Provider *p = get_pkcs11_provider(&config);
741  if (p)
742  d = new Private(this, p->name(), config);
743  else
744  d = new Private(this, QString(), QVariantMap());
745 }
746 
747 Pkcs11ConfigDlg::Pkcs11ConfigDlg(const QString &providerName, const QVariantMap &config, QWidget *parent)
748  : QDialog(parent)
749 {
750  d = new Private(this, providerName, config);
751 }
752 
753 Pkcs11ConfigDlg::~Pkcs11ConfigDlg()
754 {
755  delete d;
756 }
757 
758 void Pkcs11ConfigDlg::done(int r)
759 {
760  if (!d->allow_close)
761  return;
762 
763  d->done = true;
764  if (r == Accepted)
765  d->save();
766  QDialog::done(r);
767 }
768 
770 {
771  return (get_pkcs11_provider() ? true : false);
772 }
773 
774 #include "pkcs11configdlg.moc"
QModelIndexList indexes() const const
QCA_EXPORT void setProviderConfig(const QString &name, const QVariantMap &config)
Set provider configuration.
QString name(const QVariant &location)
void removeAt(int i)
Algorithm provider.
Definition: qca_core.h:764
virtual void done(int r)
QCA_EXPORT ProviderList providers()
Return a list of the current providers.
QMessageBox::StandardButton information(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
int size() const const
KSharedConfigPtr config()
QCA_EXPORT QVariantMap getProviderConfig(const QString &name)
Retrieve provider configuration.
QString & sprintf(const char *cformat,...)
bool isValid() const const
void resize(int size)
int count(const T &value) const const
QCA_EXPORT Provider * defaultProvider()
Return the default provider.
QCA_EXPORT bool isSupported(const char *features, const QString &provider=QString())
Test if a capability (algorithm) is available.
int toInt(bool *ok, int base) const const
bool isEmpty() const const
DisplayRole
bool isEmpty() const const
int row() const const
const QList< QKeySequence > & save()
if(recurs()&&!first)
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
int length() const const
virtual Qt::ItemFlags flags(const QModelIndex &index) const const
QCA_EXPORT void saveProviderConfig(const QString &name)
Save provider configuration to persistent storage.
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options)
QueuedConnection
QString toString() const const
virtual QString name() const =0
The name of the provider.
KIOFILEWIDGETS_EXPORT QStringList list(const QString &fileClass)
typedef ItemFlags
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sat Sep 25 2021 23:05:35 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.