From d2c74340a34cdde1cca0dd78b666d10809ddb8ec Mon Sep 17 00:00:00 2001 From: Hongmou Zhang Date: Sat, 3 Apr 2021 17:23:09 +0200 Subject: [PATCH] Add option to use both Pageant and OpenSSH agent on Windows --- src/core/Config.cpp | 1 + src/core/Config.h | 1 + src/sshagent/AgentSettingsWidget.cpp | 4 ++++ src/sshagent/AgentSettingsWidget.ui | 9 +++++++- src/sshagent/SSHAgent.cpp | 32 +++++++++++++++++++++++----- src/sshagent/SSHAgent.h | 3 +++ 6 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 58a92c1dc..22741e610 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -168,6 +168,7 @@ static const QHash configStrings = { // SSHAgent {Config::SSHAgent_Enabled, {QS("SSHAgent/Enabled"), Roaming, false}}, {Config::SSHAgent_UseOpenSSH, {QS("SSHAgent/UseOpenSSH"), Roaming, false}}, + {Config::SSHAgent_UsePageant, {QS("SSHAgent/UsePageant"), Roaming, false} }, {Config::SSHAgent_AuthSockOverride, {QS("SSHAgent/AuthSockOverride"), Local, {}}}, // FdoSecrets diff --git a/src/core/Config.h b/src/core/Config.h index e29179a0f..065aa1677 100644 --- a/src/core/Config.h +++ b/src/core/Config.h @@ -146,6 +146,7 @@ public: SSHAgent_Enabled, SSHAgent_UseOpenSSH, + SSHAgent_UsePageant, SSHAgent_AuthSockOverride, FdoSecrets_Enabled, diff --git a/src/sshagent/AgentSettingsWidget.cpp b/src/sshagent/AgentSettingsWidget.cpp index 74c3959f1..17fe50c3e 100644 --- a/src/sshagent/AgentSettingsWidget.cpp +++ b/src/sshagent/AgentSettingsWidget.cpp @@ -26,6 +26,7 @@ AgentSettingsWidget::AgentSettingsWidget(QWidget* parent) { m_ui->setupUi(this); #ifndef Q_OS_WIN + m_ui->usePageantCheckBox->setVisible(false); m_ui->useOpenSSHCheckBox->setVisible(false); #else m_ui->sshAuthSockWidget->setVisible(false); @@ -46,7 +47,9 @@ void AgentSettingsWidget::loadSettings() m_ui->enableSSHAgentCheckBox->setChecked(sshAgentEnabled); #ifdef Q_OS_WIN + m_ui->usePageantCheckBox->setChecked(sshAgent()->usePageant()); m_ui->useOpenSSHCheckBox->setChecked(sshAgent()->useOpenSSH()); + sshAgentEnabled = sshAgentEnabled && (sshAgent()->usePageant() || sshAgent()->useOpenSSH()); #else auto sshAuthSock = sshAgent()->socketPath(false); auto sshAuthSockOverride = sshAgent()->authSockOverride(); @@ -83,6 +86,7 @@ void AgentSettingsWidget::saveSettings() auto sshAuthSockOverride = m_ui->sshAuthSockOverrideEdit->text(); sshAgent()->setAuthSockOverride(sshAuthSockOverride); #ifdef Q_OS_WIN + sshAgent()->setUsePageant(m_ui->usePageantCheckBox->isChecked()); sshAgent()->setUseOpenSSH(m_ui->useOpenSSHCheckBox->isChecked()); #endif sshAgent()->setEnabled(m_ui->enableSSHAgentCheckBox->isChecked()); diff --git a/src/sshagent/AgentSettingsWidget.ui b/src/sshagent/AgentSettingsWidget.ui index 71958644f..b617d9a11 100644 --- a/src/sshagent/AgentSettingsWidget.ui +++ b/src/sshagent/AgentSettingsWidget.ui @@ -72,10 +72,17 @@ 0 + + + + Use Pageant + + + - Use OpenSSH for Windows instead of Pageant + Use OpenSSH diff --git a/src/sshagent/SSHAgent.cpp b/src/sshagent/SSHAgent.cpp index 3ba110a1f..abee23c39 100644 --- a/src/sshagent/SSHAgent.cpp +++ b/src/sshagent/SSHAgent.cpp @@ -72,10 +72,20 @@ bool SSHAgent::useOpenSSH() const return config()->get(Config::SSHAgent_UseOpenSSH).toBool(); } +bool SSHAgent::usePageant() const +{ + return config()->get(Config::SSHAgent_UsePageant).toBool(); +} + void SSHAgent::setUseOpenSSH(bool useOpenSSH) { config()->set(Config::SSHAgent_UseOpenSSH, useOpenSSH); } + +void SSHAgent::setUsePageant(bool usePageant) +{ + config()->set(Config::SSHAgent_UsePageant, usePageant); +} #endif QString SSHAgent::socketPath(bool allowOverride) const @@ -110,10 +120,14 @@ bool SSHAgent::isAgentRunning() const QFileInfo socketFileInfo(socketPath()); return !socketFileInfo.path().isEmpty() && socketFileInfo.exists(); #else - if (!useOpenSSH()) { + if (usePageant() && useOpenSSH()) { + return (FindWindowA("Pageant", "Pageant") != nullptr) && WaitNamedPipe(socketPath().toLatin1().data(), 100); + } else if (useOpenSSH()) { + return WaitNamedPipe(socketPath().toLatin1().data(), 100); + } else if (usePageant()) { return (FindWindowA("Pageant", "Pageant") != nullptr); } else { - return WaitNamedPipe(socketPath().toLatin1().data(), 100); + return false; } #endif } @@ -121,11 +135,20 @@ bool SSHAgent::isAgentRunning() const bool SSHAgent::sendMessage(const QByteArray& in, QByteArray& out) { #ifdef Q_OS_WIN - if (!useOpenSSH()) { - return sendMessagePageant(in, out); + if (usePageant() && !sendMessagePageant(in, out)) { + return false; } + if (useOpenSSH() && !sendMessageOpenSSH(in, out)) { + return false; + } + return true; +#else + return sendMessageOpenSSH(in, out); #endif +} +bool SSHAgent::sendMessageOpenSSH(const QByteArray& in, QByteArray& out) +{ QLocalSocket socket; BinaryStream stream(&socket); @@ -144,7 +167,6 @@ bool SSHAgent::sendMessage(const QByteArray& in, QByteArray& out) } socket.close(); - return true; } diff --git a/src/sshagent/SSHAgent.h b/src/sshagent/SSHAgent.h index 53f06b807..3b5e9bdf2 100644 --- a/src/sshagent/SSHAgent.h +++ b/src/sshagent/SSHAgent.h @@ -41,7 +41,9 @@ public: void setAuthSockOverride(QString& authSockOverride); #ifdef Q_OS_WIN bool useOpenSSH() const; + bool usePageant() const; void setUseOpenSSH(bool useOpenSSH); + void setUsePageant(bool usePageant); #endif const QString errorString() const; @@ -74,6 +76,7 @@ private: const quint8 SSH_AGENT_CONSTRAIN_CONFIRM = 2; bool sendMessage(const QByteArray& in, QByteArray& out); + bool sendMessageOpenSSH(const QByteArray& in, QByteArray& out); #ifdef Q_OS_WIN bool sendMessagePageant(const QByteArray& in, QByteArray& out);