mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-01-14 00:39:53 -05:00
SSH Agent: Add support for OpenSSH for Windows (#1994)
* Fixed missing includes in Bootstrap.cpp
This commit is contained in:
parent
5488f1bfc3
commit
c34b0069ff
@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Bootstrap.h"
|
#include "Bootstrap.h"
|
||||||
|
#include "config-keepassx.h"
|
||||||
#include "core/Config.h"
|
#include "core/Config.h"
|
||||||
#include "core/Translator.h"
|
#include "core/Translator.h"
|
||||||
#include "gui/MessageBox.h"
|
#include "gui/MessageBox.h"
|
||||||
@ -26,6 +27,21 @@
|
|||||||
#undef MessageBox
|
#undef MessageBox
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_RLIMIT_CORE)
|
||||||
|
#include <sys/resource.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_PR_SET_DUMPABLE)
|
||||||
|
#include <sys/prctl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_PT_DENY_ATTACH
|
||||||
|
// clang-format off
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/ptrace.h>
|
||||||
|
// clang-format on
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Bootstrap
|
namespace Bootstrap
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -140,6 +156,8 @@ namespace Bootstrap
|
|||||||
HANDLE hToken = nullptr;
|
HANDLE hToken = nullptr;
|
||||||
PTOKEN_USER pTokenUser = nullptr;
|
PTOKEN_USER pTokenUser = nullptr;
|
||||||
DWORD cbBufferSize = 0;
|
DWORD cbBufferSize = 0;
|
||||||
|
PSID pLocalSystemSid = nullptr;
|
||||||
|
DWORD pLocalSystemSidSize = SECURITY_MAX_SID_SIZE;
|
||||||
|
|
||||||
// Access control list
|
// Access control list
|
||||||
PACL pACL = nullptr;
|
PACL pACL = nullptr;
|
||||||
@ -166,8 +184,19 @@ namespace Bootstrap
|
|||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Retrieve LocalSystem account SID
|
||||||
|
pLocalSystemSid = static_cast<PSID>(HeapAlloc(GetProcessHeap(), 0, pLocalSystemSidSize));
|
||||||
|
if (pLocalSystemSid == nullptr) {
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CreateWellKnownSid(WinLocalSystemSid, nullptr, pLocalSystemSid, &pLocalSystemSidSize)) {
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate the amount of memory that must be allocated for the DACL
|
// Calculate the amount of memory that must be allocated for the DACL
|
||||||
cbACL = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pTokenUser->User.Sid);
|
cbACL = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pTokenUser->User.Sid)
|
||||||
|
+ sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pLocalSystemSid);
|
||||||
|
|
||||||
// Create and initialize an ACL
|
// Create and initialize an ACL
|
||||||
pACL = static_cast<PACL>(HeapAlloc(GetProcessHeap(), 0, cbACL));
|
pACL = static_cast<PACL>(HeapAlloc(GetProcessHeap(), 0, cbACL));
|
||||||
@ -189,6 +218,18 @@ namespace Bootstrap
|
|||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_XC_SSHAGENT
|
||||||
|
// OpenSSH for Windows ssh-agent service is running as LocalSystem
|
||||||
|
if (!AddAccessAllowedAce(
|
||||||
|
pACL,
|
||||||
|
ACL_REVISION,
|
||||||
|
PROCESS_QUERY_INFORMATION | PROCESS_DUP_HANDLE, // just enough for ssh-agent
|
||||||
|
pLocalSystemSid // known LocalSystem sid
|
||||||
|
)) {
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Set discretionary access control list
|
// Set discretionary access control list
|
||||||
bSuccess = ERROR_SUCCESS
|
bSuccess = ERROR_SUCCESS
|
||||||
== SetSecurityInfo(GetCurrentProcess(), // object handle
|
== SetSecurityInfo(GetCurrentProcess(), // object handle
|
||||||
@ -205,6 +246,9 @@ namespace Bootstrap
|
|||||||
if (pACL != nullptr) {
|
if (pACL != nullptr) {
|
||||||
HeapFree(GetProcessHeap(), 0, pACL);
|
HeapFree(GetProcessHeap(), 0, pACL);
|
||||||
}
|
}
|
||||||
|
if (pLocalSystemSid != nullptr) {
|
||||||
|
HeapFree(GetProcessHeap(), 0, pLocalSystemSid);
|
||||||
|
}
|
||||||
if (pTokenUser != nullptr) {
|
if (pTokenUser != nullptr) {
|
||||||
HeapFree(GetProcessHeap(), 0, pTokenUser);
|
HeapFree(GetProcessHeap(), 0, pTokenUser);
|
||||||
}
|
}
|
||||||
|
@ -39,23 +39,6 @@
|
|||||||
#include <time.h> // for nanosleep()
|
#include <time.h> // for nanosleep()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "config-keepassx.h"
|
|
||||||
|
|
||||||
#if defined(HAVE_RLIMIT_CORE)
|
|
||||||
#include <sys/resource.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(HAVE_PR_SET_DUMPABLE)
|
|
||||||
#include <sys/prctl.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_PT_DENY_ATTACH
|
|
||||||
// clang-format off
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/ptrace.h>
|
|
||||||
// clang-format on
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Tools
|
namespace Tools
|
||||||
{
|
{
|
||||||
QString humanReadableFileSize(qint64 bytes, quint32 precision)
|
QString humanReadableFileSize(qint64 bytes, quint32 precision)
|
||||||
|
@ -26,6 +26,9 @@ AgentSettingsWidget::AgentSettingsWidget(QWidget* parent)
|
|||||||
, m_ui(new Ui::AgentSettingsWidget())
|
, m_ui(new Ui::AgentSettingsWidget())
|
||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
|
#ifndef Q_OS_WIN
|
||||||
|
m_ui->useOpenSSHCheckBox->setVisible(false);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
AgentSettingsWidget::~AgentSettingsWidget()
|
AgentSettingsWidget::~AgentSettingsWidget()
|
||||||
@ -35,9 +38,15 @@ AgentSettingsWidget::~AgentSettingsWidget()
|
|||||||
void AgentSettingsWidget::loadSettings()
|
void AgentSettingsWidget::loadSettings()
|
||||||
{
|
{
|
||||||
m_ui->enableSSHAgentCheckBox->setChecked(config()->get("SSHAgent", false).toBool());
|
m_ui->enableSSHAgentCheckBox->setChecked(config()->get("SSHAgent", false).toBool());
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
m_ui->useOpenSSHCheckBox->setChecked(config()->get("SSHAgentOpenSSH", false).toBool());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void AgentSettingsWidget::saveSettings()
|
void AgentSettingsWidget::saveSettings()
|
||||||
{
|
{
|
||||||
config()->set("SSHAgent", m_ui->enableSSHAgentCheckBox->isChecked());
|
config()->set("SSHAgent", m_ui->enableSSHAgentCheckBox->isChecked());
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
config()->set("SSHAgentOpenSSH", m_ui->useOpenSSHCheckBox->isChecked());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,13 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="useOpenSSHCheckBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>Use OpenSSH for Windows instead of Pageant</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer">
|
<spacer name="verticalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
@ -19,10 +19,10 @@
|
|||||||
#include "SSHAgent.h"
|
#include "SSHAgent.h"
|
||||||
#include "BinaryStream.h"
|
#include "BinaryStream.h"
|
||||||
#include "KeeAgentSettings.h"
|
#include "KeeAgentSettings.h"
|
||||||
|
#include "core/Config.h"
|
||||||
#ifndef Q_OS_WIN
|
|
||||||
#include <QtNetwork>
|
#include <QtNetwork>
|
||||||
#else
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -33,6 +33,8 @@ SSHAgent::SSHAgent(QObject* parent)
|
|||||||
{
|
{
|
||||||
#ifndef Q_OS_WIN
|
#ifndef Q_OS_WIN
|
||||||
m_socketPath = QProcessEnvironment::systemEnvironment().value("SSH_AUTH_SOCK");
|
m_socketPath = QProcessEnvironment::systemEnvironment().value("SSH_AUTH_SOCK");
|
||||||
|
#else
|
||||||
|
m_socketPath = "\\\\.\\pipe\\openssh-ssh-agent";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,13 +72,22 @@ bool SSHAgent::isAgentRunning() const
|
|||||||
#ifndef Q_OS_WIN
|
#ifndef Q_OS_WIN
|
||||||
return !m_socketPath.isEmpty();
|
return !m_socketPath.isEmpty();
|
||||||
#else
|
#else
|
||||||
return (FindWindowA("Pageant", "Pageant") != nullptr);
|
if (!config()->get("SSHAgentOpenSSH").toBool()) {
|
||||||
|
return (FindWindowA("Pageant", "Pageant") != nullptr);
|
||||||
|
} else {
|
||||||
|
return WaitNamedPipe(m_socketPath.toLatin1().data(), 100);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SSHAgent::sendMessage(const QByteArray& in, QByteArray& out)
|
bool SSHAgent::sendMessage(const QByteArray& in, QByteArray& out)
|
||||||
{
|
{
|
||||||
#ifndef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
|
if (!config()->get("SSHAgentOpenSSH").toBool()) {
|
||||||
|
return sendMessagePageant(in, out);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
QLocalSocket socket;
|
QLocalSocket socket;
|
||||||
BinaryStream stream(&socket);
|
BinaryStream stream(&socket);
|
||||||
|
|
||||||
@ -97,7 +108,11 @@ bool SSHAgent::sendMessage(const QByteArray& in, QByteArray& out)
|
|||||||
socket.close();
|
socket.close();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
#else
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
bool SSHAgent::sendMessagePageant(const QByteArray& in, QByteArray& out)
|
||||||
|
{
|
||||||
HWND hWnd = FindWindowA("Pageant", "Pageant");
|
HWND hWnd = FindWindowA("Pageant", "Pageant");
|
||||||
|
|
||||||
if (!hWnd) {
|
if (!hWnd) {
|
||||||
@ -157,8 +172,8 @@ bool SSHAgent::sendMessage(const QByteArray& in, QByteArray& out)
|
|||||||
CloseHandle(handle);
|
CloseHandle(handle);
|
||||||
|
|
||||||
return (res > 0);
|
return (res > 0);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add the identity to the SSH agent.
|
* Add the identity to the SSH agent.
|
||||||
|
@ -62,12 +62,14 @@ private:
|
|||||||
~SSHAgent();
|
~SSHAgent();
|
||||||
|
|
||||||
bool sendMessage(const QByteArray& in, QByteArray& out);
|
bool sendMessage(const QByteArray& in, QByteArray& out);
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
bool sendMessagePageant(const QByteArray& in, QByteArray& out);
|
||||||
|
#endif
|
||||||
|
|
||||||
static SSHAgent* m_instance;
|
static SSHAgent* m_instance;
|
||||||
|
|
||||||
#ifndef Q_OS_WIN
|
|
||||||
QString m_socketPath;
|
QString m_socketPath;
|
||||||
#else
|
#ifdef Q_OS_WIN
|
||||||
const quint32 AGENT_MAX_MSGLEN = 8192;
|
const quint32 AGENT_MAX_MSGLEN = 8192;
|
||||||
const quint32 AGENT_COPYDATA_ID = 0x804e50ba;
|
const quint32 AGENT_COPYDATA_ID = 0x804e50ba;
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user