Make {en,de}cryption asynchronous so as to not block the UI; fix 'xxxtea' typos (it's xxtea); fix auth header suppression

This commit is contained in:
Dan Mills 2007-12-26 17:40:46 -08:00
Родитель 4712164e73
Коммит 74fa881759
5 изменённых файлов: 100 добавлений и 59 удалений

Просмотреть файл

@ -46,6 +46,8 @@ Cu.import("resource://weave/log4moz.js");
Cu.import("resource://weave/constants.js"); Cu.import("resource://weave/constants.js");
Cu.import("resource://weave/util.js"); Cu.import("resource://weave/util.js");
Function.prototype.async = generatorAsync;
function WeaveCrypto() { function WeaveCrypto() {
this._init(); this._init();
} }
@ -60,14 +62,14 @@ WeaveCrypto.prototype = {
return this.__os; return this.__os;
}, },
__xxxtea: {}, __xxtea: {},
__xxxteaLoaded: false, __xxteaLoaded: false,
get _xxxtea() { get _xxtea() {
if (!this.__xxxteaLoaded) { if (!this.__xxteaLoaded) {
Cu.import("resource://weave/xxxtea.js", this.__xxxtea); Cu.import("resource://weave/xxtea.js", this.__xxtea);
this.__xxxteaLoaded = true; this.__xxteaLoaded = true;
} }
return this.__xxxtea; return this.__xxtea;
}, },
get defaultAlgorithm() { get defaultAlgorithm() {
@ -108,12 +110,13 @@ WeaveCrypto.prototype = {
case "none": case "none":
this._log.info("Encryption disabled"); this._log.info("Encryption disabled");
break; break;
case "XXXTEA": case "XXTEA":
case "XXXTEA": // Weave 0.1 had this typo
this._log.info("Using encryption algorithm: " + data); this._log.info("Using encryption algorithm: " + data);
break; break;
default: default:
this._log.warn("Unknown encryption algorithm, resetting"); this._log.warn("Unknown encryption algorithm, resetting");
branch.setCharPref("extensions.weave.encryption", "XXXTEA"); branch.setCharPref("extensions.weave.encryption", "XXTEA");
return; // otherwise we'll send the alg changed event twice return; // otherwise we'll send the alg changed event twice
} }
// FIXME: listen to this bad boy somewhere // FIXME: listen to this bad boy somewhere
@ -126,59 +129,85 @@ WeaveCrypto.prototype = {
// Crypto // Crypto
PBEencrypt: function Crypto_PBEencrypt(data, identity, algorithm) { PBEencrypt: function Crypto_PBEencrypt(onComplete, data, identity, algorithm) {
if (!algorithm) let [self, cont] = yield;
algorithm = this.defaultAlgorithm; let listener = new EventListener(cont);
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
let ret;
if (algorithm == "none") // check to skip the 'encrypting data' log msgs
return data;
let out;
try { try {
this._log.debug("Encrypting data"); if (!algorithm)
algorithm = this.defaultAlgorithm;
switch (algorithm) { switch (algorithm) {
case "XXXTEA": case "none":
out = this._xxxtea.encrypt(data, identity.password); ret = data;
case "XXTEA":
case "XXXTEA": // Weave 0.1.12.10 and below had this typo
this._log.debug("Encrypting data");
let gen = this._xxtea.encrypt(data, identity.password);
ret = gen.next();
while (typeof(ret) == "object") {
timer.initWithCallback(listener, 0, timer.TYPE_ONE_SHOT);
yield; // Yield to main loop
ret = gen.next();
}
gen.close();
this._log.debug("Done encrypting data");
break; break;
default: default:
throw "Unknown encryption algorithm: " + algorithm; throw "Unknown encryption algorithm: " + algorithm;
} }
this._log.debug("Done encrypting data");
} catch (e) { } catch (e) {
this._log.error("Data encryption failed: " + e); this._log.error("Exception caught: " + (e.message? e.message : e));
throw 'encrypt failed';
} finally {
timer = null;
generatorDone(this, self, onComplete, ret);
yield; // onComplete is responsible for closing the generator
} }
return out; this._log.warn("generator not properly closed");
}, },
PBEdecrypt: function Crypto_PBEdecrypt(data, identity, algorithm) { PBEdecrypt: function Crypto_PBEdecrypt(onComplete, data, identity, algorithm) {
if (!algorithm) let [self, cont] = yield;
algorithm = this.defaultAlgorithm; let listener = new EventListener(cont);
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
let ret;
if (algorithm == "none") // check to skip the 'decrypting data' log msgs
return data;
let out;
try { try {
this._log.debug("Decrypting data"); if (!algorithm)
algorithm = this.defaultAlgorithm;
switch (algorithm) { switch (algorithm) {
case "XXXTEA": case "none":
out = this._xxxtea.decrypt(data, identity.password); ret = data;
case "XXTEA":
case "XXXTEA": // Weave 0.1.12.10 and below had this typo
this._log.debug("Decrypting data");
let gen = this._xxtea.decrypt(data, identity.password);
ret = gen.next();
while (typeof(ret) == "object") {
timer.initWithCallback(listener, 0, timer.TYPE_ONE_SHOT);
yield; // Yield to main loop
ret = gen.next();
}
gen.close();
this._log.debug("Done decrypting data");
break; break;
default: default:
throw "Unknown encryption algorithm: " + algorithm; throw "Unknown encryption algorithm: " + algorithm;
} }
this._log.debug("Done decrypting data");
} catch (e) { } catch (e) {
this._log.error("Data decryption failed: " + e); this._log.error("Exception caught: " + (e.message? e.message : e));
throw 'decrypt failed';
} finally {
timer = null;
generatorDone(this, self, onComplete, ret);
yield; // onComplete is responsible for closing the generator
} }
return out; this._log.warn("generator not properly closed");
} }
}; };

