1 /* vi: set sw=4 ts=4:
2 *
3 * Copyright (C) 2014 Christian Hohnstaedt.
4 *
5 * All rights reserved.
6 */
7
8 #include "lib/func.h"
9 #include "lib/base.h"
10 #include "lib/Passwd.h"
11 #include "lib/exception.h"
12 #include "XcaWarning.h"
13 #include "PwDialog.h"
14 #include <QLabel>
15 #include <QMessageBox>
16
hex2bin(QString & x,Passwd * final)17 static int hex2bin(QString &x, Passwd *final)
18 {
19 bool ok = false;
20 int len = x.length();
21
22 if (len % 2)
23 return -1;
24 len /= 2;
25
26 final->clear();
27
28 for (int i=0; i<len; i++) {
29 final->append((x.mid(i*2, 2).toInt(&ok, 16)) & 0xff);
30 if (!ok)
31 return -1;
32 }
33 return len;
34 }
35
execute(pass_info * p,Passwd * passwd,bool write,bool abort)36 enum open_result PwDialog::execute(pass_info *p, Passwd *passwd,
37 bool write, bool abort)
38 {
39 #if !defined(Q_OS_WIN32)
40 if (!IS_GUI_APP) {
41 console_write(stdout,
42 QString(COL_CYAN "%1\n" COL_LRED "%2:" COL_RESET)
43 .arg(p->getDescription())
44 .arg(tr("Password")).toUtf8());
45 *passwd = readPass();
46 return pw_ok;
47 }
48 #endif
49 PwDialog *dlg = new PwDialog(p, write);
50 if (abort)
51 dlg->addAbortButton();
52 enum open_result result = (enum open_result)dlg->exec();
53 *passwd = dlg->getPass();
54 delete dlg;
55 if (result == pw_exit)
56 throw pw_exit;
57 return result;
58 }
59
pwCallback(char * buf,int size,int rwflag,void * userdata)60 int PwDialog::pwCallback(char *buf, int size, int rwflag, void *userdata)
61 {
62 Passwd passwd;
63 enum open_result result;
64 pass_info *p = static_cast<pass_info *>(userdata);
65
66 result = PwDialog::execute(p, &passwd, rwflag, false);
67
68 size = MIN(size, passwd.size());
69 memcpy(buf, passwd.constData(), size);
70 p->setResult(result);
71 return result == pw_ok ? size : 0;
72 }
73
PwDialog(pass_info * p,bool write)74 PwDialog::PwDialog(pass_info *p, bool write)
75 :QDialog(p->getWidget())
76 {
77 pi = p;
78 setupUi(this);
79 image->setPixmap(QPixmap(pi->getImage()));
80 description->setText(pi->getDescription());
81 title->setText(pi->getType());
82 if (!pi->getTitle().isEmpty())
83 setWindowTitle(pi->getTitle());
84 else
85 setWindowTitle(XCA_TITLE);
86 if (pi->getType() != "PIN")
87 takeHex->hide();
88 setRW(write);
89 }
90
setRW(bool write)91 void PwDialog::setRW(bool write)
92 {
93 wrDialog = write;
94 if (write) {
95 label->setText(pi->getType());
96 repeatLabel->setText(tr("Repeat %1").arg(pi->getType()));
97 label->show();
98 passA->show();
99 } else {
100 repeatLabel->setText(pi->getType());
101 label->hide();
102 passA->hide();
103 }
104 }
105
accept()106 void PwDialog::accept()
107 {
108 if (wrDialog && (passA->text() != passB->text())) {
109 XCA_WARN(tr("%1 mismatch").arg(pi->getType()));
110 return;
111 }
112 QString pw = passB->text();
113 if (takeHex->isChecked()) {
114 int ret = hex2bin(pw, &final);
115 if (ret == -1) {
116 XCA_WARN(tr("Hex password must only contain the characters '0' - '9' and 'a' - 'f' and it must consist of an even number of characters"));
117 return;
118 }
119 } else {
120 final = pw.toLatin1();
121 }
122 QDialog::accept();
123 }
124
buttonPress(QAbstractButton * but)125 void PwDialog::buttonPress(QAbstractButton *but)
126 {
127 qDebug() << "buttonBox->standardButton(but)" << buttonBox->buttonRole(but) << QDialogButtonBox::DestructiveRole;
128 switch (buttonBox->buttonRole(but)) {
129 case QDialogButtonBox::AcceptRole:
130 accept();
131 break;
132 case QDialogButtonBox::RejectRole:
133 reject();
134 break;
135 case QDialogButtonBox::ResetRole:
136 done(pw_exit);
137 break;
138 default:
139 break;
140 }
141 }
142
addAbortButton()143 void PwDialog::addAbortButton()
144 {
145 buttonBox->addButton(tr("Exit"), QDialogButtonBox::ResetRole);
146 }
147