SYNERGY-1017 - Add an option to stop the app which causes secure input

This commit is contained in:
Igor Sikachyna 2021-06-08 12:24:37 +03:00
parent 3518a26df2
commit a69cd437b7
3 changed files with 89 additions and 3 deletions

View file

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

View file

@ -19,7 +19,11 @@
#define OSXHELPERS__H
#include <string>
bool isOSXSecureInputEnabled();
int getOSXSecureInputEventPID();
std::string getOSXProcessName(int pid);
bool isOSXInterfaceStyleDark();
bool isOSXUseDarkIcons();

View file

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