# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import logging
import os

from autotest_lib.client.bin import test, utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros import chrome
from autotest_lib.client.common_lib.cros.tendo import webservd_helper

# Since we parse lsof output in several places, these centralize the
# column numbering for finding things in lsof output.  For example:
# autotest 1915 root 3u IPv4 9221 0t0 TCP *:https (LISTEN)
_LSOF_COMMAND = 0
_LSOF_PID = 1
_LSOF_USER = 2
_LSOF_FD = 3
_LSOF_TYPE = 4
_LSOF_DEVICE = 5
_LSOF_NAME = 7
# In certain cases, the size/offset column is empty, making it more
# reliable to locate the last couple columns by counting from the right.
_LSOF_SIZE_OFF = 6
_LSOF_NODE = -3
_LSOF_NAME = -2

# Open ports on ARC-enabled test firmwares are different from the non-ARC case
# These files provide a whitelist of services expected to listen in each case
# (ARC and non-ARC)
_BASELINE_DEFAULT_NAME = 'baseline'
_BASELINE_ARC_NAME = 'baseline.arc'

# We log in so that we include any daemons that
# might be spawned at login in our test results.
class security_NetworkListeners_P(test.test):
    """Check the system against a whitelist of expected network-listeners."""
    version = 1

    def load_baseline(self, baseline_filename):
        """Loads the baseline of expected listeners.

        @param baseline_filename: string name of file containing relevant rules.

        """
        baseline_path = os.path.join(self.bindir, baseline_filename)
        with open(baseline_path) as f:
            lines = [line.strip() for line in f.readlines()]
        return set([line for line in lines
                    if line and not line.startswith('#')])


    def remove_autotest_noise(self, lsof_lines):
        """
        Processes underneath 'autotest' in the process tree
        unfortunately can inherit open sockets created by
        autotest. That leads to crazy-looking test failures where
        e.g. "sed" and "bash" appear to be listening on ports
        80/443. So, this takes the output of lsof and returns a
        filtered subset of it, with autotest and telemetry stuff removed.

        @param lsof_lines: a list of lines as output by the 'lsof' util.
        """
        # Compile a set of the listening sockets to ignore.
        sockets_to_ignore = set([])
        for line in lsof_lines:
            fields = line.split()
            if (fields[_LSOF_COMMAND] == 'autotest' or (
                fields[_LSOF_COMMAND] == 'python' and
                fields[_LSOF_NAME].startswith('127.0.0.1:')) or
                fields[_LSOF_NAME] == '127.0.0.1:%d' %
                utils.get_chrome_remote_debugging_port()):
                sockets_to_ignore.add(fields[_LSOF_DEVICE])

        # Now that we know which ones to ignore, iterate the output again.
        lines_to_keep = []
        for line in lsof_lines:
            fields = line.split()
            if fields[_LSOF_DEVICE] in sockets_to_ignore:
                logging.debug('Ignoring %s', line)
            else:
                lines_to_keep.append(line)
        return lines_to_keep


    def run_once(self):
        """
        Compare a list of processes, listening on TCP ports, to a
        baseline. Test fails if there are mismatches.
        """
        baseline_filename = _BASELINE_DEFAULT_NAME
        arc_mode = None

        if utils.is_arc_available():
            baseline_filename = _BASELINE_ARC_NAME
            arc_mode = 'enabled'

        with chrome.Chrome(arc_mode=arc_mode):
            cmd = (r'lsof -n -i -sTCP:LISTEN')
            cmd_output = utils.system_output(cmd, ignore_status=True,
                                             retain_output=True)
            # Use the [1:] slice to discard line 0, the lsof output header.
            lsof_lines = cmd_output.splitlines()[1:]
            # Unlike ps, we don't have a format option so we have to parse
            # lines that look like this:
            # sshd 1915 root 3u IPv4 9221 0t0 TCP *:ssh (LISTEN)
            # Out of that, we just want e.g. sshd *:ssh
            observed_set = set([])
            for line in self.remove_autotest_noise(lsof_lines):
                fields = line.split()
                observed_set.add('%s %s' % (fields[_LSOF_COMMAND],
                                            fields[_LSOF_NAME]))

            baseline_set = self.load_baseline(baseline_filename)
            # TODO(wiley) Remove when we get per-board
            #             baselines (crbug.com/406013)
            if webservd_helper.webservd_is_installed():
                baseline_set.update(self.load_baseline('baseline.webservd'))

            # If something in the observed set is not
            # covered by the baseline...
            new_listeners = observed_set.difference(baseline_set)
            if new_listeners:
                for daemon in new_listeners:
                    logging.error('Unexpected network listener: %s', daemon)

            # Or, things in baseline are missing from the system:
            missing_listeners = baseline_set.difference(observed_set)
            if missing_listeners:
                for daemon in missing_listeners:
                    logging.warning('Missing expected network listener: %s',
                                    daemon)

            # Only fail if there's unexpected listeners.
            if new_listeners:
                raise error.TestFail('Found unexpected network listeners')
