Esempio n. 1
0
def test_status(manager_glob, manager_exists, test_manager, process_status):
    """
    Tests manager.status() function in two cases:
        * PID files are created and processed are running,
        * No process is running and therefore no PID files have been created
    :param manager_glob: mock of glob.glob function
    :param manager_exists: mock of os.path.exists function
    :param test_manager: pytest fixture
    :param process_status: status to test (valid values: running/stopped/failed/restarting).
    :return:
    """
    def mock_glob(path_to_check):
        return [path_to_check.replace('*', '0234')
                ] if process_status == 'running' else []

    def mock_exists(path_to_check):
        if path_to_check == '/proc/0234':
            return process_status == 'running'
        else:
            return path_to_check.endswith(f'.{process_status.replace("ing","").replace("re", "")}') or \
                   path_to_check.endswith(f'.{process_status.replace("ing","")}')

    manager_glob.side_effect = mock_glob
    manager_exists.side_effect = mock_exists
    manager_status = status()
    assert isinstance(manager_status, dict)
    assert all(process_status == x for x in manager_status.values())
    if process_status == 'running':
        manager_exists.assert_any_call("/proc/0234")
Esempio n. 2
0
    def remove(self):
        """
        Deletes the agent.

        :return: Message.
        """

        # Check if authd is running
        manager_status = manager.status()
        if 'ossec-authd' not in manager_status or manager_status['ossec-authd'] == 'running':
            raise WazuhException(1704)

        # Get info from DB
        self._load_info_from_DB()

        f_keys_temp = '{0}.tmp'.format(common.client_keys)

        f_tmp = open(f_keys_temp, 'w')
        agent_found = False
        with open(common.client_keys) as f_k:
            for line in f_k.readlines():
                line_data = line.strip().split(' ')  # 0 -> id, 1 -> name, 2 -> ip, 3 -> key

                if self.id == line_data[0] and line_data[1][0] not in ('#!'):
                    f_tmp.write('{0} !{1} {2} {3}\n'.format(line_data[0], line_data[1], line_data[2], line_data[3]))
                    agent_found = True
                else:
                    f_tmp.write(line)
        f_tmp.close()

        if agent_found:
            # Overwrite client.keys
            move(f_keys_temp, common.client_keys)
            root_uid = getpwnam("ossec").pw_uid
            ossec_gid = getgrnam("ossec").gr_gid
            chown(common.client_keys, root_uid, ossec_gid)
            chmod(common.client_keys, 0o640)

            # Remove agent files
            agent_files = []
            agent_files.append('{0}/queue/agent-info/{1}-{2}'.format(common.ossec_path, self.name, self.ip))
            agent_files.append('{0}/queue/syscheck/({1}) {2}->syscheck'.format(common.ossec_path, self.name, self.ip))
            agent_files.append('{0}/queue/syscheck/.({1}) {2}->syscheck.cpt'.format(common.ossec_path, self.name, self.ip))
            agent_files.append('{0}/queue/syscheck/({1}) {2}->syscheck-registry'.format(common.ossec_path, self.name, self.ip))
            agent_files.append('{0}/queue/syscheck/.({1}) {2}->syscheck-registry.cpt'.format(common.ossec_path, self.name, self.ip))
            agent_files.append('{0}/queue/rootcheck/({1}) {2}->rootcheck'.format(common.ossec_path, self.name, self.ip))
            agent_files.append('{0}/queue/rids/{1}'.format(common.ossec_path, self.id))
            agent_files.append('{0}/var/db/agents/{1}-{2}.db'.format(common.ossec_path, self.id, self.name))
            agent_files.append('{0}/var/db/agents/{1}-{2}.db-wal'.format(common.ossec_path, self.id, self.name))
            agent_files.append('{0}/var/db/agents/{1}-{2}.db-shm'.format(common.ossec_path, self.id, self.name))

            for agent_file in agent_files:
                if path.exists(agent_file):
                    remove(agent_file)
        else:
            remove(f_keys_temp)
            raise WazuhException(1701, self.id)

        return 'Agent removed'
