summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/siteIdentity/browser_navigation_failures.js
blob: ddb0d93fabc835333a78e942132c973e7b0f551a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */

// Tests that the site identity indicator is properly updated for navigations
// that fail for various reasons. In particular, we currently test TLS handshake
// failures, about: pages that don't actually exist, and situations where the
// TLS handshake completes but the server then closes the connection.
// See bug 1492424, bug 1493427, and bug 1391207.

const kSecureURI =
  getRootDirectory(gTestPath).replace(
    "chrome://mochitests/content",
    "https://example.com"
  ) + "dummy_page.html";
add_task(async function () {
  await BrowserTestUtils.withNewTab(kSecureURI, async browser => {
    let identityMode = window.document.getElementById("identity-box").className;
    is(identityMode, "verifiedDomain", "identity should be secure before");

    const TLS_HANDSHAKE_FAILURE_URI = "https://ssl3.example.com/";
    // Try to connect to a server where the TLS handshake will fail.
    BrowserTestUtils.loadURIString(browser, TLS_HANDSHAKE_FAILURE_URI);
    await BrowserTestUtils.browserLoaded(
      browser,
      false,
      TLS_HANDSHAKE_FAILURE_URI,
      true
    );

    let newIdentityMode =
      window.document.getElementById("identity-box").className;
    is(
      newIdentityMode,
      "certErrorPage notSecureText",
      "identity should be unknown (not secure) after"
    );
  });
});

add_task(async function () {
  await BrowserTestUtils.withNewTab(kSecureURI, async browser => {
    let identityMode = window.document.getElementById("identity-box").className;
    is(identityMode, "verifiedDomain", "identity should be secure before");

    const BAD_ABOUT_PAGE_URI = "about:somethingthatdoesnotexist";
    // Try to load an about: page that doesn't exist
    BrowserTestUtils.loadURIString(browser, BAD_ABOUT_PAGE_URI);
    await BrowserTestUtils.browserLoaded(
      browser,
      false,
      BAD_ABOUT_PAGE_URI,
      true
    );

    let newIdentityMode =
      window.document.getElementById("identity-box").className;
    is(
      newIdentityMode,
      "unknownIdentity",
      "identity should be unknown (not secure) after"
    );
  });
});

// Helper function to start a TLS server that will accept a connection, complete
// the TLS handshake, but then close the connection.
function startServer(cert) {
  let tlsServer = Cc["@mozilla.org/network/tls-server-socket;1"].createInstance(
    Ci.nsITLSServerSocket
  );
  tlsServer.init(-1, true, -1);
  tlsServer.serverCert = cert;

  let input, output;

  let listener = {
    onSocketAccepted(socket, transport) {
      let connectionInfo = transport.securityCallbacks.getInterface(
        Ci.nsITLSServerConnectionInfo
      );
      connectionInfo.setSecurityObserver(listener);
      input = transport.openInputStream(0, 0, 0);
      output = transport.openOutputStream(0, 0, 0);
    },

    onHandshakeDone(socket, status) {
      input.asyncWait(
        {
          onInputStreamReady(readyInput) {
            try {
              input.close();
              output.close();
            } catch (e) {
              info(e);
            }
          },
        },
        0,
        0,
        Services.tm.currentThread
      );
    },

    onStopListening() {},
  };

  tlsServer.setSessionTickets(false);
  tlsServer.asyncListen(listener);

  return tlsServer;
}

// Test that if we complete a TLS handshake but the server closes the connection
// just after doing so (resulting in a "connection reset" error page), the site
// identity information gets updated appropriately (it should indicate "not
// secure").
add_task(async function () {
  await SpecialPowers.pushPrefEnv({
    // This test fails on some platforms if we leave IPv6 enabled.
    set: [["network.dns.disableIPv6", true]],
  });

  let certOverrideService = Cc[
    "@mozilla.org/security/certoverride;1"
  ].getService(Ci.nsICertOverrideService);

  let cert = getTestServerCertificate();
  // Start a server and trust its certificate.
  let server = startServer(cert);
  certOverrideService.rememberValidityOverride(
    "localhost",
    server.port,
    {},
    cert,
    true
  );

  // Un-do configuration changes we've made when the test is done.
  registerCleanupFunction(() => {
    certOverrideService.clearValidityOverride("localhost", server.port, {});
    server.close();
  });

  // Open up a new tab...
  await BrowserTestUtils.withNewTab("about:blank", async browser => {
    const TLS_HANDSHAKE_FAILURE_URI = `https://localhost:${server.port}/`;
    // Try to connect to a server where the TLS handshake will succeed, but then
    // the server closes the connection right after.
    BrowserTestUtils.loadURIString(browser, TLS_HANDSHAKE_FAILURE_URI);
    await BrowserTestUtils.browserLoaded(
      browser,
      false,
      TLS_HANDSHAKE_FAILURE_URI,
      true
    );

    let identityMode = window.document.getElementById("identity-box").className;
    is(
      identityMode,
      "certErrorPage notSecureText",
      "identity should be 'unknown'"
    );
  });
});