Пример #1
0
    def clientMessageProcessor(self, msg, data):
        logger.debug('Got message {}'.format(msg))
        if self.api is None:
            logger.info('Rest api not ready')
            return

        if msg == ipc.REQ_LOGIN:
            res = self.api.login(data).split('\t')
            # third parameter, if exists, sets maxSession duration to this.
            # First & second parameters are ip & hostname of connection source
            if len(res) >= 3:
                self.api.maxSession = int(res[2])  # Third parameter is max session duration
                msg = ipc.REQ_INFORMATION  # Senf information, requested or not, to client on login notification
        elif msg == ipc.REQ_LOGOUT:
            self.api.logout(data)
            self.onLogout(data)
        elif msg == ipc.REQ_INFORMATION:
            info = {}
            if self.api.idle is not None:
                info['idle'] = self.api.idle
            if self.api.maxSession is not None:
                info['maxSession'] = self.api.maxSession
            self.ipc.sendInformationMessage(info)
        elif msg == ipc.REQ_TICKET:
            d = json.loads('data')
            try:
                result = self.api.getTicket(d['ticketId'], d['secure'])
                self.ipc.sendTicketMessage(result)
            except Exception:
                logger.exception('Getting ticket')
                self.ipc.sendTicketMessage({'error': 'invalid ticket'})
Пример #2
0
 def run(self) -> None:
     try:
         logger.debug('Executing script: {}'.format(self.script))
         exec(self.script, globals(), None)  # pylint: disable=exec-used
     except Exception as e:
         logger.error('Error executing script: {}'.format(e))
         logger.exception()
Пример #3
0
    def SvcDoRun(self):
        '''
        Main service loop
        '''
        try:
            initCfg()

            logger.debug('running SvcDoRun')
            servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                                  servicemanager.PYS_SERVICE_STARTED,
                                  (self._svc_name_, ''))

            # call the CoInitialize to allow the registration to run in an other
            # thread
            logger.debug('Initializing com...')
            pythoncom.CoInitialize()

            # ********************************************************
            # * Ask brokers what to do before proceding to main loop *
            # ********************************************************
            while True:
                brokerConnected = self.interactWithBroker()
                if brokerConnected is False:
                    logger.debug(
                        'Interact with broker returned false, stopping service after a while'
                    )
                    self.notifyStop()
                    win32event.WaitForSingleObject(self.hWaitStop, 5000)
                    return
                elif brokerConnected is True:
                    break

                # If brokerConnected returns None, repeat the cycle
                self.doWait(16000)  # Wait for a looong while

            if self.interactWithBroker() is False:
                logger.debug(
                    'Interact with broker returned false, stopping service after a while'
                )
                self.notifyStop()
                win32event.WaitForSingleObject(self.hWaitStop, 5000)
                return

            if self.isAlive is False:
                logger.debug(
                    'The service is not alive after broker interaction, stopping it'
                )
                self.notifyStop()
                return

            if self.rebootRequested is True:
                logger.debug('Reboot has been requested, stopping service')
                self.notifyStop()
                return

            self.initIPC()
        except Exception:  # Any init exception wil be caught, service must be then restarted
            logger.exception()
            logger.debug('Exiting service with failure status')
            os._exit(-1)  # pylint: disable=protected-access

        # ********************************
        # * Registers SENS subscriptions *
        # ********************************
        logevent('Registering ISensLogon')
        subscription_guid = '{41099152-498E-11E4-8FD3-10FEED05884B}'
        sl = SensLogon(self)
        subscription_interface = pythoncom.WrapObject(sl)

        event_system = win32com.client.Dispatch(PROGID_EventSystem)

        event_subscription = win32com.client.Dispatch(PROGID_EventSubscription)
        event_subscription.EventClassID = SENSGUID_EVENTCLASS_LOGON
        event_subscription.PublisherID = SENSGUID_PUBLISHER
        event_subscription.SubscriptionName = 'UDS Actor subscription'
        event_subscription.SubscriptionID = subscription_guid
        event_subscription.SubscriberInterface = subscription_interface

        event_system.Store(PROGID_EventSubscription, event_subscription)

        logger.debug('Registered SENS, running main loop')

        # Execute script in c:\\windows\\post-uds.bat after interacting with broker, if no reboot is requested ofc
        # This will be executed only when machine gets "ready"
        try:
            if os.path.isfile(POST_CMD):
                subprocess.call([
                    POST_CMD,
                ])
            else:
                logger.info('POST file not found & not executed')
        except Exception as e:
            # Ignore output of execution command
            logger.error('Executing post command give')

        # *********************
        # * Main Service loop *
        # *********************
        # Counter used to check ip changes only once every 10 seconds, for
        # example
        counter = 0
        while self.isAlive:
            counter += 1
            # Process SENS messages, This will be a bit asyncronous (1 second
            # delay)
            pythoncom.PumpWaitingMessages()
            if counter >= 15:  # Once every 15 seconds
                counter = 0
                try:
                    self.checkIpsChanged()
                except Exception as e:
                    logger.error('Error checking ip change: {}'.format(e))
            # In milliseconds, will break
            win32event.WaitForSingleObject(self.hWaitStop, 1000)

        logger.debug('Exited main loop, deregistering SENS')

        # *******************************************
        # * Remove SENS subscription before exiting *
        # *******************************************
        event_system.Remove(PROGID_EventSubscription,
                            "SubscriptionID == " + subscription_guid)

        self.endIPC()  # Ends IPC servers
        self.endAPI()  # And deinitializes REST api if needed

        self.notifyStop()
