# Copyright (c) 2013 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 time

from autotest_lib.client.bin import test
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros import site_eap_certs
from autotest_lib.client.cros import hostapd_server
from autotest_lib.client.cros import shill_temporary_profile
from autotest_lib.client.cros import virtual_ethernet_pair

# This hacks the path so that we can import shill_proxy.
# pylint: disable=W0611
from autotest_lib.client.cros import flimflam_test_path
# pylint: enable=W0611
import shill_proxy

class network_8021xWiredAuthentication(test.test):
    """The 802.1x EAP wired authentication class.

    Runs hostapd on one side of an ethernet pair, and shill on the other.
    Configures the Ethernet service with 802.1x credentials and ensures
    that when shill detects an EAP authenticator, it is successful in
    using its credentials to gain access.

    """
    INTERFACE_NAME = 'pseudoethernet0'
    AUTHENTICATION_FLAG = 'EapAuthenticationCompleted'
    TEST_PROFILE_NAME = 'test1x'
    AUTHENTICATION_TIMEOUT = 10
    version = 1

    def get_device(self, interface_name):
        """Finds the corresponding Device object for an ethernet
        interface with the name |interface_name|.

        @param interface_name string The name of the interface to check.

        @return DBus interface object representing the associated device.

        """
        device = self._shill_proxy.find_object('Device',
                                               {'Name': interface_name})
        if device is None:
            raise error.TestFail('Device was not found.')

        return device


    def get_authenticated_flag(self, interface_name):
        """Checks whether |interface_name| has successfully negotiated
        802.1x.

        @param interface_name string The name of the interface to check.

        @return True if the authenticated flag is set, False otherwise.

        """
        device = self.get_device(interface_name)
        device_properties = device.GetProperties(utf8_strings=True)
        logging.info('Device properties are %r', device_properties)
        return shill_proxy.ShillProxy.dbus2primitive(
                device_properties[self.AUTHENTICATION_FLAG])


    def wait_for_authentication(self, interface_name):
        """Wait for |interface_name| to get to enter authentication state.

        @param interface_name string The name of the interface to check.

        """
        device = self.get_device(interface_name)
        result = self._shill_proxy.wait_for_property_in(
                         device,
                         self.AUTHENTICATION_FLAG,
                         (True,),
                         self.AUTHENTICATION_TIMEOUT)
        (successful, _, _) = result
        return successful


    def configure_credentials(self, interface_name):
        """Adds authentication properties to the Ethernet EAP service.

        @param interface_name string The name of the associated interface

        """
        service = self._shill_proxy.manager.ConfigureService({
            'Type': 'etherneteap',
            'EAP.EAP': hostapd_server.HostapdServer.EAP_TYPE,
            'EAP.InnerEAP': 'auth=%s' % hostapd_server.HostapdServer.EAP_PHASE2,
            'EAP.Identity': hostapd_server.HostapdServer.EAP_USERNAME,
            'EAP.Password': hostapd_server.HostapdServer.EAP_PASSWORD,
            'EAP.CACertPEM': site_eap_certs.ca_cert_1
        })


    def run_once(self):
        """Test main loop."""
        self._shill_proxy = shill_proxy.ShillProxy()
        manager = self._shill_proxy.manager

        with shill_temporary_profile.ShillTemporaryProfile(
                manager, profile_name=self.TEST_PROFILE_NAME):
            with virtual_ethernet_pair.VirtualEthernetPair(
                    peer_interface_name=self.INTERFACE_NAME,
                    peer_interface_ip=None) as ethernet_pair:
                if not ethernet_pair.is_healthy:
                    raise error.TestFail('Virtual ethernet pair failed.')

                if self.get_authenticated_flag(self.INTERFACE_NAME):
                    raise error.TestFail('Authentication flag already set.')

                with hostapd_server.HostapdServer(
                        interface=ethernet_pair.interface_name) as hostapd:
                    # Wait for hostapd to initialize.
                    time.sleep(1)
                    if not hostapd.running():
                        raise error.TestFail('hostapd process exited.')

                    self.configure_credentials(self.INTERFACE_NAME)
                    hostapd.send_eap_packets()
                    if not self.wait_for_authentication(self.INTERFACE_NAME):
                        raise error.TestFail('Authentication did not complete.')

                    client_mac_address = ethernet_pair.peer_interface_mac
                    if not hostapd.client_has_authenticated(client_mac_address):
                        raise error.TestFail('Server does not agree that '
                                             'client is authenticated')

                    if hostapd.client_has_logged_off(client_mac_address):
                        raise error.TestFail('Client has already logged off')

                    # Since the EAP credentials are associated with the
                    # top-most profile, popping it should cause the client
                    # to immediately log-off.
                    manager.PopProfile(self.TEST_PROFILE_NAME)

                    if self.get_authenticated_flag(self.INTERFACE_NAME):
                        raise error.TestFail('Client is still authenticated.')

                    if not hostapd.client_has_logged_off(client_mac_address):
                        raise error.TestFail('Client did not log off')

                    # Re-pushing the profile should make the EAP credentials
                    # available again, and should cause the client to
                    # re-authenticate.
                    manager.PushProfile(self.TEST_PROFILE_NAME)

                    if not self.wait_for_authentication(self.INTERFACE_NAME):
                        raise error.TestFail('Re-authentication did not '
                                             'complete.')