Esempio n. 3
0
    def check_wazuh_status(self):
        """
        There are some services that are required for wazuh to correctly process API requests. If any of those services
        is not running, the API must raise an exception indicating that:
            * It's not ready yet to process requests if services are restarting
            * There's an error in any of those services that must be adressed before using the API if any service is
              in failed status.
            * Wazuh must be started before using the API is the services are stopped.

        The basic services wazuh needs to be running are: wazuh-modulesd, ossec-remoted, ossec-analysisd, ossec-execd and wazuh-db
        """
        if self.input_json['function'] == '/manager/status' or self.input_json['function'] == '/cluster/:node_id/status':
            return
        basic_services = ('wazuh-modulesd', 'ossec-remoted', 'ossec-analysisd', 'ossec-execd', 'wazuh-db')
        status = operator.itemgetter(*basic_services)(manager.status())
        for status_name, exc_code in [('failed', 1019), ('restarting', 1017), ('stopped', 1018)]:
            if status_name in status:
                raise exception.WazuhException(exc_code, status)
Esempio n. 4
0
    def remove(self):
        """
        Deletes the agent.

        :return: Message.
        """

        # Check if authd is running
        if manager.status()['ossec-authd'] == 'running':
            raise WazuhException(1704)

        f_keys_temp = '{0}.tmp'.format(common.client_keys)

        f_tmp = open(f_keys_temp, 'w')
        agent_found = False
        with open(common.client_keys) as f_k:
            for line in f_k.readlines():
                line_data = line.strip().split(
                    ' ')  # 0 -> id, 1 -> name, 2 -> ip, 3 -> key

                if self.id == line_data[0] and line_data[1][0] not in ('#!'):
                    f_tmp.write('{0} !{1} {2} {3}\n'.format(
                        line_data[0], line_data[1], line_data[2],
                        line_data[3]))
                    agent_found = True
                else:
                    f_tmp.write(line)
        f_tmp.close()

        if agent_found:
            # Overwrite client.keys
            move(f_keys_temp, common.client_keys)
            root_uid = getpwnam("ossec").pw_uid
            ossec_gid = getgrnam("ossec").gr_gid
            chown(common.client_keys, root_uid, ossec_gid)
            chmod(common.client_keys, 0o640)
        else:
            remove(f_keys_temp)
            raise WazuhException(1701, self.id)

        return 'Agent removed'
Esempio n. 5
0
    def check_wazuh_status(self, basic_services=None):
        """
        There are some services that are required for wazuh to correctly process API requests. If any of those services
        is not running, the API must raise an exception indicating that:
            * It's not ready yet to process requests if services are restarting
            * There's an error in any of those services that must be adressed before using the API if any service is
              in failed status.
            * Wazuh must be started before using the API is the services are stopped.

        The basic services wazuh needs to be running are: wazuh-modulesd, ossec-remoted, ossec-analysisd, ossec-execd and wazuh-db
        """
        if self.input_json['function'] == '/manager/status' or self.input_json[
                'function'] == '/cluster/:node_id/status':
            return

        if not basic_services:
            basic_services = ('wazuh-modulesd', 'ossec-analysisd',
                              'ossec-execd', 'wazuh-db')
            if common.install_type != "local":
                basic_services += ('ossec-remoted', )

        status = manager.status()

        not_ready_daemons = {
            k: status[k]
            for k in basic_services
            if status[k] in ('failed', 'restarting', 'stopped')
        }

        if not_ready_daemons:
            extra_info = {
                'node_name':
                self.node_info.get('node', 'UNKNOWN NODE'),
                'not_ready_daemons':
                ', '.join([
                    f'{key}->{value}'
                    for key, value in not_ready_daemons.items()
                ])
            }
            raise exception.WazuhException(1017, extra_message=extra_info)
