mirror of
https://github.com/debauchee/barrier.git
synced 2024-12-24 03:23:15 +03:00
added feature to control uac elevation on desk switch (login screen, lock, etc)
This commit is contained in:
parent
268f3a99bb
commit
86bb49aeae
@ -404,6 +404,14 @@ void MainWindow::startSynergy()
|
|||||||
{
|
{
|
||||||
// tell client/server to talk to daemon through ipc.
|
// tell client/server to talk to daemon through ipc.
|
||||||
args << "--ipc";
|
args << "--ipc";
|
||||||
|
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
// tell the client/server to shut down when a ms windows desk
|
||||||
|
// is switched; this is because we may need to elevate or not
|
||||||
|
// based on which desk the user is in (login always needs
|
||||||
|
// elevation, where as default desk does not).
|
||||||
|
args << "--stop-on-desk-switch";
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((synergyType() == synergyClient && !clientArgs(args, app))
|
if ((synergyType() == synergyClient && !clientArgs(args, app))
|
||||||
|
@ -92,7 +92,7 @@
|
|||||||
CMSWindowsDesks::CMSWindowsDesks(
|
CMSWindowsDesks::CMSWindowsDesks(
|
||||||
bool isPrimary, bool noHooks, HINSTANCE hookLibrary,
|
bool isPrimary, bool noHooks, HINSTANCE hookLibrary,
|
||||||
const IScreenSaver* screensaver, IEventQueue& eventQueue,
|
const IScreenSaver* screensaver, IEventQueue& eventQueue,
|
||||||
IJob* updateKeys) :
|
IJob* updateKeys, bool stopOnDeskSwitch) :
|
||||||
m_isPrimary(isPrimary),
|
m_isPrimary(isPrimary),
|
||||||
m_noHooks(noHooks),
|
m_noHooks(noHooks),
|
||||||
m_is95Family(CArchMiscWindows::isWindows95Family()),
|
m_is95Family(CArchMiscWindows::isWindows95Family()),
|
||||||
@ -110,7 +110,8 @@ CMSWindowsDesks::CMSWindowsDesks(
|
|||||||
m_mutex(),
|
m_mutex(),
|
||||||
m_deskReady(&m_mutex, false),
|
m_deskReady(&m_mutex, false),
|
||||||
m_updateKeys(updateKeys),
|
m_updateKeys(updateKeys),
|
||||||
m_eventQueue(eventQueue)
|
m_eventQueue(eventQueue),
|
||||||
|
m_stopOnDeskSwitch(stopOnDeskSwitch)
|
||||||
{
|
{
|
||||||
if (hookLibrary != NULL)
|
if (hookLibrary != NULL)
|
||||||
queryHookLibrary(hookLibrary);
|
queryHookLibrary(hookLibrary);
|
||||||
@ -906,6 +907,14 @@ CMSWindowsDesks::checkDesk()
|
|||||||
desk = index->second;
|
desk = index->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if we are told to shut down on desk switch, and this is not the
|
||||||
|
// first switch, then shut down.
|
||||||
|
if (m_stopOnDeskSwitch && m_activeDesk != NULL && name != m_activeDeskName) {
|
||||||
|
LOG((CLOG_DEBUG "shutting down because of desk switch to \"%s\"", name.c_str()));
|
||||||
|
EVENTQUEUE->addEvent(CEvent(CEvent::kQuit));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// if active desktop changed then tell the old and new desk threads
|
// if active desktop changed then tell the old and new desk threads
|
||||||
// about the change. don't switch desktops when the screensaver is
|
// about the change. don't switch desktops when the screensaver is
|
||||||
// active becaue we'd most likely switch to the screensaver desktop
|
// active becaue we'd most likely switch to the screensaver desktop
|
||||||
|
@ -66,7 +66,7 @@ public:
|
|||||||
CMSWindowsDesks(
|
CMSWindowsDesks(
|
||||||
bool isPrimary, bool noHooks, HINSTANCE hookLibrary,
|
bool isPrimary, bool noHooks, HINSTANCE hookLibrary,
|
||||||
const IScreenSaver* screensaver, IEventQueue& eventQueue,
|
const IScreenSaver* screensaver, IEventQueue& eventQueue,
|
||||||
IJob* updateKeys);
|
IJob* updateKeys, bool stopOnDeskSwitch);
|
||||||
~CMSWindowsDesks();
|
~CMSWindowsDesks();
|
||||||
|
|
||||||
//! @name manipulators
|
//! @name manipulators
|
||||||
@ -305,6 +305,9 @@ private:
|
|||||||
bool m_leaveForegroundOption;
|
bool m_leaveForegroundOption;
|
||||||
|
|
||||||
IEventQueue& m_eventQueue;
|
IEventQueue& m_eventQueue;
|
||||||
|
|
||||||
|
// true if program should stop on desk switch.
|
||||||
|
bool m_stopOnDeskSwitch;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -93,7 +93,7 @@ CMSWindowsRelauncher::getSessionId()
|
|||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
CMSWindowsRelauncher::isProcessInSession(const char* name, DWORD sessionId, PHANDLE process)
|
CMSWindowsRelauncher::isProcessInSession(const char* name, DWORD sessionId, PHANDLE process = NULL)
|
||||||
{
|
{
|
||||||
// first we need to take a snapshot of the running processes
|
// first we need to take a snapshot of the running processes
|
||||||
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||||
@ -175,14 +175,15 @@ CMSWindowsRelauncher::isProcessInSession(const char* name, DWORD sessionId, PHAN
|
|||||||
CloseHandle(snapshot);
|
CloseHandle(snapshot);
|
||||||
|
|
||||||
if (pid) {
|
if (pid) {
|
||||||
|
if (process != NULL) {
|
||||||
// now get the process so we can get the process, with which
|
// now get the process so we can get the process, with which
|
||||||
// we'll use to get the process token.
|
// we'll use to get the process token.
|
||||||
LOG((CLOG_DEBUG "found %s in session %i", name, sessionId));
|
LOG((CLOG_DEBUG "found %s in session %i", name, sessionId));
|
||||||
*process = OpenProcess(MAXIMUM_ALLOWED, FALSE, pid);
|
*process = OpenProcess(MAXIMUM_ALLOWED, FALSE, pid);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOG((CLOG_DEBUG "could not find %s in session %i", name, sessionId));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -219,23 +220,29 @@ CMSWindowsRelauncher::duplicateProcessToken(HANDLE process, LPSECURITY_ATTRIBUTE
|
|||||||
return newToken;
|
return newToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
// use either an elevated token (winlogon) or the user's session
|
|
||||||
// token (non-elevated). processes launched with a non-elevated token
|
|
||||||
// cannot interact with elevated processes.
|
|
||||||
HANDLE
|
HANDLE
|
||||||
CMSWindowsRelauncher::getUserToken(DWORD sessionId, LPSECURITY_ATTRIBUTES security)
|
CMSWindowsRelauncher::getUserToken(DWORD sessionId, LPSECURITY_ATTRIBUTES security)
|
||||||
{
|
{
|
||||||
if (m_elevateProcess) {
|
// always elevate if we are at the vista/7 login screen. we could also
|
||||||
|
// elevate for the uac dialog (consent.exe) but this would be pointless,
|
||||||
|
// since synergy would re-launch as non-elevated after the desk switch,
|
||||||
|
// and so would be unusable with the new elevated process taking focus.
|
||||||
|
if (m_elevateProcess || isProcessInSession("logonui.exe", sessionId)) {
|
||||||
|
|
||||||
|
LOG((CLOG_DEBUG "getting elevated token, %s",
|
||||||
|
(m_elevateProcess ? "elevation required" : "at login screen")));
|
||||||
|
|
||||||
HANDLE process;
|
HANDLE process;
|
||||||
if (isProcessInSession("winlogon.exe", sessionId, &process)) {
|
if (isProcessInSession("winlogon.exe", sessionId, &process)) {
|
||||||
return duplicateProcessToken(process, security);
|
return duplicateProcessToken(process, security);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOG((CLOG_ERR "could not find token in session %d", sessionId));
|
LOG((CLOG_ERR "could not find winlogon in session %i", sessionId));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
LOG((CLOG_DEBUG "getting non-elevated token"));
|
||||||
return getSessionToken(sessionId, security);
|
return getSessionToken(sessionId, security);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,11 @@
|
|||||||
HINSTANCE CMSWindowsScreen::s_windowInstance = NULL;
|
HINSTANCE CMSWindowsScreen::s_windowInstance = NULL;
|
||||||
CMSWindowsScreen* CMSWindowsScreen::s_screen = NULL;
|
CMSWindowsScreen* CMSWindowsScreen::s_screen = NULL;
|
||||||
|
|
||||||
CMSWindowsScreen::CMSWindowsScreen(bool isPrimary, bool noHooks, const CGameDeviceInfo& gameDeviceInfo) :
|
CMSWindowsScreen::CMSWindowsScreen(
|
||||||
|
bool isPrimary,
|
||||||
|
bool noHooks,
|
||||||
|
const CGameDeviceInfo& gameDeviceInfo,
|
||||||
|
bool stopOnDeskSwitch) :
|
||||||
m_isPrimary(isPrimary),
|
m_isPrimary(isPrimary),
|
||||||
m_noHooks(noHooks),
|
m_noHooks(noHooks),
|
||||||
m_is95Family(CArchMiscWindows::isWindows95Family()),
|
m_is95Family(CArchMiscWindows::isWindows95Family()),
|
||||||
@ -124,7 +128,8 @@ CMSWindowsScreen::CMSWindowsScreen(bool isPrimary, bool noHooks, const CGameDevi
|
|||||||
m_hookLibrary, m_screensaver,
|
m_hookLibrary, m_screensaver,
|
||||||
*EVENTQUEUE,
|
*EVENTQUEUE,
|
||||||
new TMethodJob<CMSWindowsScreen>(this,
|
new TMethodJob<CMSWindowsScreen>(this,
|
||||||
&CMSWindowsScreen::updateKeysCB));
|
&CMSWindowsScreen::updateKeysCB),
|
||||||
|
stopOnDeskSwitch);
|
||||||
m_keyState = new CMSWindowsKeyState(m_desks, getEventTarget());
|
m_keyState = new CMSWindowsKeyState(m_desks, getEventTarget());
|
||||||
updateScreenShape();
|
updateScreenShape();
|
||||||
m_class = createWindowClass();
|
m_class = createWindowClass();
|
||||||
|
@ -40,7 +40,11 @@ class CThread;
|
|||||||
//! Implementation of IPlatformScreen for Microsoft Windows
|
//! Implementation of IPlatformScreen for Microsoft Windows
|
||||||
class CMSWindowsScreen : public CPlatformScreen {
|
class CMSWindowsScreen : public CPlatformScreen {
|
||||||
public:
|
public:
|
||||||
CMSWindowsScreen(bool isPrimary, bool noHooks, const CGameDeviceInfo &gameDevice);
|
CMSWindowsScreen(
|
||||||
|
bool isPrimary,
|
||||||
|
bool noHooks,
|
||||||
|
const CGameDeviceInfo &gameDevice,
|
||||||
|
bool stopOnDeskSwitch);
|
||||||
virtual ~CMSWindowsScreen();
|
virtual ~CMSWindowsScreen();
|
||||||
|
|
||||||
//! @name manipulators
|
//! @name manipulators
|
||||||
|
@ -87,6 +87,9 @@ CAppUtilWindows::parseArg(const int& argc, const char* const* argv, int& i)
|
|||||||
else if (app().isArg(i, argc, argv, NULL, "--game-poll-freq")) {
|
else if (app().isArg(i, argc, argv, NULL, "--game-poll-freq")) {
|
||||||
app().argsBase().m_gameDevice.m_pollFreq = atoi(argv[++i]);
|
app().argsBase().m_gameDevice.m_pollFreq = atoi(argv[++i]);
|
||||||
}
|
}
|
||||||
|
else if (app().isArg(i, argc, argv, NULL, "--stop-on-desk-switch")) {
|
||||||
|
app().argsBase().m_stopOnDeskSwitch = true;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
// option not supported here
|
// option not supported here
|
||||||
return false;
|
return false;
|
||||||
|
@ -22,6 +22,7 @@ CArgsBase::CArgsBase() :
|
|||||||
m_daemon(false), // daemon mode not supported on windows (use --service)
|
m_daemon(false), // daemon mode not supported on windows (use --service)
|
||||||
m_debugServiceWait(false),
|
m_debugServiceWait(false),
|
||||||
m_pauseOnExit(false),
|
m_pauseOnExit(false),
|
||||||
|
m_stopOnDeskSwitch(false),
|
||||||
#else
|
#else
|
||||||
m_daemon(true), // backward compatibility for unix (daemon by default)
|
m_daemon(true), // backward compatibility for unix (daemon by default)
|
||||||
#endif
|
#endif
|
||||||
|
@ -40,6 +40,7 @@ public:
|
|||||||
bool m_debugServiceWait;
|
bool m_debugServiceWait;
|
||||||
bool m_pauseOnExit;
|
bool m_pauseOnExit;
|
||||||
CGameDeviceInfo m_gameDevice;
|
CGameDeviceInfo m_gameDevice;
|
||||||
|
bool m_stopOnDeskSwitch;
|
||||||
#endif
|
#endif
|
||||||
#if WINAPI_XWINDOWS
|
#if WINAPI_XWINDOWS
|
||||||
bool m_disableXInitThreads;
|
bool m_disableXInitThreads;
|
||||||
|
@ -233,7 +233,8 @@ CScreen*
|
|||||||
CClientApp::createScreen()
|
CClientApp::createScreen()
|
||||||
{
|
{
|
||||||
#if WINAPI_MSWINDOWS
|
#if WINAPI_MSWINDOWS
|
||||||
return new CScreen(new CMSWindowsScreen(false, args().m_noHooks, args().m_gameDevice));
|
return new CScreen(new CMSWindowsScreen(
|
||||||
|
false, args().m_noHooks, args().m_gameDevice, args().m_stopOnDeskSwitch));
|
||||||
#elif WINAPI_XWINDOWS
|
#elif WINAPI_XWINDOWS
|
||||||
return new CScreen(new CXWindowsScreen(
|
return new CScreen(new CXWindowsScreen(
|
||||||
args().m_display, false, args().m_disableXInitThreads,
|
args().m_display, false, args().m_disableXInitThreads,
|
||||||
|
@ -221,7 +221,7 @@ CDaemonApp::mainLoop(bool logToFile)
|
|||||||
// (such as a stop request from the service controller).
|
// (such as a stop request from the service controller).
|
||||||
CMSWindowsScreen::init(CArchMiscWindows::instanceWin32());
|
CMSWindowsScreen::init(CArchMiscWindows::instanceWin32());
|
||||||
CGameDeviceInfo gameDevice;
|
CGameDeviceInfo gameDevice;
|
||||||
CScreen dummyScreen(new CMSWindowsScreen(false, true, gameDevice));
|
CScreen dummyScreen(new CMSWindowsScreen(false, true, gameDevice, false));
|
||||||
|
|
||||||
CString command = ARCH->setting("Command");
|
CString command = ARCH->setting("Command");
|
||||||
bool elevate = ARCH->setting("Elevate") == "1";
|
bool elevate = ARCH->setting("Elevate") == "1";
|
||||||
|
@ -645,7 +645,8 @@ CScreen*
|
|||||||
CServerApp::createScreen()
|
CServerApp::createScreen()
|
||||||
{
|
{
|
||||||
#if WINAPI_MSWINDOWS
|
#if WINAPI_MSWINDOWS
|
||||||
return new CScreen(new CMSWindowsScreen(true, args().m_noHooks, args().m_gameDevice));
|
return new CScreen(new CMSWindowsScreen(
|
||||||
|
true, args().m_noHooks, args().m_gameDevice, args().m_stopOnDeskSwitch));
|
||||||
#elif WINAPI_XWINDOWS
|
#elif WINAPI_XWINDOWS
|
||||||
return new CScreen(new CXWindowsScreen(
|
return new CScreen(new CXWindowsScreen(
|
||||||
args().m_display, true, args().m_disableXInitThreads, 0, *EVENTQUEUE));
|
args().m_display, true, args().m_disableXInitThreads, 0, *EVENTQUEUE));
|
||||||
|
@ -55,7 +55,7 @@ protected:
|
|||||||
return new CMSWindowsDesks(
|
return new CMSWindowsDesks(
|
||||||
true, false, m_hookLibrary, m_screensaver, eventQueue,
|
true, false, m_hookLibrary, m_screensaver, eventQueue,
|
||||||
new TMethodJob<CMSWindowsKeyStateTests>(
|
new TMethodJob<CMSWindowsKeyStateTests>(
|
||||||
this, &CMSWindowsKeyStateTests::updateKeysCB));
|
this, &CMSWindowsKeyStateTests::updateKeysCB), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* getEventTarget() const
|
void* getEventTarget() const
|
||||||
|
Loading…
Reference in New Issue
Block a user