1 /*
2 Copyright (C) 2011-2014 Yubico AB. All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
6 met:
7
8 1. Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 2. Redistributions in binary form must reproduce the above
12 copyright notice, this list of conditions and the following
13 disclaimer in the documentation and/or other materials provided
14 with the distribution.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "settingpage.h"
30 #include "yubikeyfinder.h"
31 #include "yubikeyutil.h"
32 #include "yubikeywriter.h"
33 #include "yubikeylogger.h"
34 #include "ui_settingpage.h"
35 #include "ui/helpbox.h"
36 #include "toolpage.h"
37
38 #include <QFile>
39 #include <QMessageBox>
40 #include <QDebug>
41 #include <QSettings>
42 #include <QSignalMapper>
43 #include <QRegExpValidator>
44
45 #include "common.h"
46
47 #define DECIMAL 0
48 #define MODHEX 1
49 #define HEX 2
50
51 #define OUT_CHAR_RATE_STD 0
52 #define OUT_CHAR_RATE_SLOWDOWN_20 1
53 #define OUT_CHAR_RATE_SLOWDOWN_40 2
54 #define OUT_CHAR_RATE_SLOWDOWN_60 3
55
SettingPage(QWidget * parent)56 SettingPage::SettingPage(QWidget *parent) :
57 QStackedWidget(parent),
58 ui(new Ui::SettingPage)
59 {
60 QSignalMapper *mapper = new QSignalMapper(this);
61 ui->setupUi(this);
62
63 m_ykConfig = NULL;
64
65 //Connect help buttons
66 connectHelpButtons();
67
68 connect(ui->updateBtn, SIGNAL(clicked()), mapper, SLOT(map()));
69 connect(ui->updateBackBtn, SIGNAL(clicked()), mapper, SLOT(map()));
70 mapper->setMapping(ui->updateBtn, Page_Update);
71 mapper->setMapping(ui->updateBackBtn, Page_Base);
72 connect(mapper, SIGNAL(mapped(int)), this, SLOT(setCurrentPage(int)));
73 m_currentPage = 0;
74 setCurrentIndex(Page_Base);
75
76 //Connect other signals and slots
77 connect(ui->restoreBtn, SIGNAL(clicked()),
78 this, SLOT(restore()));
79
80 // autosave when changing settings
81 connect(ui->custPrefixCheck, SIGNAL(clicked()), this, SLOT(save()));
82 connect(ui->logOutputCheck, SIGNAL(clicked()), this, SLOT(save()));
83 connect(ui->tabFirstBtn, SIGNAL(clicked()), this, SLOT(save()));
84 connect(ui->appendTab1Btn, SIGNAL(clicked()), this, SLOT(save()));
85 connect(ui->appendTab2Btn, SIGNAL(clicked()), this, SLOT(save()));
86 connect(ui->appendCRBtn, SIGNAL(clicked()), this, SLOT(save()));
87 connect(ui->appendDelay1Check, SIGNAL(clicked()), this, SLOT(save()));
88 connect(ui->appendDelay2Check, SIGNAL(clicked()), this, SLOT(save()));
89 connect(ui->srBtnVisibleCheck, SIGNAL(clicked()), this, SLOT(save()));
90 connect(ui->srUsbVisibleCheck, SIGNAL(clicked()), this, SLOT(save()));
91 connect(ui->srApiVisibleCheck, SIGNAL(clicked()), this, SLOT(save()));
92 connect(ui->manUpdateCheck, SIGNAL(clicked()), this, SLOT(save()));
93 connect(ui->updateCheck, SIGNAL(clicked()), this, SLOT(save()));
94 connect(ui->fastTrigCheck, SIGNAL(clicked()), this, SLOT(save()));
95 connect(ui->ledInvertCheck, SIGNAL(clicked()), this, SLOT(save()));
96 connect(ui->useNumericKeypadCheck, SIGNAL(clicked()), this, SLOT(save()));
97 connect(ui->logFormatCombo, SIGNAL(activated(int)), this, SLOT(save()));
98 connect(ui->logFormatEdit, SIGNAL(textEdited(QString)), this, SLOT(save()));
99 connect(ui->outCharRateCombo, SIGNAL(activated(int)), this, SLOT(save()));
100 connect(ui->exportCheck, SIGNAL(clicked()), this, SLOT(save()));
101
102 connect(YubiKeyFinder::getInstance(), SIGNAL(keyFound(bool, bool*, int)),
103 this, SLOT(keyFound(bool, bool*)));
104
105 QRegExp modHexRx("^[cbdefghijklnrtuv]{0,4}$");
106 ui->custPrefixModhexTxt->setValidator(new QRegExpValidator(modHexRx, this));
107 QRegExp decRx("^[0-9]{0,5}$");
108 ui->custPrefixDecTxt->setValidator(new QRegExpValidator(decRx, this));
109 QRegExp hexRx("^[0-9a-f]{0,4}$");
110 ui->custPrefixHexTxt->setValidator(new QRegExpValidator(hexRx, this));
111 }
112
~SettingPage()113 SettingPage::~SettingPage() {
114 delete ui->custPrefixModhexTxt->validator();
115 if(m_ykConfig != NULL) {
116 delete m_ykConfig;
117 }
118 delete ui;
119 }
120
connectHelpButtons()121 void SettingPage::connectHelpButtons() {
122 //Map the values of the help buttons
123
124 //Create a QMapper
125 QSignalMapper *mapper = new QSignalMapper(this);
126
127 //Connect the clicked signal with the QSignalMapper
128 connect(ui->outFormatHelpBtn, SIGNAL(clicked()), mapper, SLOT(map()));
129 connect(ui->outSpeedHelpBtn, SIGNAL(clicked()), mapper, SLOT(map()));
130 connect(ui->srVisibilityHelpBtn, SIGNAL(clicked()), mapper, SLOT(map()));
131 connect(ui->updateHelpBtn, SIGNAL(clicked()), mapper, SLOT(map()));
132 connect(ui->swapHelpBtn, SIGNAL(clicked()), mapper, SLOT(map()));
133 connect(ui->manUpdateHelpBtn, SIGNAL(clicked()), mapper, SLOT(map()));
134 connect(ui->logFormatEditHelpBtn, SIGNAL(clicked()), mapper, SLOT(map()));
135
136 //Set a value for each button
137 mapper->setMapping(ui->outFormatHelpBtn, HelpBox::Help_OutputFormat);
138 mapper->setMapping(ui->outSpeedHelpBtn, HelpBox::Help_OutputSpeed);
139 mapper->setMapping(ui->srVisibilityHelpBtn, HelpBox::Help_SrNoVisibility);
140 mapper->setMapping(ui->updateHelpBtn, HelpBox::Help_AllowUpdate);
141 mapper->setMapping(ui->swapHelpBtn, HelpBox::Help_Swap);
142 mapper->setMapping(ui->manUpdateHelpBtn, HelpBox::Help_ManUpdate);
143 mapper->setMapping(ui->logFormatEditHelpBtn, HelpBox::Help_LogFormat);
144
145 //Connect the mapper
146 connect(mapper, SIGNAL(mapped(int)), this, SIGNAL(showHelp(int)));
147 connect(ui->configProtectionBox, SIGNAL(showHelp(int)), this, SIGNAL(showHelp(int)));
148 }
149
setCurrentPage(int pageIndex)150 void SettingPage::setCurrentPage(int pageIndex) {
151 m_currentPage = pageIndex;
152 setCurrentIndex(pageIndex);
153 }
154
init()155 void SettingPage::init() {
156 load();
157 }
158
restoreDefaults()159 void SettingPage::restoreDefaults() {
160 QSettings settings;
161
162 settings.setValue(SG_CUSTOMER_PREFIX_USED, false);
163 settings.setValue(SG_CUSTOMER_PREFIX, 0);
164
165 settings.setValue(SG_LOG_DISABLED, false);
166 // we continue loading LOG_FILENAME since we use that to check if settings are loaded
167 settings.setValue(SG_LOG_FILENAME, YubiKeyLogger::defaultLogFilename());
168 settings.setValue(SG_LOG_FORMAT, YubiKeyLogger::Format_Traditional);
169
170 settings.setValue(SG_EXPORT_FILENAME, YubiKeyWriter::defaultExportFilename());
171 settings.setValue(SG_IMPORT_FILENAME, ToolPage::defaultImportFilename());
172
173 settings.setValue(SG_TAB_FIRST, false);
174 settings.setValue(SG_APPEND_TAB1, false);
175 settings.setValue(SG_APPEND_TAB2, false);
176 settings.setValue(SG_APPEND_CR, true);
177 settings.setValue(SG_APPEND_DELAY1, false);
178 settings.setValue(SG_APPEND_DELAY2, false);
179 settings.setValue(SG_PACING_10MS, false);
180 settings.setValue(SG_PACING_20MS, false);
181
182 settings.setValue(SG_SR_BTN_VISIBLE, true);
183 settings.setValue(SG_SR_USB_VISIBLE, false);
184 settings.setValue(SG_SR_API_VISIBLE, true);
185
186 settings.setValue(SG_MAN_UPDATE, false);
187
188 settings.setValue(SG_ALLOW_UPDATE, true);
189 settings.setValue(SG_FAST_TRIG, false);
190 settings.setValue(SG_USE_NUMERIC_KEYPAD, false);
191
192 settings.setValue(SG_OATH_HOTP8, false);
193 settings.setValue(SG_REQUIRE_INPUT, false);
194 settings.setValue(SG_HMAC_LT64, true);
195
196 settings.setValue(SG_STRONG_PW1, false);
197 settings.setValue(SG_STRONG_PW2, false);
198 settings.setValue(SG_STRONG_PW3, false);
199
200 settings.setValue(SG_EXPORT_PREFERENCE, false);
201 }
202
load()203 void SettingPage::load() {
204 QSettings settings;
205
206 QString logFilename = settings.value(SG_LOG_FILENAME).toString();
207 bool logDisabled = settings.value(SG_LOG_DISABLED).toBool();
208 int logFormat = settings.value(SG_LOG_FORMAT).toInt();
209 if(logFilename.isEmpty()) {
210 //This is the first time... set defaults
211 restoreDefaults();
212 }
213
214 YubiKeyLogger::setLogFilename(logFilename);
215
216 QString exportFilename = settings.value(SG_EXPORT_FILENAME).toString();
217 if(!exportFilename.isEmpty()) {
218 YubiKeyWriter::setExportFilename(exportFilename);
219 }
220
221 QString importFilename = settings.value(SG_IMPORT_FILENAME).toString();
222 if(!importFilename.isEmpty()) {
223 ToolPage::setImportFilename(importFilename);
224 }
225
226 //General settings...
227 //Customer prefix
228 bool custPrefixUsed = settings.value(SG_CUSTOMER_PREFIX_USED).toBool();
229 if(custPrefixUsed) {
230 ui->custPrefixCheck->setChecked(true);
231
232 int custPrefix = settings.value(SG_CUSTOMER_PREFIX).toInt();
233 if(custPrefix > 0) {
234 custPrefixChanged(DECIMAL, QString::number(custPrefix));
235 ui->custPrefixDecTxt->setEnabled(true);
236 ui->custPrefixModhexTxt->setEnabled(true);
237 ui->custPrefixHexTxt->setEnabled(true);
238 }
239 } else {
240 ui->custPrefixCheck->setChecked(false);
241
242 ui->custPrefixDecTxt->clear();
243 ui->custPrefixDecTxt->setEnabled(false);
244 ui->custPrefixModhexTxt->clear();
245 ui->custPrefixModhexTxt->setEnabled(false);
246 ui->custPrefixHexTxt->clear();
247 ui->custPrefixHexTxt->setEnabled(false);
248 }
249
250
251 // OTP output settings...
252 ui->tabFirstBtn->setChecked(settings.value(SG_TAB_FIRST).toBool());
253 ui->appendTab1Btn->setChecked(settings.value(SG_APPEND_TAB1).toBool());
254 ui->appendTab2Btn->setChecked(settings.value(SG_APPEND_TAB2).toBool());
255 ui->appendCRBtn->setChecked(settings.value(SG_APPEND_CR).toBool());
256
257 ui->appendDelay1Check->setChecked(settings.value(SG_APPEND_DELAY1).toBool());
258 ui->appendDelay2Check->setChecked(settings.value(SG_APPEND_DELAY2).toBool());
259
260 bool pacing10ms = settings.value(SG_PACING_10MS).toBool();
261 bool pacing20ms = settings.value(SG_PACING_20MS).toBool();
262 int outCharRateIndex = 0;
263 if(pacing10ms) {
264 if(pacing20ms) {
265 outCharRateIndex = OUT_CHAR_RATE_SLOWDOWN_60;
266 } else {
267 outCharRateIndex = OUT_CHAR_RATE_SLOWDOWN_20;
268 }
269 } else if(pacing20ms) {
270 outCharRateIndex = OUT_CHAR_RATE_SLOWDOWN_40;
271 }
272 ui->outCharRateCombo->setCurrentIndex(outCharRateIndex);
273
274
275 //Serial # visibility settings...
276 ui->srBtnVisibleCheck->setChecked(settings.value(SG_SR_BTN_VISIBLE).toBool());
277 ui->srUsbVisibleCheck->setChecked(settings.value(SG_SR_USB_VISIBLE).toBool());
278 ui->srApiVisibleCheck->setChecked(settings.value(SG_SR_API_VISIBLE).toBool());
279
280 //Static Password settings...
281 ui->manUpdateCheck->setChecked(settings.value(SG_MAN_UPDATE).toBool());
282
283 //Updatable settings...
284 if(settings.contains(SG_ALLOW_UPDATE)) {
285 ui->updateCheck->setChecked(settings.value(SG_ALLOW_UPDATE).toBool());
286 } else {
287 ui->updateCheck->setChecked(true);
288 }
289
290 // extended settings..
291 ui->fastTrigCheck->setChecked(settings.value(SG_FAST_TRIG).toBool());
292 ui->useNumericKeypadCheck->setChecked(settings.value(SG_USE_NUMERIC_KEYPAD).toBool());
293 ui->ledInvertCheck->setChecked(settings.value(SG_LED_INVERT).toBool());
294
295 //Logging settings...
296 if(logDisabled) {
297 YubiKeyLogger::disableLogging();
298
299 ui->logOutputCheck->setChecked(false);
300 ui->logFormatCombo->setEnabled(false);
301 ui->logFormatEdit->setEnabled(false);
302 } else {
303 YubiKeyLogger::enableLogging();
304
305 ui->logOutputCheck->setChecked(true);
306 ui->logFormatCombo->setEnabled(true);
307 ui->logFormatCombo->setCurrentIndex(logFormat);
308 YubiKeyLogger::setLogFormat((YubiKeyLogger::Format)logFormat);
309 if(logFormat == YubiKeyLogger::Format_Flexible) {
310 QString format = settings.value(SG_LOG_FLEXIBLE).toString();
311 ui->logFormatEdit->setEnabled(true);
312 ui->logFormatEdit->setText(format);
313 YubiKeyLogger::setFlexibleFormat(format);
314 } else {
315 ui->logFormatEdit->setEnabled(false);
316 }
317 }
318
319 ui->exportCheck->setChecked(settings.value(SG_EXPORT_PREFERENCE).toBool());
320
321 //Signal everyone
322 emit settingsChanged();
323 }
324
save()325 void SettingPage::save() {
326 QSettings settings;
327
328 //General settings...
329
330 //Customer prefix
331 int custPrefix = 0;
332 if(ui->custPrefixCheck->isChecked()) {
333 settings.setValue(SG_CUSTOMER_PREFIX_USED, true);
334 custPrefix = ui->custPrefixDecTxt->text().toInt();
335 } else {
336 settings.setValue(SG_CUSTOMER_PREFIX_USED, false);
337 }
338 settings.setValue(SG_CUSTOMER_PREFIX, custPrefix);
339
340
341 // OTP output settings...
342 settings.setValue(SG_TAB_FIRST, ui->tabFirstBtn->isChecked());
343 settings.setValue(SG_APPEND_TAB1, ui->appendTab1Btn->isChecked());
344 settings.setValue(SG_APPEND_TAB2, ui->appendTab2Btn->isChecked());
345 settings.setValue(SG_APPEND_CR, ui->appendCRBtn->isChecked());
346 settings.setValue(SG_APPEND_DELAY1, ui->appendDelay1Check->isChecked());
347 settings.setValue(SG_APPEND_DELAY2, ui->appendDelay2Check->isChecked());
348
349 switch(ui->outCharRateCombo->currentIndex()) {
350 case OUT_CHAR_RATE_STD:
351 settings.setValue(SG_PACING_10MS, false);
352 settings.setValue(SG_PACING_20MS, false);
353 break;
354 case OUT_CHAR_RATE_SLOWDOWN_20:
355 settings.setValue(SG_PACING_10MS, true);
356 settings.setValue(SG_PACING_20MS, false);
357 break;
358 case OUT_CHAR_RATE_SLOWDOWN_40:
359 settings.setValue(SG_PACING_10MS, false);
360 settings.setValue(SG_PACING_20MS, true);
361 break;
362 case OUT_CHAR_RATE_SLOWDOWN_60:
363 settings.setValue(SG_PACING_10MS, true);
364 settings.setValue(SG_PACING_20MS, true);
365 break;
366 }
367
368 //Serial # visibility settings...
369 settings.setValue(SG_SR_BTN_VISIBLE, ui->srBtnVisibleCheck->isChecked());
370 settings.setValue(SG_SR_USB_VISIBLE, ui->srUsbVisibleCheck->isChecked());
371 settings.setValue(SG_SR_API_VISIBLE, ui->srApiVisibleCheck->isChecked());
372
373 //Static Password settings...
374 settings.setValue(SG_MAN_UPDATE, ui->manUpdateCheck->isChecked());
375
376 // Updatable settings...
377 settings.setValue(SG_ALLOW_UPDATE, ui->updateCheck->isChecked());
378
379 // Extended settings
380 settings.setValue(SG_FAST_TRIG, ui->fastTrigCheck->isChecked());
381 settings.setValue(SG_USE_NUMERIC_KEYPAD, ui->useNumericKeypadCheck->isChecked());
382 settings.setValue(SG_LED_INVERT, ui->ledInvertCheck->isChecked());
383
384 //Logging settings...
385 if(ui->logOutputCheck->isChecked()) {
386 settings.setValue(SG_LOG_DISABLED, false);
387 settings.setValue(SG_LOG_FORMAT, ui->logFormatCombo->currentIndex());
388 if(ui->logFormatCombo->currentIndex() == YubiKeyLogger::Format_Flexible) {
389 settings.setValue(SG_LOG_FLEXIBLE, ui->logFormatEdit->text());
390 }
391 } else {
392 settings.setValue(SG_LOG_DISABLED, true);
393 }
394
395 settings.setValue(SG_EXPORT_PREFERENCE, ui->exportCheck->isChecked());
396
397 //Reload settings
398 load();
399
400 showStatusMessage(tr(SETTINGS_SAVED), 0);
401 }
402
restore()403 void SettingPage::restore() {
404 //Confirm restore
405 //Confirm from client
406 switch (
407 QMessageBox::question(
408 this, tr(RESTORE_SETTING),
409 tr(WARN_RESTORE_SETTING),
410 tr("&Yes"), tr("&No"), QString::null, 1, 1 ))
411 {
412 case 0:
413 restoreDefaults();
414 //Reload settings
415 load();
416 showStatusMessage(tr(SETTINGS_RESTORED), 0);
417
418 break;
419 default:
420 break;
421 }
422 }
423
on_custPrefixCheck_stateChanged(int state)424 void SettingPage::on_custPrefixCheck_stateChanged(int state) {
425 if(state == 0) {
426 ui->custPrefixDecTxt->setEnabled(false);
427 ui->custPrefixModhexTxt->setEnabled(false);
428 ui->custPrefixHexTxt->setEnabled(false);
429 } else {
430 ui->custPrefixDecTxt->setEnabled(true);
431 ui->custPrefixModhexTxt->setEnabled(true);
432 ui->custPrefixHexTxt->setEnabled(true);
433 }
434 }
435
on_custPrefixDecTxt_editingFinished()436 void SettingPage::on_custPrefixDecTxt_editingFinished() {
437 custPrefixChanged(DECIMAL, ui->custPrefixDecTxt->text());
438 save();
439 }
440
on_custPrefixModhexTxt_editingFinished()441 void SettingPage::on_custPrefixModhexTxt_editingFinished() {
442 custPrefixChanged(MODHEX, ui->custPrefixModhexTxt->text());
443 save();
444 }
445
on_custPrefixHexTxt_editingFinished()446 void SettingPage::on_custPrefixHexTxt_editingFinished() {
447 custPrefixChanged(HEX, ui->custPrefixHexTxt->text());
448 save();
449 }
450
on_doUpdateBtn_clicked()451 void SettingPage::on_doUpdateBtn_clicked() {
452 int slot;
453
454 if(ui->updateSlot1Radio->isChecked()) {
455 slot = 1;
456 } else if(ui->updateSlot2Radio->isChecked()) {
457 slot = 2;
458 } else {
459 emit showStatusMessage(tr(ERR_CONF_SLOT_NOT_SELECTED), 1);
460 return;
461 }
462
463 if(m_ykConfig != NULL) {
464 delete m_ykConfig;
465 }
466 m_ykConfig = new YubiKeyConfig();
467
468 m_ykConfig->setProgrammingMode(YubiKeyConfig::Mode_Update);
469 m_ykConfig->setConfigSlot(slot);
470
471 // set serial
472 m_ykConfig->setSerial(QString::number(YubiKeyFinder::getInstance()->serial()));
473
474 // access code
475 m_ykConfig->setCurrentAccessCodeTxt(
476 ui->configProtectionBox->currentAccessCode());
477 m_ykConfig->setNewAccessCodeTxt(
478 ui->configProtectionBox->newAccessCode(),
479 ui->configProtectionBox->newAccMode());
480
481 if(ui->updateDormantCheck->isChecked()) {
482 m_ykConfig->setDormant(true);
483 }
484
485 //Write
486 connect(YubiKeyWriter::getInstance(), SIGNAL(configWritten(bool, const QString &)),
487 this, SLOT(updateConfigWritten(bool, const QString &)));
488
489 YubiKeyWriter::getInstance()->writeConfig(m_ykConfig);
490 }
491
updateConfigWritten(bool written,const QString & msg)492 void SettingPage::updateConfigWritten(bool written, const QString &msg) {
493 disconnect(YubiKeyWriter::getInstance(), SIGNAL(configWritten(bool, const QString &)),
494 this, SLOT(updateConfigWritten(bool, const QString &)));
495
496 if(written) {
497 qDebug() << "Configuration updated." << msg;
498 emit showStatusMessage(tr("Configuration successfully updated.", 0));
499 } else {
500 qDebug() << "Failed update.";
501 emit showStatusMessage(msg, 1);;
502 }
503
504 }
505
on_swapBtn_clicked()506 void SettingPage::on_swapBtn_clicked() {
507 if(m_ykConfig != NULL) {
508 delete m_ykConfig;
509 }
510 m_ykConfig = new YubiKeyConfig();
511
512 m_ykConfig->setProgrammingMode(YubiKeyConfig::Mode_Swap);
513
514 // set serial
515 m_ykConfig->setSerial(QString::number(YubiKeyFinder::getInstance()->serial()));
516
517 // access code
518 m_ykConfig->setCurrentAccessCodeTxt(
519 ui->configProtectionBox->currentAccessCode());
520 m_ykConfig->setNewAccessCodeTxt(
521 ui->configProtectionBox->newAccessCode(),
522 ui->configProtectionBox->newAccMode());
523
524 //Write
525 connect(YubiKeyWriter::getInstance(), SIGNAL(configWritten(bool, const QString &)),
526 this, SLOT(swapWritten(bool, const QString &)));
527
528 YubiKeyWriter::getInstance()->writeConfig(m_ykConfig);
529 }
530
swapWritten(bool written,const QString & msg)531 void SettingPage::swapWritten(bool written, const QString &msg) {
532 disconnect(YubiKeyWriter::getInstance(), SIGNAL(configWritten(bool, const QString &)),
533 this, SLOT(swapWritten(bool, const QString &)));
534
535 if(written) {
536 qDebug() << "Configurations swapped." << msg;
537 emit showStatusMessage(tr("Configuration successfully swapped.", 0));
538 } else {
539 qDebug() << "Failed swapping." << msg;
540 emit showStatusMessage(msg, 1);;
541 }
542 }
543
keyFound(bool found,bool * featuresMatrix)544 void SettingPage::keyFound(bool found, bool* featuresMatrix) {
545 if(found) {
546 if(featuresMatrix[YubiKeyFinder::Feature_Updatable]) {
547 ui->updateBtn->setEnabled(true);
548 }
549 } else {
550 ui->updateBtn->setEnabled(false);
551 }
552 }
553
custPrefixChanged(int type,QString src)554 void SettingPage::custPrefixChanged(int type, QString src) {
555 unsigned char buf[16];
556 memset(buf, 0, sizeof(buf));
557 size_t bufLen = 0;
558
559 switch(type) {
560 // decimal
561 case DECIMAL:
562 {
563 QString tmp = QString::number(src.toULongLong(), 16);
564 size_t len = tmp.length();
565 if(len % 2 != 0) {
566 len++;
567 }
568 YubiKeyUtil::qstrClean(&tmp, (size_t)len, true);
569 YubiKeyUtil::qstrHexDecode(buf, &bufLen, tmp);
570 break;
571 }
572 // modhex
573 case MODHEX:
574 YubiKeyUtil::qstrModhexDecode(buf, &bufLen, src);
575 break;
576 // hex
577 case HEX:
578 YubiKeyUtil::qstrHexDecode(buf, &bufLen, src);
579 break;
580 }
581 QString hex = YubiKeyUtil::qstrHexEncode(buf, bufLen);
582 QString modhex = YubiKeyUtil::qstrModhexEncode(buf, bufLen);
583 bool ok = false;
584 qulonglong dec = hex.toULongLong(&ok, 16);
585 if(dec > 0) {
586 ui->custPrefixDecTxt->setText(QString::number(dec));
587 ui->custPrefixModhexTxt->setText(modhex);
588 ui->custPrefixHexTxt->setText(hex);
589 }
590 }
591
reloadSettings()592 void SettingPage::reloadSettings() {
593 load();
594 }
595