Esempio n. 6
0
    def remove(self):
        """
        Deletes the agent.

        :return: Message.
        """

        # Check if authd is running
        if manager.status()['ossec-authd'] == 'running':
            raise WazuhException(1704)

        f_keys_temp = '{0}.tmp'.format(common.client_keys)

        f_tmp = open(f_keys_temp, 'w')
        agent_found = False
        with open(common.client_keys) as f_k:
            for line in f_k.readlines():
                line_data = line.strip().split(' ')  # 0 -> id, 1 -> name, 2 -> ip, 3 -> key

                if self.id == line_data[0] and line_data[1][0] not in ('#!'):
                    f_tmp.write('{0} !{1} {2} {3}\n'.format(line_data[0], line_data[1], line_data[2], line_data[3]))
                    agent_found = True
                else:
                    f_tmp.write(line)
        f_tmp.close()

        if agent_found:
            # Overwrite client.keys
            move(f_keys_temp, common.client_keys)
            root_uid = getpwnam("ossec").pw_uid
            ossec_gid = getgrnam("ossec").gr_gid
            chown(common.client_keys, root_uid, ossec_gid)
            chmod(common.client_keys, 0o640)
        else:
            remove(f_keys_temp)
            raise WazuhException(1701, self.id)

        return 'Agent removed'
Esempio n. 7
0
    # set appropiate permissions to the cluster.log file
    chown('{0}/logs/cluster.log'.format(common.ossec_path), common.ossec_uid,
          common.ossec_gid)
    chmod('{0}/logs/cluster.log'.format(common.ossec_path), 0o660)

    if error_msg:
        logger.error(error_msg)
        exit()

    # Signals
    signal(SIGINT, signal_handler)
    signal(SIGTERM, signal_handler)

    # Check if it is already running
    if status()['wazuh-clusterd'] == 'running':
        clean_exit(reason="wazuh_clusterd is already running", error=True)

    # Foreground/Daemon
    if not args.f:
        res_code = pyDaemon()

    # Get cluster config
    try:
        cluster_config = read_config()
    except WazuhException as e:
        clean_exit(reason=str(e), error=True)

    if not cluster_config or cluster_config['disabled'] == 'yes':
        clean_exit(reason="Cluster disabled", error=True)
Esempio n. 8
0
def get_status_json():
    return {
        "enabled": "yes" if check_cluster_status() else "no",
        "running": "yes" if status()['wazuh-clusterd'] == 'running' else "no"
    }
