Beispiel #1
0
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))
Beispiel #2
0
    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.')