Skip to content

Commit bdcf8fb

Browse files
author
redwire
committed
Making changes to appease the mentor gods
1 parent fd6e4bd commit bdcf8fb

File tree

1 file changed

+70
-48
lines changed

1 file changed

+70
-48
lines changed

src/chrome/content/code/RulesetUpdater.js

Lines changed: 70 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
/* Hardcoded public key used to verify the signature over the update data */
1818
const RULESET_UPDATE_KEY = '';
1919

20-
/* extension release branch preference key */
20+
/* extension release branch pereference key */
2121
const BRANCH_PREF = 'extensions.https_everywhere.branch_name';
2222

2323
/* extension release version preference key */
@@ -74,8 +74,9 @@ function fetchUpdate() {
7474
function conditionallyApplyUpdate(update) {
7575
https_everywhereLog(INFO, "Got update data:");
7676
https_everywhereLog(INFO, update);
77+
var em = Cc['@mozilla.org/extensions/manager;1'].getService(Ci.nsIExtensionManager);
7778
var updateObj = JSON.parse(update);
78-
var extVersion = _prefs.getCharPref(VERSION_PREF);
79+
var extVersion = em.getItemForID("https-everywhere@eff.org").version;
7980
var extBranch = _prefs.getCharPref(BRANCH_PREF);
8081
var rulesetVersion = _prefs.getCharPref(RULESET_VERSION_PREF);
8182
https_everywhereLog(INFO, "Inside call to conditionallyApplyUpdate");
@@ -94,7 +95,7 @@ function conditionallyApplyUpdate(update) {
9495
https_everywhereLog(INFO, "Successfully fetched update.json.sig file data");
9596
if (verifyUpdateSignature(update, signature)) {
9697
https_everywhereLog(INFO, "Ruleset update data signature verified successfully");
97-
fetchRulesetDBFile(updateObj.source, updateObj.hashfn, updateObj.hash);
98+
fetchVerifyAndApplyDBFile(updateObj.source, updateObj.version, updateObj.hashfn, updateObj.hash);
9899
} else {
99100
https_everywhereLog(WARN, 'Validation of the update signature provided failed.');
100101
// TODO
@@ -145,19 +146,24 @@ function checkVersionRequirements(extVersion, rsVersion, newVersion) {
145146
* @return string - The hex-encoded hash of the file's contents.
146147
*/
147148
function hashBinaryFile(path, length, hashfn) {
149+
var READONLY = 0x01;
150+
var READ_PERMISSIONS = 0444;
151+
var NOFLAGS = 0;
148152
var f = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsILocalFile);
149153
var istream = Cc['@mozilla.org/network/file-input-stream;1']
150154
.createInstance(Ci.nsIFileInputStream);
151155
var binaryIn = Cc['@mozilla.org/binaryinputstream;1'].createInstance(Ci.nsIBinaryInputStream);
152156
var hashing = Cc['@mozilla.org/security/hash;1'].createInstance(Ci.nsICryptoHash);
153-
if (hashfn === 'md5') hashing.init(hashing.MD5);
154-
else if (hashfn === 'sha1') hashing.init(hashing.SHA1);
155-
else if (hashfn === 'sha256') hashing.init(hashing.SHA256);
156-
else if (hashfn === 'sha384') hashing.init(hashing.SHA384);
157-
else if (hashfn === 'sha512') hashing.init(hashing.SHA512);
158-
else return null; // It's a better idea to fail than do the wrong thing here.
157+
switch (hashfn) {
158+
case 'md5': hashing.init(hashing.MD5); break;
159+
case 'sha1': hashing.init(hashing.SHA1); break;
160+
case 'sha256': hashing.init(hashing.SHA256); break;
161+
case 'sha384': hashing.init(hashing.SHA384); break;
162+
case 'sha512': hashing.init(hashing.SHA512); break;
163+
default: return '';
164+
}
159165
f.initWithPath(path);
160-
istream.init(f, 0x01, 0444, 0);
166+
istream.init(f, READONLY, READ_PERMISSIONS, NOFLAGS);
161167
binaryIn.setInputStream(istream);
162168
hashing.updateFromStream(binaryIn, length);
163169
var hash = hashing.finish(false); // Get binary data back
@@ -172,51 +178,66 @@ function hashBinaryFile(path, length, hashfn) {
172178
* matches what update.json says it should be, and then makes the call to apply the new
173179
* rulesets database.
174180
*
175-
* @param url - The URL from which to fetch the new rulesets database file.
176-
* @param hashfn - The name of the hash function to use when hashingthe database file.
177-
* @param hash - The hash provided by update.json.
181+
* @param url - The URL from which to fetch the new rulesets database file.
182+
* @param version - The ruleset version (eg: 5.0.0.1).
183+
* @param hashfn - The name of the hash function to use when hashingthe database file.
184+
* @param hash - The hash provided by update.json.
178185
*/
179-
function fetchRulesetDBFile(url, hashfn, hash) {
180-
https_everywhereLog(INFO, "Making request to get database file at " + url);
181-
var xhr = Cc['@mozilla.org/xmlextras/xmlhttprequest;1'].createInstance(Ci.nsIXMLHttpRequest);
182-
xhr.open("GET", url, true);
183-
xhr.responseType = 'arraybuffer';
184-
xhr.onload = function(evt) {
185-
var arrayBuffer = xhr.response;
186-
if (arrayBuffer) {
187-
var byteArray = new Uint8Array(arrayBuffer);
188-
https_everywhereLog(INFO, "byteArray has length " + byteArray.length);
189-
var file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsILocalFile);
190-
var outstream = Cc['@mozilla.org/network/file-output-stream;1']
191-
.createInstance(Ci.nsIFileOutputStream);
192-
var binout = Cc['@mozilla.org/binaryoutputstream;1'].createInstance(Ci.nsIBinaryOutputStream);
193-
file.initWithPath(TMP_RULESET_DBFILE_PATH);
194-
outstream.init(file, -1, -1, 0);
195-
binout.setOutputStream(outstream);
196-
binout.writeByteArray(byteArray, byteArray.length);
197-
outstream.close();
198-
dbHash = hashBinaryFile(TMP_RULESET_DBFILE_PATH, byteArray.length, hashfn);
199-
https_everywhereLog(INFO, "dbhash = " + dbHash);
200-
if (dbHash === hash) {
201-
https_everywhereLog(INFO,
202-
'Hash of database file downloaded matches the hash provided by update.json');
203-
applyNewRuleset();
186+
function fetchVerifyAndApplyDBFile(url, version, hashfn, hash) {
187+
var DEFAULT_PERMISSIONS = -1;
188+
var NOFLAGS = 0;
189+
(function recur(max_times) {
190+
https_everywhereLog(INFO, "Making request to get database file at " + url);
191+
var xhr = Cc['@mozilla.org/xmlextras/xmlhttprequest;1'].createInstance(Ci.nsIXMLHttpRequest);
192+
xhr.open("GET", url, true);
193+
xhr.responseType = 'arraybuffer';
194+
xhr.onload = function(evt) {
195+
var arrayBuffer = xhr.response;
196+
if (arrayBuffer) {
197+
var byteArray = new Uint8Array(arrayBuffer);
198+
https_everywhereLog(INFO, "byteArray has length " + byteArray.length);
199+
var file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsILocalFile);
200+
var outstream = Cc['@mozilla.org/network/file-output-stream;1']
201+
.createInstance(Ci.nsIFileOutputStream);
202+
var binout = Cc['@mozilla.org/binaryoutputstream;1'].createInstance(Ci.nsIBinaryOutputStream);
203+
file.initWithPath(TMP_RULESET_DBFILE_PATH);
204+
outstream.init(file, DEFAULT_PERMISSIONS, DEFAULT_PERMISSIONS, NOFLAGS);
205+
binout.setOutputStream(outstream);
206+
binout.writeByteArray(byteArray, byteArray.length);
207+
outstream.close();
208+
var dbHash = hashBinaryFile(TMP_RULESET_DBFILE_PATH, byteArray.length, hashfn);
209+
https_everywhereLog(INFO, "dbhash = " + dbHash);
210+
if (dbHash === hash) {
211+
https_everywhereLog(INFO,
212+
'Hash of database file downloaded matches the hash provided by update.json');
213+
applyNewRuleset(version);
214+
} else {
215+
https_everywhereLog(INFO, 'Hash of database file did not match the one in update.json');
216+
if (max_times > 0) { // Strict limit test
217+
recur(max_times - 1);
218+
}
219+
// TODO: Ping EFF URL to report authenticity verification failure
220+
}
204221
} else {
205-
https_everywhereLog(INFO, 'Hash of database file did not match the one in update.json');
206-
// TODO: Ping EFF URL to report authenticity verification failure
222+
https_everywhereLog(INFO, 'Did not download any database data');
223+
if (max_times > 0) { // Strict limit test
224+
recur(max_times - 1);
225+
}
226+
// TODO: Ping EFF URL to report download failure
207227
}
208-
} else {
209-
https_everywhereLog(INFO, 'Did not download any database data');
210-
// TODO: Ping EFF URL to report download failure
211-
}
212-
};
213-
xhr.send(null);
228+
};
229+
xhr.send(null);
230+
})(MAX_RSUPDATE_FETCHES);
214231
}
215232

216233
/* Moves the downloaded rulesets database into a permanent location and reinitializes
217234
* HTTPSRules to use the rulesets.
235+
*
236+
* @param version - The ruleset version.
218237
*/
219-
function applyNewRuleset() {
238+
function applyNewRuleset(version) {
239+
var DIRECTORY_TYPE = 1;
240+
var DIRECTORY_PERMISSIONS = 0777;
220241
https_everywhereLog(INFO, 'In applyNewRuleset');
221242
var updatedPath = HTTPSEverywhere.instance.UPDATED_RULESET_DBFILE_PATH();
222243
var permFile = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsILocalFile);
@@ -229,14 +250,15 @@ function applyNewRuleset() {
229250
permFile.remove(false);
230251
https_everywhereLog(INFO, 'Removed existing updated database file');
231252
} else if (!permParent.exists()) {
232-
permParent.create(1, 0777);
253+
permParent.create(DIRECTORY_TYPE, DIRECTORY_PERMISSIONS);
233254
https_everywhereLog(INFO, 'Created directory for downloaded ruleset database files');
234255
}
235256
tempFile.moveTo(
236257
permParent,
237258
OS.Path.basename(updatedPath));
238259
https_everywhereLog(INFO, 'Copied new database file to permanent location');
239260
HTTPSRules.init();
261+
_prefs.setCharPref(RULESET_VERSION_PREF, version);
240262
https_everywhereLog(INFO, 'Reinitialized HTTPSRules with new database');
241263
}
242264

0 commit comments

Comments
 (0)