コード例 #1
0
ファイル: tcp.py プロジェクト: mazen-hasoun/checkmk
    def _decrypt(output, encryption_settings):
        # type: (RawAgentData, Dict[str, str]) -> RawAgentData
        if output.startswith(b"<<<"):
            # The output is not encrypted.
            if encryption_settings["use_regular"] == "enforce":
                raise MKAgentError(
                    "Agent output is plaintext but encryption is enforced by configuration"
                )
            return output

        if encryption_settings["use_regular"] not in ["enforce", "allow"]:
            return output

        try:
            # simply check if the protocol is an actual number
            protocol = int(output[0:2])

            output = TCPDataSource._decrypt_package(
                output[2:], encryption_settings["passphrase"], protocol)
        except ValueError:
            raise MKAgentError("Unsupported protocol version: %s" %
                               str(output[:2]))
        except Exception as e:
            if encryption_settings["use_regular"] == "enforce":
                raise MKAgentError("Failed to decrypt agent output: %s" % e)

            # of course the package might indeed have been encrypted but
            # in an incorrect format, but how would we find that out?
            # In this case processing the output will fail

        return output
コード例 #2
0
ファイル: tcp.py プロジェクト: mazen-hasoun/checkmk
    def _execute(self):
        # type: () -> RawAgentData
        if self._use_only_cache:
            raise MKAgentError(
                "Got no data: No usable cache file present at %s" %
                self._cache_file_path())

        self._verify_ipaddress()

        output = self._fetch_raw_data(
            socket.socket(
                socket.AF_INET6 if self._host_config.is_ipv6_primary else
                socket.AF_INET, socket.SOCK_STREAM), (
                    self._ipaddress,
                    self.port,
                ), self.timeout, self._logger)

        if not output:  # may be caused by xinetd not allowing our address
            raise MKEmptyAgentData("Empty output from agent at TCP port %s" %
                                   self.port)

        if len(output) < 16:
            raise MKAgentError("Too short output from agent: %r" % output)

        output = self._decrypt(output, self._host_config.agent_encryption)
        return output
コード例 #3
0
ファイル: tcp.py プロジェクト: surajrb/checkmk
    def _decrypt(self, output):
        # type: (RawAgentData) -> RawAgentData
        if output.startswith(b"<<<"):
            self._logger.debug("Output is not encrypted")
            if self._encryption_settings["use_regular"] == "enforce":
                raise MKAgentError(
                    "Agent output is plaintext but encryption is enforced by configuration"
                )
            return output

        if self._encryption_settings["use_regular"] not in [
                "enforce", "allow"
        ]:
            self._logger.debug("Output is not encrypted")
            return output

        try:
            self._logger.debug("Decrypt encrypted output")
            output = self._real_decrypt(output)
        except MKAgentError:
            raise
        except Exception as e:
            if self._encryption_settings["use_regular"] == "enforce":
                raise MKAgentError("Failed to decrypt agent output: %s" % e)

            # of course the package might indeed have been encrypted but
            # in an incorrect format, but how would we find that out?
            # In this case processing the output will fail

        return output
コード例 #4
0
ファイル: tcp.py プロジェクト: bsmr/tribe29-checkmk
    def _execute(self):
        # type: () -> RawAgentData
        if self._use_only_cache:
            raise MKAgentError(
                "Got no data: No usable cache file present at %s" %
                self._cache_file_path())

        verify_ipaddress(self._ipaddress)
        assert self._ipaddress

        with TCPDataFetcher(
                socket.AF_INET6
                if self._host_config.is_ipv6_primary else socket.AF_INET,
            (self._ipaddress, self.port),
                self.timeout,
                self._host_config.agent_encryption,
        ) as fetcher:
            output = fetcher.data()
            if not output:  # may be caused by xinetd not allowing our address
                raise MKEmptyAgentData("Empty output from agent at %s:%d" %
                                       (self._ipaddress, self.port))
            if len(output) < 16:
                raise MKAgentError("Too short output from agent: %r" % output)
            return output
        raise MKAgentError("Failed to read data")
