#!/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
    loop_device = r'/dev/loop[0-9]+$'
    root_device = r'/dev/root$'
    # 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']},
        '/sys/fs/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},
        '/opt/google/containers/android/rootfs/android-data/data/dalvik-cache/'
        'arm': {
            'type': ['ext4'],
            'options': standard_rw_options},
        '/opt/google/containers/android/rootfs/android-data/data/dalvik-cache/'
        'x86': {
            'type': ['ext4'],
            'options': standard_rw_options},
        '/opt/google/containers/android/rootfs/android-data/data/dalvik-cache/'
        'x86_64': {
            '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': {
            'device': loop_device,
            'type': ['squashfs'],
            'options': ['ro']},
        '/opt/google/containers/android/rootfs/root/system/lib/arm': {
            'device': loop_device,
            'type': ['squashfs'],
            'options': ['ro', 'nosuid', 'nodev']},
        '/opt/google/containers/arc-sdcard/mountpoints/container-root': {
            'device': loop_device,
            'type': ['squashfs'],
            'options': ['ro', 'noexec']},
        '/opt/google/containers/arc-obb-mounter/mountpoints/container-root': {
            'device': loop_device,
            'type': ['squashfs'],
            'options': ['ro', 'noexec']},
        '/run/arc/adbd': {
            'type': ['tmpfs'],
            'options': standard_rw_options + ['mode=770']},
        '/run/arc/debugfs/sync': {
            'type': ['debugfs'],
            'options': standard_rw_options },
        '/run/arc/debugfs/tracing': {  # for devices in dev mode.
            'type': ['debugfs', 'tracefs'],
            'options': standard_rw_options },
        '/run/arc/media': {
            'type': ['tmpfs'] ,
            'options': standard_ro_options + ['mode=755']},
        '/run/arc/obb': {
            'type': ['tmpfs'],
            'options': standard_ro_options + ['mode=755']},
        '/run/arc/oem': {
            'type': ['tmpfs'],
            'options': standard_rw_options + ['mode=755']},
        '/run/arc/sdcard': {
            'type': ['tmpfs'],
            'options': standard_ro_options + ['mode=755']},
        '/run/arc/shared_mounts': {
            'type': ['tmpfs'],
            'options': standard_rw_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},
        # TODO: /run is already a tmpfs mountpoint, so ip should probably
        # be modified to detect that, and not create a second mountpoint.
        # crbug.com/757953
        '/run/netns': {'type': ['tmpfs'], '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/config': {
            'type': ['configfs'],
            'options': standard_rw_options},
        '/sys/kernel/debug': {
            'type': ['debugfs'],
            'options': standard_rw_options},
        '/sys/kernel/debug/tracing': {
            'type': ['tracefs'],
            'options': standard_rw_options},
        '/sys/kernel/security': {
            'type': ['securityfs'],
            '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},
        '/run/imageloader': {
            'type': ['tmpfs'],
            'options': standard_rw_options},
    }

    # /var/run and /var/lock are bind mounts of /run and /run/lock,
    # respectively. Duplicate the entries accordingly.
    expected_mount_options['/var/run'] = expected_mount_options['/run']
    expected_mount_options['/var/lock'] = expected_mount_options['/run/lock']

    # Base for of {/run,/etc}/daemon-store/<daemon-name> directories.
    run_daemon_store_base = "/run/daemon-store/"
    etc_daemon_store_base = "/etc/daemon-store/"
    expected_daemon_store_mount_options = {
        'type': ['tmpfs'],
        'options': standard_rw_options + ['mode=755']
    }

    # This lists mount points that host mounts created in developer mode, after
    # regular mount operations taking place during boot have completed. These
    # are ignored when checking mounts present in the live system.
    testmode_modded_fses = set(
        ['/home', '/tmp', '/usr/local', '/var/db/pkg', '/var/lib/portage'])

    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
            # For ARC, normalize some container paths.
            fields[1] = re.sub(r'^/run/containers/android_[^/]{6}/',
                               r'/run/containers/android/',
                               fields[1])
            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 or not in mtab, 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_daemon_store_directory(self, daemon_name):
        """
        Check whether /run/daemon-store/<daemon-name> is root-owned and there is
        a corresponding /etc/daemon-store/<daemon-name> folder.

        @param daemon_name: The last part of /run/daemon-store/<daemon-name>.
        Returns:
            int, the number errors detected.
        """
        errors = 0

        run_daemon_store = self.run_daemon_store_base + daemon_name
        errors += self.checkid(run_daemon_store, 0)

        etc_daemon_store = self.etc_daemon_store_base + daemon_name
        if not os.path.exists(etc_daemon_store):
            logging.error(
                'Daemon store "%s" does not have a corresponding "%s" '
                'directory', run_daemon_store, etc_daemon_store)
            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(['/'])
        # nsfs is ignored because it's a kernel filesystem used with
        # network namespaces, and is not a traditional filesystem where
        # arbitrary files may be created and executed.
        ignored_types = set(['ecryptfs', 'nsfs'])
        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 fs in self.expected_mount_options:
                    mount_options = self.expected_mount_options[fs]
                elif fs.startswith(self.run_daemon_store_base):
                    # Handle mounts inside /run/daemon-store as a special case.
                    daemon_name = fs[len(self.run_daemon_store_base):]
                    errors += self.check_daemon_store_directory(daemon_name)
                    mount_options = self.expected_daemon_store_mount_options
                else:
                    logging.error(
                            'No expectations entry for "%s" with info "%s"',
                            fs, mtab[fs])
                    errors += 1
                    continue

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

                device_type = mtab[fs]['device']
                if ('device' in mount_options) and (
                    re.match(mount_options['device'], device_type) is None):
                    logging.error(
                            '[%s] "%s" is device "%s", expected device "%s"',
                            mtab_path, fs, device_type, mount_options['device'])
                    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:
            errors += self.checkid(dir, 0)

        # 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)