Пример #4
0
    def interactWithBroker(self):
        '''
        Returns True to continue to main loop, false to stop & exit service
        '''
        # If no configuration is found, stop service
        if cfg is None:
            logger.fatal('No configuration found, stopping service')
            return False

        self.api = REST.Api(cfg['host'], cfg['masterKey'], cfg['ssl'])

        # Wait for Broker to be ready
        counter = 0
        while self.isAlive:
            try:
                # getNetworkInfo is a generator function
                netInfo = tuple(operations.getNetworkInfo())
                self.knownIps = dict(((i.mac, i.ip) for i in netInfo))
                ids = ','.join([i.mac for i in netInfo])
                if ids == '':
                    # Wait for any network interface to be ready
                    logger.debug('No valid network interfaces found, retrying in a while...')
                    raise Exception()
                logger.debug('Ids: {}'.format(ids))
                self.api.init(ids)
                # Set remote logger to notify log info to broker
                logger.setRemoteLogger(self.api)

                break
            except REST.InvalidKeyError:
                logger.fatal('Can\'t sync with broker: Invalid broker Master Key')
                return False
            except REST.UnmanagedHostError:
                # Maybe interface that is registered with broker is not enabled already?
                # Right now, we thing that the interface connected to broker is
                # the interface that broker will know, let's see how this works
                logger.fatal('This host is not managed by UDS Broker (ids: {})'.format(ids))
                return False  # On unmanaged hosts, there is no reason right now to continue running
            except Exception as e:
                logger.debug('Exception on network info: retrying')
                logger.exception()
                # Any other error is expectable and recoverable, so let's wait a bit and retry again
                # but, if too many errors, will log it (one every minute, for
                # example)
                counter += 1
                if counter % 60 == 0:  # Every 5 minutes, raise a log
                    logger.info('Trying to inititialize connection with broker (last error: {})'.format(exceptionToMessage(e)))
                # Wait a bit before next check
                self.doWait(5000)

        # Broker connection is initialized, now get information about what to
        # do
        counter = 0
        while self.isAlive:
            try:
                logger.debug('Requesting information of what to do now')
                info = self.api.information()
                data = info.split('\r')
                if len(data) != 2:
                    logger.error('The format of the information message is not correct (got {})'.format(info))
                    raise Exception
                params = data[1].split('\t')
                if data[0] == 'rename':
                    try:
                        if len(params) == 1:  # Simple rename
                            logger.debug('Renaming computer to {}'.format(params[0]))
                            self.rename(params[0])
                        # Rename with change password for an user
                        elif len(params) == 4:
                            logger.debug('Renaming computer to {}'.format(params))
                            self.rename(params[0], params[1], params[2], params[3])
                        else:
                            logger.error('Got invalid parameter for rename operation: {}'.format(params))
                            return False
                        break
                    except Exception as e:
                        logger.error('Error at computer renaming stage: {}'.format(e.message))
                        return False
                elif data[0] == 'domain':
                    if len(params) != 5:
                        logger.error('Got invalid parameters for domain message: {}'.format(params))
                        return False
                    self.joinDomain(params[0], params[1], params[2], params[3], params[4])
                    break
                else:
                    logger.error('Unrecognized action sent from broker: {}'.format(data[0]))
                    return False  # Stop running service
            except REST.UserServiceNotFoundError:
                logger.error('The host has lost the sync state with broker! (host uuid changed?)')
                return False
            except Exception:
                if counter % 60 == 0:
                    logger.warn('Too many retries in progress, though still trying (last error: {})'.format(exceptionToMessage(e)))
                counter += 1
                # Any other error is expectable and recoverable, so let's wait
                # a bit and retry again
                # Wait a bit before next check
                self.doWait(5000)

        if self.rebootRequested:
            try:
                operations.reboot()
            except Exception as e:
                logger.error('Exception on reboot: {}'.format(e.message))
            return False  # Stops service

        return True
