# Copyright 2017 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.
"""
Wrapper for D-Bus calls ot the AuthPolicy daemon.
"""

import logging
import os
import sys

import dbus

from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import utils
from autotest_lib.client.cros import upstart


class AuthPolicy(object):
    """
    Wrapper for D-Bus calls ot the AuthPolicy daemon.

    The AuthPolicy daemon handles Active Directory domain join, user
    authentication and policy fetch. This class is a wrapper around the D-Bus
    interface to the daemon.

    """

    # Log file written by authpolicyd.
    _LOG_FILE = '/var/log/authpolicy.log'

    # Number of log lines to include in error logs.
    _LOG_LINE_LIMIT = 50

    # The usual system log file (minijail logs there!).
    _SYSLOG_FILE = '/var/log/messages'

    # Authpolicy daemon D-Bus parameters.
    _DBUS_SERVICE_NAME = 'org.chromium.AuthPolicy'
    _DBUS_SERVICE_PATH = '/org/chromium/AuthPolicy'
    _DBUS_INTERFACE_NAME = 'org.chromium.AuthPolicy'
    _DBUS_ERROR_SERVICE_UNKNOWN = 'org.freedesktop.DBus.Error.ServiceUnknown'

    # Default timeout in seconds for D-Bus calls.
    _DEFAULT_TIMEOUT = 120

    def __init__(self, bus_loop, proto_binding_location):
        """
        Constructor

        Creates and returns a D-Bus connection to authpolicyd. The daemon must
        be running.

        @param bus_loop: glib main loop object.
        @param proto_binding_location: the location of generated python bindings
                                       for authpolicy protobufs.
        """

        # Pull in protobuf bindings.
        sys.path.append(proto_binding_location)

        self._bus_loop = bus_loop
        self.restart()

    def restart(self):
        """
        Restarts authpolicyd and rebinds to D-Bus interface.
        """
        logging.info('restarting authpolicyd')
        upstart.restart_job('authpolicyd')
        bus = dbus.SystemBus(self._bus_loop)
        proxy = bus.get_object(self._DBUS_SERVICE_NAME, self._DBUS_SERVICE_PATH)
        self._authpolicyd = dbus.Interface(proxy, self._DBUS_INTERFACE_NAME)

    def stop(self):
        """
        Turns debug logs off.

        Stops authpolicyd.
        """
        logging.info('stopping authpolicyd')

        # Reset log level and stop. Ignore errors that occur when authpolicy is
        # already down.
        try:
            self.set_default_log_level(0)
        except dbus.exceptions.DBusException as ex:
            if ex.get_dbus_name() != self._DBUS_ERROR_SERVICE_UNKNOWN:
                raise
        try:
            upstart.stop_job('authpolicyd')
        except error.CmdError as ex:
            if (ex.result_obj.exit_status == 0):
                raise

        self._authpolicyd = None

    def join_ad_domain(self,
                       user_principal_name,
                       password,
                       machine_name,
                       machine_domain=None,
                       machine_ou=None):
        """
        Joins a machine (=device) to an Active Directory domain.

        @param user_principal_name: Logon name of the user (with @realm) who
            joins the machine to the domain.
        @param password: Password corresponding to user_principal_name.
        @param machine_name: Netbios computer (aka machine) name for the joining
            device.
        @param machine_domain: Domain (realm) the machine should be joined to.
            If not specified, the machine is joined to the user's realm.
        @param machine_ou: Array of organizational units (OUs) from leaf to
            root. The machine is put into the leaf OU. If not specified, the
            machine account is created in the default 'Computers' OU.

        @return A tuple with the ErrorType and the joined domain returned by the
            D-Bus call.

        """

        from active_directory_info_pb2 import JoinDomainRequest

        request = JoinDomainRequest()
        request.user_principal_name = user_principal_name
        request.machine_name = machine_name
        if machine_ou:
            request.machine_ou.extend(machine_ou)
        if machine_domain:
            request.machine_domain = machine_domain

        with self.PasswordFd(password) as password_fd:
            return self._authpolicyd.JoinADDomain(
                    dbus.ByteArray(request.SerializeToString()),
                    dbus.types.UnixFd(password_fd),
                    timeout=self._DEFAULT_TIMEOUT,
                    byte_arrays=True)

    def authenticate_user(self, user_principal_name, account_id, password):
        """
        Authenticates a user with an Active Directory domain.

        @param user_principal_name: User logon name (user@example.com) for the
            Active Directory domain.
        #param account_id: User account id (aka objectGUID). May be empty.
        @param password: Password corresponding to user_principal_name.

        @return A tuple with the ErrorType and an ActiveDirectoryAccountInfo
                blob string returned by the D-Bus call.

        """

        from active_directory_info_pb2 import ActiveDirectoryAccountInfo
        from active_directory_info_pb2 import AuthenticateUserRequest
        from active_directory_info_pb2 import ERROR_NONE

        request = AuthenticateUserRequest()
        request.user_principal_name = user_principal_name
        if account_id:
            request.account_id = account_id

        with self.PasswordFd(password) as password_fd:
            error_value, account_info_blob = self._authpolicyd.AuthenticateUser(
                    dbus.ByteArray(request.SerializeToString()),
                    dbus.types.UnixFd(password_fd),
                    timeout=self._DEFAULT_TIMEOUT,
                    byte_arrays=True)
            account_info = ActiveDirectoryAccountInfo()
            if error_value == ERROR_NONE:
                account_info.ParseFromString(account_info_blob)
            return error_value, account_info

    def refresh_user_policy(self, account_id):
        """
        Fetches user policy and sends it to Session Manager.

        @param account_id: User account ID (aka objectGUID).

        @return ErrorType from the D-Bus call.

        """

        return self._authpolicyd.RefreshUserPolicy(
                dbus.String(account_id),
                timeout=self._DEFAULT_TIMEOUT,
                byte_arrays=True)

    def refresh_device_policy(self):
        """
        Fetches device policy and sends it to Session Manager.

        @return ErrorType from the D-Bus call.

        """

        return self._authpolicyd.RefreshDevicePolicy(
                timeout=self._DEFAULT_TIMEOUT, byte_arrays=True)

    def change_machine_password(self):
        """
        Changes machine password.

        @return ErrorType from the D-Bus call.

        """
        return self._authpolicyd.ChangeMachinePasswordForTesting(
                timeout=self._DEFAULT_TIMEOUT, byte_arrays=True)

    def set_default_log_level(self, level):
        """
        Fetches device policy and sends it to Session Manager.

        @param level: Log level, 0=quiet, 1=taciturn, 2=chatty, 3=verbose.

        @return error_message: Error message, empty if no error occurred.

        """

        return self._authpolicyd.SetDefaultLogLevel(level, byte_arrays=True)

    def print_log_tail(self):
        """
        Prints out authpolicyd log tail. Catches and prints out errors.

        """

        try:
            cmd = 'tail -n %s %s' % (self._LOG_LINE_LIMIT, self._LOG_FILE)
            log_tail = utils.run(cmd).stdout
            logging.info('Tail of %s:\n%s', self._LOG_FILE, log_tail)
        except error.CmdError as ex:
            logging.error('Failed to print authpolicyd log tail: %s', ex)

    def print_seccomp_failure_info(self):
        """
        Detects seccomp failures and prints out the failing syscall.

        """

        # Exit code 253 is minijail's marker for seccomp failures.
        cmd = 'grep -q "failed: exit code 253" %s' % self._LOG_FILE
        if utils.run(cmd, ignore_status=True).exit_status == 0:
            logging.error('Seccomp failure detected!')
            cmd = 'grep -oE "blocked syscall: \\w+" %s | tail -1' % \
                    self._SYSLOG_FILE
            try:
                logging.error(utils.run(cmd).stdout)
                logging.error(
                        'This can happen if you changed a dependency of '
                        'authpolicyd. Consider whitelisting this syscall in '
                        'the appropriate -seccomp.policy file in authpolicyd.'
                        '\n')
            except error.CmdError as ex:
                logging.error(
                        'Failed to determine reason for seccomp issue: %s', ex)

    def clear_log(self):
        """
        Clears the authpolicy daemon's log file.

        """

        try:
            utils.run('echo "" > %s' % self._LOG_FILE)
        except error.CmdError as ex:
            logging.error('Failed to clear authpolicyd log file: %s', ex)

    class PasswordFd(object):
        """
        Writes password into a file descriptor.

        Use in a 'with' statement to automatically close the returned file
        descriptor.

        @param password: Plaintext password string.

        @return A file descriptor (pipe) containing the password.

        """

        def __init__(self, password):
            self._password = password
            self._read_fd = None

        def __enter__(self):
            """Creates the password file descriptor."""
            self._read_fd, write_fd = os.pipe()
            os.write(write_fd, self._password)
            os.close(write_fd)
            return self._read_fd

        def __exit__(self, mytype, value, traceback):
            """Closes the password file descriptor again."""
            if self._read_fd:
                os.close(self._read_fd)
