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

__author__ = 'kdlucas@chromium.org (Kelly Lucas)'

import logging
import os
import re
import shutil
import stat

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

class platform_FilePerms(test.test):
    """
    Test file permissions.
    """
    version = 2
    mount_path = '/bin/mount'
    standard_options = ['nosuid', 'nodev', 'noexec']
    standard_rw_options = ['rw'] + standard_options
    standard_ro_options = ['ro'] + standard_options
    # When adding an expectation that isn't simply "standard_*_options",
    # please leave either an explanation for why that mount is special,
    # or a bug number tracking work to harden that mount point, in a comment.
    expected_mount_options = {
        '/dev': {
            'type': 'devtmpfs',
            'options': ['rw', 'nosuid', 'noexec', 'mode=755']},
        '/dev/pstore': {
            'type': 'pstore',
            'options': standard_rw_options},
        '/dev/pts': { # Special case, we want to track gid/mode too.
            'type': 'devpts',
            'options': ['rw', 'nosuid', 'noexec', 'gid=5', 'mode=620']},
        '/dev/shm': {'type': 'tmpfs', 'options': standard_rw_options},
        '/home': {'type': 'ext4', 'options': standard_rw_options},
        '/home/chronos': {'type': 'ext4', 'options': standard_rw_options},
        '/media': {'type': 'tmpfs', 'options': standard_rw_options},
        '/mnt/stateful_partition': {
            'type': 'ext4',
            'options': standard_rw_options},
        '/mnt/stateful_partition/encrypted': {
            'type': 'ext4',
            'options': standard_rw_options},
        # Special case - Android container has devices and suid programs.
        # Note that after the user logs in we remount it as "exec",
        # therefore we do not enforce 'noexec'.
        '/opt/google/containers/android/rootfs/root': {
            'type': 'squashfs',
            'options': ['ro']},
        '/opt/google/containers/android/rootfs/root/vendor': {
            'type': 'squashfs',
            'options': ['ro', 'nosuid', 'nodev']},
        '/opt/google/containers/arc-sdcard/mountpoints/container-root': {
            'type': 'squashfs',
            'options': ['ro', 'noexec']},
        '/opt/google/containers/arc-downloads-filesystem/mountpoints/container-root': {
            'type': 'squashfs',
            'options': ['ro', 'noexec']},
        '/opt/google/containers/arc-obb-mounter/mountpoints/container-root': {
            'type': 'squashfs',
            'options': ['ro', 'noexec']},
        '/opt/google/containers/arc-removable-media/mountpoints/container-root': {
            'type': 'squashfs',
            'options': ['ro', 'noexec']},
        '/run/arc/obb': {
            'type': 'tmpfs',
            'options': standard_ro_options + ['mode=755']},
        '/proc': { 'type': 'proc', 'options': standard_rw_options},
        '/run': { # Special case, we want to track mode too.
            'type': 'tmpfs',
            'options': standard_rw_options + ['mode=755']},
        # Special case, we want to track group/mode too.
        # gid 605 == debugfs-access
        '/run/debugfs_gpu': {
            'type': 'debugfs',
            'options': standard_rw_options + ['gid=605', 'mode=750']},
        '/run/lock': {'type': 'tmpfs', 'options': standard_rw_options},
        '/run/imageloader/PepperFlashPlayer': {
            'type': 'squashfs',
            'options': ['ro', 'nodev', 'nosuid']},
        '/sys': {'type': 'sysfs', 'options': standard_rw_options},
        '/sys/fs/cgroup': {
            'type': 'tmpfs',
            'options': standard_rw_options + ['mode=755']},
        '/sys/fs/cgroup/cpu': {
            'type': 'cgroup',
            'options': standard_rw_options},
        '/sys/fs/cgroup/cpuacct': {
            'type': 'cgroup',
            'options': standard_rw_options},
        '/sys/fs/cgroup/cpuset': {
            'type': 'cgroup',
            'options': standard_rw_options},
        '/sys/fs/cgroup/devices': {
            'type': 'cgroup',
            'options': standard_rw_options},
        '/sys/fs/cgroup/freezer': {
            'type': 'cgroup',
            'options': standard_rw_options},
        '/sys/fs/cgroup/schedtune': {
            'type': 'cgroup',
            'options': standard_rw_options},
        '/sys/fs/fuse/connections': {
            'type': 'fusectl',
            'options': standard_rw_options},
        '/sys/fs/selinux': {
            'type': 'selinuxfs',
            'options': ['rw', 'nosuid', 'noexec']},
        '/sys/kernel/debug': {
            'type': 'debugfs',
            'options': standard_rw_options},
        '/sys/kernel/debug/tracing': {
            'type': 'tracefs',
            'options': standard_rw_options},
        '/tmp': {'type': 'tmpfs', 'options': standard_rw_options},
        '/var': {'type': 'ext4', 'options': standard_rw_options},
        '/usr/share/oem': {
            'type': 'ext4',
            'options': standard_ro_options},
    }
    testmode_modded_fses = set(['/home', '/tmp', '/usr/local'])
    # TODO(yusukes): Remove shared_fonts_ variables once we switch to overlayfs.
    shared_fonts_pattern = (r'/opt/google/containers/android/rootfs/root/'
                            r'system/fonts/.*\.tt[cf]')
    shared_fonts_expected_mount_options = {
        # The fonts are bind-mounted versions of fonts in /usr/share/fonts. Use
        # the same type and options for '/'.
        'type': 'ext2',
        'options': ['ro'],
    }


    def checkid(self, fs, userid):
        """
        Check that the uid and gid for |fs| match |userid|.

        @param fs: string, directory or file path.
        @param userid: userid to check for.
        Returns:
            int, the number errors (non-matches) detected.
        """
        errors = 0

        if not os.access(fs, os.F_OK):
            # The path does not exist, so exit early.
            return errors

        uid = os.stat(fs)[stat.ST_UID]
        gid = os.stat(fs)[stat.ST_GID]

        if userid != uid:
            logging.error('Wrong uid in filesystem "%s"', fs)
            errors += 1
        if userid != gid:
            logging.error('Wrong gid in filesystem "%s"', fs)
            errors += 1

        return errors


    def get_perm(self, fs):
        """
        Check the file permissions of a filesystem.

        @param fs: string, mount point for filesystem to check.
        Returns:
            int, equivalent to unix permissions.
        """
        MASK = 0777

        if not os.access(fs, os.F_OK):
            # The path does not exist, so exit early.
            return None

        fstat = os.stat(fs)
        mode = fstat[stat.ST_MODE]

        fperm = oct(mode & MASK)
        return fperm


    def read_mtab(self, mtab_path='/etc/mtab'):
        """
        Helper function to read the mtab file into a dict

        @param mtab_path: path to '/etc/mtab'
        Returns:
          dict, mount points as keys, and another dict with
          options list, device and type as values.
        """
        file_handle = open(mtab_path, 'r')
        lines = file_handle.readlines()
        file_handle.close()

        # Save mtab to the results dir to diagnose failures.
        shutil.copyfile(mtab_path,
                        os.path.join(self.resultsdir,
                                     os.path.basename(mtab_path)))

        comment_re = re.compile("#.*$")
        mounts = {}
        for line in lines:
            # remove any comments first
            line = comment_re.sub("", line)
            fields = line.split()
            # ignore malformed lines
            if len(fields) < 4:
                continue
            # Don't include rootfs in the list, because it maps to the
            # same location as /dev/root: '/' (and we don't care about
            # its options at the moment).
            if fields[0] == 'rootfs':
                continue
            mounts[fields[1]] = {'device': fields[0],
                                 'type': fields[2],
                                 'options': fields[3].split(',')}
        return mounts


    def try_write(self, fs):
        """
        Try to write a file in the given filesystem.

        @param fs: string, file system to use.
        Returns:
            int, number of errors encountered:
            0 = write successful,
            >0 = write not successful.
        """

        TEXT = 'This is filler text for a test file.\n'

        tempfile = os.path.join(fs, 'test')
        try:
            fh = open(tempfile, 'w')
            fh.write(TEXT)
            fh.close()
        except OSError: # This error will occur with read only filesystem.
            return 1
        except IOError, e:
            return 1

        if os.path.exists(tempfile):
            os.remove(tempfile)

        return 0


    def check_mounted_read_only(self, filesystem):
        """
        Check the permissions of a filesystem according to /etc/mtab.

        @param filesystem: string, file system device to check.
        Returns:
            1 if rw, 0 if ro
        """

        errors = 0
        mtab = self.read_mtab()
        if not (filesystem in mtab.keys()):
            logging.error('Could not find filesystem "%s" in mtab', filesystem)
            errors += 1
            return errors # no point in continuing this test.
        if not ('ro' in mtab[filesystem]['options']):
            logging.error('Filesystem "%s" is not mounted read-only',
                          filesystem)
            errors += 1
        return errors


    def check_mount_options(self):
        """
        Check the permissions of all non-rootfs filesystems to make
        sure they have the right mount options. In order to do this,
        both the live system state, and a log-snapshot of what the system
        looked like prior to dev-mode/test-mode modifications were applied,
        are validated.

        Note that since this test is not a UITest, and takes place
        while the system waits at a login screen, mount options are
        not checked for a mounted cryptohome or guestfs. Consult the
        security_ProfilePermissions test for those checks.

        Args:
            (none)
        Returns:
            int, the number of errors identified in mount options.
        """
        errors = 0
        # Perform mount-option checks of both mount options as
        # captured during boot, and, the live system state.  After the
        # first pass (where we process mount_options.log), grow the
        # list of ignored filesystems to include all those we know are
        # tweaked by devmode/mod-for-test mode. This properly sets
        # expectations for the second pass.
        mtabs = ['/var/log/mount_options.log', '/etc/mtab']
        ignored_fses = set(['/'])
        ignored_types = set(['ecryptfs'])
        for mtab_path in mtabs:
            mtab = self.read_mtab(mtab_path=mtab_path)
            for fs in mtab.keys():
                if fs in ignored_fses:
                    continue

                fs_type = mtab[fs]['type']
                if fs_type in ignored_types:
                    logging.warning('Ignoring filesystem "%s" with type "%s"',
                                 fs, fs_type)
                    continue
                if re.match(self.shared_fonts_pattern, fs):
                  mount_options = self.shared_fonts_expected_mount_options
                elif fs in self.expected_mount_options:
                  mount_options = self.expected_mount_options[fs]
                else:
                    logging.error(
                            'No expectations entry for "%s" with info "%s"',
                            fs, mtab[fs])
                    errors += 1
                    continue

                if fs_type != mount_options['type']:
                    logging.error(
                            '[%s] "%s" has type "%s", expected type "%s"',
                            mtab_path, fs, fs_type, mount_options['type'])
                    errors += 1

                # For options, require the specified options to be present.
                # Do not consider it an error if extra options are present.
                # (This makes it easy to deal with options we don't wish
                # to track closely, like devtmpfs's nr_inodes= for example.)
                seen = set(mtab[fs]['options'])
                expected = set(mount_options['options'])
                missing = expected - seen
                if (missing):
                    logging.error('[%s] "%s" is missing options "%s"',
                                  mtab_path, fs, missing)
                    errors += 1

            ignored_fses.update(self.testmode_modded_fses)

        return errors


    def run_once(self):
        """
        Main testing routine for platform_FilePerms.
        """
        errors = 0

        # Root owned directories with expected permissions.
        root_dirs = {'/': ['0755'],
                     '/bin': ['0755'],
                     '/boot': ['0755'],
                     '/dev': ['0755'],
                     '/etc': ['0755'],
                     '/home': ['0755'],
                     '/lib': ['0755'],
                     '/media': ['0777'],
                     '/mnt': ['0755'],
                     '/mnt/stateful_partition': ['0755'],
                     '/opt': ['0755'],
                     '/proc': ['0555'],
                     '/run': ['0755'],
                     '/sbin': ['0755'],
                     '/sys': ['0555', '0755'],
                     '/tmp': ['0777'],
                     '/usr': ['0755'],
                     '/usr/bin': ['0755'],
                     '/usr/lib': ['0755'],
                     '/usr/local': ['0755'],
                     '/usr/sbin': ['0755'],
                     '/usr/share': ['0755'],
                     '/var': ['0755'],
                     '/var/cache': ['0755']}

        # Read-only directories
        ro_dirs = ['/', '/bin', '/boot', '/etc', '/lib', '/mnt',
                   '/opt', '/sbin', '/usr', '/usr/bin', '/usr/lib',
                   '/usr/sbin', '/usr/share']

        # Root directories writable by root
        root_rw_dirs = ['/run', '/var', '/var/lib', '/var/cache', '/var/log',
                        '/usr/local']

        # Ensure you cannot write files in read only directories.
        for dir in ro_dirs:
            if self.try_write(dir) == 0:
                logging.error('Root can write to read-only dir "%s"', dir)
                errors += 1

        # Ensure the uid and gid are correct for root owned directories.
        for dir in root_dirs:
            if self.checkid(dir, 0) > 0:
                errors += 1

        # Ensure root can write into root dirs with rw access.
        for dir in root_rw_dirs:
            if self.try_write(dir) > 0:
                errors += 1

        # Check permissions on root owned directories.
        for dir in root_dirs:
            fperms = self.get_perm(dir)
            if fperms is not None and fperms not in root_dirs[dir]:
                logging.error('"%s" has "%s" permissions', dir, fperms)
                errors += 1

        errors += self.check_mounted_read_only('/')

        # Check mount options on mount points.
        errors += self.check_mount_options()

        # If errors is not zero, there were errors.
        if errors > 0:
            raise error.TestFail('Found %d permission errors' % errors)