Пример #5
0
    def SvcDoRun(self):
        '''
        Main service loop
        '''
        try:
            initCfg()

            logger.debug('running SvcDoRun')
            servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                                  servicemanager.PYS_SERVICE_STARTED,
                                  (self._svc_name_, ''))

            # call the CoInitialize to allow the registration to run in an other
            # thread
            logger.debug('Initializing com...')
            pythoncom.CoInitialize()

            # ********************************************************
            # * Ask brokers what to do before proceding to main loop *
            # ********************************************************
            if self.interactWithBroker() is False:
                logger.debug(
                    'Interact with broker returned false, stopping service after a while'
                )
                self.notifyStop()
                win32event.WaitForSingleObject(self.hWaitStop, 5000)
                return

            if self.isAlive is False:
                logger.debug(
                    'The service is not alive after broker interaction, stopping it'
                )
                self.notifyStop()
                return

            if self.rebootRequested is True:
                logger.debug('Reboot has been requested, stopping service')
                self.notifyStop()
                return

            self.initIPC()
        except Exception:  # Any init exception wil be caught, service must be then restarted
            logger.exception()
            logger.debug('Exiting service with failure status')
            os._exit(-1)  # pylint: disable=protected-access

        # ********************************
        # * Registers SENS subscriptions *
        # ********************************
        logevent('Registering ISensLogon')
        subscription_guid = '{41099152-498E-11E4-8FD3-10FEED05884B}'
        sl = SensLogon(self)
        subscription_interface = pythoncom.WrapObject(sl)

        event_system = win32com.client.Dispatch(PROGID_EventSystem)

        event_subscription = win32com.client.Dispatch(PROGID_EventSubscription)
        event_subscription.EventClassID = SENSGUID_EVENTCLASS_LOGON
        event_subscription.PublisherID = SENSGUID_PUBLISHER
        event_subscription.SubscriptionName = 'UDS Actor subscription'
        event_subscription.SubscriptionID = subscription_guid
        event_subscription.SubscriberInterface = subscription_interface

        event_system.Store(PROGID_EventSubscription, event_subscription)

        logger.debug('Registered SENS, running main loop')

        # *********************
        # * Main Service loop *
        # *********************
        # Counter used to check ip changes only once every 10 seconds, for
        # example
        counter = 0
        while self.isAlive:
            counter += 1
            # Process SENS messages, This will be a bit asyncronous (1 second
            # delay)
            pythoncom.PumpWaitingMessages()
            if counter % 10 == 0:
                self.checkIpsChanged()
            # In milliseconds, will break
            win32event.WaitForSingleObject(self.hWaitStop, 1000)

        logger.debug('Exited main loop, deregistering SENS')

        # *******************************************
        # * Remove SENS subscription before exiting *
        # *******************************************
        event_system.Remove(PROGID_EventSubscription,
                            "SubscriptionID == " + subscription_guid)

        self.endIPC()  # Ends IPC servers
        self.endAPI()  # And deinitializes REST api if needed

        self.notifyStop()