コード例 #5
0
    def _get_agent_info_program(self, commandline, command_stdin):
        # type: (Union[bytes, Text], Optional[bytes]) -> RawAgentData
        exepath = commandline.split()[0]  # for error message, hide options!

        self._logger.debug("Calling external program %r" % (commandline))
        p = None
        try:
            if config.monitoring_core == "cmc":
                p = subprocess.Popen(  # nosec
                    commandline,
                    shell=True,
                    stdin=subprocess.PIPE if command_stdin else open(os.devnull),
                    stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE,
                    preexec_fn=os.setsid,
                    close_fds=True,
                )
            else:
                # We can not create a separate process group when running Nagios
                # Upon reaching the service_check_timeout Nagios only kills the process
                # group of the active check.
                p = subprocess.Popen(  # nosec
                    commandline,
                    shell=True,
                    stdin=subprocess.PIPE if command_stdin else open(os.devnull),
                    stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE,
                    close_fds=True,
                )

            if command_stdin:
                stdout, stderr = p.communicate(input=ensure_bytestr(command_stdin))
            else:
                stdout, stderr = p.communicate()
            exitstatus = p.returncode

        except MKTimeout:
            # On timeout exception try to stop the process to prevent child process "leakage"
            if p:
                os.killpg(os.getpgid(p.pid), signal.SIGTERM)
                p.wait()
            raise
        finally:
            # The stdout and stderr pipe are not closed correctly on a MKTimeout
            # Normally these pipes getting closed after p.communicate finishes
            # Closing them a second time in a OK scenario won't hurt neither..
            if p:
                if p.stdout is None or p.stderr is None:
                    raise Exception("stdout needs to be set")
                p.stdout.close()
                p.stderr.close()

        if exitstatus:
            if exitstatus == 127:
                raise MKAgentError("Program '%s' not found (exit code 127)" % exepath)
            else:
                raise MKAgentError("Agent exited with code %d: %s" % (exitstatus, stderr))

        return stdout
コード例 #6
0
ファイル: ipmi.py プロジェクト: sri-sysad/checkmk
    def _execute(self) -> RawAgentData:
        if not self._credentials:
            raise MKAgentError("Missing credentials")

        if self.ipaddress is None:
            raise MKAgentError("Missing IP address")

        with IPMIDataFetcher(self.ipaddress, self._credentials["username"],
                             self._credentials["password"]) as fetcher:
            return fetcher.data()
        raise MKAgentError("Failed to read data")
コード例 #7
0
ファイル: tcp.py プロジェクト: AngusWarren/checkmk
    def _execute(
        self,
        *,
        selected_raw_sections: Optional[SelectedRawSections],
    ) -> AgentRawData:
        if TCPConfigurator._use_only_cache:
            raise MKAgentError("Got no data: No usable cache file present at %s" %
                               self.configurator.file_cache.path)

        with TCPFetcher.from_json(self.configurator.configure_fetcher()) as fetcher:
            return fetcher.fetch()
        raise MKAgentError("Failed to read data")
コード例 #8
0
    def configure_fetcher(self) -> Dict[str, Any]:
        if not self.credentials:
            raise MKAgentError("Missing credentials")

        if self.ipaddress is None:
            raise MKAgentError("Missing IP address")

        return {
            "file_cache": self.file_cache.configure(),
            "address": self.ipaddress,
            "username": self.credentials["username"],
            "password": self.credentials["password"],
        }
コード例 #9
0
ファイル: ipmi.py プロジェクト: surajrb/checkmk
    def _execute(self):
        # type: () -> RawAgentData
        if not self._credentials:
            raise MKAgentError("Missing credentials")

        if self._ipaddress is None:
            raise MKAgentError("Missing IP address")

        with IPMIDataFetcher(self._ipaddress, self._credentials["username"],
                             self._credentials["password"],
                             self._logger) as fetcher:
            data = fetcher.data()
        return data
コード例 #10
0
ファイル: ipmi.py プロジェクト: fmattheus/checkmk
    def _make_fetcher(self) -> IPMIFetcher:
        if not self.credentials:
            raise MKAgentError("Missing credentials")

        if self.ipaddress is None:
            raise MKAgentError("Missing IP address")

        return IPMIFetcher(
            self._make_file_cache(),
            address=self.ipaddress,
            username=self.credentials["username"],
            password=self.credentials["password"],
        )
