# Copyright 2018 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 subprocess
import shutil
import tempfile

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

MOUNT_PATH=tempfile.mkdtemp()

class security_NosymfollowMountOption(test.test):
    """
    Mount filesystems with the "nosymfollow" option and ensure symlink
    traversal is blocked.
    """
    version = 1

    def __init__(self, *args, **kwargs):
        # TODO(mortonm): add a function to utils to do this kernel version
        # check and raise NAError.
        version = utils.get_kernel_version()
        if version == "3.8.11" or version == "3.10.18":
            raise error.TestNAError('Test is n/a for kernels older than 3.14')
        super(security_NosymfollowMountOption,
            self).__init__(*args, **kwargs)
        self._failure = False

    def cleanup(self):
        """
        Clean up test environment.
        """
        super(security_NosymfollowMountOption, self).cleanup()
        shutil.rmtree(MOUNT_PATH)

    def _fail(self, msg):
        """
        Log failure message and record failure.

        @param msg: String to log.

        """
        logging.error(msg)
        self._failure = True

    def umount(self):
        """
        Unmount file system at MOUNT_PATH location.
        """
        try:
            subprocess.check_output(["/bin/umount", MOUNT_PATH])
        except subprocess.CalledProcessError, e:
            self._fail("umount call failed")

    def mount_and_test_with_string(self, mount_options, restrict_symlinks):
        """
        Mount file system with given options, check it was mounted with
        correct options, and make sure symlink traversal restriction works as
        expected.

        @param mount_options: Mount options string.

        @param restrict_symlinks: True if mount options should cause symlinks
        to be restricted, False otherwise.

        """
        try:
            subprocess.check_output(["/bin/mount",
                                            "-n",
                                            "-t",
                                            "tmpfs",
                                            "-o",
                                            mount_options,
                                            "tmpfs",
                                            MOUNT_PATH])
        except subprocess.CalledProcessError:
            self._fail("mount call failed")
            return

        try:
            ps = subprocess.Popen(('mount'), stdout=subprocess.PIPE)
            output = subprocess.check_output(('grep',MOUNT_PATH),
                                                        stdin=ps.stdout)
            ps.wait()

            for arg in mount_options.split(','):
                if arg == "nosymfollow":
                    continue
                else:
                    if output.find(arg) == -1:
                        self._fail("filesystem missing '%s' arg" % arg)
                        return

            try:
                open(MOUNT_PATH + "/file", "w+")
                os.symlink(MOUNT_PATH + "/file", MOUNT_PATH + "/link")
            except IOError:
                self._fail("creating/linking files failed")
                return

            traversal_restricted = False
            try:
                open(MOUNT_PATH + "/link", "r")
            except IOError:
                traversal_restricted = True

            if restrict_symlinks:
                if not traversal_restricted:
                    self._fail("symlink traversal was not restricted")
                    return
            else:
                if traversal_restricted:
                    self._fail("symlink traversal was restricted")
        finally:
            self.umount()

    def run_once(self):
        """
        Runs the test, mounting filesystems and checking symlink traversal
        behavior.
        """
        self.mount_and_test_with_string("nosymfollow", True)
        self.mount_and_test_with_string("nosymfollow,"
                                        "context=u:object_r:tmpfs:s0,"
                                        "fscontext=u:object_r:tmpfs:s0", True)
        self.mount_and_test_with_string("context=u:object_r:tmpfs:s0,"
                                        "nosymfollow,"
                                        "fscontext=u:object_r:tmpfs:s0", True)
        self.mount_and_test_with_string("context=u:object_r:tmpfs:s0,"
                                        "fscontext=u:object_r:tmpfs:s0,"
                                        "nosymfollow", True)
        self.mount_and_test_with_string("nodev,noexec,nosuid,nosymfollow", True)
        self.mount_and_test_with_string("nodev,noexec,nosuid", False)

        # Make the test fail if any unexpected behaviour got detected. Note
        # that the error log output that will be included in the failure
        # message mentions the failed location to aid debugging.
        if self._failure:
            raise error.TestFail('Unexpected mount behavior')
