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'})
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()
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()
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
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()
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()
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
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()