def run(self): # pylint: disable=too-many-locals,too-many-branches,too-many-statements with log_context({'instance': 'service connection'}): logger.debug("ServiceConnectionThread started...") self.running = True self.connected = False self.cancelled = False try: # pylint: disable=too-many-nested-blocks verify_server_cert = ( config.get('global', 'verify_server_cert') or config.get('global', 'verify_server_cert_by_ca')) ca_cert_file = config.ca_cert_file self.prepare_ca_cert_file() compression = config.get('config_service', 'compression') if "localhost" in self._configServiceUrl or "127.0.0.1" in self._configServiceUrl: compression = False verify_server_cert = False if verify_server_cert: if os.path.exists(ca_cert_file): logger.info( "Server verification enabled, using CA cert file '%s'", ca_cert_file) else: logger.error( "Server verification enabled, but CA cert file '%s' not found, skipping verification", ca_cert_file) ca_cert_file = None verify_server_cert = False tryNum = 0 while not self.cancelled and not self.connected: tryNum += 1 try: logger.notice("Connecting to config server '%s' #%d", self._configServiceUrl, tryNum) self.setStatusMessage( _("Connecting to config server '%s' #%d") % (self._configServiceUrl, tryNum)) if len(self._username.split('.')) < 3: raise Exception( f"Domain missing in username '{self._username}'" ) logger.debug( "JSONRPCBackend address=%s, verify_server_cert=%s, ca_cert_file=%s, proxy_url=%s, application=%s", self._configServiceUrl, verify_server_cert, ca_cert_file, config.get('global', 'proxy_url'), f"opsiclientd/{__version__}") self.configService = JSONRPCBackend( address=self._configServiceUrl, username=self._username, password=self._password, verify_server_cert=verify_server_cert, ca_cert_file=ca_cert_file, proxy_url=config.get('global', 'proxy_url'), application=f"opsiclientd/{__version__}", compression=compression, ip_version=config.get('global', 'ip_version')) self.configService.accessControl_authenticated() # pylint: disable=no-member self.connected = True self.connectionError = None serverVersion = self.configService.serverVersion self.setStatusMessage( _("Connected to config server '%s'") % self._configServiceUrl) logger.notice( "Connected to config server '%s' (name=%s, version=%s)", self._configServiceUrl, self.configService.serverName, serverVersion) if serverVersion and (serverVersion[0] > 4 or (serverVersion[0] == 4 and serverVersion[1] > 1)): if not os.path.exists( config.ca_cert_file ) or verify_server_cert or config.get( 'global', 'install_opsi_ca_into_os_store'): # Renew CA if not exists or connection is verified try: update_ca_cert(self.configService, allow_remove=True) except Exception as err: # pylint: disable=broad-except logger.error(err, exc_info=True) except OpsiServiceVerificationError as verificationError: self.connectionError = forceUnicode(verificationError) self.setStatusMessage( _("Failed to connect to config server '%s': Service verification failure" ) % self._configServiceUrl) logger.error( "Failed to connect to config server '%s': %s", self._configServiceUrl, verificationError) break except Exception as error: # pylint: disable=broad-except self.connectionError = forceUnicode(error) self.setStatusMessage( _("Failed to connect to config server '%s': %s") % (self._configServiceUrl, forceUnicode(error))) logger.info( "Failed to connect to config server '%s': %s", self._configServiceUrl, error) logger.debug(error, exc_info=True) if isinstance(error, OpsiAuthenticationError): fqdn = System.getFQDN() try: fqdn = forceFqdn(fqdn) except Exception as fqdnError: # pylint: disable=broad-except logger.warning( "Failed to get fqdn from os, got '%s': %s", fqdn, fqdnError) break if self._username != fqdn: logger.notice( "Connect failed with username '%s', got fqdn '%s' from os, trying fqdn", self._username, fqdn) self._username = fqdn else: break if 'is not supported by the backend' in self.connectionError.lower( ): try: from cryptography.hazmat.backends import default_backend # pylint: disable=import-outside-toplevel logger.debug( "Got the following crypto backends: %s", default_backend()._backends) # pylint: disable=no-member,protected-access except Exception as cryptoCheckError: # pylint: disable=broad-except logger.debug( "Failed to get info about installed crypto modules: %s", cryptoCheckError) for _unused in range( 3): # Sleeping before the next retry time.sleep(1) except Exception as err: # pylint: disable=broad-except logger.error(err, exc_info=True) finally: self.running = False
def __init__(self): baseDir = self._getBaseDirectory() self._temporaryConfigServiceUrls = [] self._temporaryDepotDrive = [] self._temporary_depot_path = None self._config_file_mtime = 0 self.disabledEventTypes = [] self._config = { "system": { "program_files_dir": "", }, "global": { "base_dir": baseDir, "config_file": os.path.join(baseDir, "opsiclientd", "opsiclientd.conf"), "log_file": "opsiclientd.log", "log_level": LOG_NOTICE, "keep_rotated_logs": 10, "max_log_size": 5, # In MB "max_log_transfer_size": 5, # In MB "host_id": System.getFQDN().lower(), "opsi_host_key": "", "wait_for_gui_timeout": 120, "block_login_notifier": "", "verify_server_cert": False, "verify_server_cert_by_ca": False, "trust_uib_opsi_ca": True, "install_opsi_ca_into_os_store": False, "proxy_url": "system", "suspend_bitlocker_on_reboot": False, "ip_version": "auto" }, "config_service": { "url": [], "compression": True, "connection_timeout": 10, "user_cancelable_after": 0, "sync_time_from_service": False }, "depot_server": { # The id of the depot the client is assigned to "master_depot_id": "", # The id of the depot currently set as (dynamic) depot "depot_id": "", "url": "", "drive": "", "username": "******", }, "cache_service": { "product_cache_max_size": 6000000000, "extension_config_dir": "", "include_product_group_ids": [], "exclude_product_group_ids": [] }, "control_server": { "interface": "0.0.0.0", "port": 4441, "ssl_server_key_file": os.path.join(baseDir, "opsiclientd", "opsiclientd.pem"), "ssl_server_cert_file": os.path.join(baseDir, "opsiclientd", "opsiclientd.pem"), "static_dir": os.path.join(baseDir, "opsiclientd", "static_html"), "max_authentication_failures": 5, "kiosk_api_active": True, "process_actions_event": "auto" }, "notification_server": { "interface": "127.0.0.1", "start_port": 44000, "popup_port": 45000, }, "opsiclientd_rpc": { "command": "", }, "opsiclientd_notifier": { "command": "", }, "action_processor": { "local_dir": "", "remote_dir": "", "remote_common_dir": "", "filename": "", "command": "", "run_as_user": "******", "create_user": True, "delete_user": True, "create_environment": False, } } self._applySystemSpecificConfiguration()