コード例 #11
0
ファイル: ipmi.py プロジェクト: surajrb/checkmk
    def _sensors_section(self):
        # type: () -> RawAgentData
        if self._command is None:
            raise MKAgentError("Not connected")

        self._logger.debug("Fetching sensor data via UDP from %s:623",
                           self._command.bmc)

        try:
            sdr = ipmi_sdr.SDR(self._command)
        except NotImplementedError as e:
            self._logger.log(VERBOSE, "Failed to fetch sensor data: %r", e)
            self._logger.debug("Exception", exc_info=True)
            return b""

        sensors = []
        has_no_gpu = not self._has_gpu()
        for number in sdr.get_sensor_numbers():
            rsp = self._command.raw_command(command=0x2d,
                                            netfn=4,
                                            data=(number, ))
            if 'error' in rsp:
                continue

            reading = sdr.sensors[number].decode_sensor_reading(rsp['data'])
            if reading is not None:
                # sometimes (wrong) data for GPU sensors is reported, even if
                # not installed
                if "GPU" in reading.name and has_no_gpu:
                    continue
                sensors.append(_parse_sensor_reading(number, reading))

        return b"<<<mgmt_ipmi_sensors:sep(124)>>>\n" + b"".join(
            [b"|".join(sensor) + b"\n" for sensor in sensors])
コード例 #12
0
ファイル: tcp.py プロジェクト: mazen-hasoun/checkmk
    def _fetch_raw_data(sock, address, timeout, logger):
        # type: (socket.socket, Tuple[Optional[str], int], float, logging.Logger) -> RawAgentData
        output_lines = []  # type: List[bytes]
        logger.debug("Connecting via TCP to %s:%d (%ss timeout)", address[0],
                     address[1], timeout)
        try:
            sock.settimeout(timeout)
            sock.connect(address)
            sock.settimeout(None)

            logger.debug("Reading data from agent")

            while True:
                data = sock.recv(4096, socket.MSG_WAITALL)
                if not data:
                    break
                output_lines.append(data)

        except socket.error as e:
            if cmk.utils.debug.enabled():
                raise
            raise MKAgentError("Communication failed: %s" % e)
        finally:
            sock.close()

        return b''.join(output_lines)
コード例 #13
0
ファイル: programs.py プロジェクト: deatheibon/checkmk
 def data(self):
     # type: () -> RawAgentData
     if self._process is None:
         raise MKAgentError("No process")
     stdout, stderr = self._process.communicate(
         input=ensure_bytestr(self._stdin) if self._stdin else None)
     if self._process.returncode == 127:
         exepath = self._cmdline.split()[
             0]  # for error message, hide options!
         raise MKAgentError("Program '%s' not found (exit code 127)" %
                            six.ensure_str(exepath))
     if self._process.returncode:
         raise MKAgentError(
             "Agent exited with code %d: %s" %
             (self._process.returncode, six.ensure_str(stderr)))
     return stdout
コード例 #14
0
ファイル: _abstract.py プロジェクト: selten/checkmk
    def _get_raw_data(
        self,
        *,
        selected_raw_sections: Optional[SelectedRawSections],
    ) -> Tuple[BoundedAbstractRawData, bool]:
        """Returns the current raw data of this data source

        It either uses previously cached raw data of this data source or
        executes the data source to get new data.

        The "raw data" is the raw byte string returned by the source for
        AgentDataSource sources. The SNMPDataSource source already
        return the final info data structure.
        """
        file_cache = self._make_file_cache()
        raw_data = file_cache.read()
        if raw_data:
            self._logger.log(VERBOSE, "Use cached data")
            return raw_data, True

        if raw_data is None and config.simulation_mode:
            raise MKAgentError("Got no data (Simulation mode enabled and no cachefile present)")

        self._logger.log(VERBOSE, "Execute data source")
        raw_data = self._execute(selected_raw_sections=selected_raw_sections)
        file_cache.write(raw_data)
        return raw_data, False
コード例 #15
0
    def _get_raw_data(self):
        # type: () -> Tuple[BoundedAbstractRawData, bool]
        """Returns the current raw data of this data source

        It either uses previously cached raw data of this data source or
        executes the data source to get new data.

        The "raw data" is the raw byte string returned by the source for
        CheckMKAgentDataSource sources. The SNMPDataSource source already
        return the final info data structure.
        """
        raw_data = self._read_cache_file()
        if raw_data:
            self._logger.log(VERBOSE, "Use cached data")
            return raw_data, True

        elif raw_data is None and config.simulation_mode:
            raise MKAgentError(
                "Got no data (Simulation mode enabled and no cachefile present)"
            )

        self._logger.log(VERBOSE, "Execute data source")
        raw_data = self._execute()
        self._write_cache_file(raw_data)
        return raw_data, False
