1
0
mirror of https://github.com/moparisthebest/mail synced 2025-01-30 22:50:17 -05:00

fix cleartext leak during sync

This commit is contained in:
Felix Hammerl 2013-12-06 15:03:42 +01:00
parent 544fae4aad
commit 7353fcb0bf
2 changed files with 61 additions and 21 deletions

View File

@ -318,9 +318,16 @@ define(function(require) {
return; return;
} }
var encryptedMsg = _.findWhere(messages, {
uid: message.uid
});
encryptedMsg.unread = message.unread;
encryptedMsg.answered = message.answered;
self._localStoreMessages({ self._localStoreMessages({
folder: folder.path, folder: folder.path,
emails: [message] emails: [encryptedMsg]
}, function(err) { }, function(err) {
if (err) { if (err) {
self._account.busy = false; self._account.busy = false;
@ -485,24 +492,41 @@ define(function(require) {
}); });
deltaF2.forEach(function(header) { deltaF2.forEach(function(header) {
// we don't work on the header, we work on the live object // do a short round trip to the database to avoid re-encrypting,
var msg = _.findWhere(folder.messages, { // instead use the encrypted object in the storage
uid: header.uid self._localListMessages({
});
msg.unread = header.unread;
msg.answered = header.answered;
self._localStoreMessages({
folder: folder.path, folder: folder.path,
emails: [msg] uid: header.uid
}, function(err) { }, function(err, storedMsgs) {
if (err) { if (err) {
self._account.busy = false; self._account.busy = false;
callback(err); callback(err);
return; return;
} }
after(); var storedMsg = storedMsgs[0];
storedMsg.unread = header.unread;
storedMsg.answered = header.answered;
self._localStoreMessages({
folder: folder.path,
emails: [storedMsg]
}, function(err) {
if (err) {
self._account.busy = false;
callback(err);
return;
}
// after the metadata of the encrypted object has changed, proceed with the live object
var liveMsg = _.findWhere(folder.messages, {
uid: header.uid
});
liveMsg.unread = header.unread;
liveMsg.answered = header.answered;
after();
});
}); });
}); });
} }
@ -796,6 +820,9 @@ define(function(require) {
EmailDAO.prototype._localListMessages = function(options, callback) { EmailDAO.prototype._localListMessages = function(options, callback) {
var dbType = 'email_' + options.folder; var dbType = 'email_' + options.folder;
if (typeof options.uid !== 'undefined') {
dbType = dbType + '_' + options.uid;
}
this._devicestorage.listItems(dbType, 0, null, callback); this._devicestorage.listItems(dbType, 0, null, callback);
}; };

View File

@ -532,7 +532,7 @@ define(function(require) {
}); });
describe('_localListMessages', function() { describe('_localListMessages', function() {
it('should work', function(done) { it('should work without uid', function(done) {
var folder = 'FOLDAAAA'; var folder = 'FOLDAAAA';
devicestorageStub.listItems.withArgs('email_' + folder, 0, null).yields(); devicestorageStub.listItems.withArgs('email_' + folder, 0, null).yields();
@ -540,6 +540,17 @@ define(function(require) {
folder: folder folder: folder
}, done); }, done);
}); });
it('should work with uid', function(done) {
var folder = 'FOLDAAAA',
uid = 123;
devicestorageStub.listItems.withArgs('email_' + folder + '_' + uid, 0, null).yields();
dao._localListMessages({
folder: folder,
uid: uid
}, done);
});
}); });
describe('_localStoreMessages', function() { describe('_localStoreMessages', function() {
@ -1517,7 +1528,7 @@ define(function(require) {
}).yields(); }).yields();
localStoreStub = sinon.stub(dao, '_localStoreMessages').withArgs({ localStoreStub = sinon.stub(dao, '_localStoreMessages').withArgs({
folder: folder, folder: folder,
emails: [dummyDecryptedMail] emails: [inStorage]
}).yields(); }).yields();
dao.sync({ dao.sync({
@ -1538,6 +1549,9 @@ define(function(require) {
expect(markStub.calledOnce).to.be.true; expect(markStub.calledOnce).to.be.true;
expect(localStoreStub.calledOnce).to.be.true; expect(localStoreStub.calledOnce).to.be.true;
expect(inStorage.unread).to.equal(dummyDecryptedMail.unread);
expect(inStorage.answered).to.equal(dummyDecryptedMail.answered);
done(); done();
}); });
}); });
@ -1633,10 +1647,7 @@ define(function(require) {
localListStub = sinon.stub(dao, '_localListMessages').yields(null, [inStorage]); localListStub = sinon.stub(dao, '_localListMessages').yields(null, [inStorage]);
imapListStub = sinon.stub(dao, '_imapListMessages').yields(null, [inImap]); imapListStub = sinon.stub(dao, '_imapListMessages').yields(null, [inImap]);
markStub = sinon.stub(dao, '_imapMark'); markStub = sinon.stub(dao, '_imapMark');
localStoreStub = sinon.stub(dao, '_localStoreMessages').withArgs({ localStoreStub = sinon.stub(dao, '_localStoreMessages').yields();
folder: folder,
emails: [dummyDecryptedMail]
}).yields();
dao.sync({ dao.sync({
folder: folder folder: folder
@ -1651,12 +1662,13 @@ define(function(require) {
expect(dao._account.busy).to.be.false; expect(dao._account.busy).to.be.false;
expect(dao._account.folders[0]).to.not.be.empty; expect(dao._account.folders[0]).to.not.be.empty;
expect(localListStub.calledOnce).to.be.true; expect(localListStub.calledTwice).to.be.true;
expect(imapListStub.calledOnce).to.be.true; expect(imapListStub.calledOnce).to.be.true;
expect(markStub.called).to.be.false; expect(markStub.called).to.be.false;
expect(localStoreStub.calledOnce).to.be.true; expect(localStoreStub.calledOnce).to.be.true;
expect(dummyDecryptedMail.unread).to.equal(inImap.unread); expect(dummyDecryptedMail.unread).to.equal(inImap.unread);
expect(inStorage.unread).to.equal(inImap.unread);
done(); done();
}); });
@ -1697,12 +1709,13 @@ define(function(require) {
expect(err).to.exist; expect(err).to.exist;
expect(dao._account.busy).to.be.false; expect(dao._account.busy).to.be.false;
expect(dao._account.folders[0]).to.not.be.empty; expect(dao._account.folders[0]).to.not.be.empty;
expect(localListStub.calledOnce).to.be.true; expect(localListStub.calledTwice).to.be.true;
expect(imapListStub.calledOnce).to.be.true; expect(imapListStub.calledOnce).to.be.true;
expect(markStub.called).to.be.false; expect(markStub.called).to.be.false;
expect(localStoreStub.calledOnce).to.be.true; expect(localStoreStub.calledOnce).to.be.true;
expect(dummyDecryptedMail.unread).to.equal(inImap.unread); expect(inStorage.unread).to.equal(inImap.unread);
expect(dummyDecryptedMail.unread).to.equal(true); // the live object has not been touched!
done(); done();
}); });