Esempio n. 9
0
    def _add(self, name, ip, id=None, key=None, force=-1):
        """
        Adds a agent to OSSEC.
        2 uses:
            - name and ip [force]: Add an agent like manage_agents (generate id and key).
            - name, ip, id, key [force]: Insert an agent with an existing id and key.

        :param name: name of the new agent.
        :param ip: IP of the new agent. It can be an IP, IP/NET or ANY.
        :param id: ID of the new agent.
        :param key: Key of the new agent.
        :param force: Remove old agents with same IP if disconnected since <force> seconds
        :return: Agent ID.
        """

        # Check arguments
        if id:
            id = id.zfill(3)

        if key and len(key) < 64:
            raise WazuhException(1709)

        force = force if type(force) == int else int(force)

        # Check if authd is running
        manager_status = manager.status()
        if 'ossec-authd' not in manager_status or manager_status[
                'ossec-authd'] == 'running':
            raise WazuhException(1704)

        # Check if ip, name or id exist in client.keys
        last_id = 0
        with open(common.client_keys) as f_k:
            for line in f_k.readlines():
                if line[0] in ('# '):  # starts with # or ' '
                    continue

                line_data = line.strip().split(
                    ' ')  # 0 -> id, 1 -> name, 2 -> ip, 3 -> key

                line_id = int(line_data[0])
                if last_id < line_id:
                    last_id = line_id

                if line_data[1][0] in ('#!'):  # name starts with # or !
                    continue

                if id and id == line_data[0]:
                    raise WazuhException(1708, id)
                if name == line_data[1]:
                    raise WazuhException(1705, name)
                if ip.lower() != 'any' and ip == line_data[2]:
                    if force < 0:
                        raise WazuhException(1706, ip)
                    else:
                        if force == 0 or Agent.check_if_delete_agent(
                                line_data[0], force):
                            Agent.remove_agent(line_data[0], backup=True)
                        else:
                            raise WazuhException(1706, ip)

        if not id:
            agent_id = str(last_id + 1).zfill(3)
        else:
            agent_id = id

        if not key:
            # Generate key
            epoch_time = int(time())
            str1 = "{0}{1}{2}".format(epoch_time, name, platform())
            str2 = "{0}{1}".format(ip, agent_id)
            hash1 = md5(str1.encode())
            hash1.update(urandom(64))
            hash2 = md5(str2.encode())
            hash1.update(urandom(64))
            agent_key = hash1.hexdigest() + hash2.hexdigest()
        else:
            agent_key = key

        # Tmp file
        f_keys_temp = '{0}.tmp'.format(common.client_keys)
        copyfile(common.client_keys, f_keys_temp)

        # Write key
        with open(f_keys_temp, 'a') as f_kt:
            f_kt.write('{0} {1} {2} {3}\n'.format(agent_id, name, ip,
                                                  agent_key))

        # Overwrite client.keys
        move(f_keys_temp, common.client_keys)
        root_uid = getpwnam("ossec").pw_uid
        ossec_gid = getgrnam("ossec").gr_gid
        chown(common.client_keys, root_uid, ossec_gid)
        chmod(common.client_keys, 0o640)

        self.id = agent_id