Пример #6
0
    def SvcDoRun(self):
        '''
        Main service loop
        '''
        try:
            initCfg()

            logger.debug('running SvcDoRun')
            servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                                  servicemanager.PYS_SERVICE_STARTED,
                                  (self._svc_name_, ''))

            # call the CoInitialize to allow the registration to run in an other
            # thread
            logger.debug('Initializing com...')
            pythoncom.CoInitialize()

            # ********************************************************
            # * Ask brokers what to do before proceding to main loop *
            # ********************************************************
            if self.interactWithBroker() is False:
                logger.debug('Interact with broker returned false, stopping service after a while')
                self.notifyStop()
                win32event.WaitForSingleObject(self.hWaitStop, 5000)
                return

            if self.isAlive is False:
                logger.debug('The service is not alive after broker interaction, stopping it')
                self.notifyStop()
                return

            if self.rebootRequested is True:
                logger.debug('Reboot has been requested, stopping service')
                self.notifyStop()
                return

            self.initIPC()
        except Exception:  # Any init exception wil be caught, service must be then restarted
            logger.exception()
            logger.debug('Exiting service with failure status')
            os._exit(-1)  # pylint: disable=protected-access

        # ********************************
        # * Registers SENS subscriptions *
        # ********************************
        logevent('Registering ISensLogon')
        subscription_guid = '{41099152-498E-11E4-8FD3-10FEED05884B}'
        sl = SensLogon(self)
        subscription_interface = pythoncom.WrapObject(sl)

        event_system = win32com.client.Dispatch(PROGID_EventSystem)

        event_subscription = win32com.client.Dispatch(PROGID_EventSubscription)
        event_subscription.EventClassID = SENSGUID_EVENTCLASS_LOGON
        event_subscription.PublisherID = SENSGUID_PUBLISHER
        event_subscription.SubscriptionName = 'UDS Actor subscription'
        event_subscription.SubscriptionID = subscription_guid
        event_subscription.SubscriberInterface = subscription_interface

        event_system.Store(PROGID_EventSubscription, event_subscription)

        logger.debug('Registered SENS, running main loop')

        # *********************
        # * Main Service loop *
        # *********************
        # Counter used to check ip changes only once every 10 seconds, for
        # example
        counter = 0
        while self.isAlive:
            counter += 1
            # Process SENS messages, This will be a bit asyncronous (1 second
            # delay)
            pythoncom.PumpWaitingMessages()
            if counter % 10 == 0:
                self.checkIpsChanged()
            # In milliseconds, will break
            win32event.WaitForSingleObject(self.hWaitStop, 1000)

        logger.debug('Exited main loop, deregistering SENS')

        # *******************************************
        # * Remove SENS subscription before exiting *
        # *******************************************
        event_system.Remove(
            PROGID_EventSubscription, "SubscriptionID == " + subscription_guid)

        self.endIPC()  # Ends IPC servers
        self.endAPI()  # And deinitializes REST api if needed

        self.notifyStop()
