# Copyright (c) 2012 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 csv
import getopt
import logging
import os
import re

from collections import namedtuple

from autotest_lib.client.bin import test
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import utils


PS_FIELDS = "pid,ppid,comm:32,euser:%d,ruser:%d,args"
PsOutput = namedtuple("PsOutput",
                      ' '.join([field.split(':')[0]
                                for field in PS_FIELDS.split(',')]))

MINIJAIL_OPTS = { "mj_uid": "-u",
                  "mj_gid": "-g",
                  "mj_pidns": "-p",
                  "mj_caps": "-c",
                  "mj_filter": "-S" }


class security_SandboxedServices(test.test):
    version = 1


    def get_minijail_opts(self):
        """Parses Minijail's help and generates a getopt string."
        """

        help = utils.system_output("minijail0 -h", ignore_status=True)
        help_lines = help.splitlines()[1:]

        opt_list = []

        for line in help_lines:
            # Example lines:
            #     '  -c <caps>:  restrict caps to <caps>'
            #     '  -s:         use seccomp'
            m = re.search("-(\w)( <.+>)?:", line)

            if m:
                opt_list.append(m.groups()[0])

                if m.groups()[1]:
                    # The option takes an argument
                    opt_list.append(':')

        return ''.join(opt_list)


    def get_running_processes(self):
        usermax = utils.system_output("cut -d: -f1 /etc/passwd | wc -L",
                                      ignore_status=True)
        usermax = max(int(usermax), 8)
        ps_cmd = "ps --no-headers -ww -eo " + (PS_FIELDS % (usermax, usermax))
        ps_fields_len = len(PS_FIELDS.split(','))

        output = utils.system_output(ps_cmd)
        running_processes = [PsOutput(*line.split(None, ps_fields_len - 1))
                             for line in output.splitlines()]
        return running_processes


    def load_baseline(self):
        """The baseline file lists the services we know and
        whether (and how) they are sandboxed.
        """

        baseline_path = os.path.join(self.bindir, 'baseline')
        dict_reader = csv.DictReader(open(baseline_path))
        return dict([(d["exe"], d) for d in dict_reader])


    def load_exclusions(self):
        """The exclusions file lists running programs
        that we don't care about (for now).
        """

        exclusions_path = os.path.join(self.bindir, 'exclude')
        return set([line.strip() for line in open(exclusions_path)])


    def minijail_ok(self, launcher, expected):
        """Checks whether the Minijail invocation
        has the correct commandline options.
        """

        opts, args = getopt.getopt(launcher.args.split()[1:],
                                   self.get_minijail_opts())
        optset = set([opt[0] for opt in opts])

        missing_opts = []
        new_opts = []

        for check, opt in MINIJAIL_OPTS.iteritems():
            if expected[check] == "Yes":
                if opt not in optset:
                    missing_opts.append(check)
            elif expected[check] == "No":
                if opt in optset:
                    new_opts.append(check)

        if len(new_opts) > 0:
            logging.error("New Minijail opts for '%s': %s" %
                          (expected["exe"], ', '.join(new_opts)))

        if len(missing_opts) > 0:
            logging.error("Missing Minijail options for '%s': %s" %
                          (expected["exe"], ', '.join(missing_opts)))

        return (len(new_opts) + len(missing_opts)) == 0


    def dump_services(self, running_services, minijail_processes):
        """Leaves a list of running services in the results dir
        so that we can update the baseline file if necessary.
        """

        csv_file = csv.writer(open(os.path.join(self.resultsdir,
                                                "running_services"), 'w'))

        for service in running_services:
            service_minijail = ""

            if service.ppid in minijail_processes:
                launcher = minijail_processes[service.ppid]
                service_minijail = launcher.args.split("--")[0].strip()

            row = [service.comm, service.euser, service.args, service_minijail]
            csv_file.writerow(row)


    def log_process_list(self, logger, title, list):
        report = "%s: %s" % (title, ', '.join(list))
        logger(report)


    def log_process_list_warn(self, title, list):
        self.log_process_list(logging.warn, title, list)


    def log_process_list_error(self, title, list):
        self.log_process_list(logging.error, title, list)


    def run_once(self):
        """Inspects the process list, looking for root and sandboxed processes
        (with some exclusions). If we have a baseline entry for a given process,
        confirms it's an exact match. Warns if we see root or sandboxed
        processes that we have no baseline for, and warns if we have
        baselines for processes not seen running.
        """

        baseline = self.load_baseline()
        exclusions = self.load_exclusions()
        running_processes = self.get_running_processes()

        kthreadd_pid = -1

        running_services = {}
        minijail_processes = {}

        # Filter running processes list
        for process in running_processes:
            exe = process.comm

            if exe == "kthreadd":
                kthreadd_pid = process.pid
                continue

            # Don't worry about kernel threads
            if process.ppid == kthreadd_pid:
                continue

            if exe in exclusions:
                continue

            # Remember minijail0 invocations
            if exe == "minijail0":
                minijail_processes[process.pid] = process
                continue

            running_services[exe] = process

        # Find differences between running services and baseline
        services_set = set(running_services.keys())
        baseline_set = set(baseline.keys())

        new_services = services_set.difference(baseline_set)
        stale_baselines = baseline_set.difference(services_set)

        # Check baseline
        sandbox_delta = []
        for exe in services_set.intersection(baseline_set):
            process = running_services[exe]

            # If the process is not running as the correct user
            if process.euser != baseline[exe]["euser"]:
                sandbox_delta.append(exe)
                continue

            # If this process is supposed to be sandboxed
            if baseline[exe]["mj_uid"] == "Yes":
                # If it's not being launched from Minijail,
                # it's not sandboxed wrt the baseline.
                if process.ppid not in minijail_processes:
                    sandbox_delta.append(exe)
                else:
                    launcher = minijail_processes[process.ppid]
                    expected = baseline[exe]
                    if not self.minijail_ok(launcher, expected):
                        sandbox_delta.append(exe)

        # Save current run to results dir
        self.dump_services(running_services.values(), minijail_processes)

        if len(stale_baselines) > 0:
            self.log_process_list_warn("Stale baselines", stale_baselines)

        if len(new_services) > 0:
            self.log_process_list_warn("New services", new_services)

        if len(sandbox_delta) > 0:
            self.log_process_list_error("Failed sandboxing", sandbox_delta)
            raise error.TestFail("One or more processes failed sandboxing")
