def getfqdn(name='', conf=None): """ Get the fqdn. If ``name`` is not given it will try various ways to get a valid fqdn from the current host. If ``conf`` but no name is given it will try to read the FQDN from the specified configuration file. """ if not name: try: return forceFqdn(os.environ["OPSI_HOSTNAME"]) except KeyError: # not set in environment. pass # lazy import to avoid circular dependency from OPSI.Util.Config import getGlobalConfig if conf is not None: hostname = getGlobalConfig('hostname', conf) else: hostname = getGlobalConfig('hostname') if hostname: return forceFqdn(hostname) return forceFqdn(socket.getfqdn(name))
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 testForceFqdnRequiresHostnameRootZoneAndTopLevelDomain(hostname): forceFqdn(hostname)
def testForceFqdnAlwaysReturnsLowercase(domain): assert 'bla.domain.invalid' == forceFqdn(domain)
def testForceFqdnRemovesTrailingDot(): assert 'abc.example.local' == forceFqdn('abc.example.local.')