Пример #7
0
    def interactWithBroker(self):
        '''
        Returns True to continue to main loop, false to stop & exit service
        '''
        # If no configuration is found, stop service
        if cfg is None:
            logger.fatal('No configuration found, stopping service')
            return False

        self.api = REST.Api(cfg['host'], cfg['masterKey'], cfg['ssl'])

        # Wait for Broker to be ready
        counter = 0
        while self.isAlive:
            try:
                # getNetworkInfo is a generator function
                netInfo = tuple(operations.getNetworkInfo())
                self.knownIps = dict(((i.mac, i.ip) for i in netInfo))
                ids = ','.join([i.mac for i in netInfo])
                if ids == '':
                    # Wait for any network interface to be ready
                    logger.debug(
                        'No valid network interfaces found, retrying in a while...'
                    )
                    raise Exception()
                logger.debug('Ids: {}'.format(ids))
                self.api.init(ids)
                # Set remote logger to notify log info to broker
                logger.setRemoteLogger(self.api)

                break
            except REST.InvalidKeyError:
                logger.fatal(
                    'Can\'t sync with broker: Invalid broker Master Key')
                return False
            except REST.UnmanagedHostError:
                # Maybe interface that is registered with broker is not enabled already?
                # Right now, we thing that the interface connected to broker is
                # the interface that broker will know, let's see how this works
                logger.fatal(
                    'This host is not managed by UDS Broker (ids: {})'.format(
                        ids))
                return False  # On unmanaged hosts, there is no reason right now to continue running
            except Exception as e:
                logger.debug('Exception on network info: retrying')
                logger.exception()
                # Any other error is expectable and recoverable, so let's wait a bit and retry again
                # but, if too many errors, will log it (one every minute, for
                # example)
                counter += 1
                if counter % 60 == 0:  # Every 5 minutes, raise a log
                    logger.info(
                        'Trying to inititialize connection with broker (last error: {})'
                        .format(exceptionToMessage(e)))
                # Wait a bit before next check
                self.doWait(5000)

        # Broker connection is initialized, now get information about what to
        # do
        counter = 0
        while self.isAlive:
            try:
                logger.debug('Requesting information of what to do now')
                info = self.api.information()
                data = info.split('\r')
                if len(data) != 2:
                    logger.error(
                        'The format of the information message is not correct (got {})'
                        .format(info))
                    raise Exception
                params = data[1].split('\t')
                if data[0] == 'rename':
                    try:
                        if len(params) == 1:  # Simple rename
                            logger.debug('Renaming computer to {}'.format(
                                params[0]))
                            self.rename(params[0])
                        # Rename with change password for an user
                        elif len(params) == 4:
                            logger.debug(
                                'Renaming computer to {}'.format(params))
                            self.rename(params[0], params[1], params[2],
                                        params[3])
                        else:
                            logger.error(
                                'Got invalid parameter for rename operation: {}'
                                .format(params))
                            return False
                        break
                    except Exception as e:
                        logger.error(
                            'Error at computer renaming stage: {}'.format(
                                e.message))
                        return False
                elif data[0] == 'domain':
                    if len(params) != 5:
                        logger.error(
                            'Got invalid parameters for domain message: {}'.
                            format(params))
                        return False
                    self.joinDomain(params[0], params[1], params[2], params[3],
                                    params[4])
                    break
                else:
                    logger.error(
                        'Unrecognized action sent from broker: {}'.format(
                            data[0]))
                    return False  # Stop running service
            except REST.UserServiceNotFoundError:
                logger.error(
                    'The host has lost the sync state with broker! (host uuid changed?)'
                )
                return False
            except Exception:
                if counter % 60 == 0:
                    logger.warn(
                        'Too many retries in progress, though still trying (last error: {})'
                        .format(exceptionToMessage(e)))
                counter += 1
                # Any other error is expectable and recoverable, so let's wait
                # a bit and retry again
                # Wait a bit before next check
                self.doWait(5000)

        if self.rebootRequested:
            try:
                operations.reboot()
            except Exception as e:
                logger.error('Exception on reboot: {}'.format(e.message))
            return False  # Stops service

        return True
