From 4dee16c9faa2a3305c3b5d09aeb320b0af06be51 Mon Sep 17 00:00:00 2001 From: Toni Spets Date: Tue, 5 Nov 2019 21:30:34 +0200 Subject: [PATCH] SSH Agent: SSH_AUTH_SOCK override and conn test Fixes #3795 --- src/sshagent/AgentSettingsWidget.cpp | 37 ++++++++++++++++- src/sshagent/AgentSettingsWidget.ui | 61 ++++++++++++++++++++++++++++ src/sshagent/SSHAgent.cpp | 35 +++++++++++++++- src/sshagent/SSHAgent.h | 1 + 4 files changed, 132 insertions(+), 2 deletions(-) diff --git a/src/sshagent/AgentSettingsWidget.cpp b/src/sshagent/AgentSettingsWidget.cpp index be23c6906..f95a19845 100644 --- a/src/sshagent/AgentSettingsWidget.cpp +++ b/src/sshagent/AgentSettingsWidget.cpp @@ -17,9 +17,11 @@ */ #include "AgentSettingsWidget.h" +#include "SSHAgent.h" #include "ui_AgentSettingsWidget.h" #include "core/Config.h" +#include AgentSettingsWidget::AgentSettingsWidget(QWidget* parent) : QWidget(parent) @@ -28,7 +30,13 @@ AgentSettingsWidget::AgentSettingsWidget(QWidget* parent) m_ui->setupUi(this); #ifndef Q_OS_WIN m_ui->useOpenSSHCheckBox->setVisible(false); +#else + m_ui->sshAuthSockWidget->setVisible(false); #endif + auto sshAgentEnabled = config()->get("SSHAgent", false).toBool(); + m_ui->sshAuthSockMessageWidget->setVisible(sshAgentEnabled); + m_ui->sshAuthSockMessageWidget->setCloseButtonVisible(false); + m_ui->sshAuthSockMessageWidget->setAutoHideTimeout(-1); } AgentSettingsWidget::~AgentSettingsWidget() @@ -37,15 +45,42 @@ AgentSettingsWidget::~AgentSettingsWidget() void AgentSettingsWidget::loadSettings() { - m_ui->enableSSHAgentCheckBox->setChecked(config()->get("SSHAgent", false).toBool()); + auto sshAgentEnabled = config()->get("SSHAgent", false).toBool(); + m_ui->enableSSHAgentCheckBox->setChecked(sshAgentEnabled); #ifdef Q_OS_WIN m_ui->useOpenSSHCheckBox->setChecked(config()->get("SSHAgentOpenSSH", false).toBool()); +#else + auto sshAuthSock = QProcessEnvironment::systemEnvironment().value("SSH_AUTH_SOCK"); + auto sshAuthSockOverride = config()->get("SSHAuthSockOverride", "").toString(); + m_ui->sshAuthSockLabel->setText(sshAuthSock.isEmpty() ? tr("(empty)") : sshAuthSock); + m_ui->sshAuthSockOverrideEdit->setText(sshAuthSockOverride); #endif + + if (sshAgentEnabled) { + m_ui->sshAuthSockMessageWidget->setVisible(true); + +#ifndef Q_OS_WIN + if (sshAuthSock.isEmpty() && sshAuthSockOverride.isEmpty()) { + m_ui->sshAuthSockMessageWidget->showMessage( + tr("No SSH Agent socket available. Either make sure SSH_AUTH_SOCK environment variable exists or set " + "an override."), + MessageWidget::Warning); + return; + } +#endif + if (SSHAgent::instance()->testConnection()) { + m_ui->sshAuthSockMessageWidget->showMessage(tr("SSH Agent connection is working!"), + MessageWidget::Positive); + } else { + m_ui->sshAuthSockMessageWidget->showMessage(SSHAgent::instance()->errorString(), MessageWidget::Error); + } + } } void AgentSettingsWidget::saveSettings() { config()->set("SSHAgent", m_ui->enableSSHAgentCheckBox->isChecked()); + config()->set("SSHAuthSockOverride", m_ui->sshAuthSockOverrideEdit->text()); #ifdef Q_OS_WIN config()->set("SSHAgentOpenSSH", m_ui->useOpenSSHCheckBox->isChecked()); #endif diff --git a/src/sshagent/AgentSettingsWidget.ui b/src/sshagent/AgentSettingsWidget.ui index ff7435abe..20142f1c9 100644 --- a/src/sshagent/AgentSettingsWidget.ui +++ b/src/sshagent/AgentSettingsWidget.ui @@ -37,6 +37,59 @@ + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + SSH_AUTH_SOCK value + + + + + + + + Monospace + + + + (empty) + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + SSH_AUTH_SOCK override + + + + + + + + + + + + @@ -52,6 +105,14 @@ + + + MessageWidget + QWidget +
gui/MessageWidget.h
+ 1 +
+
diff --git a/src/sshagent/SSHAgent.cpp b/src/sshagent/SSHAgent.cpp index c7c174fdc..571f7b99f 100644 --- a/src/sshagent/SSHAgent.cpp +++ b/src/sshagent/SSHAgent.cpp @@ -35,7 +35,10 @@ SSHAgent::SSHAgent(QObject* parent) : QObject(parent) { #ifndef Q_OS_WIN - m_socketPath = QProcessEnvironment::systemEnvironment().value("SSH_AUTH_SOCK"); + m_socketPath = config()->get("SSHAuthSockOverride", "").toString(); + if (m_socketPath.isEmpty()) { + m_socketPath = QProcessEnvironment::systemEnvironment().value("SSH_AUTH_SOCK"); + } #else m_socketPath = "\\\\.\\pipe\\openssh-ssh-agent"; #endif @@ -181,6 +184,36 @@ bool SSHAgent::sendMessagePageant(const QByteArray& in, QByteArray& out) } #endif +/** + * Test if connection to SSH agent is working. + * + * @return true on success + */ +bool SSHAgent::testConnection() +{ + if (!isAgentRunning()) { + m_error = tr("No agent running, cannot test connection."); + return false; + } + + QByteArray requestData; + BinaryStream request(&requestData); + + request.write(SSH_AGENTC_REQUEST_IDENTITIES); + + QByteArray responseData; + if (!sendMessage(requestData, responseData)) { + return false; + } + + if (responseData.length() < 1 || static_cast(responseData[0]) != SSH_AGENT_IDENTITIES_ANSWER) { + m_error = tr("Agent protocol error."); + return false; + } + + return true; +} + /** * Add the identity to the SSH agent. * diff --git a/src/sshagent/SSHAgent.h b/src/sshagent/SSHAgent.h index 940d8c554..92389112f 100644 --- a/src/sshagent/SSHAgent.h +++ b/src/sshagent/SSHAgent.h @@ -37,6 +37,7 @@ public: const QString errorString() const; bool isAgentRunning() const; + bool testConnection(); bool addIdentity(OpenSSHKey& key, KeeAgentSettings& settings); bool removeIdentity(OpenSSHKey& key); void setAutoRemoveOnLock(const OpenSSHKey& key, bool autoRemove);