Просмотреть файл

@ -105,7 +105,7 @@ DAVCollection.prototype = {
let key; let key;
for (key in headers) { for (key in headers) {
if (key == 'Authentication') if (key == 'Authorization')
this._log.debug("HTTP Header " + key + ": ***** (suppressed)"); this._log.debug("HTTP Header " + key + ": ***** (suppressed)");
else else
this._log.debug("HTTP Header " + key + ": " + headers[key]); this._log.debug("HTTP Header " + key + ": " + headers[key]);

Просмотреть файл

@ -387,8 +387,10 @@ Engine.prototype = {
this._log.error("Could not upload files to server"); // eep? this._log.error("Could not upload files to server"); // eep?
} else { } else {
let data = Crypto.PBEencrypt(serializeCommands(server.deltas), Crypto.PBEencrypt.async(Crypto, cont,
this._cryptoId); serializeCommands(server.deltas),
this._cryptoId);
let data = yield;
this._dav.PUT(this.deltasFile, data, cont); this._dav.PUT(this.deltasFile, data, cont);
let deltasPut = yield; let deltasPut = yield;
@ -519,18 +521,22 @@ Engine.prototype = {
this._dav.GET(this.snapshotFile, cont); this._dav.GET(this.snapshotFile, cont);
resp = yield; resp = yield;
this._checkStatus(resp.status, "Could not download snapshot."); this._checkStatus(resp.status, "Could not download snapshot.");
let data = Crypto.PBEdecrypt(resp.responseText, Crypto.PBEdecrypt.async(Crypto, cont,
this._cryptoId, resp.responseText,
status.snapEncryption); this._cryptoId,
status.snapEncryption);
let data = yield;
snap.data = eval(data); snap.data = eval(data);
this._log.info("Downloading server deltas"); this._log.info("Downloading server deltas");
this._dav.GET(this.deltasFile, cont); this._dav.GET(this.deltasFile, cont);
resp = yield; resp = yield;
this._checkStatus(resp.status, "Could not download deltas."); this._checkStatus(resp.status, "Could not download deltas.");
data = Crypto.PBEdecrypt(resp.responseText, Crypto.PBEdecrypt.async(Crypto, cont,
this._cryptoId, resp.responseText,
status.deltasEncryption); this._cryptoId,
status.deltasEncryption);
data = yield;
allDeltas = eval(data); allDeltas = eval(data);
deltas = eval(data); deltas = eval(data);
@ -542,9 +548,11 @@ Engine.prototype = {
this._dav.GET(this.deltasFile, cont); this._dav.GET(this.deltasFile, cont);
resp = yield; resp = yield;
this._checkStatus(resp.status, "Could not download deltas."); this._checkStatus(resp.status, "Could not download deltas.");
let data = Crypto.PBEdecrypt(resp.responseText, Crypto.PBEdecrypt.async(Crypto, cont,
this._cryptoId, resp.responseText,
status.deltasEncryption); this._cryptoId,
status.deltasEncryption);
let data = yield;
allDeltas = eval(data); allDeltas = eval(data);
deltas = allDeltas.slice(this._snapshot.version - status.snapVersion); deltas = allDeltas.slice(this._snapshot.version - status.snapVersion);
@ -556,9 +564,11 @@ Engine.prototype = {
this._dav.GET(this.deltasFile, cont); this._dav.GET(this.deltasFile, cont);
resp = yield; resp = yield;
this._checkStatus(resp.status, "Could not download deltas."); this._checkStatus(resp.status, "Could not download deltas.");
let data = Crypto.PBEdecrypt(resp.responseText, Crypto.PBEdecrypt.async(Crypto, cont,
this._cryptoId, resp.responseText,
status.deltasEncryption); this._cryptoId,
status.deltasEncryption);
let data = yield;
allDeltas = eval(data); allDeltas = eval(data);
deltas = []; deltas = [];
@ -632,8 +642,10 @@ Engine.prototype = {
let ret = false; let ret = false;
try { try {
let data = Crypto.PBEencrypt(this._snapshot.serialize(), Crypto.PBEencrypt.async(Crypto, cont,
this._cryptoId); this._snapshot.serialize(),
this._cryptoId);
let data = yield;
this._dav.PUT(this.snapshotFile, data, cont); this._dav.PUT(this.snapshotFile, data, cont);
resp = yield; resp = yield;
this._checkStatus(resp.status, "Could not upload snapshot."); this._checkStatus(resp.status, "Could not upload snapshot.");

Просмотреть файл

@ -141,7 +141,7 @@ SyncCore.prototype = {
}); });
} catch (e) { } catch (e) {
this._log.error("Exception caught: " + e.message); this._log.error("Exception caught: " + (e.message? e.message : e));
} finally { } finally {
timer = null; timer = null;
@ -297,7 +297,7 @@ SyncCore.prototype = {
ret = {propagations: propagations, conflicts: conflicts}; ret = {propagations: propagations, conflicts: conflicts};
} catch (e) { } catch (e) {
this._log.error("Exception caught: " + e.message); this._log.error("Exception caught: " + (e.message? e.message : e));
} finally { } finally {
timer = null; timer = null;

Просмотреть файл

@ -8,4 +8,4 @@ pref("extensions.weave.bookmarks", true);
pref("extensions.weave.history", true); pref("extensions.weave.history", true);
pref("extensions.weave.schedule", 1); pref("extensions.weave.schedule", 1);
pref("extensions.weave.lastsync", "0"); pref("extensions.weave.lastsync", "0");
pref("extensions.weave.encryption", "XXXTEA"); pref("extensions.weave.encryption", "XXTEA");