FdoSecrets: check and show PID and executable for existing secret service process

This commit is contained in:
Aetf 2019-12-01 21:13:07 -05:00 committed by Jonathan White
parent 0383aa104c
commit 792c1c94f7
6 changed files with 112 additions and 5 deletions

View File

@ -24,6 +24,8 @@
#include "gui/DatabaseTabWidget.h"
#include <QFile>
#include <utility>
using FdoSecrets::Service;
@ -56,7 +58,7 @@ void FdoSecretsPlugin::updateServiceState()
if (!m_secretService && m_dbTabs) {
m_secretService.reset(new Service(this, m_dbTabs));
connect(m_secretService.data(), &Service::error, this, [this](const QString& msg) {
emit error(tr("Fdo Secret Service: %1").arg(msg));
emit error(tr("<b>Fdo Secret Service:</b> %1").arg(msg));
});
if (!m_secretService->initialize()) {
m_secretService.reset();
@ -95,3 +97,29 @@ void FdoSecretsPlugin::emitRequestShowNotification(const QString& msg, const QSt
}
emit requestShowNotification(msg, title, 10000);
}
QString FdoSecretsPlugin::reportExistingService() const
{
auto pidStr = tr("Unknown", "Unknown PID");
auto exeStr = tr("Unknown", "Unknown executable path");
// try get pid
auto pid = QDBusConnection::sessionBus().interface()->servicePid(DBUS_SERVICE_SECRET);
if (pid.isValid()) {
pidStr = QString::number(pid.value());
// try get the first part of the cmdline, which usually is the executable name/path
QFile proc(QStringLiteral("/proc/%1/cmdline").arg(pid.value()));
if (proc.open(QFile::ReadOnly)) {
auto parts = proc.readAll().split('\0');
if (parts.length() >= 1) {
exeStr = QString::fromLocal8Bit(parts[0]).trimmed();
}
}
}
auto otherService = tr("<i>PID: %1, Executable: %2</i>", "<i>PID: 1234, Executable: /path/to/exe</i>")
.arg(pidStr, exeStr.toHtmlEscaped());
return tr("Another secret service is running (%1).<br/>"
"Please stop/remove it before re-enabling the Secret Service Integration.")
.arg(otherService);
}

View File

@ -64,6 +64,12 @@ public:
*/
DatabaseTabWidget* dbTabs() const;
/**
* Check the running secret service and returns info about it
* @return html string suitable to be shown in the UI
*/
QString reportExistingService() const;
public slots:
void emitRequestSwitchToDatabases();
void emitRequestShowNotification(const QString& msg, const QString& title = {});

View File

@ -59,9 +59,8 @@ namespace FdoSecrets
bool Service::initialize()
{
if (!QDBusConnection::sessionBus().registerService(QStringLiteral(DBUS_SERVICE_SECRET))) {
qDebug() << "Another secret service is running";
emit error(tr("Failed to register DBus service at %1: another secret service is running.")
.arg(QLatin1Literal(DBUS_SERVICE_SECRET)));
emit error(tr("Failed to register DBus service at %1.<br/>").arg(QLatin1String(DBUS_SERVICE_SECRET))
+ m_plugin->reportExistingService());
return false;
}

View File

@ -27,6 +27,8 @@
#include "gui/DatabaseWidget.h"
#include <QAction>
#include <QDBusConnection>
#include <QDBusConnectionInterface>
#include <QHeaderView>
#include <QItemEditorFactory>
#include <QStyledItemDelegate>
@ -236,6 +238,8 @@ SettingsWidgetFdoSecrets::SettingsWidgetFdoSecrets(FdoSecretsPlugin* plugin, QWi
, m_plugin(plugin)
{
m_ui->setupUi(this);
m_ui->warningMsg->setHidden(true);
m_ui->warningMsg->setCloseButtonVisible(false);
auto sessModel = new SettingsSessionModel(plugin, this);
m_ui->tableSessions->setModel(sessModel);
@ -262,6 +266,12 @@ SettingsWidgetFdoSecrets::SettingsWidgetFdoSecrets(FdoSecretsPlugin* plugin, QWi
m_ui->tabWidget->setEnabled(m_ui->enableFdoSecretService->isChecked());
connect(m_ui->enableFdoSecretService, &QCheckBox::toggled, m_ui->tabWidget, &QTabWidget::setEnabled);
// background checking
m_checkTimer.setInterval(2000);
connect(&m_checkTimer, &QTimer::timeout, this, &SettingsWidgetFdoSecrets::checkDBusName);
connect(m_plugin, &FdoSecretsPlugin::secretServiceStarted, &m_checkTimer, &QTimer::stop);
connect(m_plugin, SIGNAL(secretServiceStopped()), &m_checkTimer, SLOT(start()));
}
void SettingsWidgetFdoSecrets::setupView(QAbstractItemView* view,
@ -300,4 +310,48 @@ void SettingsWidgetFdoSecrets::saveSettings()
FdoSecrets::settings()->setNoConfirmDeleteItem(m_ui->noConfirmDeleteItem->isChecked());
}
void SettingsWidgetFdoSecrets::showMessage(const QString& text, MessageWidget::MessageType type)
{
// Show error messages for a longer time to make sure the user can read them
if (type == MessageWidget::Error) {
m_ui->warningMsg->setCloseButtonVisible(true);
m_ui->warningMsg->showMessage(text, type, -1);
} else {
m_ui->warningMsg->setCloseButtonVisible(false);
m_ui->warningMsg->showMessage(text, type, 2000);
}
}
void SettingsWidgetFdoSecrets::showEvent(QShowEvent* event)
{
QWidget::showEvent(event);
QTimer::singleShot(0, this, &SettingsWidgetFdoSecrets::checkDBusName);
m_checkTimer.start();
}
void SettingsWidgetFdoSecrets::hideEvent(QHideEvent* event)
{
QWidget::hideEvent(event);
m_checkTimer.stop();
}
void SettingsWidgetFdoSecrets::checkDBusName()
{
if (m_plugin->serviceInstance()) {
// only need checking if the service is not started or failed to start.
return;
}
auto reply = QDBusConnection::sessionBus().interface()->isServiceRegistered(QStringLiteral(DBUS_SERVICE_SECRET));
if (!reply.isValid()) {
showMessage(tr("<b>Error:</b> Failed to connect to DBus. Please check your DBus setup."), MessageWidget::Error);
return;
}
if (reply.value()) {
showMessage(tr("<b>Warning:</b> ") + m_plugin->reportExistingService(), MessageWidget::Warning);
return;
}
m_ui->warningMsg->hideMessage();
}
#include "SettingsWidgetFdoSecrets.moc"

View File

@ -18,7 +18,10 @@
#ifndef KEEPASSXC_SETTINGSWIDGETFDOSECRETS_H
#define KEEPASSXC_SETTINGSWIDGETFDOSECRETS_H
#include "gui/MessageWidget.h"
#include <QScopedPointer>
#include <QTimer>
#include <QWidget>
class QAbstractItemView;
@ -50,6 +53,14 @@ public slots:
void loadSettings();
void saveSettings();
private slots:
void checkDBusName();
void showMessage(const QString& text, MessageWidget::MessageType type);
protected:
void showEvent(QShowEvent* event) override;
void hideEvent(QHideEvent* event) override;
private:
void setupView(QAbstractItemView* view, int manageColumn, int editorTypeId, QItemEditorCreatorBase* creator);
@ -57,6 +68,7 @@ private:
QScopedPointer<Ui::SettingsWidgetFdoSecrets> m_ui;
QScopedPointer<QItemEditorFactory> m_factory;
FdoSecretsPlugin* m_plugin;
QTimer m_checkTimer;
};
#endif // KEEPASSXC_SETTINGSWIDGETFDOSECRETS_H

View File

@ -15,7 +15,7 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QWidget" name="warningMsg" native="true"/>
<widget class="MessageWidget" name="warningMsg" native="true"/>
</item>
<item>
<widget class="QCheckBox" name="enableFdoSecretService">
@ -132,6 +132,14 @@
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>MessageWidget</class>
<extends>QWidget</extends>
<header>gui/MessageWidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>