1 /* vi: set sw=4 ts=4:
2 *
3 * Copyright (C) 2001 - 2014 Christian Hohnstaedt.
4 *
5 * All rights reserved.
6 */
7
8
9 #include "ImportMulti.h"
10 #include "XcaWarning.h"
11 #include "MainWindow.h"
12 #include "lib/pki_base.h"
13 #include "lib/pki_pkcs7.h"
14 #include "lib/pki_pkcs12.h"
15 #include "lib/pki_crl.h"
16 #include "lib/pki_multi.h"
17 #include "lib/pki_scard.h"
18 #include "lib/pki_evp.h"
19 #include "lib/pki_temp.h"
20 #include "CrlDetail.h"
21 #include "CertDetail.h"
22 #include "KeyDetail.h"
23
24 #include <QPushButton>
25 #include <QMessageBox>
26 #include <QLabel>
27 #include <QInputDialog>
28 #include <QUrl>
29 #include <QMimeData>
30 #include <typeinfo>
31
ImportMulti(QWidget * parent)32 ImportMulti::ImportMulti(QWidget *parent)
33 : QDialog(parent ?: mainwin)
34 {
35 setupUi(this);
36 setWindowTitle(XCA_TITLE);
37 image->setPixmap(QPixmap(":certImg"));
38 listView->setEditTriggers(QAbstractItemView::NoEditTriggers);
39 mcont = new db_token();
40 listView->setModel(mcont);
41 listView->setIconSize(QPixmap(":key").size());
42 listView->setSelectionMode(QAbstractItemView::ExtendedSelection);
43 connect( listView, SIGNAL(doubleClicked(const QModelIndex &)),
44 this, SLOT(on_butDetails_clicked()));
45 deleteToken->hide();
46 renameToken->hide();
47 slotInfo->hide();
48 setAcceptDrops(true);
49 setWindowModality(Qt::WindowModal);
50 }
51
tokenInfo(const slotid & s)52 void ImportMulti::tokenInfo(const slotid &s)
53 {
54 slot = s;
55 mcont->setSlot(slot);
56 deleteToken->show();
57 renameToken->show();
58 slotInfo->show();
59 listView->setEditTriggers(QAbstractItemView::EditKeyPressed);
60
61 pkcs11 p11;
62
63 QString info = p11.driverInfo(slot);
64 tkInfo ti = p11.tokenInfo(slot);
65 info += tr("\nName: %1\nModel: %2\nSerial: %3").
66 arg(ti.label()).arg(ti.model()).arg(ti.serial());
67
68 slotInfo->setText(info);
69 image->setPixmap(QPixmap(":scardImg"));
70 heading->setText(tr("Manage security token"));
71 setAcceptDrops(false);
72 }
73
addItem(pki_base * pki)74 void ImportMulti::addItem(pki_base *pki)
75 {
76 if (!pki)
77 return;
78
79 if (pki->pkiSource == unknown)
80 pki->pkiSource = imported;
81 pki_multi *pm = dynamic_cast<pki_multi*>(pki);
82 if (pm) {
83 QList<pki_base*> items = pm->pull();
84 foreach(pki_base *inner, items)
85 addItem(inner);
86 delete pm;
87 return;
88 }
89
90 pki_x509 *cert = dynamic_cast<pki_x509 *>(pki);
91 pki_crl *crl = dynamic_cast<pki_crl *>(pki);
92 pki_x509super *cert_or_req = dynamic_cast<pki_x509super *>(pki);
93
94 if (cert)
95 cert->setSigner(cert->findIssuer());
96 if (cert_or_req)
97 cert_or_req->lookupKey();
98 if (crl)
99 crl->lookupIssuer();
100
101 if (!dynamic_cast<pki_key*>(pki) &&
102 !dynamic_cast<pki_x509name*>(pki))
103 {
104 XCA_WARN(tr("The type of the item '%1' is not recognized").
105 arg(pki->getClassName()));
106 delete pki;
107 return;
108 }
109 mcont->inToCont(pki);
110 mcont->rename_token_in_database(dynamic_cast<pki_scard*>(pki));
111 }
112
openDB() const113 bool ImportMulti::openDB() const
114 {
115 if (!Database.isOpen()) {
116 if (mainwin->init_database(QString()) == 2)
117 return false;
118 if (!Database.isOpen())
119 mainwin->load_database();
120 }
121 return Database.isOpen();
122 }
123
dragEnterEvent(QDragEnterEvent * event)124 void ImportMulti::dragEnterEvent(QDragEnterEvent *event)
125 {
126 if (event->mimeData()->hasUrls())
127 event->acceptProposedAction();
128 }
129
dropEvent(QDropEvent * event)130 void ImportMulti::dropEvent(QDropEvent *event)
131 {
132 QList<QUrl> urls = event->mimeData()->urls();
133 QUrl u;
134 QStringList failed;
135 pki_multi *pki = new pki_multi();
136
137 foreach(u, urls)
138 pki->probeAnything(u.toLocalFile());
139
140 failed << pki->failed_files;
141 importError(failed);
142 addItem(pki);
143 event->acceptProposedAction();
144 }
145
on_butRemove_clicked()146 void ImportMulti::on_butRemove_clicked()
147 {
148 QItemSelectionModel *selectionModel = listView->selectionModel();
149 QModelIndexList indexes = selectionModel->selectedIndexes();
150 QModelIndex index;
151 QString items;
152
153 foreach(index, indexes) {
154 if (index.column() != 0)
155 continue;
156 mcont->remFromCont(index);
157 pki_base *pki = db_base::fromIndex(index);
158 delete pki;
159 }
160 if (mcont->rowCount(QModelIndex()) == 0)
161 accept();
162 }
163
on_butOk_clicked()164 void ImportMulti::on_butOk_clicked()
165 {
166 if (!openDB())
167 return;
168
169 Transaction;
170 if (!TransBegin())
171 return;
172
173 while (mcont->rowCount(QModelIndex()))
174 import(mcont->index(0, 0, QModelIndex()));
175
176 TransCommit();
177 accept();
178 }
179
on_butImport_clicked()180 void ImportMulti::on_butImport_clicked()
181 {
182 QItemSelectionModel *selectionModel = listView->selectionModel();
183 QModelIndexList indexes = selectionModel->selectedIndexes();
184
185 if (!openDB())
186 return;
187
188 Transaction;
189 if (!TransBegin())
190 return;
191 foreach(QModelIndex index, indexes) {
192 if (index.column() != 0)
193 continue;
194 import(index);
195 }
196 TransCommit();
197 if (mcont->rowCount(QModelIndex()) == 0)
198 accept();
199 }
200
on_deleteToken_clicked()201 void ImportMulti::on_deleteToken_clicked()
202 {
203 QItemSelectionModel *selectionModel = listView->selectionModel();
204 QModelIndexList indexes = selectionModel->selectedIndexes();
205 QModelIndex index;
206 QString items;
207
208 foreach(index, indexes) {
209 if (index.column() != 0)
210 continue;
211 pki_base *pki = db_base::fromIndex(index);
212 try {
213 pki->deleteFromToken(slot);
214 mcont->remFromCont(index);
215 delete pki;
216 } catch (errorEx &err) {
217 XCA_ERROR(err);
218 }
219 }
220 }
on_renameToken_clicked()221 void ImportMulti::on_renameToken_clicked()
222 {
223 QItemSelectionModel *selectionModel = listView->selectionModel();
224 QModelIndexList indexes = selectionModel->selectedIndexes();
225 QModelIndex index;
226 QString items;
227
228 foreach(index, indexes) {
229 if (index.column() != 0)
230 continue;
231 listView->edit(index);
232 break;
233 }
234 }
235
import(const QModelIndex & idx)236 pki_base *ImportMulti::import(const QModelIndex &idx)
237 {
238 pki_base *pki = mcont->fromIndex(idx);
239
240 for (int i = 0; i < mcont->rowCount(idx); i++)
241 import(mcont->index(i, 0, idx));
242
243 if (!pki)
244 return NULL;
245
246 mcont->remFromCont(idx);
247
248 if (!Database.isOpen()) {
249 delete pki;
250 return NULL;
251 }
252 return Database.insert(pki);
253 }
254
on_butDetails_clicked()255 void ImportMulti::on_butDetails_clicked()
256 {
257 QItemSelectionModel *selectionModel = listView->selectionModel();
258 QModelIndex index;
259
260 if (!selectionModel->selectedIndexes().count())
261 return;
262
263 index = selectionModel->selectedIndexes().first();
264 pki_base *pki = db_base::fromIndex(index);
265
266 if (!pki)
267 return;
268 try {
269 pki_x509super *pki_super = dynamic_cast<pki_x509super*>(pki);
270 if (pki_super) {
271 CertDetail::showCert(this, pki_super);
272 return;
273 }
274 pki_key *key = dynamic_cast<pki_key*>(pki);
275 if (key) {
276 KeyDetail::showKey(this, key);
277 return;
278 }
279 pki_crl *crl = dynamic_cast<pki_crl*>(pki);
280 if (crl) {
281 CrlDetail::showCrl(this, crl);
282 return;
283 }
284 pki_temp *temp = dynamic_cast<pki_temp*>(pki);
285 if (temp) {
286 XCA_WARN(tr("Details of the item '%1' cannot be shown")
287 .arg("XCA template"));
288 return;
289 }
290 XCA_WARN(tr("The type of the item '%1' is not recognized").
291 arg(pki->getClassName()));
292 }
293 catch (errorEx &err) {
294 XCA_ERROR(err);
295 }
296 }
297
~ImportMulti()298 ImportMulti::~ImportMulti()
299 {
300 QModelIndex idx = listView->currentIndex();
301 while (idx != QModelIndex()) {
302 mcont->remFromCont(idx);
303 delete db_base::fromIndex(idx);
304 idx = listView->currentIndex();
305 }
306 listView->setModel(NULL);
307 delete mcont;
308 }
309
entries()310 int ImportMulti::entries()
311 {
312 return mcont->allItemsCount();
313 }
314
importError(QStringList failed)315 void ImportMulti::importError(QStringList failed)
316 {
317 if (failed.count() == 1) {
318 XCA_INFO(tr("The file '%1' did not contain PKI data").
319 arg(failed[0]));
320 } else if (failed.count() > 1) {
321 XCA_INFO(tr("The %1 files: '%2' did not contain PKI data").
322 arg(failed.count()).
323 arg(failed.join("', '")));
324 }
325 }
326
execute(int force,QStringList failed)327 void ImportMulti::execute(int force, QStringList failed)
328 {
329 importError(failed);
330
331 /* if there is nothing to import don't pop up */
332 if (entries() == 0) {
333 accept();
334 return;
335 }
336 /* if there is only 1 item and force is 0 import it silently */
337 if (entries() == 1 && force == 0 && openDB()) {
338 QModelIndex idx = mcont->index(0, 0, QModelIndex());
339 pki_base *pki = import(idx);
340 if (pki && !Settings["suppress_messages"])
341 XCA_INFO(pki->getMsg(pki_base::msg_import).
342 arg(pki->getIntName()));
343 accept();
344 return;
345 }
346 /* the behaviour for more than one item */
347 exec();
348 }
349