From aeeff84c6fdbe62cab53710854b0648ebf7ab116 Mon Sep 17 00:00:00 2001 From: Igor Sikachyna Date: Fri, 4 Jun 2021 13:54:18 +0300 Subject: [PATCH] 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 30067ba8f3..81b4ae37cd 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 f21775da47..e88803cf3d 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 05643ad506..d8bd31b825 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 ce5aa45920..59298c8782 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 fa29e86748..234b42759a 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();