This commit is contained in:
Spamtributor 2025-11-03 23:38:18 +01:00 committed by GitHub
commit df6e963637
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 47 additions and 19 deletions

View file

@ -326,7 +326,7 @@ QString DatabaseOpenWidget::filename()
return m_filename;
}
void DatabaseOpenWidget::enterKey(const QString& pw, const QString& keyFile)
void DatabaseOpenWidget::enterKey(const QString& pw, const QString& keyFile, const QString& yubikey)
{
if (unlockingDatabase()) {
qWarning("Ignoring unlock request for %s because of running unlock action.", qPrintable(m_filename));
@ -335,11 +335,12 @@ void DatabaseOpenWidget::enterKey(const QString& pw, const QString& keyFile)
m_ui->editPassword->setText(pw);
m_ui->keyFileLineEdit->setText(keyFile);
m_blockQuickUnlock = true;
openDatabase();
openDatabase(yubikey);
}
void DatabaseOpenWidget::openDatabase()
void DatabaseOpenWidget::openDatabase(const QString& yubikey)
{
// Cache this variable for future use then reset
bool blockQuickUnlock = m_blockQuickUnlock || isOnQuickUnlockScreen();
@ -350,7 +351,7 @@ void DatabaseOpenWidget::openDatabase()
m_ui->messageWidget->hide();
QCoreApplication::processEvents();
const auto databaseKey = buildDatabaseKey();
const auto databaseKey = buildDatabaseKey(yubikey);
if (!databaseKey) {
setUserInteractionLock(false);
return;
@ -430,7 +431,7 @@ void DatabaseOpenWidget::openDatabase()
}
}
QSharedPointer<CompositeKey> DatabaseOpenWidget::buildDatabaseKey()
QSharedPointer<CompositeKey> DatabaseOpenWidget::buildDatabaseKey(const QString& yubikey)
{
auto databaseKey = QSharedPointer<CompositeKey>::create();
@ -490,6 +491,29 @@ QSharedPointer<CompositeKey> DatabaseOpenWidget::buildDatabaseKey()
}
#ifdef WITH_XC_YUBIKEY
if (!yubikey.isEmpty()) {
unsigned int serial = 0;
int slot;
bool ok = false;
auto parts = yubikey.split(":");
slot = parts[0].toInt(&ok);
if (!ok || (slot != 1 && slot != 2)) {
return {};
}
if (parts.size() > 1) {
serial = parts[1].toUInt(&ok, 10);
if (!ok) {
return {};
}
}
auto crKey = QSharedPointer<ChallengeResponseKey>(new ChallengeResponseKey({serial, slot}));
databaseKey->addChallengeResponseKey(crKey);
}
auto lastChallengeResponse = config()->get(Config::LastChallengeResponse).toHash();
lastChallengeResponse.remove(m_filename);

View file

@ -49,7 +49,7 @@ public:
void load(const QString& filename);
QString filename();
void clearForms();
void enterKey(const QString& pw, const QString& keyFile);
void enterKey(const QString& pw, const QString& keyFile, const QString& yubikey = {});
QSharedPointer<Database> database();
bool unlockingDatabase();
void showMessage(const QString& text, MessageWidget::MessageType type, int autoHideTimeout);
@ -67,7 +67,7 @@ signals:
protected:
bool event(QEvent* event) override;
void keyPressEvent(QKeyEvent* event) override;
QSharedPointer<CompositeKey> buildDatabaseKey();
QSharedPointer<CompositeKey> buildDatabaseKey(const QString& yubikey = {});
void setUserInteractionLock(bool state);
const QScopedPointer<Ui::DatabaseOpenWidget> m_ui;
@ -76,7 +76,7 @@ protected:
bool m_retryUnlockWithEmptyPassword = false;
protected slots:
virtual void openDatabase();
virtual void openDatabase(const QString& yubikey = {});
void reject();
private slots:

View file

@ -156,7 +156,8 @@ void DatabaseTabWidget::openDatabase()
void DatabaseTabWidget::addDatabaseTab(const QString& filePath,
bool inBackground,
const QString& password,
const QString& keyfile)
const QString& keyfile,
const QString& yubikey)
{
QString cleanFilePath = QDir::toNativeSeparators(filePath);
QFileInfo fileInfo(cleanFilePath);
@ -173,7 +174,7 @@ void DatabaseTabWidget::addDatabaseTab(const QString& filePath,
Q_ASSERT(dbWidget);
if (dbWidget
&& dbWidget->database()->canonicalFilePath().compare(canonicalFilePath, FILE_CASE_SENSITIVE) == 0) {
dbWidget->performUnlockDatabase(password, keyfile);
dbWidget->performUnlockDatabase(password, keyfile, yubikey);
if (!inBackground) {
// switch to existing tab if file is already open
setCurrentIndex(indexOf(dbWidget));
@ -184,7 +185,7 @@ void DatabaseTabWidget::addDatabaseTab(const QString& filePath,
auto* dbWidget = new DatabaseWidget(QSharedPointer<Database>::create(cleanFilePath), this);
addDatabaseTab(dbWidget, inBackground);
dbWidget->performUnlockDatabase(password, keyfile);
dbWidget->performUnlockDatabase(password, keyfile, yubikey);
updateLastDatabases(dbWidget->database());
}

View file

@ -53,7 +53,8 @@ public slots:
void addDatabaseTab(const QString& filePath,
bool inBackground = false,
const QString& password = {},
const QString& keyfile = {});
const QString& keyfile = {},
const QString& yubikey = {});
void addDatabaseTab(DatabaseWidget* dbWidget, bool inBackground = false);
bool closeDatabaseTab(int index);
bool closeDatabaseTab(DatabaseWidget* dbWidget);

View file

@ -1720,7 +1720,7 @@ void DatabaseWidget::removePasskeyFromEntry()
}
#endif
void DatabaseWidget::performUnlockDatabase(const QString& password, const QString& keyfile)
void DatabaseWidget::performUnlockDatabase(const QString& password, const QString& keyfile, const QString& yubikey)
{
if (password.isEmpty() && keyfile.isEmpty()) {
return;
@ -1728,7 +1728,7 @@ void DatabaseWidget::performUnlockDatabase(const QString& password, const QStrin
if (!m_db->isInitialized() || isLocked()) {
switchToOpenDatabase();
m_databaseOpenWidget->enterKey(password, keyfile);
m_databaseOpenWidget->enterKey(password, keyfile, yubikey);
}
}

View file

@ -244,7 +244,7 @@ public slots:
void switchToOpenDatabase();
void switchToOpenDatabase(const QString& filePath);
void switchToOpenDatabase(const QString& filePath, const QString& password, const QString& keyFile);
void performUnlockDatabase(const QString& password, const QString& keyfile = {});
void performUnlockDatabase(const QString& password, const QString& keyfile = {}, const QString& yubikey = {});
void emptyRecycleBin();
// Search related slots

View file

@ -888,9 +888,9 @@ void MainWindow::clearLastDatabases()
}
}
void MainWindow::openDatabase(const QString& filePath, const QString& password, const QString& keyfile)
void MainWindow::openDatabase(const QString& filePath, const QString& password, const QString& keyfile, const QString& yubikey)
{
m_ui->tabWidget->addDatabaseTab(filePath, false, password, keyfile);
m_ui->tabWidget->addDatabaseTab(filePath, false, password, keyfile, yubikey);
}
void MainWindow::updateMenuActionState()

View file

@ -70,7 +70,7 @@ signals:
void databaseUnlockDialogFinished(bool accepted, DatabaseWidget* dbWidget);
public slots:
void openDatabase(const QString& filePath, const QString& password = {}, const QString& keyfile = {});
void openDatabase(const QString& filePath, const QString& password = {}, const QString& keyfile = {}, const QString& yubikey = {});
void appExit();
bool isHardwareKeySupported();
bool refreshHardwareKeys();

View file

@ -81,6 +81,7 @@ int main(int argc, char** argv)
"localconfig", QObject::tr("path to a custom local config file"), "localconfig");
QCommandLineOption lockOption("lock", QObject::tr("lock all open databases"));
QCommandLineOption keyfileOption("keyfile", QObject::tr("key file of the database"), "keyfile");
QCommandLineOption yubikeyOption("yubikey", QObject::tr("Yubikey slot and optional serial used to access the database (e.g., 1:7370001)."), "slot[:serial");
QCommandLineOption pwstdinOption("pw-stdin", QObject::tr("read password of the database from stdin"));
QCommandLineOption allowScreenCaptureOption("allow-screencapture",
QObject::tr("allow screenshots and app recording (Windows/macOS)"));
@ -93,6 +94,7 @@ int main(int argc, char** argv)
parser.addOption(localConfigOption);
parser.addOption(lockOption);
parser.addOption(keyfileOption);
parser.addOption(yubikeyOption);
parser.addOption(pwstdinOption);
parser.addOption(debugInfoOption);
parser.addOption(allowScreenCaptureOption);
@ -205,7 +207,7 @@ int main(int argc, char** argv)
out << QObject::tr("Database password: ") << Qt::flush;
password = Utils::getPassword();
}
mainWindow.openDatabase(filename, password, parser.value(keyfileOption));
mainWindow.openDatabase(filename, password, parser.value(keyfileOption), parser.value(yubikeyOption));
}
// start minimized if configured