コード例 #16
0
ファイル: tcp.py プロジェクト: surajrb/checkmk
    def _raw_data(self):
        # type: () -> RawAgentData
        self._logger.debug("Reading data from agent")
        if not self._socket:
            return b""

        def recvall(sock):
            # type: (socket.socket) -> bytes
            buffer = []  # type: List[bytes]
            while True:
                data = sock.recv(4096, socket.MSG_WAITALL)
                if not data:
                    break
                buffer.append(data)
            return b"".join(buffer)

        try:
            output = recvall(self._socket)
            if not output:  # may be caused by xinetd not allowing our address
                raise MKEmptyAgentData("Empty output from agent at %s:%d" %
                                       self._address)
            return output
        except socket.error as e:
            if cmk.utils.debug.enabled():
                raise
            raise MKAgentError("Communication failed: %s" % e)
コード例 #17
0
ファイル: tcp.py プロジェクト: surajrb/checkmk
    def _real_decrypt(self, output):
        # type: (RawAgentData) -> RawAgentData
        try:
            # simply check if the protocol is an actual number
            protocol = int(output[:2])
        except ValueError:
            raise MKAgentError("Unsupported protocol version: %r" % output[:2])
        encrypted_pkg = output[2:]
        encryption_key = self._encryption_settings["passphrase"]

        encrypt_digest = sha256 if protocol == 2 else md5

        # Adapt OpenSSL handling of key and iv
        def derive_key_and_iv(password, key_length, iv_length):
            # type: (bytes, int, int) -> Tuple[bytes, bytes]
            d = d_i = b''
            while len(d) < key_length + iv_length:
                d_i = encrypt_digest(d_i + password).digest()
                d += d_i
            return d[:key_length], d[key_length:key_length + iv_length]

        key, iv = derive_key_and_iv(encryption_key.encode("utf-8"), 32,
                                    AES.block_size)
        decryption_suite = AES.new(key, AES.MODE_CBC, iv)
        decrypted_pkg = decryption_suite.decrypt(encrypted_pkg)
        # Strip of fill bytes of openssl
        return decrypted_pkg[0:-decrypted_pkg[-1]]
コード例 #18
0
ファイル: piggyback.py プロジェクト: deatheibon/checkmk
 def _execute(self):
     # type: () -> RawAgentData
     with PiggyBackDataFetcher(self._hostname, self._ipaddress,
                               self._time_settings) as fetcher:
         self._summary = fetcher.summary()
         return fetcher.data()
     raise MKAgentError("Failed to read data")
コード例 #19
0
ファイル: programs.py プロジェクト: deatheibon/checkmk
 def _execute(self):
     # type: () -> RawAgentData
     self._logger.debug("Calling external program %r" %
                        (self.source_cmdline))
     with ProgramDataFetcher(self.source_cmdline, self.source_stdin,
                             self._logger) as fetcher:
         return fetcher.data()
     raise MKAgentError("Failed to read data")
コード例 #20
0
ファイル: ipmi.py プロジェクト: surajrb/checkmk
 def __exit__(self, exc_type, exc_value, traceback):
     # type: (Optional[Type[BaseException]], Optional[BaseException], Optional[TracebackType]) -> bool
     self.close()
     if isinstance(exc_type, IpmiException) and not exc_value:
         # Raise a more specific exception
         raise MKAgentError("IPMI communication failed: %r" % exc_type)
     if not cmk.utils.debug.enabled():
         return False
     return True
コード例 #21
0
ファイル: programs.py プロジェクト: AngusWarren/checkmk
 def _execute(
     self,
     *,
     selected_raw_sections: Optional[SelectedRawSections],
 ) -> AgentRawData:
     # TODO(ml): Do something with the selection.
     with ProgramFetcher.from_json(self.configurator.configure_fetcher()) as fetcher:
         return fetcher.fetch()
     raise MKAgentError("Failed to read data")
