Add option to use both Pageant and OpenSSH agent on Windows

This commit is contained in:
Hongmou Zhang 2021-04-03 17:23:09 +02:00 committed by Jonathan White
parent 250cd1933c
commit d2c74340a3
6 changed files with 44 additions and 6 deletions

View File

@ -168,6 +168,7 @@ static const QHash<Config::ConfigKey, ConfigDirective> 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

View File

@ -146,6 +146,7 @@ public:
SSHAgent_Enabled,
SSHAgent_UseOpenSSH,
SSHAgent_UsePageant,
SSHAgent_AuthSockOverride,
FdoSecrets_Enabled,

View File

@ -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());

View File

@ -72,10 +72,17 @@
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QCheckBox" name="usePageantCheckBox">
<property name="text">
<string>Use Pageant</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="useOpenSSHCheckBox">
<property name="text">
<string>Use OpenSSH for Windows instead of Pageant</string>
<string>Use OpenSSH</string>
</property>
</widget>
</item>

View File

@ -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;
}

View File

@ -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);