re-encrypt the mailbox field when changing a pad password

pull/1/head
yflory 5 years ago
parent 0a5bf7a5c2
commit bb0365622b

@ -779,7 +779,7 @@ define([
}); });
}; };
common.changePadPassword = function (Crypt, href, newPassword, edPublic, cb) { common.changePadPassword = function (Crypt, Crypto, href, newPassword, edPublic, cb) {
if (!href) { return void cb({ error: 'EINVAL_HREF' }); } if (!href) { return void cb({ error: 'EINVAL_HREF' }); }
var parsed = Hash.parsePadUrl(href); var parsed = Hash.parsePadUrl(href);
if (!parsed.hash) { return void cb({ error: 'EINVAL_HREF' }); } if (!parsed.hash) { return void cb({ error: 'EINVAL_HREF' }); }
@ -787,6 +787,8 @@ define([
var warning = false; var warning = false;
var newHash, newRoHref; var newHash, newRoHref;
var oldChannel; var oldChannel;
var oldSecret;
var oldMetadata;
var newSecret; var newSecret;
if (parsed.hashData.version >= 2) { if (parsed.hashData.version >= 2) {
@ -803,27 +805,61 @@ define([
var optsGet = {}; var optsGet = {};
var optsPut = { var optsPut = {
password: newPassword password: newPassword,
metadata: {}
}; };
Nthen(function (waitFor) { Nthen(function (waitFor) {
if (parsed.hashData && parsed.hashData.password) { if (parsed.hashData && parsed.hashData.password) {
common.getPadAttribute('password', waitFor(function (err, password) { common.getPadAttribute('password', waitFor(function (err, password) {
optsGet.password = password; optsGet.password = password;
}), href); }), href);
} }
common.getPadAttribute('owners', waitFor(function (err, owners) { }).nThen(function (waitFor) {
if (!Array.isArray(owners) || owners.indexOf(edPublic) === -1) { oldSecret = Hash.getSecrets(parsed.type, parsed.hash, optsGet.password);
// We're not an owner, we shouldn't be able to change the password! oldChannel = oldSecret.channel;
waitFor.abort(); common.getPadMetadata({channel: oldChannel}, waitFor(function (metadata) {
return void cb({ error: 'EPERM' }); oldMetadata = metadata;
}));
}).nThen(function (waitFor) {
// Get owners, mailbox and expiration time
var owners = oldMetadata.owners;
if (!Array.isArray(owners) || owners.indexOf(edPublic) === -1) {
// We're not an owner, we shouldn't be able to change the password!
waitFor.abort();
return void cb({ error: 'EPERM' });
}
optsPut.metadata.owners = owners;
var mailbox = oldMetadata.mailbox;
if (mailbox) {
// Create the encryptors to be able to decrypt and re-encrypt the mailboxes
var oldCrypto = Crypto.createEncryptor(oldSecret.keys);
var newCrypto = Crypto.createEncryptor(newSecret.keys);
var m;
if (typeof(mailbox) === "string") {
try {
m = newCrypto.encrypt(oldCrypto.decrypt(mailbox, true, true));
} catch (e) {}
} else if (mailbox && typeof(mailbox) == "object") {
m = {};
Object.keys(mailbox).forEach(function (ed) {
console.log(mailbox[ed]);
try {
m[ed] = newCrypto.encrypt(oldCrypto.decrypt(mailbox[ed], true, true));
} catch (e) {
console.error(e);
}
});
} }
optsPut.owners = owners; optsPut.metadata.mailbox = m;
}), href); }
// XXX get the mailbox fields, decrypt all the mailboxes, reencrypt them, and put them in the metadata
// XXX also use optsPut.metadata (and fix it in cryptget) instead of optsPut.owners var expire = oldMetadata.expire;
common.getPadAttribute('expire', waitFor(function (err, expire) { optsPut.metadata.expire = (expire - (+new Date())) / 1000; // Lifetime in seconds
optsPut.expire = (expire - (+new Date())) / 1000; // Lifetime in seconds
}), href);
}).nThen(function (waitFor) { }).nThen(function (waitFor) {
Crypt.get(parsed.hash, waitFor(function (err, val) { Crypt.get(parsed.hash, waitFor(function (err, val) {
if (err) { if (err) {
@ -838,8 +874,6 @@ define([
}), optsPut); }), optsPut);
}), optsGet); }), optsGet);
}).nThen(function (waitFor) { }).nThen(function (waitFor) {
var secret = Hash.getSecrets(parsed.type, parsed.hash, optsGet.password);
oldChannel = secret.channel;
pad.leavePad({ pad.leavePad({
channel: oldChannel channel: oldChannel
}, waitFor()); }, waitFor());

@ -77,7 +77,12 @@ proxy.mailboxes = {
}; };
// Send a message to someone else // Send a message to someone else
var sendTo = Mailbox.sendTo = function (ctx, type, msg, user, cb) { var sendTo = Mailbox.sendTo = function (ctx, type, msg, user, _cb) {
var cb = _cb || function (obj) {
if (obj && obj.error) {
console.error(obj.error);
}
};
if (!Crypto.Mailbox) { if (!Crypto.Mailbox) {
return void cb({error: "chainpad-crypto is outdated and doesn't support mailboxes."}); return void cb({error: "chainpad-crypto is outdated and doesn't support mailboxes."});
} }

@ -911,7 +911,7 @@ define([
sframeChan.on('Q_PAD_PASSWORD_CHANGE', function (data, cb) { sframeChan.on('Q_PAD_PASSWORD_CHANGE', function (data, cb) {
var href = data.href || window.location.href; var href = data.href || window.location.href;
Cryptpad.changePadPassword(Cryptget, href, data.password, edPublic, cb); Cryptpad.changePadPassword(Cryptget, Crypto, href, data.password, edPublic, cb);
}); });
sframeChan.on('Q_CHANGE_USER_PASSWORD', function (data, cb) { sframeChan.on('Q_CHANGE_USER_PASSWORD', function (data, cb) {
@ -1020,7 +1020,7 @@ define([
// Try to get the owner's mailbox from the pad metadata first. // Try to get the owner's mailbox from the pad metadata first.
// If it's is an older owned pad, check if the owner is a friend // If it's is an older owned pad, check if the owner is a friend
// or an acquaintance (from async-store directly in requestAccess) // or an acquaintance (from async-store directly in requestAccess)
Cryptpad.pad.getPadMetadata({ Cryptpad.padRpc.getPadMetadata({
channel: secret.channel channel: secret.channel
}, waitFor(function (obj) { }, waitFor(function (obj) {
obj = obj || {}; obj = obj || {};

Loading…
Cancel
Save