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