Esempio n. 10
0
    def remove(self, backup=False):
        """
        Deletes the agent.

        :param backup: Create backup before removing the agent.
        :return: Message.
        """

        # Check if authd is running
        manager_status = manager.status()
        if 'ossec-authd' not in manager_status or manager_status[
                'ossec-authd'] == 'running':
            raise WazuhException(1704)

        # Get info from DB
        self._load_info_from_DB()

        f_keys_temp = '{0}.tmp'.format(common.client_keys)

        f_tmp = open(f_keys_temp, 'w')
        agent_found = False
        with open(common.client_keys) as f_k:
            for line in f_k.readlines():
                line_data = line.strip().split(
                    ' ')  # 0 -> id, 1 -> name, 2 -> ip, 3 -> key

                if self.id == line_data[0] and line_data[1][0] not in ('#!'):
                    f_tmp.write('{0} !{1} {2} {3}\n'.format(
                        line_data[0], line_data[1], line_data[2],
                        line_data[3]))
                    agent_found = True
                else:
                    f_tmp.write(line)
        f_tmp.close()

        if not agent_found:
            remove(f_keys_temp)
            raise WazuhException(1701, self.id)

        # Overwrite client.keys
        move(f_keys_temp, common.client_keys)
        root_uid = getpwnam("ossec").pw_uid
        ossec_gid = getgrnam("ossec").gr_gid
        chown(common.client_keys, root_uid, ossec_gid)
        chmod(common.client_keys, 0o640)

        # Remove rid file
        rids_file = '{0}/queue/rids/{1}'.format(common.ossec_path, self.id)
        if path.exists(rids_file):
            remove(rids_file)

        if not backup:
            # Remove agent files
            agent_files = []
            agent_files.append('{0}/queue/agent-info/{1}-{2}'.format(
                common.ossec_path, self.name, self.ip))
            agent_files.append('{0}/queue/syscheck/({1}) {2}->syscheck'.format(
                common.ossec_path, self.name, self.ip))
            agent_files.append(
                '{0}/queue/syscheck/.({1}) {2}->syscheck.cpt'.format(
                    common.ossec_path, self.name, self.ip))
            agent_files.append(
                '{0}/queue/syscheck/({1}) {2}->syscheck-registry'.format(
                    common.ossec_path, self.name, self.ip))
            agent_files.append(
                '{0}/queue/syscheck/.({1}) {2}->syscheck-registry.cpt'.format(
                    common.ossec_path, self.name, self.ip))
            agent_files.append(
                '{0}/queue/rootcheck/({1}) {2}->rootcheck'.format(
                    common.ossec_path, self.name, self.ip))
            agent_files.append('{0}/queue/rids/{1}'.format(
                common.ossec_path, self.id))
            agent_files.append('{0}/var/db/agents/{1}-{2}.db'.format(
                common.ossec_path, self.id, self.name))
            agent_files.append('{0}/var/db/agents/{1}-{2}.db-wal'.format(
                common.ossec_path, self.id, self.name))
            agent_files.append('{0}/var/db/agents/{1}-{2}.db-shm'.format(
                common.ossec_path, self.id, self.name))

            for agent_file in agent_files:
                if path.exists(agent_file):
                    remove(agent_file)
        else:
            # Create backup directory
            # /var/ossec/backup/agents/yyyy/Mon/dd/id-name-ip[tag]
            date_part = date.today().strftime('%Y/%b/%d')
            main_agent_backup_dir = '{0}/backup/agents/{1}/{2}-{3}-{4}'.format(
                common.ossec_path, date_part, self.id, self.name, self.ip)
            agent_backup_dir = main_agent_backup_dir

            not_agent_dir = True
            i = 0
            while not_agent_dir:
                if path.exists(agent_backup_dir):
                    i += 1
                    agent_backup_dir = '{0}-{1}'.format(
                        main_agent_backup_dir,
                        str(i).zfill(3))
                else:
                    makedirs(agent_backup_dir)
                    chmod_r(agent_backup_dir, 0o750)
                    not_agent_dir = False

            # Move agent file
            agent_files = []
            agent_files.append([
                '{0}/queue/agent-info/{1}-{2}'.format(common.ossec_path,
                                                      self.name, self.ip),
                '{0}/agent-info'.format(agent_backup_dir)
            ])
            agent_files.append([
                '{0}/queue/syscheck/({1}) {2}->syscheck'.format(
                    common.ossec_path, self.name, self.ip),
                '{0}/syscheck'.format(agent_backup_dir)
            ])
            agent_files.append([
                '{0}/queue/syscheck/.({1}) {2}->syscheck.cpt'.format(
                    common.ossec_path, self.name, self.ip),
                '{0}/syscheck.cpt'.format(agent_backup_dir)
            ])
            agent_files.append([
                '{0}/queue/syscheck/({1}) {2}->syscheck-registry'.format(
                    common.ossec_path, self.name, self.ip),
                '{0}/syscheck-registry'.format(agent_backup_dir)
            ])
            agent_files.append([
                '{0}/queue/syscheck/.({1}) {2}->syscheck-registry.cpt'.format(
                    common.ossec_path, self.name, self.ip),
                '{0}/syscheck-registry.cpt'.format(agent_backup_dir)
            ])
            agent_files.append([
                '{0}/queue/rootcheck/({1}) {2}->rootcheck'.format(
                    common.ossec_path, self.name, self.ip),
                '{0}/rootcheck'.format(agent_backup_dir)
            ])

            for agent_file in agent_files:
                if path.exists(
                        agent_file[0]) and not path.exists(agent_file[1]):
                    rename(agent_file[0], agent_file[1])

        return 'Agent removed'
