mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Backed out changeset 1da29f893381 (bug 1328718) for win7pgo xperf failures a=backout
MozReview-Commit-ID: 9ZEMF0QqM9v
This commit is contained in:
parent
d4e290db24
commit
d474766ce1
@ -1,99 +0,0 @@
|
||||
This system add-on is a follow-up to the MITM prevalence experiment. The purpose
|
||||
is to facilitate rolling out the disabling of SHA-1 in signatures on
|
||||
certificates issued by publicly-trusted roots. When installed, this add-on will
|
||||
perform a number of checks to determine if it should change the preference that
|
||||
controls the SHA-1 policy. First, this should only apply to users on the beta
|
||||
update channel. It should also only apply to users who have not otherwise
|
||||
changed the policy to always allow or always forbid SHA-1. Additionally, it
|
||||
must double-check that the user is not affected by a TLS intercepting proxy
|
||||
using a publicly-trusted root. If these checks pass, the add-on will divide the
|
||||
population into a test group and a control group (starting on a 10%/90% split).
|
||||
The test group will have the policy changed. After doing this, a telemetry
|
||||
payload is reported with the following values:
|
||||
|
||||
* cohortName -- the name of the group this user is in:
|
||||
1. "notSafeToDisableSHA1" if the user is behind a MITM proxy using a
|
||||
publicly-trusted root
|
||||
2. "optedOut" if the user already set the SHA-1 policy to always allow or
|
||||
always forbid
|
||||
3. "optedIn" if the user already set the SHA-1 policy to only allow for
|
||||
non-built-in roots
|
||||
4. "test" if the user is in the test cohort (and SHA-1 will be disabled)
|
||||
5. "control" if the user is not in the test cohort
|
||||
* errorCode -- 0 for successful connections, some PR error code otherwise
|
||||
* error -- a short description of one of four error conditions encountered, if
|
||||
applicable, and an empty string otherwise:
|
||||
1. "timeout" if the connection to telemetry.mozilla.org timed out
|
||||
2. "user override" if the user has stored a permanent certificate exception
|
||||
override for telemetry.mozilla.org (due to technical limitations, we can't
|
||||
gather much information in this situation)
|
||||
3. "certificate reverification" if re-building the certificate chain after
|
||||
connecting failed for some reason (unfortunately this step is necessary
|
||||
due to technical limitations)
|
||||
4. "connection error" if the connection to telemetry.mozilla.org failed for
|
||||
another reason
|
||||
* chain -- a list of dictionaries each corresponding to a certificate in the
|
||||
verified certificate chain, if it was successfully constructed. The first
|
||||
entry is the end-entity certificate. The last entry is the root certificate.
|
||||
This will be empty if the connection failed or if reverification failed. Each
|
||||
element in the list contains the following values:
|
||||
* sha256Fingerprint -- a hex string representing the SHA-256 hash of the
|
||||
certificate
|
||||
* isBuiltInRoot -- true if the certificate is a trust anchor in the web PKI,
|
||||
false otherwise
|
||||
* signatureAlgorithm -- a description of the algorithm used to sign the
|
||||
certificate. Will be one of "md2WithRSAEncryption", "md5WithRSAEncryption",
|
||||
"sha1WithRSAEncryption", "sha256WithRSAEncryption",
|
||||
"sha384WithRSAEncryption", "sha512WithRSAEncryption", "ecdsaWithSHA1",
|
||||
"ecdsaWithSHA224", "ecdsaWithSHA256", "ecdsaWithSHA384", "ecdsaWithSHA512",
|
||||
or "unknown".
|
||||
* disabledSHA1 -- true if SHA-1 was disabled, false otherwise
|
||||
* didNotDisableSHA1Because -- a short string describing why SHA-1 could not be
|
||||
disabled, if applicable. Reasons are limited to:
|
||||
1. "MITM" if the user is behind a TLS intercepting proxy using a
|
||||
publicly-trusted root
|
||||
2. "connection error" if there was an error connecting to
|
||||
telemetry.mozilla.org
|
||||
3. "code error" if some inconsistent state was detected, and it was
|
||||
determined that the experiment should not attempt to change the
|
||||
preference
|
||||
4. "preference:userReset" if the user reset the SHA-1 policy after it had
|
||||
been changed by this add-on
|
||||
5. "preference:allow" if the user had already configured Firefox to always
|
||||
accept SHA-1 signatures
|
||||
6. "preference:forbid" if the user had already configured Firefox to always
|
||||
forbid SHA-1 signatures
|
||||
|
||||
For a connection not intercepted by a TLS proxy and where the user is in the
|
||||
test cohort, the expected result will be:
|
||||
|
||||
{ "cohortName": "test",
|
||||
"errorCode": 0,
|
||||
"error": "",
|
||||
"chain": [
|
||||
{ "sha256Fingerprint": "197feaf3faa0f0ad637a89c97cb91336bfc114b6b3018203cbd9c3d10c7fa86c",
|
||||
"isBuiltInRoot": false,
|
||||
"signatureAlgorithm": "sha256WithRSAEncryption"
|
||||
},
|
||||
{ "sha256Fingerprint": "154c433c491929c5ef686e838e323664a00e6a0d822ccc958fb4dab03e49a08f",
|
||||
"isBuiltInRoot": false,
|
||||
"signatureAlgorithm": "sha256WithRSAEncryption"
|
||||
},
|
||||
{ "sha256Fingerprint": "4348a0e9444c78cb265e058d5e8944b4d84f9662bd26db257f8934a443c70161",
|
||||
"isBuiltInRoot": true,
|
||||
"signatureAlgorithm": "sha1WithRSAEncryption"
|
||||
}
|
||||
],
|
||||
"disabledSHA1": true,
|
||||
"didNotDisableSHA1Because": ""
|
||||
}
|
||||
|
||||
When this result is encountered, the user's preferences are updated to disable
|
||||
SHA-1 in signatures on certificates issued by publicly-trusted roots.
|
||||
Similarly, if the user is behind a TLS intercepting proxy but the root
|
||||
certificate is not part of the public web PKI, we can also disable SHA-1 in
|
||||
signatures on certificates issued by publicly-trusted roots.
|
||||
|
||||
If the user has already indicated in their preferences that they will always
|
||||
accept SHA-1 in signatures or that they will never accept SHA-1 in signatures,
|
||||
then the preference is not changed.
|
306
browser/extensions/disableSHA1rollout/bootstrap.js
vendored
306
browser/extensions/disableSHA1rollout/bootstrap.js
vendored
@ -1,306 +0,0 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/Preferences.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/UpdateUtils.jsm");
|
||||
Cu.import("resource://gre/modules/TelemetryController.jsm");
|
||||
|
||||
// Percentage of the population to attempt to disable SHA-1 for, by channel.
|
||||
const TEST_THRESHOLD = {
|
||||
beta: 0.1, // 10%
|
||||
};
|
||||
|
||||
const PREF_COHORT_SAMPLE = "disableSHA1.rollout.cohortSample";
|
||||
const PREF_COHORT_NAME = "disableSHA1.rollout.cohort";
|
||||
const PREF_SHA1_POLICY = "security.pki.sha1_enforcement_level";
|
||||
const PREF_SHA1_POLICY_SET_BY_ADDON = "disableSHA1.rollout.policySetByAddOn";
|
||||
const PREF_SHA1_POLICY_RESET_BY_USER = "disableSHA1.rollout.userResetPref";
|
||||
|
||||
const SHA1_MODE_ALLOW = 0;
|
||||
const SHA1_MODE_FORBID = 1;
|
||||
const SHA1_MODE_IMPORTED_ROOTS_ONLY = 3;
|
||||
const SHA1_MODE_CURRENT_DEFAULT = 4;
|
||||
|
||||
function startup() {
|
||||
Preferences.observe(PREF_SHA1_POLICY, policyPreferenceChanged);
|
||||
}
|
||||
|
||||
function install() {
|
||||
let updateChannel = UpdateUtils.getUpdateChannel(false);
|
||||
if (updateChannel in TEST_THRESHOLD) {
|
||||
makeRequest().then(defineCohort).catch((e) => console.error(e));
|
||||
}
|
||||
}
|
||||
|
||||
function policyPreferenceChanged() {
|
||||
let currentPrefValue = Preferences.get(PREF_SHA1_POLICY,
|
||||
SHA1_MODE_CURRENT_DEFAULT);
|
||||
Preferences.reset(PREF_SHA1_POLICY_RESET_BY_USER);
|
||||
if (currentPrefValue == SHA1_MODE_CURRENT_DEFAULT) {
|
||||
Preferences.set(PREF_SHA1_POLICY_RESET_BY_USER, true);
|
||||
}
|
||||
}
|
||||
|
||||
function defineCohort(result) {
|
||||
let userOptedOut = optedOut();
|
||||
let userOptedIn = optedIn();
|
||||
let shouldNotDisableSHA1Because = reasonToNotDisableSHA1(result);
|
||||
let safeToDisableSHA1 = shouldNotDisableSHA1Because.length == 0;
|
||||
let updateChannel = UpdateUtils.getUpdateChannel(false);
|
||||
let testGroup = getUserSample() < TEST_THRESHOLD[updateChannel];
|
||||
|
||||
let cohortName;
|
||||
if (!safeToDisableSHA1) {
|
||||
cohortName = "notSafeToDisableSHA1";
|
||||
} else if (userOptedOut) {
|
||||
cohortName = "optedOut";
|
||||
} else if (userOptedIn) {
|
||||
cohortName = "optedIn";
|
||||
} else if (testGroup) {
|
||||
cohortName = "test";
|
||||
Preferences.ignore(PREF_SHA1_POLICY, policyPreferenceChanged);
|
||||
Preferences.set(PREF_SHA1_POLICY, SHA1_MODE_IMPORTED_ROOTS_ONLY);
|
||||
Preferences.observe(PREF_SHA1_POLICY, policyPreferenceChanged);
|
||||
Preferences.set(PREF_SHA1_POLICY_SET_BY_ADDON, true);
|
||||
} else {
|
||||
cohortName = "control";
|
||||
}
|
||||
Preferences.set(PREF_COHORT_NAME, cohortName);
|
||||
reportTelemetry(result, cohortName, shouldNotDisableSHA1Because,
|
||||
cohortName == "test");
|
||||
}
|
||||
|
||||
function shutdown(data, reason) {
|
||||
Preferences.ignore(PREF_SHA1_POLICY, policyPreferenceChanged);
|
||||
}
|
||||
|
||||
function uninstall() {
|
||||
}
|
||||
|
||||
function getUserSample() {
|
||||
let prefValue = Preferences.get(PREF_COHORT_SAMPLE, undefined);
|
||||
let value = 0.0;
|
||||
|
||||
if (typeof(prefValue) == "string") {
|
||||
value = parseFloat(prefValue, 10);
|
||||
return value;
|
||||
}
|
||||
|
||||
value = Math.random();
|
||||
|
||||
Preferences.set(PREF_COHORT_SAMPLE, value.toString().substr(0, 8));
|
||||
return value;
|
||||
}
|
||||
|
||||
function reportTelemetry(result, cohortName, didNotDisableSHA1Because,
|
||||
disabledSHA1) {
|
||||
result.cohortName = cohortName;
|
||||
result.disabledSHA1 = disabledSHA1;
|
||||
if (cohortName == "optedOut") {
|
||||
let userResetPref = Preferences.get(PREF_SHA1_POLICY_RESET_BY_USER, false);
|
||||
let currentPrefValue = Preferences.get(PREF_SHA1_POLICY,
|
||||
SHA1_MODE_CURRENT_DEFAULT);
|
||||
if (userResetPref) {
|
||||
didNotDisableSHA1Because = "preference:userReset";
|
||||
} else if (currentPrefValue == SHA1_MODE_ALLOW) {
|
||||
didNotDisableSHA1Because = "preference:allow";
|
||||
} else {
|
||||
didNotDisableSHA1Because = "preference:forbid";
|
||||
}
|
||||
}
|
||||
result.didNotDisableSHA1Because = didNotDisableSHA1Because;
|
||||
return TelemetryController.submitExternalPing("disableSHA1rollout", result,
|
||||
{});
|
||||
}
|
||||
|
||||
function optedIn() {
|
||||
let policySetByAddOn = Preferences.get(PREF_SHA1_POLICY_SET_BY_ADDON, false);
|
||||
let currentPrefValue = Preferences.get(PREF_SHA1_POLICY,
|
||||
SHA1_MODE_CURRENT_DEFAULT);
|
||||
return currentPrefValue == SHA1_MODE_IMPORTED_ROOTS_ONLY && !policySetByAddOn;
|
||||
}
|
||||
|
||||
function optedOut() {
|
||||
// Users can also opt-out by setting the policy to always allow or always
|
||||
// forbid SHA-1, or by resetting the preference after this add-on has changed
|
||||
// it (in that case, this will be reported the next time this add-on is
|
||||
// updated).
|
||||
let currentPrefValue = Preferences.get(PREF_SHA1_POLICY,
|
||||
SHA1_MODE_CURRENT_DEFAULT);
|
||||
let userResetPref = Preferences.get(PREF_SHA1_POLICY_RESET_BY_USER, false);
|
||||
return currentPrefValue == SHA1_MODE_ALLOW ||
|
||||
currentPrefValue == SHA1_MODE_FORBID ||
|
||||
userResetPref;
|
||||
}
|
||||
|
||||
function delocalizeAlgorithm(localizedString) {
|
||||
let bundle = Services.strings.createBundle(
|
||||
"chrome://pipnss/locale/pipnss.properties");
|
||||
let algorithmStringIdsToOIDDescriptionMap = {
|
||||
"CertDumpMD2WithRSA": "md2WithRSAEncryption",
|
||||
"CertDumpMD5WithRSA": "md5WithRSAEncryption",
|
||||
"CertDumpSHA1WithRSA": "sha1WithRSAEncryption",
|
||||
"CertDumpSHA256WithRSA": "sha256WithRSAEncryption",
|
||||
"CertDumpSHA384WithRSA": "sha384WithRSAEncryption",
|
||||
"CertDumpSHA512WithRSA": "sha512WithRSAEncryption",
|
||||
"CertDumpAnsiX962ECDsaSignatureWithSha1": "ecdsaWithSHA1",
|
||||
"CertDumpAnsiX962ECDsaSignatureWithSha224": "ecdsaWithSHA224",
|
||||
"CertDumpAnsiX962ECDsaSignatureWithSha256": "ecdsaWithSHA256",
|
||||
"CertDumpAnsiX962ECDsaSignatureWithSha384": "ecdsaWithSHA384",
|
||||
"CertDumpAnsiX962ECDsaSignatureWithSha512": "ecdsaWithSHA512",
|
||||
};
|
||||
|
||||
let description;
|
||||
Object.keys(algorithmStringIdsToOIDDescriptionMap).forEach((l10nID) => {
|
||||
let candidateLocalizedString = bundle.GetStringFromName(l10nID);
|
||||
if (localizedString == candidateLocalizedString) {
|
||||
description = algorithmStringIdsToOIDDescriptionMap[l10nID];
|
||||
}
|
||||
});
|
||||
if (!description) {
|
||||
return "unknown";
|
||||
}
|
||||
return description;
|
||||
}
|
||||
|
||||
function getSignatureAlgorithm(cert) {
|
||||
// Certificate ::= SEQUENCE {
|
||||
// tbsCertificate TBSCertificate,
|
||||
// signatureAlgorithm AlgorithmIdentifier,
|
||||
// signatureValue BIT STRING }
|
||||
let certificate = cert.ASN1Structure.QueryInterface(Ci.nsIASN1Sequence);
|
||||
let signatureAlgorithm = certificate.ASN1Objects
|
||||
.queryElementAt(1, Ci.nsIASN1Sequence);
|
||||
// AlgorithmIdentifier ::= SEQUENCE {
|
||||
// algorithm OBJECT IDENTIFIER,
|
||||
// parameters ANY DEFINED BY algorithm OPTIONAL }
|
||||
|
||||
// If parameters is NULL (or empty), signatureAlgorithm won't be a container
|
||||
// under this implementation. Just get its displayValue.
|
||||
if (!signatureAlgorithm.isValidContainer) {
|
||||
return signatureAlgorithm.displayValue;
|
||||
}
|
||||
let oid = signatureAlgorithm.ASN1Objects.queryElementAt(0, Ci.nsIASN1Object);
|
||||
return oid.displayValue;
|
||||
}
|
||||
|
||||
function processCertChain(chain) {
|
||||
let output = [];
|
||||
let enumerator = chain.getEnumerator();
|
||||
while (enumerator.hasMoreElements()) {
|
||||
let cert = enumerator.getNext().QueryInterface(Ci.nsIX509Cert);
|
||||
output.push({
|
||||
sha256Fingerprint: cert.sha256Fingerprint.replace(/:/g, "").toLowerCase(),
|
||||
isBuiltInRoot: cert.isBuiltInRoot,
|
||||
signatureAlgorithm: delocalizeAlgorithm(getSignatureAlgorithm(cert)),
|
||||
});
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
class CertificateVerificationResult {
|
||||
constructor(resolve) {
|
||||
this.resolve = resolve;
|
||||
}
|
||||
|
||||
verifyCertFinished(aPRErrorCode, aVerifiedChain, aEVStatus) {
|
||||
let result = { errorCode: aPRErrorCode, error: "", chain: [] };
|
||||
if (aPRErrorCode == 0) {
|
||||
result.chain = processCertChain(aVerifiedChain);
|
||||
} else {
|
||||
result.error = "certificate reverification";
|
||||
}
|
||||
this.resolve(result);
|
||||
}
|
||||
}
|
||||
|
||||
function makeRequest() {
|
||||
return new Promise((resolve) => {
|
||||
let hostname = "telemetry.mozilla.org";
|
||||
let req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
|
||||
.createInstance(Ci.nsIXMLHttpRequest);
|
||||
req.open("GET", "https://" + hostname);
|
||||
req.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
|
||||
req.timeout = 30000;
|
||||
req.addEventListener("error", (evt) => {
|
||||
// If we can't connect to telemetry.mozilla.org, then how did we even
|
||||
// download the experiment? In any case, we may still be able to get some
|
||||
// information.
|
||||
let result = { error: "connection error" };
|
||||
if (evt.target.channel && evt.target.channel.securityInfo) {
|
||||
let securityInfo = evt.target.channel.securityInfo
|
||||
.QueryInterface(Ci.nsITransportSecurityInfo);
|
||||
if (securityInfo) {
|
||||
result.errorCode = securityInfo.errorCode;
|
||||
}
|
||||
if (securityInfo && securityInfo.failedCertChain) {
|
||||
result.chain = processCertChain(securityInfo.failedCertChain);
|
||||
}
|
||||
}
|
||||
resolve(result);
|
||||
});
|
||||
req.addEventListener("timeout", (evt) => {
|
||||
resolve({ error: "timeout" });
|
||||
});
|
||||
req.addEventListener("load", (evt) => {
|
||||
let securityInfo = evt.target.channel.securityInfo
|
||||
.QueryInterface(Ci.nsITransportSecurityInfo);
|
||||
if (securityInfo.securityState &
|
||||
Ci.nsIWebProgressListener.STATE_CERT_USER_OVERRIDDEN) {
|
||||
resolve({ error: "user override" });
|
||||
return;
|
||||
}
|
||||
let sslStatus = securityInfo.QueryInterface(Ci.nsISSLStatusProvider)
|
||||
.SSLStatus;
|
||||
let certdb = Cc["@mozilla.org/security/x509certdb;1"]
|
||||
.getService(Ci.nsIX509CertDB);
|
||||
let result = new CertificateVerificationResult(resolve);
|
||||
// Unfortunately, we don't have direct access to the verified certificate
|
||||
// chain as built by the AuthCertificate hook, so we have to re-build it
|
||||
// here. In theory we are likely to get the same result.
|
||||
certdb.asyncVerifyCertAtTime(sslStatus.serverCert,
|
||||
2, // certificateUsageSSLServer
|
||||
0, // flags
|
||||
hostname,
|
||||
Date.now() / 1000,
|
||||
result);
|
||||
});
|
||||
req.send();
|
||||
});
|
||||
}
|
||||
|
||||
// As best we know, it is safe to disable SHA1 if the connection was successful
|
||||
// and either the connection was MITM'd by a root not in the public PKI or the
|
||||
// chain is part of the public PKI and is the one served by the real
|
||||
// telemetry.mozilla.org.
|
||||
// This will return a short string description of why it might not be safe to
|
||||
// disable SHA1 or an empty string if it is safe to disable SHA1.
|
||||
function reasonToNotDisableSHA1(result) {
|
||||
if (!("errorCode" in result) || result.errorCode != 0) {
|
||||
return "connection error";
|
||||
}
|
||||
if (!("chain" in result)) {
|
||||
return "code error";
|
||||
}
|
||||
if (!result.chain[result.chain.length - 1].isBuiltInRoot) {
|
||||
return "";
|
||||
}
|
||||
if (result.chain.length != 3) {
|
||||
return "MITM";
|
||||
}
|
||||
const kEndEntityFingerprint = "197feaf3faa0f0ad637a89c97cb91336bfc114b6b3018203cbd9c3d10c7fa86c";
|
||||
const kIntermediateFingerprint = "154c433c491929c5ef686e838e323664a00e6a0d822ccc958fb4dab03e49a08f";
|
||||
const kRootFingerprint = "4348a0e9444c78cb265e058d5e8944b4d84f9662bd26db257f8934a443c70161";
|
||||
if (result.chain[0].sha256Fingerprint != kEndEntityFingerprint ||
|
||||
result.chain[1].sha256Fingerprint != kIntermediateFingerprint ||
|
||||
result.chain[2].sha256Fingerprint != kRootFingerprint) {
|
||||
return "MITM";
|
||||
}
|
||||
return "";
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
#filter substitution
|
||||
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>disableSHA1rollout@mozilla.org</em:id>
|
||||
<em:version>1.0</em:version>
|
||||
<em:type>2</em:type>
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
<em:multiprocessCompatible>true</em:multiprocessCompatible>
|
||||
|
||||
<!-- Target Application this theme can install into,
|
||||
with minimum and maximum supported versions. -->
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>@MOZ_APP_VERSION@</em:minVersion>
|
||||
<em:maxVersion>@MOZ_APP_MAXVERSION@</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
<!-- Front End MetaData -->
|
||||
<em:name>SHA-1 deprecation staged rollout</em:name>
|
||||
<em:description>Staged rollout deprecating SHA-1 in certificate signatures.</em:description>
|
||||
</Description>
|
||||
</RDF>
|
@ -1,16 +0,0 @@
|
||||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
|
||||
DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION']
|
||||
|
||||
FINAL_TARGET_FILES.features['disableSHA1rollout@mozilla.org'] += [
|
||||
'bootstrap.js'
|
||||
]
|
||||
|
||||
FINAL_TARGET_PP_FILES.features['disableSHA1rollout@mozilla.org'] += [
|
||||
'install.rdf.in'
|
||||
]
|
@ -6,7 +6,6 @@
|
||||
|
||||
DIRS += [
|
||||
'aushelper',
|
||||
'disableSHA1rollout',
|
||||
'e10srollout',
|
||||
'pdfjs',
|
||||
'pocket',
|
||||
|
Loading…
Reference in New Issue
Block a user