コード例 #22
0
ファイル: snmp.py プロジェクト: sri-sysad/checkmk
 def _execute(self) -> SNMPRawData:
     ip_lookup.verify_ipaddress(self.ipaddress)
     with SNMPDataFetcher(
             self._make_oid_infos(),
             self._use_snmpwalk_cache,
             self._snmp_config,
     ) as fetcher:
         return fetcher.data()
     raise MKAgentError("Failed to read data")
コード例 #23
0
 def _execute(
     self,
     *,
     selected_raw_sections: Optional[SelectedRawSections],
 ) -> AgentRawData:
     with PiggyBackFetcher.from_json(
             self.configurator.configure_fetcher()) as fetcher:
         return fetcher.fetch()
     raise MKAgentError("Failed to read data")
コード例 #24
0
ファイル: piggyback.py プロジェクト: selten/checkmk
 def _execute(
     self,
     *,
     selected_raw_sections: Optional[SelectedRawSections],
 ) -> RawAgentData:
     self._summary = self._summarize()
     with PiggyBackDataFetcher(self.hostname, self.ipaddress, self._time_settings) as fetcher:
         return fetcher.data()
     raise MKAgentError("Failed to read data")
コード例 #25
0
ファイル: ipmi.py プロジェクト: surajrb/checkmk
    def data(self):
        # type: () -> RawAgentData
        if self._command is None:
            raise MKAgentError("Not connected")

        output = b""
        output += self._sensors_section()
        output += self._firmware_section()
        return output
コード例 #26
0
 def _execute(self):
     # type: () -> RawSNMPData
     verify_ipaddress(self._ipaddress)
     with SNMPDataFetcher(
             self._make_oid_infos(),
             self._use_snmpwalk_cache,
             self._snmp_config,
             self._logger,
     ) as fetcher:
         return fetcher.data()
     raise MKAgentError("Failed to read data")
コード例 #27
0
ファイル: snmp.py プロジェクト: AngusWarren/checkmk
 def _execute(
     self,
     *,
     selected_raw_sections: Optional[SelectedRawSections],
 ) -> SNMPRawData:
     # This is wrong
     configurator = cast(SNMPConfigurator, self.configurator)
     configurator.selected_raw_sections = selected_raw_sections  # checking only
     # End of wrong
     with SNMPFetcher.from_json(
             self.configurator.configure_fetcher()) as fetcher:
         return fetcher.fetch()
     raise MKAgentError("Failed to read data")
コード例 #28
0
ファイル: tcp.py プロジェクト: deatheibon/checkmk
    def _execute(self):
        # type: () -> RawAgentData
        if self._use_only_cache:
            raise MKAgentError(
                "Got no data: No usable cache file present at %s" %
                self._cache_file_path())

        verify_ipaddress(self._ipaddress)

        with TCPDataFetcher(
                socket.AF_INET6
                if self._host_config.is_ipv6_primary else socket.AF_INET,
            (self._ipaddress, self.port),
                self.timeout,
                self._host_config.agent_encryption,
                self._logger,
        ) as fetcher:
            output = fetcher.data()
            if len(output) < 16:
                raise MKAgentError("Too short output from agent: %r" % output)
            return output
        raise MKAgentError("Failed to read data")
コード例 #29
0
    def _execute(
        self,
        *,
        selected_raw_sections: Optional[SelectedRawSections],
    ) -> RawAgentData:
        if not self._credentials:
            raise MKAgentError("Missing credentials")

        if self.ipaddress is None:
            raise MKAgentError("Missing IP address")

        if selected_raw_sections is None:
            # pylint: disable=unused-variable
            # TODO(ml): Should we pass that to the fetcher?
            selected_raw_section_names = {SectionName("mgmt_ipmi_sensors")}

        with IPMIDataFetcher(
                self.ipaddress,
                self._credentials["username"],
                self._credentials["password"],
        ) as fetcher:
            return fetcher.data()
        raise MKAgentError("Failed to read data")
コード例 #30
0
 def _execute(
     self,
     *,
     selected_raw_sections: Optional[SelectedRawSections],
 ) -> SNMPRawData:
     ip_lookup.verify_ipaddress(self.ipaddress)
     with SNMPDataFetcher(
             self._make_oid_infos(
                 selected_raw_sections=selected_raw_sections),
             self._use_snmpwalk_cache,
             self._snmp_config,
     ) as fetcher:
         return fetcher.data()
     raise MKAgentError("Failed to read data")