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/util.js");
Function.prototype.async = generatorAsync;
function WeaveCrypto() {
this._init();
}
@ -60,14 +62,14 @@ WeaveCrypto.prototype = {
return this.__os;
},
__xxxtea: {},
__xxxteaLoaded: false,
get _xxxtea() {
if (!this.__xxxteaLoaded) {
Cu.import("resource://weave/xxxtea.js", this.__xxxtea);
this.__xxxteaLoaded = true;
__xxtea: {},
__xxteaLoaded: false,
get _xxtea() {
if (!this.__xxteaLoaded) {
Cu.import("resource://weave/xxtea.js", this.__xxtea);
this.__xxteaLoaded = true;
}
return this.__xxxtea;
return this.__xxtea;
},
get defaultAlgorithm() {
@ -108,12 +110,13 @@ WeaveCrypto.prototype = {
case "none":
this._log.info("Encryption disabled");
break;
case "XXXTEA":
case "XXTEA":
case "XXXTEA": // Weave 0.1 had this typo
this._log.info("Using encryption algorithm: " + data);
break;
default:
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
}
// FIXME: listen to this bad boy somewhere
@ -126,59 +129,85 @@ WeaveCrypto.prototype = {
// Crypto
PBEencrypt: function Crypto_PBEencrypt(data, identity, algorithm) {
if (!algorithm)
algorithm = this.defaultAlgorithm;
PBEencrypt: function Crypto_PBEencrypt(onComplete, data, identity, algorithm) {
let [self, cont] = yield;
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 {
this._log.debug("Encrypting data");
if (!algorithm)
algorithm = this.defaultAlgorithm;
switch (algorithm) {
case "XXXTEA":
out = this._xxxtea.encrypt(data, identity.password);
case "none":
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;
default:
throw "Unknown encryption algorithm: " + algorithm;
}
this._log.debug("Done encrypting data");
} catch (e) {
this._log.error("Data encryption failed: " + e);
throw 'encrypt failed';
this._log.error("Exception caught: " + (e.message? e.message : e));
} 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) {
if (!algorithm)
algorithm = this.defaultAlgorithm;
PBEdecrypt: function Crypto_PBEdecrypt(onComplete, data, identity, algorithm) {
let [self, cont] = yield;
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 {
this._log.debug("Decrypting data");
if (!algorithm)
algorithm = this.defaultAlgorithm;
switch (algorithm) {
case "XXXTEA":
out = this._xxxtea.decrypt(data, identity.password);
case "none":
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;
default:
throw "Unknown encryption algorithm: " + algorithm;
}
this._log.debug("Done decrypting data");
} catch (e) {
this._log.error("Data decryption failed: " + e);
throw 'decrypt failed';
this._log.error("Exception caught: " + (e.message? e.message : e));
} 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;
for (key in headers) {
if (key == 'Authentication')
if (key == 'Authorization')
this._log.debug("HTTP Header " + key + ": ***** (suppressed)");
else
this._log.debug("HTTP Header " + key + ": " + headers[key]);

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

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

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

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

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

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