summaryrefslogtreecommitdiffstats
path: root/toolkit/mozapps/extensions/test/xpcshell/test_loadManifest_isPrivileged.js
blob: 0886a35c2f9ce45536561608fa3a97c4bb0a7da6 (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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

const { XPIInstall } = ChromeUtils.import(
  "resource://gre/modules/addons/XPIInstall.jsm"
);
const {
  XPIInternal: {
    BuiltInLocation,
    KEY_APP_PROFILE,
    KEY_APP_SYSTEM_DEFAULTS,
    KEY_APP_SYSTEM_PROFILE,
    TemporaryInstallLocation,
    XPIStates,
  },
} = ChromeUtils.import("resource://gre/modules/addons/XPIProvider.jsm");

AddonTestUtils.init(this);
AddonTestUtils.overrideCertDB();

// Disable "xpc::IsInAutomation()", since it would override the behavior
// we're testing for.
Services.prefs.setBoolPref(
  "security.turn_off_all_security_so_that_viruses_can_take_over_this_computer",
  false
);

Services.prefs.setIntPref(
  "extensions.enabledScopes",
  // SCOPE_PROFILE is enabled by default,
  // SCOPE_APPLICATION is to enable KEY_APP_SYSTEM_PROFILE, which we need to
  // test the combination (isSystem && !isBuiltin) in test_system_location.
  AddonManager.SCOPE_PROFILE | AddonManager.SCOPE_APPLICATION
);
// test_builtin_system_location tests the (isSystem && isBuiltin) combination
// (i.e. KEY_APP_SYSTEM_DEFAULTS). That location only exists if this directory
// is found:
const distroDir = FileUtils.getDir("ProfD", ["sysfeatures"], true);
registerDirectory("XREAppFeat", distroDir);

function getInstallLocation({
  isBuiltin = false,
  isSystem = false,
  isTemporary = false,
}) {
  if (isTemporary) {
    // Temporary installation. Signatures will not be verified.
    return TemporaryInstallLocation; // KEY_APP_TEMPORARY
  }
  let location;
  if (isSystem) {
    if (isBuiltin) {
      // System location. Signatures will not be verified.
      location = XPIStates.getLocation(KEY_APP_SYSTEM_DEFAULTS);
    } else {
      // Normandy installations. Signatures will be verified.
      location = XPIStates.getLocation(KEY_APP_SYSTEM_PROFILE);
    }
  } else if (isBuiltin) {
    // Packaged with the application. Signatures will not be verified.
    location = BuiltInLocation; // KEY_APP_BUILTINS
  } else {
    // By default - The profile directory. Signatures will be verified.
    location = XPIStates.getLocation(KEY_APP_PROFILE);
  }
  // Sanity checks to make sure that the flags match the expected values.
  if (location.isSystem !== isSystem) {
    ok(false, `${location.name}, unexpected isSystem=${location.isSystem}`);
  }
  if (location.isBuiltin !== isBuiltin) {
    ok(false, `${location.name}, unexpected isBuiltin=${location.isBuiltin}`);
  }
  return location;
}

async function testLoadManifest({ location, expectPrivileged }) {
  location ??= getInstallLocation({});
  let xpi = await AddonTestUtils.createTempWebExtensionFile({
    manifest: {
      browser_specific_settings: { gecko: { id: "@with-privileged-perm" } },
      permissions: ["mozillaAddons", "cookies"],
    },
  });
  let actualPermissions;
  let { messages } = await AddonTestUtils.promiseConsoleOutput(async () => {
    if (location.isTemporary && !expectPrivileged) {
      ExtensionTestUtils.failOnSchemaWarnings(false);
      await Assert.rejects(
        XPIInstall.loadManifestFromFile(xpi, location),
        /Extension is invalid/,
        "load manifest failed with privileged permission"
      );
      ExtensionTestUtils.failOnSchemaWarnings(true);
      return;
    }
    let addon = await XPIInstall.loadManifestFromFile(xpi, location);
    actualPermissions = addon.userPermissions;
    equal(addon.isPrivileged, expectPrivileged, "addon.isPrivileged");
  });
  if (expectPrivileged) {
    AddonTestUtils.checkMessages(messages, {
      expected: [],
      forbidden: [
        {
          message: /Reading manifest: Invalid extension permission/,
        },
      ],
    });
    Assert.deepEqual(
      actualPermissions,
      { origins: [], permissions: ["mozillaAddons", "cookies"] },
      "Privileged permission should exist"
    );
  } else if (location.isTemporary) {
    AddonTestUtils.checkMessages(messages, {
      expected: [
        {
          message:
            /Using the privileged permission 'mozillaAddons' requires a privileged add-on/,
        },
      ],
      forbidden: [],
    });
  } else {
    AddonTestUtils.checkMessages(messages, {
      expected: [
        {
          message:
            /Reading manifest: Invalid extension permission: mozillaAddons/,
        },
      ],
      forbidden: [],
    });
    Assert.deepEqual(
      actualPermissions,
      { origins: [], permissions: ["cookies"] },
      "Privileged permission should be ignored"
    );
  }
}

add_task(async function setup() {
  await ExtensionTestUtils.startAddonManager();
});

add_task(async function test_regular_addon() {
  AddonTestUtils.usePrivilegedSignatures = false;
  await testLoadManifest({
    expectPrivileged: false,
  });
});

add_task(async function test_privileged_signature() {
  AddonTestUtils.usePrivilegedSignatures = true;
  await testLoadManifest({
    expectPrivileged: true,
  });
});

add_task(async function test_system_signature() {
  AddonTestUtils.usePrivilegedSignatures = "system";
  await testLoadManifest({
    expectPrivileged: true,
  });
});

add_task(async function test_builtin_location() {
  AddonTestUtils.usePrivilegedSignatures = false;
  await testLoadManifest({
    expectPrivileged: true,
    location: getInstallLocation({ isBuiltin: true }),
  });
});

add_task(async function test_system_location() {
  AddonTestUtils.usePrivilegedSignatures = false;
  await testLoadManifest({
    expectPrivileged: false,
    location: getInstallLocation({ isSystem: true }),
  });
});

add_task(async function test_builtin_system_location() {
  AddonTestUtils.usePrivilegedSignatures = false;
  await testLoadManifest({
    expectPrivileged: true,
    location: getInstallLocation({ isSystem: true, isBuiltin: true }),
  });
});

add_task(async function test_temporary_regular() {
  AddonTestUtils.usePrivilegedSignatures = false;
  Services.prefs.setBoolPref("extensions.experiments.enabled", false);
  await testLoadManifest({
    expectPrivileged: false,
    location: getInstallLocation({ isTemporary: true }),
  });
});

add_task(async function test_temporary_privileged_signature() {
  AddonTestUtils.usePrivilegedSignatures = true;
  Services.prefs.setBoolPref("extensions.experiments.enabled", false);
  await testLoadManifest({
    expectPrivileged: true,
    location: getInstallLocation({ isTemporary: true }),
  });
});

add_task(async function test_temporary_experiments_enabled() {
  AddonTestUtils.usePrivilegedSignatures = false;
  Services.prefs.setBoolPref("extensions.experiments.enabled", true);

  // Experiments can only be used if AddonSettings.EXPERIMENTS_ENABLED is true.
  // This is the condition behind the flag, minus Cu.isInAutomation. Currently
  // that flag is false despite this being a test (see bug 1598804), but that
  // is desired in this case because we want the test to confirm the real-world
  // behavior instead of test-specific behavior.
  const areTemporaryExperimentsAllowed =
    !AppConstants.MOZ_REQUIRE_SIGNING ||
    AppConstants.NIGHTLY_BUILD ||
    AppConstants.MOZ_DEV_EDITION;

  await testLoadManifest({
    expectPrivileged: areTemporaryExperimentsAllowed,
    location: getInstallLocation({ isTemporary: true }),
  });
});