Esempio n. 11
0
    def _add(self, name, ip):
        """
        Adds the agent to OSSEC.

        :param name: name of the new agent.
        :param ip: IP of the new agent. It can be an IP, IP/NET or ANY.
        :return: Agent ID.
        """

        # Check if authd is running
        if manager.status()['ossec-authd'] == 'running':
            raise WazuhException(1704)

        # Check if ip or name exist in client.keys
        last_id = 0
        with open(common.client_keys) as f_k:
            for line in f_k.readlines():
                if line[0] in ('# '):  # starts with # or ' '
                    continue

                line_data = line.strip().split(
                    ' ')  # 0 -> id, 1 -> name, 2 -> ip, 3 -> key

                if line_data[1][0] in ('#!'):  # name starts with # or !
                    continue

                if name == line_data[1]:
                    raise WazuhException(1705, name)
                if ip.lower() != 'any' and ip == line_data[2]:
                    raise WazuhException(1706, ip)

                id = int(line_data[0])
                if last_id < id:
                    last_id = id

        last_id = str(last_id + 1).zfill(3)

        # Tmp file
        f_keys_temp = '{0}.tmp'.format(common.client_keys)
        copyfile(common.client_keys, f_keys_temp)

        # Generate key
        random_number = randrange(1, 999999)
        epoch_time = int(time())
        str1 = "{0}{1}{2}{3}".format(epoch_time, name, random_number,
                                     platform())
        random_number = randrange(1, 999999)
        str2 = "{0}{1}{2}".format(ip, last_id, random_number)
        hash1 = md5()
        hash1.update(str1.encode())
        hash2 = md5()
        hash2.update(str2.encode())
        new_key = hash1.hexdigest() + hash2.hexdigest()

        # Write key
        with open(f_keys_temp, 'a') as f_kt:
            f_kt.write('{0} {1} {2} {3}\n'.format(last_id, name, ip, new_key))

        # Overwrite client.keys
        move(f_keys_temp, common.client_keys)
        root_uid = getpwnam("ossec").pw_uid
        ossec_gid = getgrnam("ossec").gr_gid
        chown(common.client_keys, root_uid, ossec_gid)
        chmod(common.client_keys, 0o640)

        self.id = last_id
Esempio n. 12
0
    def _add(self, name, ip):
        """
        Adds the agent to OSSEC.

        :param name: name of the new agent.
        :param ip: IP of the new agent. It can be an IP, IP/NET or ANY.
        :return: Agent ID.
        """

        # Check if authd is running
        if manager.status()['ossec-authd'] == 'running':
            raise WazuhException(1704)

        # Check if ip or name exist in client.keys
        last_id = 0
        with open(common.client_keys) as f_k:
            for line in f_k.readlines():
                if line[0] in ('# '):  # starts with # or ' '
                    continue

                line_data = line.strip().split(' ')  # 0 -> id, 1 -> name, 2 -> ip, 3 -> key

                if line_data[1][0] in ('#!'):  # name starts with # or !
                    continue

                if name == line_data[1]:
                    raise WazuhException(1705, name)
                if ip.lower() != 'any' and ip == line_data[2]:
                    raise WazuhException(1706, ip)

                id = int(line_data[0])
                if last_id < id:
                    last_id = id

        last_id = str(last_id + 1).zfill(3)

        # Tmp file
        f_keys_temp = '{0}.tmp'.format(common.client_keys)
        copyfile(common.client_keys, f_keys_temp)

        # Generate key
        random_number = randrange(1, 999999)
        epoch_time = int(time())
        str1 = "{0}{1}{2}{3}".format(epoch_time, name, random_number, platform())
        random_number = randrange(1, 999999)
        str2 = "{0}{1}{2}".format(ip, last_id, random_number)
        hash1 = md5()
        hash1.update(str1.encode())
        hash2 = md5()
        hash2.update(str2.encode())
        new_key = hash1.hexdigest() + hash2.hexdigest()

        # Write key
        with open(f_keys_temp, 'a') as f_kt:
            f_kt.write('{0} {1} {2} {3}\n'.format(last_id, name, ip, new_key))

        # Overwrite client.keys
        move(f_keys_temp, common.client_keys)
        root_uid = getpwnam("ossec").pw_uid
        ossec_gid = getgrnam("ossec").gr_gid
        chown(common.client_keys, root_uid, ossec_gid)
        chmod(common.client_keys, 0o640)

        self.id = last_id