# Copyright (c) 2012 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 json
import logging

from autotest_lib.client.common_lib import error
from autotest_lib.client.cros import cros_ui_test

"""A test verifying that Chrome Bluetooth Settings UI isn't vulnerable to XSS

Uses PyAuto to execute JavaScript on the clients, using API calls to create
fake devices with malicious input and simulating user interaction to test
display implementation for vulnerabilities.
"""

class security_BluetoothUIXSS(cros_ui_test.UITest):
    version = 1

    # List of malicious strings to try as inputs to the UI.
    # Note that these strings must be escaped to be contained in JavaScript
    # double quote strings.
    _MALICIOUS_STRINGS = [
            'fake',
            '<SCRIPT>alert(1)</SCRIPT>',
            '>\'>\\"><SCRIPT>alert(1)</SCRIPT>',
            '<IMG SRC=\\"javascript:alert(1)\\">',
            ('<A HREF=\\"data:text/html;base64,'
                    'PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pgo=\\">...</A>'),
            '<div>',
            '<textarea>',
            '<style>',
            ('[0xC0][0xBC]SCRIPT[0xC0][0xBE]alert(1)[0xC0][0xBC]/SCRIPT[0xC0]'
                    '[0xBE]'),
            '+ADw-SCRIPT+AD4-alert(1)+ADw-/SCRIPT+AD4-',
            '&#<script>alert(1)</script>;',
            '<!-- Hello -- world > <SCRIPT>alert(1)</SCRIPT> -->',
            '<!<!-- Hello world > <SCRIPT>alert(1)</SCRIPT> -->',
            '\x3CSCRIPT\x3Ealert(1)\x3C/SCRIPT\x3E',
            '<IMG SRC=\\"j[0x00]avascript:alert(1)\\">',
            '<BASE HREF=\\"javascript:1;/**/\\"><IMG SRC=\\"alert(1)\\">',
            'javascript:alert(1);',
            ' xss_injection=\\"\\" ',
            '\\" xss_injection=\\"',
            '\' xss_injection=\'',
            '<!--',
            '\'',
            '\\"'
    ]

    # JavaScript helper function to determine the number of tag and text nodes
    # on a page.  Also looks for an injected attribute named "xss_injection".
    _NUMBER_OF_NODES_FUNC = """
            function numberOfNodesIn(currentNode) {
              if(currentNode.getAttribute && currentNode.getAttribute(
                  "xss_injection")) {
                var results = {
                    "effects_found":true,
                    "reason":"XSS attribute injection was successful"};
                window.domAutomationController.send(JSON.stringify(results));
                throw "XSS injection success";
              }
              var currentCount = currentNode.childNodes.length,
                  total = currentCount;
              for (var i = 0; i < currentCount; i++) total += numberOfNodesIn(
                  currentNode.childNodes[i]);
              return total;}
            """

    # JavaScript helper function to record the number of DOM nodes on a page
    # before and after calling a function to alter the DOM and compare the
    # difference result to an expected difference.
    _TEST_FOR_EFFECTS_FUNC = """
            function testForEffects(changeFunction, additionExpected) {
              var numberOfNodesBeforeAdding = numberOfNodesIn(document);
              changeFunction();
              var numberOfNodesAfterAdding = numberOfNodesIn(document);
              var reason = (numberOfNodesAfterAdding -
                  numberOfNodesBeforeAdding) + " new nodes found, " +
                  additionExpected + " expected.";
              var results = {
                  "effects_found":!(numberOfNodesAfterAdding ==
                  numberOfNodesBeforeAdding + additionExpected),
                  "reason":reason};
              return results;
            }
            """

    def add_bluetooth_device_to_list(self, name, address, paired, bonded,
            connected):
        """Adds a fake Bluetooth device and checks for side effects.

        Uses JavaScript API calls to create a malicious fake Bluetooth device
        and counts the number of text/tag nodes on the web page to make sure
        that XSS wasn't successful.

        Args:
            name: String name of the fake device.
            address: String address of the fake device.
            paired: Boolean for whether or not device is already paired.
            bonded: Boolean for whether or not device is already bonded.
            connected: Boolean for whether or not device is already connected.

        Returns:
            A boolean representing whether or not XSS was successful.
        """
        if paired:
            _NUMBER_OF_EXPECTED_NEW_NODES = 0
        else:
            _NUMBER_OF_EXPECTED_NEW_NODES = 5

        output = json.loads(self.pyauto.ExecuteJavascript("""
                %s
                %s
                function testAddToBluetoothList(name, address, paired, bonded,
                    connected, additionExpected) {
                  var addBluetoothDevice = function() {
                    options.BrowserOptions.addBluetoothDevice(
                        {"name":name, "address":address, "paired":paired,
                        "bonded":bonded, "connected":connected});
                  };
                  var results = testForEffects(addBluetoothDevice,
                      additionExpected);
                  options.BrowserOptions.removeBluetoothDevice(address);
                  window.domAutomationController.send(JSON.stringify(results));
                }
                testAddToBluetoothList("%s", "%s", %s, %s, %s, %d);
                """ % (self._NUMBER_OF_NODES_FUNC, self._TEST_FOR_EFFECTS_FUNC,
                name, address, str(paired).lower(), str(bonded).lower(),
                str(connected).lower(), _NUMBER_OF_EXPECTED_NEW_NODES)))

        side_effects_found = output['effects_found']

        if not side_effects_found:
            log_msg = '[PASS]'
        else:
            log_msg = '[FAIL]'
            self.pyauto.NavigateToURL('chrome://settings-frame/')

        logging.debug('%s Added device with name "%s", address "%s", paired:%s,'
                ' bonded:%s, connected:%s; %s' % (log_msg,
                name, address, paired, bonded, connected, output['reason']))

        return side_effects_found

    def add_bluetooth_devices_to_list(self, name, address):
        """Adds a fake Bluetooth device in all possible configurations.

        Calls add_bluetooth_device_to_list for each possible combination of
        paired, bonded, and connected flags for full coverage of a given name/
        address pair.

        Args:
            name: String name of the desired fake Bluetooth device.
            address: String address of the desired fake Bluetooth device.

        Returns:
            A boolean representing whether or not XSS was successful.
        """
        side_effects_found = self.add_bluetooth_device_to_list(name, address,
                False, False, False)
        side_effects_found = self.add_bluetooth_device_to_list(name, address,
                False, False, True) or side_effects_found
        side_effects_found = self.add_bluetooth_device_to_list(name, address,
                False, True, False) or side_effects_found
        side_effects_found = self.add_bluetooth_device_to_list(name, address,
                False, True, True) or side_effects_found
        side_effects_found = self.add_bluetooth_device_to_list(name, address,
                True, False, False) or side_effects_found
        side_effects_found = self.add_bluetooth_device_to_list(name, address,
                True, False, True) or side_effects_found
        side_effects_found = self.add_bluetooth_device_to_list(name, address,
                True, True, False) or side_effects_found
        side_effects_found = self.add_bluetooth_device_to_list(name, address,
                True, True, True) or side_effects_found
        return side_effects_found

    def test_adding(self):
        """Tests adding malicious Bluetooth devices.

        Calls add_bluetooth_devices_to_list() for all malicious strings.

        Returns:
            A boolean representing whether or not XSS is possible when
            adding a Bluetooth device.
        """
        self.pyauto.NavigateToURL('chrome://settings-frame/')

        side_effects_found = False
        for entry in self._MALICIOUS_STRINGS:
            side_effects_found = self.add_bluetooth_devices_to_list(entry,
                    entry) or side_effects_found
        return side_effects_found

    def connect_bluetooth_device(self, name, address, paired, bonded,
            connected):
        """Connects a fake Bluetooth device and checks for side effects.

        Uses JavaScript UI API calls to simulate connecting to a fake Bluetooth
        device and counts the number of text/tag nodes on the web page to make
        sure that XSS wasn't successful.

        Args:
            name: String name of the fake device.
            address: String address of the fake device.
            paired: Boolean for whether or not device is already paired.
            bonded: Boolean for whether or not device is already bonded.
            connected: Boolean for whether or not device is already connected.

        Returns:
            A boolean representing whether or not XSS was successful.
        """
        # list of strings representing Bluetooth pairing states
        _PAIRING_STATES = ['bluetoothStartConnecting',
                'bluetoothEnterPinCode', 'bluetoothEnterPasskey',
                'bluetoothRemotePinCode', 'bluetoothRemotePasskey',
                'bluetoothConfirmPasskey']

        self.pyauto.NavigateToURL('chrome://settings-frame/')

        is_clean = True
        side_effects_found = False
        for state in _PAIRING_STATES:
            if is_clean:
                new_nodes_expected = 8
            else:
                new_nodes_expected = 0
            js = """
                %s
                %s
                function testConnectBluetoothDevice(name, address, paired,
                    bonded, connected, pairing, additionExpected) {
                  var device = {"name":name, "address":address, "paired":paired,
                      "bonded":bonded, "connected":connected,
                      "pairing":pairing};
                  var connectBluetoothDevice = function(device) {
                    return function() {
                      options.BluetoothPairing.showDialog(device);
                    };
                  };
                  device.pairing = pairing;
                  results = testForEffects(connectBluetoothDevice(device),
                      additionExpected);
                  if(results.effects_found) {
                    window.domAutomationController.send(JSON.stringify(
                        results));
                    return;
                  }
                  window.domAutomationController.send(JSON.stringify(results));
                }
                testConnectBluetoothDevice("%s", "%s", %s, %s, %s, "%s", %d);
                """ % (self._NUMBER_OF_NODES_FUNC, self._TEST_FOR_EFFECTS_FUNC,
                name, address, str(paired).lower(), str(bonded).lower(),
                str(connected).lower(), state, new_nodes_expected)
            output = json.loads(self.pyauto.ExecuteJavascript(js))

            side_effects_found_now = output['effects_found']

            if not side_effects_found_now:
                log_msg = '[PASS]'
                is_clean = False
            else:
                side_effects_found = True
                log_msg = '[FAIL]'
                self.pyauto.NavigateToURL('chrome://settings-frame/')
                is_clean = True

            logging.debug('%s Connected device at stage %s with name "%s", '
            'address "%s", paired:%s, bonded:%s, connected:%s; %s' % (log_msg,
                    state, name, address, paired, bonded, connected,
                    output['reason']))

        return side_effects_found

    def connect_bluetooth_devices(self, name, address):
        """Connects a Bluetooth device in all possible configurations.

        Calls connect_bluetooth_device for each normally possible combination
        of paired, bonded, and connected flags for full coverage of a given
        name/address pair.

        Args:
            name: String name of the desired fake Bluetooth device.
            address: String address of the desired fake Bluetooth device.

        Returns:
            A boolean representing whether or not XSS was successful.
        """
        side_effects_found = self.connect_bluetooth_device(name, address, False,
                False, False)
        side_effects_found = self.connect_bluetooth_device(name, address, False,
                True, False) or side_effects_found
        return side_effects_found

    def test_connecting(self):
        """Tests connecting to malicious Bluetooth devices.

        Calls connect_bluetooth_devices() for all malicious strings.

        Returns:
            A boolean representing whether or not XSS is possible when
            connecting to a Bluetooth device.
        """
        side_effects_found = False
        for entry in self._MALICIOUS_STRINGS:
            side_effects_found = self.connect_bluetooth_devices(entry,
                    entry) or side_effects_found
        return side_effects_found

    def set_up(self):
        """Sets up environment for testing.

        Checks if Bluetooth was already turned on and turns it on if it wasn't
        on already.
        """
        self.pyauto.NavigateToURL('chrome://settings-frame/')
        setup_js = ('$("advanced-settings-expander").click();'
                'var bluetooth_was_enabled = $("enable-bluetooth").checked;'
                'if(!bluetooth_was_enabled) $("enable-bluetooth").click();'
                'var results = {"bluetooth_was_enabled":bluetooth_was_enabled};'
                'window.domAutomationController.send(JSON.stringify(results));')
        self.start_env = json.loads(self.pyauto.ExecuteJavascript(setup_js))

    def tear_down(self):
        """Tears down environment after testing.

        Disables Bluetooth if it was disabled before testing.
        """
        if not self.start_env['bluetooth_was_enabled']:
            self.pyauto.NavigateToURL('chrome://settings-frame/')
            teardown_js = ('$("advanced-settings-expander").click();'
                    '$("enable-bluetooth").click();'
                    'window.domAutomationController.send("")')
            self.pyauto.ExecuteJavascript(teardown_js)

    def run_once(self):
        """Main function.

        Runs all test helper functions.

        Raises:
            error.TestFail if XSS was successful in any test.
        """
        self.set_up()

        side_effects_found = self.test_adding()
        side_effects_found = self.test_connecting() or side_effects_found

        self.tear_down()

        if side_effects_found:
            raise error.TestFail('XSS vulnerabilities were found.')
