# 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 dbus
import logging
import sys

from autotest_lib.client.bin import test
from autotest_lib.client.cros import shill_temporary_profile
from autotest_lib.client.common_lib import error
from autotest_lib.client.cros.networking import wifi_proxy

class network_WiFiInvalidParameters(test.test):
    """Test that shill will reject invalid WiFi service configurations.

    In particular, this test checks shill's behavior with invalid SSIDs,
    WEP keys, and WPA passphrases.

    """
    version = 1
    unique_counter = 1


    SSID_TOO_LONG = ('MaxLengthSSID' * 8)[:33]
    SSID_TOO_SHORT = ''

    WPA_PASSPHRASE_TOO_LONG = ('x123456789' * 8)[:64]
    WPA_PASSPHRASE_TOO_SHORT= 'x123456'
    WPA_PMK_TOO_LONG = ('0123456789' * 8)[:65]


    @staticmethod
    def get_ssid():
        """@return string a unique SSID."""
        reserved_value = network_WiFiInvalidParameters.unique_counter
        network_WiFiInvalidParameters.unique_counter += 1
        return 'an ssid%d' % reserved_value


    def check_bad_ssids(self, shill):
        """Assert that shill will reject attempts connect to invalid SSIDs.

        @param shill ShillProxy object representing shill.

        """
        bad_ssids = [self.SSID_TOO_LONG, self.SSID_TOO_SHORT]
        for ssid in bad_ssids:
            config_params = {shill.SERVICE_PROPERTY_TYPE: 'wifi',
                             shill.SERVICE_PROPERTY_SSID: ssid,
                             shill.SERVICE_PROPERTY_SECURITY: 'none'}
            try:
                accepted = True
                shill.manager.ConfigureService(config_params)
            except dbus.exceptions.DBusException, e:
                accepted = False
                if (e.get_dbus_name() !=
                        'org.chromium.flimflam.Error.InvalidNetworkName'):
                    raise error.TestFail('Got an unexpected exception from '
                                         'shill: %s: %s.' %
                                         (e.get_dbus_name(),
                                          e.get_dbus_message()))
            if accepted:
                raise error.TestFail('Expected shill to stop us, but it let us '
                                     'configure a bad SSID "%r"' % ssid)


    def check_bad_wep_keys(self, shill):
        """Assert that shill will reject attempts to use invalid WEP keys.

        @param shill ShillProxy object representing shill.

        """
        LONG_HEX_STRING = '0123456789abcdef' * 8
        BAD_PREFIXES = ('4', '001', '-22', 'a', )
        bad_keys = []
        # Generate a bunch of hex keys.  Some of these are good ASCII keys, but
        # we'll fix this in a moment.
        for index in range(4):
            for length in range(0, 10) + range(11, 26) + range(27, 30):
                bad_keys.append('%d:%s' % (index, LONG_HEX_STRING[:length]))
                bad_keys.append('%d:0x%s' % (index, LONG_HEX_STRING[:length]))
        # |bad_keys| contains all bad hex keys, but some of those hex keys
        # could be interpretted as valid ASCII keys.  Lets take those out.
        good_keys = []
        for key in bad_keys:
            # 5 and 13 length keys are just ASCII keys.  7 and 15 are ASCII keys
            # with the key index prefix.
            if len(key) in (5, 7, 13, 15):
                good_keys.append(key)
        map(bad_keys.remove, good_keys)
        # Now add some keys that are bad because the prefix is no good.
        for valid_key in (LONG_HEX_STRING[:10], LONG_HEX_STRING[:26]):
            for prefix in BAD_PREFIXES:
                bad_keys.append('%s:%s' % (prefix, valid_key))
                bad_keys.append('%s:0x%s' % (prefix, valid_key))
        for valid_key in ('wep40', 'wep104is13len'):
            for prefix in BAD_PREFIXES:
                bad_keys.append('%s:%s' % (prefix, valid_key))
        for key in bad_keys:
            config_params = {shill.SERVICE_PROPERTY_TYPE: 'wifi',
                             shill.SERVICE_PROPERTY_SSID: self.get_ssid(),
                             shill.SERVICE_PROPERTY_PASSPHRASE: key,
                             shill.SERVICE_PROPERTY_SECURITY: 'wep'}
            try:
                accepted = True
                shill.manager.ConfigureService(config_params)
            except dbus.exceptions.DBusException, e:
                accepted = False
                if (e.get_dbus_name() !=
                        'org.chromium.flimflam.Error.InvalidPassphrase'):
                    raise error.TestFail('Got an unexpected exception from '
                                         'shill: %s: %s.' %
                                         (e.get_dbus_name(),
                                          e.get_dbus_message()))

            if accepted:
                raise error.TestFail('Expected shill to stop us, but it let us '
                                     'configure a bad WEP key: %s' % key)

        for key in good_keys:
            config_params = {shill.SERVICE_PROPERTY_TYPE: 'wifi',
                             shill.SERVICE_PROPERTY_SSID: self.get_ssid(),
                             shill.SERVICE_PROPERTY_PASSPHRASE: key,
                             shill.SERVICE_PROPERTY_SECURITY: 'wep'}
            try:
                shill.manager.ConfigureService(config_params)
            except:
                logging.error('%r', sys.exc_info())
                raise error.TestFail('shill should let us use a WEP key '
                                     'like: %s' % key)


    def check_bad_wpa_passphrases(self, shill):
        """Assert that shill will reject invalid WPA passphrases.

        @param shill ShillProxy object representing shill.

        """
        bad_passphrases = [self.WPA_PASSPHRASE_TOO_LONG,
                           self.WPA_PASSPHRASE_TOO_SHORT,
                           self.WPA_PMK_TOO_LONG]
        for psk in bad_passphrases:
            for security in ('rsn', 'wpa', 'psk'):
                config_params = {shill.SERVICE_PROPERTY_TYPE: 'wifi',
                                 shill.SERVICE_PROPERTY_SSID: self.get_ssid(),
                                 shill.SERVICE_PROPERTY_PASSPHRASE: psk,
                                 shill.SERVICE_PROPERTY_SECURITY: security}
                try:
                    accepted = True
                    shill.manager.ConfigureService(config_params)
                except dbus.exceptions.DBusException, e:
                    accepted = False
                    if (e.get_dbus_name() !=
                            'org.chromium.flimflam.Error.InvalidPassphrase'):
                        raise error.TestFail('Got an unexpected exception from '
                                             'shill: %s: %s.' %
                                             (e.get_dbus_name(),
                                              e.get_dbus_message()))
                if accepted:
                    raise error.TestFail('Expected shill to stop us, but it '
                                         'let us configure a bad passphrase: '
                                         '%s' % psk)


    def run_once(self):
        """Test body."""
        shill = wifi_proxy.WifiProxy.get_proxy()
        with shill_temporary_profile.ShillTemporaryProfile(shill.manager):
            self.check_bad_ssids(shill)
            self.check_bad_wep_keys(shill)
            self.check_bad_wpa_passphrases(shill)
