From d19f1bcd9a64f4eaa269b276ee5a71615842b2e7 Mon Sep 17 00:00:00 2001 From: Igor Sikachyna Date: Thu, 3 Jun 2021 13:04:45 +0300 Subject: [PATCH 01/11] SYNERGY-1017 - Added a basic IO registry search for secure input presence --- src/lib/platform/OSXScreen.h | 1 + src/lib/platform/OSXScreen.mm | 73 +++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/src/lib/platform/OSXScreen.h b/src/lib/platform/OSXScreen.h index fcc0e20f8..e9bd90b8d 100644 --- a/src/lib/platform/OSXScreen.h +++ b/src/lib/platform/OSXScreen.h @@ -32,6 +32,7 @@ #include #include #include +#include extern "C" { typedef int CGSConnectionID; diff --git a/src/lib/platform/OSXScreen.mm b/src/lib/platform/OSXScreen.mm index bd3a69b06..ddeaf4416 100755 --- a/src/lib/platform/OSXScreen.mm +++ b/src/lib/platform/OSXScreen.mm @@ -845,9 +845,82 @@ OSXScreen::disable() m_isOnScreen = m_isPrimary; } +std::string CFStringRefToStdString(const CFStringRef pCFStringRef) +{ + const char* pCStr = NULL; + + std::string sRet; + + if (pCFStringRef) + { + pCStr = CFStringGetCStringPtr(pCFStringRef, kCFStringEncodingMacRoman); + if(pCStr) + sRet.assign(pCStr); + } + return sRet; +} + +bool isSecureInput() { + NXEventHandle handle = MACH_PORT_NULL; + io_service_t service = MACH_PORT_NULL, service_p = MACH_PORT_NULL; + mach_port_t masterPort; + io_name_t n; + char buf[4096]; + uint32_t s = sizeof(buf); + + kern_return_t kr = IOMasterPort( MACH_PORT_NULL, &masterPort ); + if(kr != KERN_SUCCESS) return false; + + service = IORegistryEntryFromPath( masterPort, kIOServicePlane ":/" ); + IORegistryEntryGetParentEntry(service, kIOServicePlane, &service_p); + CFTypeRef consoleUsers = IORegistryEntrySearchCFProperty(service_p, kIOServicePlane, CFSTR("IOConsoleUsers"), NULL, kIORegistryIterateParents | kIORegistryIterateRecursively); + if(!consoleUsers) return false; + + CFTypeID type = CFGetTypeID(consoleUsers); + if(type != CFArrayGetTypeID()) + { + CFRelease(consoleUsers); + return false; + } + CFTypeRef dict = CFArrayGetValueAtIndex((CFArrayRef)consoleUsers, 0); + if(!dict) + { + CFRelease(consoleUsers); + return false; + } + type = CFGetTypeID(dict); + if(type != CFDictionaryGetTypeID()) + { + CFRelease(consoleUsers); + return false; + } + + CFIndex count = CFDictionaryGetCount((CFDictionaryRef)dict); + const void * keys [count]; + const void * values [count]; + CFDictionaryGetKeysAndValues((CFDictionaryRef)dict, reinterpret_cast(keys), reinterpret_cast(values)); + for(CFIndex i = 0; i < count; ++i) { + CFIndex keySize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(reinterpret_cast(keys[i])), kCFStringEncodingASCII); + char key [keySize + 1]; + + if(!CFStringGetCString(reinterpret_cast(keys[i]), key, keySize + 1, kCFStringEncodingASCII)) { + continue; + } + LOG((CLOG_INFO "registry %s", key)); + } + + + CFIndex secureInputCount = CFDictionaryGetCountOfKey((CFDictionaryRef)dict, CFSTR("kCGSSessionSecureInputPID")); + CFRelease(consoleUsers); + return secureInputCount > 0; +} + void OSXScreen::enter() { + + bool secure = isSecureInput(); + showCursor(); if (m_isPrimary) { From d0d6dad1c5792b149fbb5737626593bb4d731a92 Mon Sep 17 00:00:00 2001 From: Igor Sikachyna Date: Thu, 3 Jun 2021 14:08:02 +0300 Subject: [PATCH 02/11] SYNERGY-1017 - Add notification --- CMakeLists.txt | 2 ++ src/lib/platform/OSXScreen.mm | 24 +++++++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e287d3a09..c8e9fae2e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -173,6 +173,7 @@ if (UNIX) find_library (lib_ApplicationServices ApplicationServices) find_library (lib_Foundation Foundation) find_library (lib_Carbon Carbon) + find_library (lib_UserNotifications UserNotifications) list (APPEND libs ${lib_ScreenSaver} @@ -180,6 +181,7 @@ if (UNIX) ${lib_ApplicationServices} ${lib_Foundation} ${lib_Carbon} + ${lib_UserNotifications} ) else() # not-apple diff --git a/src/lib/platform/OSXScreen.mm b/src/lib/platform/OSXScreen.mm index ddeaf4416..fa29e8674 100755 --- a/src/lib/platform/OSXScreen.mm +++ b/src/lib/platform/OSXScreen.mm @@ -46,6 +46,11 @@ #include #include #include +#include +#include +#include +#include +#include // This isn't in any Apple SDK that I know of as of yet. enum { @@ -919,7 +924,24 @@ void OSXScreen::enter() { - bool secure = isSecureInput(); + // Configure the notification's payload. + UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init]; + content.title = [NSString localizedUserNotificationStringForKey:@"Hello!" arguments:nil]; + content.body = [NSString localizedUserNotificationStringForKey:@"Hello_message_body" + arguments:nil]; + content.sound = [UNNotificationSound defaultSound]; + + // Deliver the notification in five seconds. + UNTimeIntervalNotificationTrigger* trigger = [UNTimeIntervalNotificationTrigger + triggerWithTimeInterval:5 repeats:NO]; + UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:@"FiveSecond" + content:content trigger:trigger]; + + // Schedule the notification. + UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter]; + [center addNotificationRequest:request]; + + bool secure = isSecureInput(); showCursor(); From aeeff84c6fdbe62cab53710854b0648ebf7ab116 Mon Sep 17 00:00:00 2001 From: Igor Sikachyna Date: Fri, 4 Jun 2021 13:54:18 +0300 Subject: [PATCH 03/11] SYNERGY-1017 - Add secure input detection and notification --- src/gui/src/MainWindow.cpp | 20 +++++++++++ src/gui/src/MainWindow.h | 6 ++++ src/gui/src/OSXHelpers.h | 2 ++ src/gui/src/OSXHelpers.mm | 65 +++++++++++++++++++++++++++++++++++ src/lib/platform/OSXScreen.mm | 25 +------------- 5 files changed, 94 insertions(+), 24 deletions(-) diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index 30067ba8f..81b4ae37c 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -328,6 +328,23 @@ void MainWindow::saveSettings() GUI::Config::ConfigWriter::make()->globalSave(); } +void MainWindow::checkSystemInterruptions() +{ + if(synergyType() == synergyServer) + { +#if defined(Q_OS_MAC) + if(!m_isSecureInputNotificationShown && isOSXSecureInputEnabled()) + { + 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 strikes while the secure input is enabled")); + message.exec(); + } +#endif + } +} + void MainWindow::zeroConfToggled() { #if !defined(SYNERGY_ENTERPRISE) && defined(SYNERGY_AUTOCONFIG) updateZeroconfService(); @@ -698,6 +715,7 @@ void MainWindow::startSynergy() connect(synergyProcess(), SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(synergyFinished(int, QProcess::ExitStatus))); connect(synergyProcess(), SIGNAL(readyReadStandardOutput()), this, SLOT(logOutput())); connect(synergyProcess(), SIGNAL(readyReadStandardError()), this, SLOT(logError())); + connect(&m_systemInterruptionCheckTimer, SIGNAL(timeout()), this, SLOT(checkSystemInterruptions())); } qDebug() << args; @@ -1015,6 +1033,7 @@ void MainWindow::setSynergyState(qSynergyState state) connect (m_pButtonToggleStart, SIGNAL(clicked()), m_pActionStopSynergy, SLOT(trigger())); m_pButtonToggleStart->setText(tr("&Stop")); m_pButtonApply->setEnabled(true); + m_systemInterruptionCheckTimer.start(5000); // check every 5 seconds } else if (state == synergyDisconnected) { @@ -1022,6 +1041,7 @@ void MainWindow::setSynergyState(qSynergyState state) connect (m_pButtonToggleStart, SIGNAL(clicked()), m_pActionStartSynergy, SLOT(trigger())); m_pButtonToggleStart->setText(tr("&Start")); m_pButtonApply->setEnabled(false); + m_systemInterruptionCheckTimer.stop(); } bool running = false; diff --git a/src/gui/src/MainWindow.h b/src/gui/src/MainWindow.h index f21775da4..e88803cf3 100644 --- a/src/gui/src/MainWindow.h +++ b/src/gui/src/MainWindow.h @@ -164,6 +164,7 @@ public slots: void logError(); void updateFound(const QString& version); void saveSettings(); + void checkSystemInterruptions(); /// @brief Receives the signal that the auto config option has changed void zeroConfToggled(); @@ -246,6 +247,11 @@ public slots: QString m_SecureSocketVersion; // brief Contains the version of the Secure Socket currently active ServerConnection m_serverConnection; ClientConnection m_clientConnection; + QTimer m_systemInterruptionCheckTimer; // Timer used for sceduling a task for detecting the system + // operations preventing the Synergy from working properly +#if defined(Q_OS_MAC) + bool m_isSecureInputNotificationShown = false; +#endif void updateAutoConfigWidgets(); diff --git a/src/gui/src/OSXHelpers.h b/src/gui/src/OSXHelpers.h index 05643ad50..d8bd31b82 100644 --- a/src/gui/src/OSXHelpers.h +++ b/src/gui/src/OSXHelpers.h @@ -19,6 +19,8 @@ #define OSXHELPERS__H +bool isOSXSecureInputEnabled(); +void OSXSendSecureInputNotification(); bool isOSXInterfaceStyleDark(); bool isOSXUseDarkIcons(); diff --git a/src/gui/src/OSXHelpers.mm b/src/gui/src/OSXHelpers.mm index ce5aa4592..59298c878 100644 --- a/src/gui/src/OSXHelpers.mm +++ b/src/gui/src/OSXHelpers.mm @@ -20,6 +20,71 @@ #import #import #import +#import +#import + +NSString* runCommand(NSString* commandToRun) +{ + NSTask *task = [[NSTask alloc] init]; + [task setLaunchPath:@"/bin/sh"]; + + NSArray *arguments = [NSArray arrayWithObjects: + @"-c" , + [NSString stringWithFormat:@"%@", commandToRun], + nil]; + NSLog(@"run command:%@", commandToRun); + [task setArguments:arguments]; + + NSPipe *pipe = [NSPipe pipe]; + [task setStandardOutput:pipe]; + + NSFileHandle *file = [pipe fileHandleForReading]; + + [task launch]; + + NSData *data = [file readDataToEndOfFile]; + + NSString *output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + return output; +} + +bool +isOSXSecureInputEnabled() +{ + //NSString *output = runCommand(@"ioreg -l -w 0 | grep kCGSSessionSecureInputPID"); + //NSLog (@"grep returned:\n%@", output); + + /* + int pid = [[NSProcessInfo processInfo] processIdentifier]; + NSPipe *pipe = [NSPipe pipe]; + NSFileHandle *file = pipe.fileHandleForReading; + + NSTask *task = [[NSTask alloc] init]; + task.launchPath = @"/usr/sbin/ioreg"; + task.arguments = @[@"-l", @"-w", @"0"]; + task.standardOutput = pipe; + + [task launch]; + + NSData *data = [file readDataToEndOfFile]; + [file closeFile]; + + NSString *grepOutput = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding]; + NSLog (@"grep returned:\n%@", grepOutput); + */ + + std::array buffer; + std::string result; + std::unique_ptr pipe(popen("ioreg -l -w 0 | grep kCGSSessionSecureInputPID", "r"), pclose); + if (!pipe) { + return false; + } + while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) + { + result += buffer.data(); + } + return result.length() > 0; +} bool isOSXInterfaceStyleDark() diff --git a/src/lib/platform/OSXScreen.mm b/src/lib/platform/OSXScreen.mm index fa29e8674..234b42759 100755 --- a/src/lib/platform/OSXScreen.mm +++ b/src/lib/platform/OSXScreen.mm @@ -46,11 +46,6 @@ #include #include #include -#include -#include -#include -#include -#include // This isn't in any Apple SDK that I know of as of yet. enum { @@ -923,25 +918,7 @@ bool isSecureInput() { void OSXScreen::enter() { - - // Configure the notification's payload. - UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init]; - content.title = [NSString localizedUserNotificationStringForKey:@"Hello!" arguments:nil]; - content.body = [NSString localizedUserNotificationStringForKey:@"Hello_message_body" - arguments:nil]; - content.sound = [UNNotificationSound defaultSound]; - - // Deliver the notification in five seconds. - UNTimeIntervalNotificationTrigger* trigger = [UNTimeIntervalNotificationTrigger - triggerWithTimeInterval:5 repeats:NO]; - UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:@"FiveSecond" - content:content trigger:trigger]; - - // Schedule the notification. - UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter]; - [center addNotificationRequest:request]; - - bool secure = isSecureInput(); + bool secure = isSecureInput(); showCursor(); From 11d5bbc1bc932b02ed0ff98e44bd677dedcdd7dd Mon Sep 17 00:00:00 2001 From: Igor Sikachyna Date: Fri, 4 Jun 2021 13:59:47 +0300 Subject: [PATCH 04/11] SYNERGY-1017 - Remove redundant code changes --- CMakeLists.txt | 2 - src/gui/src/OSXHelpers.h | 1 - src/gui/src/OSXHelpers.mm | 47 ----------------------- src/lib/platform/OSXScreen.h | 1 - src/lib/platform/OSXScreen.mm | 72 ----------------------------------- 5 files changed, 123 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c8e9fae2e..e287d3a09 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -173,7 +173,6 @@ if (UNIX) find_library (lib_ApplicationServices ApplicationServices) find_library (lib_Foundation Foundation) find_library (lib_Carbon Carbon) - find_library (lib_UserNotifications UserNotifications) list (APPEND libs ${lib_ScreenSaver} @@ -181,7 +180,6 @@ if (UNIX) ${lib_ApplicationServices} ${lib_Foundation} ${lib_Carbon} - ${lib_UserNotifications} ) else() # not-apple diff --git a/src/gui/src/OSXHelpers.h b/src/gui/src/OSXHelpers.h index d8bd31b82..15876aecf 100644 --- a/src/gui/src/OSXHelpers.h +++ b/src/gui/src/OSXHelpers.h @@ -20,7 +20,6 @@ #define OSXHELPERS__H bool isOSXSecureInputEnabled(); -void OSXSendSecureInputNotification(); bool isOSXInterfaceStyleDark(); bool isOSXUseDarkIcons(); diff --git a/src/gui/src/OSXHelpers.mm b/src/gui/src/OSXHelpers.mm index 59298c878..e9bd75a7d 100644 --- a/src/gui/src/OSXHelpers.mm +++ b/src/gui/src/OSXHelpers.mm @@ -23,56 +23,9 @@ #import #import -NSString* runCommand(NSString* commandToRun) -{ - NSTask *task = [[NSTask alloc] init]; - [task setLaunchPath:@"/bin/sh"]; - - NSArray *arguments = [NSArray arrayWithObjects: - @"-c" , - [NSString stringWithFormat:@"%@", commandToRun], - nil]; - NSLog(@"run command:%@", commandToRun); - [task setArguments:arguments]; - - NSPipe *pipe = [NSPipe pipe]; - [task setStandardOutput:pipe]; - - NSFileHandle *file = [pipe fileHandleForReading]; - - [task launch]; - - NSData *data = [file readDataToEndOfFile]; - - NSString *output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - return output; -} - bool isOSXSecureInputEnabled() { - //NSString *output = runCommand(@"ioreg -l -w 0 | grep kCGSSessionSecureInputPID"); - //NSLog (@"grep returned:\n%@", output); - - /* - int pid = [[NSProcessInfo processInfo] processIdentifier]; - NSPipe *pipe = [NSPipe pipe]; - NSFileHandle *file = pipe.fileHandleForReading; - - NSTask *task = [[NSTask alloc] init]; - task.launchPath = @"/usr/sbin/ioreg"; - task.arguments = @[@"-l", @"-w", @"0"]; - task.standardOutput = pipe; - - [task launch]; - - NSData *data = [file readDataToEndOfFile]; - [file closeFile]; - - NSString *grepOutput = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding]; - NSLog (@"grep returned:\n%@", grepOutput); - */ - std::array buffer; std::string result; std::unique_ptr pipe(popen("ioreg -l -w 0 | grep kCGSSessionSecureInputPID", "r"), pclose); diff --git a/src/lib/platform/OSXScreen.h b/src/lib/platform/OSXScreen.h index e9bd90b8d..fcc0e20f8 100644 --- a/src/lib/platform/OSXScreen.h +++ b/src/lib/platform/OSXScreen.h @@ -32,7 +32,6 @@ #include #include #include -#include extern "C" { typedef int CGSConnectionID; diff --git a/src/lib/platform/OSXScreen.mm b/src/lib/platform/OSXScreen.mm index 234b42759..bd3a69b06 100755 --- a/src/lib/platform/OSXScreen.mm +++ b/src/lib/platform/OSXScreen.mm @@ -845,81 +845,9 @@ OSXScreen::disable() m_isOnScreen = m_isPrimary; } -std::string CFStringRefToStdString(const CFStringRef pCFStringRef) -{ - const char* pCStr = NULL; - - std::string sRet; - - if (pCFStringRef) - { - pCStr = CFStringGetCStringPtr(pCFStringRef, kCFStringEncodingMacRoman); - if(pCStr) - sRet.assign(pCStr); - } - return sRet; -} - -bool isSecureInput() { - NXEventHandle handle = MACH_PORT_NULL; - io_service_t service = MACH_PORT_NULL, service_p = MACH_PORT_NULL; - mach_port_t masterPort; - io_name_t n; - char buf[4096]; - uint32_t s = sizeof(buf); - - kern_return_t kr = IOMasterPort( MACH_PORT_NULL, &masterPort ); - if(kr != KERN_SUCCESS) return false; - - service = IORegistryEntryFromPath( masterPort, kIOServicePlane ":/" ); - IORegistryEntryGetParentEntry(service, kIOServicePlane, &service_p); - CFTypeRef consoleUsers = IORegistryEntrySearchCFProperty(service_p, kIOServicePlane, CFSTR("IOConsoleUsers"), NULL, kIORegistryIterateParents | kIORegistryIterateRecursively); - if(!consoleUsers) return false; - - CFTypeID type = CFGetTypeID(consoleUsers); - if(type != CFArrayGetTypeID()) - { - CFRelease(consoleUsers); - return false; - } - CFTypeRef dict = CFArrayGetValueAtIndex((CFArrayRef)consoleUsers, 0); - if(!dict) - { - CFRelease(consoleUsers); - return false; - } - type = CFGetTypeID(dict); - if(type != CFDictionaryGetTypeID()) - { - CFRelease(consoleUsers); - return false; - } - - CFIndex count = CFDictionaryGetCount((CFDictionaryRef)dict); - const void * keys [count]; - const void * values [count]; - CFDictionaryGetKeysAndValues((CFDictionaryRef)dict, reinterpret_cast(keys), reinterpret_cast(values)); - for(CFIndex i = 0; i < count; ++i) { - CFIndex keySize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(reinterpret_cast(keys[i])), kCFStringEncodingASCII); - char key [keySize + 1]; - - if(!CFStringGetCString(reinterpret_cast(keys[i]), key, keySize + 1, kCFStringEncodingASCII)) { - continue; - } - LOG((CLOG_INFO "registry %s", key)); - } - - - CFIndex secureInputCount = CFDictionaryGetCountOfKey((CFDictionaryRef)dict, CFSTR("kCGSSessionSecureInputPID")); - CFRelease(consoleUsers); - return secureInputCount > 0; -} - void OSXScreen::enter() { - bool secure = isSecureInput(); - showCursor(); if (m_isPrimary) { From f2e42efe41f0830aad3a9db5395b8bb74ebc53cd Mon Sep 17 00:00:00 2001 From: Igor Sikachyna Date: Fri, 4 Jun 2021 18:20:13 +0300 Subject: [PATCH 05/11] SYNERGY-1017 - Update secure input message --- src/gui/src/MainWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index 81b4ae37c..c530c8091 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -338,7 +338,7 @@ void MainWindow::checkSystemInterruptions() 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 strikes while the secure input is enabled")); + 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(); } #endif From 85b8def2b4c9e8f04ab0345bdcc90beb325f8c10 Mon Sep 17 00:00:00 2001 From: Igor Sikachyna Date: Fri, 4 Jun 2021 18:53:29 +0300 Subject: [PATCH 06/11] SYNERGY-1017 - Update changelog --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 1ced2d11a..8131eeab6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,7 @@ Bug fixes: Enhancements: - #6998 Remove functionality related to the screen saver synchronisation - #7026 Update the way we package OpenSSL for Windows build +- #7030 Add user nofication for secure input on Mac =========== v1.14.0-rc1 From eef8413b0be9b7cad2769ccdd44b0c196a6330a2 Mon Sep 17 00:00:00 2001 From: Igor Sikachyna Date: Mon, 7 Jun 2021 11:51:31 +0300 Subject: [PATCH 07/11] SYNERGY-1017 - Resolve code smell --- src/gui/src/MainWindow.cpp | 2 +- src/gui/src/MainWindow.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index c530c8091..495552047 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -328,7 +328,7 @@ void MainWindow::saveSettings() GUI::Config::ConfigWriter::make()->globalSave(); } -void MainWindow::checkSystemInterruptions() +void MainWindow::checkSystemInterruptions() const { if(synergyType() == synergyServer) { diff --git a/src/gui/src/MainWindow.h b/src/gui/src/MainWindow.h index e88803cf3..3cc08a73d 100644 --- a/src/gui/src/MainWindow.h +++ b/src/gui/src/MainWindow.h @@ -164,7 +164,7 @@ public slots: void logError(); void updateFound(const QString& version); void saveSettings(); - void checkSystemInterruptions(); + void checkSystemInterruptions() const; /// @brief Receives the signal that the auto config option has changed void zeroConfToggled(); From a9949fdd804515563c434d0c011dfbe1ace9f8ef Mon Sep 17 00:00:00 2001 From: Igor Sikachyna Date: Mon, 7 Jun 2021 11:54:04 +0300 Subject: [PATCH 08/11] SYNERGY-1017 - Remove const --- src/gui/src/MainWindow.cpp | 2 +- src/gui/src/MainWindow.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index 495552047..c530c8091 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -328,7 +328,7 @@ void MainWindow::saveSettings() GUI::Config::ConfigWriter::make()->globalSave(); } -void MainWindow::checkSystemInterruptions() const +void MainWindow::checkSystemInterruptions() { if(synergyType() == synergyServer) { diff --git a/src/gui/src/MainWindow.h b/src/gui/src/MainWindow.h index 3cc08a73d..e88803cf3 100644 --- a/src/gui/src/MainWindow.h +++ b/src/gui/src/MainWindow.h @@ -164,7 +164,7 @@ public slots: void logError(); void updateFound(const QString& version); void saveSettings(); - void checkSystemInterruptions() const; + void checkSystemInterruptions(); /// @brief Receives the signal that the auto config option has changed void zeroConfToggled(); From 3e5626e48ac3e9bc7a8d699ada9713e01ccc6515 Mon Sep 17 00:00:00 2001 From: Igor Sikachyna Date: Mon, 7 Jun 2021 13:30:39 +0300 Subject: [PATCH 09/11] SYNERGY-1017 - Simplify the check for secure input --- src/gui/src/OSXHelpers.mm | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/gui/src/OSXHelpers.mm b/src/gui/src/OSXHelpers.mm index e9bd75a7d..2d43aa2a2 100644 --- a/src/gui/src/OSXHelpers.mm +++ b/src/gui/src/OSXHelpers.mm @@ -22,21 +22,13 @@ #import #import #import +#import + bool isOSXSecureInputEnabled() { - std::array buffer; - std::string result; - std::unique_ptr pipe(popen("ioreg -l -w 0 | grep kCGSSessionSecureInputPID", "r"), pclose); - if (!pipe) { - return false; - } - while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) - { - result += buffer.data(); - } - return result.length() > 0; + return IsSecureEventInputEnabled(); } bool From 3518a26df2c598efe66c044ff4ad3bbe98c1dbe8 Mon Sep 17 00:00:00 2001 From: Igor Sikachyna Date: Mon, 7 Jun 2021 13:35:42 +0300 Subject: [PATCH 10/11] SYNERGY-1017 - Remove redundant imports --- src/gui/src/OSXHelpers.mm | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/gui/src/OSXHelpers.mm b/src/gui/src/OSXHelpers.mm index 2d43aa2a2..511709ebf 100644 --- a/src/gui/src/OSXHelpers.mm +++ b/src/gui/src/OSXHelpers.mm @@ -20,8 +20,6 @@ #import #import #import -#import -#import #import From a69cd437b7a45e255374a7b060856b6d3002403a Mon Sep 17 00:00:00 2001 From: Igor Sikachyna Date: Tue, 8 Jun 2021 12:24:37 +0300 Subject: [PATCH 11/11] SYNERGY-1017 - Add an option to stop the app which causes secure input --- src/gui/src/MainWindow.cpp | 25 +++++++++++++-- src/gui/src/OSXHelpers.h | 4 +++ src/gui/src/OSXHelpers.mm | 63 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 3 deletions(-) diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index c530c8091..d46458754 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -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 } diff --git a/src/gui/src/OSXHelpers.h b/src/gui/src/OSXHelpers.h index 15876aecf..cfae2b4a4 100644 --- a/src/gui/src/OSXHelpers.h +++ b/src/gui/src/OSXHelpers.h @@ -19,7 +19,11 @@ #define OSXHELPERS__H +#include + bool isOSXSecureInputEnabled(); +int getOSXSecureInputEventPID(); +std::string getOSXProcessName(int pid); bool isOSXInterfaceStyleDark(); bool isOSXUseDarkIcons(); diff --git a/src/gui/src/OSXHelpers.mm b/src/gui/src/OSXHelpers.mm index 511709ebf..9a919ec9e 100644 --- a/src/gui/src/OSXHelpers.mm +++ b/src/gui/src/OSXHelpers.mm @@ -20,7 +20,15 @@ #import #import #import +#import + #import +#import +#import +#import +#import +#import +#import 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::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() {