--- a/services/sync/modules/service.js
+++ b/services/sync/modules/service.js
@@ -177,16 +177,24 @@ WeaveSvc.prototype = {
},
get password() { return ID.get('WeaveID').password; },
set password(value) { ID.get('WeaveID').password = value; },
get passphrase() { return ID.get('WeaveCryptoID').password; },
set passphrase(value) { ID.get('WeaveCryptoID').password = value; },
+ // chrome-provided callbacks for when the service needs a password/passphrase
+ set onGetPassword(value) {
+ ID.get('WeaveID').onGetPassword = value;
+ },
+ set onGetPassphrase(value) {
+ ID.get('WeaveCryptoID').onGetPassword = value;
+ },
+
get baseURL() {
let url = Utils.prefs.getCharPref("serverURL");
if (url && url[url.length-1] != '/')
url = url + '/';
return url;
},
set baseURL(value) {
Utils.prefs.setCharPref("serverURL", value);
@@ -291,17 +299,18 @@ WeaveSvc.prototype = {
// Create Weave identities (for logging in, and for encryption)
ID.set('WeaveID', new Identity('Mozilla Services Password', this.username));
Auth.defaultAuthenticator = new BasicAuthenticator(ID.get('WeaveID'));
ID.set('WeaveCryptoID',
new Identity('Mozilla Services Encryption Passphrase', this.username));
let url = this.baseURL + this.username;
- PubKeys.defaultKeyUri = url + "keys/pubkey";
+ PubKeys.defaultKeyUri = url + "/keys/pubkey";
+ PrivKeys.defaultKeyUri = url + "/keys/privkey";
if (Utils.prefs.getBoolPref("autoconnect") &&
this.username && this.username != 'nobody')
try {
yield this.login(self.cb);
yield this.sync(self.cb);
} catch (e) {}
self.done();
@@ -484,21 +493,66 @@ WeaveSvc.prototype = {
let cb = function WeaveSvc_serverWipeCb() {
let self = yield;
this._log.error("Server wipe not supported");
this.logout();
};
this._notify("server-wipe", "", this._localLock(cb)).async(this, onComplete);
},
+ // stuff we need to to after login, before we can really do
+ // anything (e.g. key setup)
+ _remoteSetup: function WeaveSvc__remoteSetup() {
+ let self = yield;
+ let ret = false; // false to abort sync
+
+ // FIXME: too easy to generate a keypair. we should be absolutely certain
+ // that the keys are not there (404) and that it's not some other
+ // transient network problem instead
+ let needKeys = true;
+ let pubkey = yield PubKeys.getDefaultKey(self.cb);
+ if (pubkey) {
+ // make sure we have a matching privkey
+ let privkey = yield PrivKeys.get(self.cb, pubkey.privateKeyUri);
+ if (privkey) {
+ needKeys = false;
+ ret = true;
+ }
+ }
+
+ if (needKeys) {
+ let pass = yield ID.get('WeaveCryptoID').getPassword(self.cb);
+ if (pass) {
+ let keys = PubKeys.createKeypair(pass, PubKeys.defaultKeyUri,
+ PrivKeys.defaultKeyUri);
+ try {
+ yield keys.pubkey.put(self.cb);
+ yield keys.privkey.put(self.cb);
+ ret = true;
+ } catch (e) {
+ this._log.error("Could not upload keys: " + Utils.exceptionStr(e));
+ this._log.error(keys.pubkey.lastRequest.responseText);
+ }
+ } else {
+ this._log.warn("Could not get encryption passphrase");
+ }
+ }
+
+ self.done(ret);
+ },
+
// These are per-engine
_sync: function WeaveSvc__sync() {
let self = yield;
+ if (!(yield this._remoteSetup.async(this, self.cb))) {
+ throw "aborting sync, remote setup failed";
+ }
+
//this._log.debug("Refreshing client list");
//yield ClientData.refresh(self.cb);
let engines = Engines.getAll();
for (let i = 0; i < engines.length; i++) {
if (this.cancelRequested)
continue;