SYNERGY-1017 - Add an option to stop the app which causes secure input
This commit is contained in:
parent
3518a26df2
commit
a69cd437b7
3 changed files with 89 additions and 3 deletions
|
|
@ -333,13 +333,32 @@ void MainWindow::checkSystemInterruptions()
|
|||
if(synergyType() == synergyServer)
|
||||
{
|
||||
#if defined(Q_OS_MAC)
|
||||
if(!m_isSecureInputNotificationShown && isOSXSecureInputEnabled())
|
||||
if(!isOSXSecureInputEnabled())
|
||||
{
|
||||
m_isSecureInputNotificationShown = false;
|
||||
}
|
||||
else if(!m_isSecureInputNotificationShown)
|
||||
{
|
||||
// avoid showing multiple duplicate messages
|
||||
m_isSecureInputNotificationShown = true;
|
||||
|
||||
QMessageBox message(this);
|
||||
message.addButton(QObject::tr("Accept"), QMessageBox::AcceptRole);
|
||||
message.setText(QObject::tr("Secure input was enabled in your system by another application. Synergy will not be able to send keyboard strokes while the secure input is enabled"));
|
||||
message.exec();
|
||||
std::string messageText =
|
||||
"Secure input was enabled in your system by another application. " \
|
||||
"Synergy will not be able to send keyboard strokes while the secure input is enabled\n\n";
|
||||
int secureInputProcessPID = getOSXSecureInputEventPID();
|
||||
std::string infringingProcessName = getOSXProcessName(secureInputProcessPID);
|
||||
|
||||
// IO registry may not contain the secure input process PID
|
||||
// in this case don't add an option to quit the infringing app
|
||||
if(secureInputProcessPID == 0) infringingProcessName = "unknown";
|
||||
else message.addButton(QString("Quit %1").arg(infringingProcessName.c_str()), QMessageBox::ApplyRole);
|
||||
messageText += "Infringing process is " + infringingProcessName;
|
||||
message.setText(QObject::tr(messageText.c_str()));
|
||||
|
||||
// if user decides to stop the app send the SIGTERM signal
|
||||
if (message.exec() == QMessageBox::Accepted && secureInputProcessPID) kill(secureInputProcessPID, SIGTERM);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,11 @@
|
|||
|
||||
#define OSXHELPERS__H
|
||||
|
||||
#include <string>
|
||||
|
||||
bool isOSXSecureInputEnabled();
|
||||
int getOSXSecureInputEventPID();
|
||||
std::string getOSXProcessName(int pid);
|
||||
bool isOSXInterfaceStyleDark();
|
||||
bool isOSXUseDarkIcons();
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,15 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
#import <CoreData/CoreData.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <base/Log.h>
|
||||
|
||||
#import <Carbon/Carbon.h>
|
||||
#import <mach/mach_port.h>
|
||||
#import <mach/mach_interface.h>
|
||||
#import <mach/mach_init.h>
|
||||
#import <IOKit/IOMessage.h>
|
||||
#import <IOKit/IOKitLib.h>
|
||||
#import <libproc.h>
|
||||
|
||||
|
||||
bool
|
||||
|
|
@ -29,6 +37,61 @@ isOSXSecureInputEnabled()
|
|||
return IsSecureEventInputEnabled();
|
||||
}
|
||||
|
||||
int
|
||||
getOSXSecureInputEventPID()
|
||||
{
|
||||
io_service_t service = MACH_PORT_NULL, service_root = MACH_PORT_NULL;
|
||||
mach_port_t masterPort;
|
||||
|
||||
kern_return_t kr = IOMasterPort( MACH_PORT_NULL, &masterPort );
|
||||
if(kr != KERN_SUCCESS) return 0;
|
||||
|
||||
// IO registry refuses to tap into the root level directly
|
||||
// as a workaround access the parent of the top user level
|
||||
service = IORegistryEntryFromPath( masterPort, kIOServicePlane ":/" );
|
||||
IORegistryEntryGetParentEntry(service, kIOServicePlane, &service_root);
|
||||
|
||||
std::unique_ptr<std::remove_pointer<CFTypeRef>::type, decltype(&CFRelease)> consoleUsers(
|
||||
IORegistryEntrySearchCFProperty(service_root, kIOServicePlane, CFSTR("IOConsoleUsers"), NULL, kIORegistryIterateParents | kIORegistryIterateRecursively),
|
||||
CFRelease
|
||||
);
|
||||
if(!consoleUsers) return 0;
|
||||
|
||||
CFTypeID type = CFGetTypeID(consoleUsers.get());
|
||||
if(type != CFArrayGetTypeID()) return 0;
|
||||
|
||||
CFTypeRef dict = CFArrayGetValueAtIndex((CFArrayRef)consoleUsers.get(), 0);
|
||||
if(!dict) return 0;
|
||||
|
||||
type = CFGetTypeID(dict);
|
||||
if(type != CFDictionaryGetTypeID()) return 0;
|
||||
|
||||
CFTypeRef secureInputPID = nullptr;
|
||||
CFDictionaryGetValueIfPresent((CFDictionaryRef)dict, CFSTR("kCGSSessionSecureInputPID"), &secureInputPID);
|
||||
|
||||
if(secureInputPID == nullptr) return 0;
|
||||
|
||||
type = CFGetTypeID(secureInputPID);
|
||||
if(type != CFNumberGetTypeID()) return 0;
|
||||
|
||||
auto pidRef = (CFNumberRef)secureInputPID;
|
||||
CFNumberType numberType = CFNumberGetType(pidRef);
|
||||
if(numberType != kCFNumberSInt32Type) return 0;
|
||||
|
||||
int pid;
|
||||
CFNumberGetValue(pidRef, kCFNumberSInt32Type, &pid);
|
||||
return pid;
|
||||
}
|
||||
|
||||
std::string
|
||||
getOSXProcessName(int pid)
|
||||
{
|
||||
if(!pid) return "";
|
||||
char buf[128];
|
||||
proc_name(pid, buf, sizeof(buf));
|
||||
return buf;
|
||||
}
|
||||
|
||||
bool
|
||||
isOSXInterfaceStyleDark()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue