Example #1
0
    def setBlockLogin(self, blockLogin, handleNotifier=True):  # pylint: disable=too-many-branches
        blockLogin = forceBool(blockLogin)
        changed = self._blockLogin != blockLogin
        self._blockLogin = blockLogin
        logger.notice("Block login now set to '%s'", self._blockLogin)

        if self._blockLogin:
            if not self._blockLoginEventId:
                self._blockLoginEventId = timeline.addEvent(
                    title="Blocking login",
                    description="User login blocked",
                    category="block_login",
                    durationEvent=True)

            if not self._blockLoginNotifierPid and config.get(
                    'global', 'block_login_notifier'):
                if handleNotifier and RUNNING_ON_WINDOWS:
                    logger.info("Starting block login notifier app")
                    # Start block login notifier on physical console
                    sessionId = System.getActiveConsoleSessionId()
                    while True:
                        try:
                            self._blockLoginNotifierPid = System.runCommandInSession(
                                command=config.get('global',
                                                   'block_login_notifier'),
                                sessionId=sessionId,
                                desktop='winlogon',
                                waitForProcessEnding=False)[2]
                            break
                        except Exception as err:  # pylint: disable=broad-except
                            logger.error(
                                "Failed to start block login notifier app: %s",
                                err)
                            break
        else:
            if self._blockLoginEventId:
                timeline.setEventEnd(eventId=self._blockLoginEventId)
                self._blockLoginEventId = None

            if handleNotifier and self._blockLoginNotifierPid:
                try:
                    logger.info(
                        "Terminating block login notifier app (pid %s)",
                        self._blockLoginNotifierPid)
                    System.terminateProcess(
                        processId=self._blockLoginNotifierPid)
                except Exception as err:  # pylint: disable=broad-except
                    logger.warning(
                        "Failed to terminate block login notifier app: %s",
                        err)
                self._blockLoginNotifierPid = None

        if changed and self._controlPipe:
            try:
                self._controlPipe.executeRpc("blockLogin", self._blockLogin)
            except Exception as rpc_error:  # pylint: disable=broad-except
                logger.debug(rpc_error)
Example #2
0
    def getCurrentActiveDesktopName(self, sessionId=None):
        if not RUNNING_ON_WINDOWS:
            return None

        if not ('opsiclientd_rpc' in config.getDict()
                and 'command' in config.getDict()['opsiclientd_rpc']):
            raise Exception("opsiclientd_rpc command not defined")

        if sessionId is None:
            sessionId = System.getActiveSessionId()
            if sessionId is None:
                sessionId = System.getActiveConsoleSessionId()

        rpc = f"setCurrentActiveDesktopName(\"{sessionId}\", System.getActiveDesktopName())"
        cmd = config.get('opsiclientd_rpc', 'command') + ' "' + rpc.replace(
            '"', '\\"') + '"'
        try:
            System.runCommandInSession(command=cmd,
                                       sessionId=sessionId,
                                       desktop="winlogon",
                                       waitForProcessEnding=True,
                                       timeoutSeconds=60,
                                       noWindow=True)
        except Exception as err:  # pylint: disable=broad-except
            logger.error(err)

        desktop = self._currentActiveDesktopName.get(sessionId)
        if not desktop:
            logger.warning(
                "Failed to get current active desktop name for session %s, using 'default'",
                sessionId)
            desktop = "default"
            self._currentActiveDesktopName[sessionId] = desktop
        logger.debug(
            "Returning current active dektop name '%s' for session %s",
            desktop, sessionId)
        return desktop
Example #3
0
    def switchDesktop(self, desktop, sessionId=None):  # pylint: disable=no-self-use
        if not ('opsiclientd_rpc' in config.getDict()
                and 'command' in config.getDict()['opsiclientd_rpc']):
            raise Exception("opsiclientd_rpc command not defined")

        desktop = forceUnicode(desktop)
        if sessionId is None:
            sessionId = System.getActiveSessionId()
            if sessionId is None:
                sessionId = System.getActiveConsoleSessionId()
        sessionId = forceInt(sessionId)

        rpc = f"noop(System.switchDesktop('{desktop}'))"
        cmd = f'{config.get("opsiclientd_rpc", "command")} "{rpc}"'

        try:
            System.runCommandInSession(command=cmd,
                                       sessionId=sessionId,
                                       desktop=desktop,
                                       waitForProcessEnding=True,
                                       timeoutSeconds=60,
                                       noWindow=True)
        except Exception as err:  # pylint: disable=broad-except
            logger.error(err)
Example #4
0
    def showPopup(self,
                  message,
                  mode='prepend',
                  addTimestamp=True,
                  displaySeconds=0):  # pylint: disable=too-many-branches,too-many-statements, too-many-locals
        if mode not in ('prepend', 'append', 'replace'):
            mode = 'prepend'
        port = config.get('notification_server', 'popup_port')
        if not port:
            raise Exception('notification_server.popup_port not defined')

        notifierCommand = config.get('opsiclientd_notifier', 'command')
        if not notifierCommand:
            raise Exception('opsiclientd_notifier.command not defined')
        notifierCommand = f'{notifierCommand} -s {os.path.join("notifier", "popup.ini")}'

        if addTimestamp:
            message = "=== " + time.strftime(
                "%Y-%m-%d %H:%M:%S") + " ===\n" + message

        with self._popupNotificationLock:  # pylint: disable=too-many-nested-blocks
            if (mode in ('prepend', 'append') and self._popupNotificationServer
                    and self._popupNotificationServer.isListening()):
                # Already runnning
                try:
                    for subject in self._popupNotificationServer.getSubjects():
                        if subject.getId() == 'message':
                            if mode == 'prepend':
                                message = message + "\n\n" + subject.getMessage(
                                )
                            else:
                                message = subject.getMessage(
                                ) + "\n\n" + message
                            break
                except Exception as err:  # pylint: disable=broad-except
                    logger.warning(err, exc_info=True)

            self.hidePopup()

            popupSubject = MessageSubject(id='message')
            choiceSubject = ChoiceSubject(id='choice')
            popupSubject.setMessage(message)

            logger.notice(
                "Starting popup message notification server on port %d", port)
            try:
                self._popupNotificationServer = NotificationServer(
                    address="127.0.0.1",
                    start_port=port,
                    subjects=[popupSubject, choiceSubject])
                self._popupNotificationServer.daemon = True
                with log_context({'instance': 'popup notification server'}):
                    if not self._popupNotificationServer.start_and_wait(
                            timeout=30):
                        raise Exception(
                            "Timed out while waiting for notification server")
            except Exception as err:  # pylint: disable=broad-except
                logger.error("Failed to start notification server: %s", err)
                raise

            notifierCommand = notifierCommand.replace(
                '%port%', str(self._popupNotificationServer.port)).replace(
                    '%id%', "popup")

            choiceSubject.setChoices([_('Close')])
            choiceSubject.setCallbacks([self.popupCloseCallback])

            sessionIds = System.getActiveSessionIds()
            if not sessionIds:
                sessionIds = [System.getActiveConsoleSessionId()]
            for sessionId in sessionIds:
                desktops = [None]
                if RUNNING_ON_WINDOWS:
                    desktops = ["default", "winlogon"]
                for desktop in desktops:
                    try:
                        System.runCommandInSession(command=notifierCommand,
                                                   sessionId=sessionId,
                                                   desktop=desktop,
                                                   waitForProcessEnding=False)
                    except Exception as err:  # pylint: disable=broad-except
                        logger.error(
                            "Failed to start popup message notifier app in session %s on desktop %s: %s",
                            sessionId, desktop, err)

            class PopupClosingThread(threading.Thread):
                def __init__(self, opsiclientd, seconds):
                    super().__init__()
                    self.opsiclientd = opsiclientd
                    self.seconds = seconds
                    self.stopped = False

                def stop(self):
                    self.stopped = True

                def run(self):
                    while not self.stopped:
                        time.sleep(1)
                        if time.time() > self.seconds:
                            break
                    if not self.stopped:
                        logger.debug("hiding popup window")
                        self.opsiclientd.hidePopup()

            # last popup decides end time (even if unlimited)
            if self._popupClosingThread and self._popupClosingThread.is_alive(
            ):
                self._popupClosingThread.stop()
            if displaySeconds > 0:
                logger.debug("displaying popup for %s seconds", displaySeconds)
                self._popupClosingThread = PopupClosingThread(
                    self,
                    time.time() + displaySeconds)
                self._popupClosingThread.start()