Пример #8
0
    def SvcDoRun(self):  # pylint: disable=too-many-statements, too-many-branches
        '''
        Main service loop
        '''
        try:
            initCfg()

            logger.debug('running SvcDoRun')
            servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                                  servicemanager.PYS_SERVICE_STARTED,
                                  (self._svc_name_, ''))

            # call the CoInitialize to allow the registration to run in an other
            # thread
            logger.debug('Initializing com...')
            pythoncom.CoInitialize()

            # ********************************************************
            # * Ask brokers what to do before proceding to main loop *
            # ********************************************************
            while True:
                brokerConnected = self.interactWithBroker()
                if brokerConnected is False:
                    logger.debug('Interact with broker returned false, stopping service after a while')
                    self.notifyStop()
                    win32event.WaitForSingleObject(self.hWaitStop, 5000)
                    return
                elif brokerConnected is True:
                    break

                # If brokerConnected returns None, repeat the cycle
                self.doWait(16000)  # Wait for a looong while

            if self.interactWithBroker() is False:
                logger.debug('Interact with broker returned false, stopping service after a while')
                self.notifyStop()
                win32event.WaitForSingleObject(self.hWaitStop, 5000)
                return

            if self.isAlive is False:
                logger.debug('The service is not alive after broker interaction, stopping it')
                self.notifyStop()
                return

            if self.rebootRequested is True:
                logger.debug('Reboot has been requested, stopping service')
                self.notifyStop()
                return

            self.initIPC()
        except Exception:  # Any init exception wil be caught, service must be then restarted
            logger.exception()
            logger.debug('Exiting service with failure status')
            os._exit(-1)  # pylint: disable=protected-access

        # ********************************
        # * Registers SENS subscriptions *
        # ********************************
        logevent('Registering ISensLogon')
        subscription_guid = '{41099152-498E-11E4-8FD3-10FEED05884B}'
        sl = SensLogon(self)
        subscription_interface = pythoncom.WrapObject(sl)

        event_system = win32com.client.Dispatch(PROGID_EventSystem)

        event_subscription = win32com.client.Dispatch(PROGID_EventSubscription)
        event_subscription.EventClassID = SENSGUID_EVENTCLASS_LOGON
        event_subscription.PublisherID = SENSGUID_PUBLISHER
        event_subscription.SubscriptionName = 'UDS Actor subscription'
        event_subscription.SubscriptionID = subscription_guid
        event_subscription.SubscriberInterface = subscription_interface

        event_system.Store(PROGID_EventSubscription, event_subscription)

        logger.debug('Registered SENS, running main loop')

        # Execute script in c:\\windows\\post-uds.bat after interacting with broker, if no reboot is requested ofc
        # This will be executed only when machine gets "ready"
        try:
            if os.path.isfile(POST_CMD):
                subprocess.call([POST_CMD, ])
            else:
                logger.info('POST file not found & not executed')
        except Exception as e:
            # Ignore output of execution command
            logger.error('Executing post command give')

        # *********************
        # * Main Service loop *
        # *********************
        # Counter used to check ip changes only once every 10 seconds, for
        # example
        counter = 0
        while self.isAlive:
            counter += 1
            # Process SENS messages, This will be a bit asyncronous (1 second
            # delay)
            pythoncom.PumpWaitingMessages()
            if counter >= 15:  # Once every 15 seconds
                counter = 0
                try:
                    self.checkIpsChanged()
                except Exception as e:
                    logger.error('Error checking ip change: {}'.format(e))
            # In milliseconds, will break
            win32event.WaitForSingleObject(self.hWaitStop, 1000)

        logger.debug('Exited main loop, deregistering SENS')

        # *******************************************
        # * Remove SENS subscription before exiting *
        # *******************************************
        event_system.Remove(
            PROGID_EventSubscription, "SubscriptionID == " + subscription_guid)

        self.endIPC()  # Ends IPC servers
        self.endAPI()  # And deinitializes REST api if needed

        self.notifyStop()