# Copyright (c) 2011 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.
#
#    Based on tests from http://bazaar.launchpad.net/~ubuntu-bugcontrol/qa-regression-testing/master/view/head:/scripts/test-kernel-security.py
#    Copyright (C) 2008-2011 Canonical Ltd.
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License version 3,
#    as published by the Free Software Foundation.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program. If not, see <http://www.gnu.org/licenses/>.

import pwd
import tempfile
import shutil
import logging, os
from autotest_lib.client.bin import test, utils
from autotest_lib.client.common_lib import error

class security_HardlinkRestrictions(test.test):
    version = 1

    def _passed(self, msg):
        logging.info('ok: %s' % (msg))

    def _failed(self, msg):
        logging.error('FAIL: %s' % (msg))
        self._failures.append(msg)

    def _fatal(self, msg):
        logging.error('FATAL: %s' % (msg))
        raise error.TestError(msg)

    def check(self, boolean, msg, fatal=False):
        if boolean == True:
            self._passed(msg)
        else:
            msg = "could not satisfy '%s'" % (msg)
            if fatal:
                self._fatal(msg)
            else:
                self._failed(msg)

    def _is_readable(self, path, user, expected=True):
        rc = utils.system("su -c 'cat %s' %s" % (path, user),
                          ignore_status=True)
        status = (rc == 0)

        if status != expected:
            if expected:
                self._failed("'%s' was unable to read file '%s'" %
                             (user, path))
            else:
                self._failed("'%s' was able to read file '%s'" %
                             (user, path))
        return status

    def _is_writable(self, path, user, expected=True):
        rc = utils.system("su -c 'echo > %s' %s" % (path, user),
                          ignore_status=True)
        status = (rc == 0)

        if status != expected:
            if expected:
                self._failed("'%s' was unable to write file '%s'" %
                             (user, path))
            else:
                self._failed("'%s' was able to write file '%s'" %
                             (user, path))
        return status

    def _can_hardlink(self, source, target, user, expected=True):
        rc = utils.system("su -c 'ln %s %s' %s" % (source, target, user),
                          ignore_status=True)
        status = (rc == 0)

        if status != expected:
            if expected:
                self._failed("'%s' was unable to hardlink file '%s' as '%s'" %
                             (user, source, target))
            else:
                self._failed("'%s' was able to hardlink file '%s' as '%s'" %
                             (user, source, target))

        # Check and clean up hardlink if it was created.
        if os.path.exists(target):
            if not expected:
                self._failed("'%s' was able to create hardlink '%s' to '%s'" %
                             (user, target, source))
            os.unlink(target)

        return status

    def _check_hardlinks(self, user):
        uid = pwd.getpwnam(user)[2]

        # Verify we have a distinct user.
        if uid == 0:
            self._failed("The '%s' user is root(%d)!" % (user, uid))
            return

        # Build a world-writable directory, owned by user.
        tmpdir = tempfile.mkdtemp(prefix='hardlinks-')
        self._rmdir.append(tmpdir)
        os.chown(tmpdir, uid, 0)

        # Create test target files.
        secret = tempfile.NamedTemporaryFile(prefix="secret-")
        readable = tempfile.NamedTemporaryFile(prefix="readable-")
        os.chmod(readable.name, 0444)
        available = tempfile.NamedTemporaryFile(prefix="available-")
        os.chmod(available.name, 0666)

        # Verify secret target is unreadable/unwritable.
        self._is_readable(secret.name, user, expected=False)
        self._is_writable(secret.name, user, expected=False)
        # Verify readable target is only readable.
        self._is_readable(readable.name, user)
        self._is_writable(readable.name, user, expected=False)
        # Verify available target is both readable/writable.
        self._is_readable(available.name, user)
        self._is_writable(available.name, user)

        # Create pathnames for hardlinks.
        mine = os.path.join(tmpdir, 'mine')
        evil = os.path.join(tmpdir, 'evil')
        not_evil = os.path.join(tmpdir, 'not-evil')

        # Allow hardlink to files owned by the user, or writable.
        self._is_writable(mine, user)
        self._can_hardlink(mine, not_evil, user)
        self._can_hardlink(available.name, not_evil, user)

        # Disallow hardlinking to unwritable or unreadlabe files.
        self._can_hardlink(readable.name, evil, user, expected=False)
        self._can_hardlink(secret.name, evil, user, expected=False)

        # Disallow hardlinks to unowned non-regular files. This uses
        # /dev because the other locations are mounted nodev, which
        # will cause the read/write tests to fail.
        devdir = tempfile.mkdtemp(prefix="hardlinks-", dir="/dev")
        self._rmdir.append(devdir)
        os.chown(devdir, uid, 0)
        null = os.path.join(devdir, "null")
        dev_evil = os.path.join(devdir, "evil")
        dev_not_evil = os.path.join(devdir, "not-evil")
        utils.system("mknod -m 0666 %s c 1 3" % (null))
        self._is_readable(null, user)
        self._is_writable(null, user)
        self._can_hardlink(null, dev_evil, user, expected=False)

        # Allow hardlinks to owned non-regular files.
        os.chown(null, uid, 0)
        self._can_hardlink(null, dev_not_evil, user)

        # Allow CAP_FOWNER to hardlink non-regular files.
        self._can_hardlink(null, dev_not_evil, "root")

    def run_once(self):
        # Empty failure list means test passes.
        self._failures = []

        # Prepare list of directories to clean up.
        self._rmdir = []

        # Verify Yama exists and has hardlink restrictions enabled.
        sysctl = "/proc/sys/kernel/yama/protected_nonaccess_hardlinks"
        self.check(os.path.exists(sysctl), "%s exists" % (sysctl), fatal=True)
        self.check(open(sysctl).read() == '1\n', "%s enabled" % (sysctl),
                   fatal=True)

        # Test the basic "user hardlinks to unwritable source" situation
        # first, in a more auditable way than the extensive behavior tests
        # that follow.
        if os.path.exists("/tmp/evil-hardlink"):
            os.unlink("/tmp/evil-hardlink")
        rc = utils.system("su -c 'ln /etc/shadow /tmp/evil-hardlink' chronos",
                          ignore_status=True)
        if rc != 1 or os.path.exists("/tmp/evil-hardlink"):
            self._failed("chronos user was able to create malicious hardlink")

        # Test hardlink restrictions.
        self._check_hardlinks(user='chronos')

        # Clean up from the tests.
        for path in self._rmdir:
            if os.path.exists(path):
                shutil.rmtree(path, ignore_errors=True)

        # Raise a failure if anything unexpected was seen.
        if len(self._failures):
            raise error.TestFail((", ".join(self._failures)))
