# 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 logging
import os
import pwd
import stat

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.cros import cryptohome


class security_ProfilePermissions(test.test):
    """Check permissions of files of logged in and guest user."""
    version = 1
    _HOMEDIR_MODE = 0710

    def initialize(self, logged_in):
        self._logged_in = logged_in

    def check_owner_mode(self, path, expected_owner, expected_mode):
        """
        Checks if the file/directory at 'path' is owned by 'expected_owner'
        with permissions matching 'expected_mode'.
        Returns True if they match, else False.
        Logs any mismatches to logging.error.

        @param path: file path to test.
        @param expected_owner: expected owner of the file.
        @param expected_mode: expected permission mode of the file.

        """
        s = os.stat(path)
        actual_owner = pwd.getpwuid(s.st_uid).pw_name
        actual_mode = stat.S_IMODE(s.st_mode)
        if (expected_owner != actual_owner or
            expected_mode != actual_mode):
            logging.error("%s - Expected %s:%s, saw %s:%s",
                         path, expected_owner, oct(expected_mode),
                         actual_owner, oct(actual_mode))
            return False
        else:
            return True


    def run_once(self):
        with chrome.Chrome(logged_in=self._logged_in) as cr:
            username = (cr.username if self._logged_in
                                    else cryptohome.GUEST_USER_NAME)

            """Check permissions within cryptohome for anything too permissive.
            """
            passes = []

            homepath = "/home/chronos"
            passes.append(self.check_owner_mode(homepath, "chronos", 0755))

            user_mountpt = cryptohome.user_path(username)
            passes.append(self.check_owner_mode(user_mountpt, "chronos",
                                                self._HOMEDIR_MODE))

            # TODO(benchan): Refactor the following code to use some helper
            # functions instead of find commands.

            # An array of shell commands, each representing a test that
            # passes if it emits no output. The first test is the main one.
            # In general, writable by anyone else is bad, as is owned by
            # anyone else. Any exceptions to that are pruned out of the
            # first test and checked individually by subsequent tests.
            cmds = [
                ('find -L "%s" -path "%s" -o '
                 # Avoid false-positives on SingletonLock, SingletonCookie, etc.
                 ' \\( -name "Singleton*" -a -type l \\) -o '
                 ' -path "%s/user" -prune -o '
                 ' -path "%s/Downloads" -prune -o '
                 ' -path "%s/flimflam" -prune -o '
                 ' -path "%s/shill" -prune -o '
                 ' -path "%s/.chaps" -prune -o '
                 ' -path "%s/u-*" -prune -o '
                 ' -path "%s/crash" -prune -o '
                 ' \\( -perm /022 -o \\! -user chronos \\) -ls') %
                (homepath, homepath, homepath, user_mountpt, user_mountpt,
                user_mountpt, user_mountpt, homepath, homepath),
                # /home/chronos/user and /home/chronos/user/Downloads are owned
                # by the chronos-access group and with a group execute
                # permission.
                'find -L "%s" -maxdepth 0 \\( \\! -perm 710 '
                '-o \\! -user chronos -o \\! -group chronos-access \\) -ls' %
                user_mountpt,
                'find -L "%s/Downloads" -maxdepth 0 \\( \\! -perm 710 '
                '-o \\! -user chronos -o \\! -group chronos-access \\) -ls' %
                user_mountpt,
                'find -L "%s/flimflam" \\( -perm /077 -o \\! -user root \\) -ls'
                % user_mountpt,
                'find -L "%s/shill" \\( -perm /077 -o \\! -user root \\) -ls' %
                user_mountpt,
                'find -L "%s/.chaps -name auth_data_salt -prune -o '
                '\\! -user chaps -o \\! -group chronos-access -o -perm /027 -ls'
                % user_mountpt,
                'find -L "%s/.chaps -name auth_data_salt -a '
                '\\( \\! -user root -o -perm /077 \\) -ls' % user_mountpt,
            ]

            for cmd in cmds:
                cmd_output = utils.system_output(cmd, ignore_status=True)
                if cmd_output:
                    passes.append(False)
                    logging.error(cmd_output)

            # This next section only applies if we have a real vault mounted
            # (ie, not a BWSI tmpfs).
            if cryptohome.is_permanent_vault_mounted(username):
                # Also check the permissions of the underlying vault and
                # supporting directory structure.
                mountpath = cryptohome.get_mounted_vault_path(username)

                # On ecryptfs backend, there's a 'vault' directory storing the
                # encrypted data. If it exists, check its ownership as well.
                vaultpath = os.path.join(mountpath, '../vault')
                if os.path.exists(vaultpath):
                    passes.append(self.check_owner_mode(vaultpath,
                                                        "root", 0700))
                passes.append(self.check_owner_mode(mountpath, "root", 0700))
                passes.append(self.check_owner_mode(mountpath + "/../master.0",
                                                    "root", 0600))
                passes.append(self.check_owner_mode(mountpath + "/../",
                                                    "root", 0700))
                passes.append(self.check_owner_mode(mountpath + "/../../",
                                                    "root", 0700))

            if False in passes:
                raise error.TestFail(
                    'Bad permissions found on cryptohome files')
