mirror of
https://github.com/moparisthebest/mail
synced 2024-11-22 17:02:17 -05:00
Merge remote-tracking branch 'origin/dev/security-review'
This commit is contained in:
commit
e62e085771
@ -20,7 +20,12 @@ define(function(require) {
|
|||||||
// push handler
|
// push handler
|
||||||
if (emailDao) {
|
if (emailDao) {
|
||||||
emailDao.onIncomingMessage = function(email) {
|
emailDao.onIncomingMessage = function(email) {
|
||||||
if (email.subject.indexOf(str.subjectPrefix) === -1) {
|
if (!email.subject) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (email.subject.indexOf(str.subjectPrefix) === -1 ||
|
||||||
|
email.subject === str.subjectPrefix + str.verificationSubject) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,9 +486,8 @@ define(function(require) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// imap filtering may not be sufficient, since google filters out
|
// imap filtering is insufficient, since google ignores non-alphabetical characters
|
||||||
// non-alphabetical characters
|
if (message.subject.indexOf(str.subjectPrefix.trim()) === -1) {
|
||||||
if (message.subject.indexOf(str.subjectPrefix) === -1) {
|
|
||||||
syncNextItem();
|
syncNextItem();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -718,7 +717,7 @@ define(function(require) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function verify(email, localCallback) {
|
function verify(email, localCallback) {
|
||||||
var uuid, index, verifyUrlPrefix = config.cloudUrl + config.verificationUrl;
|
var uuid, isValidUuid, index, verifyUrlPrefix = config.cloudUrl + config.verificationUrl;
|
||||||
|
|
||||||
if (!email.unread) {
|
if (!email.unread) {
|
||||||
// don't bother if the email was already marked as read
|
// don't bother if the email was already marked as read
|
||||||
@ -733,8 +732,14 @@ define(function(require) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uuid = email.body.substr(index + verifyUrlPrefix.length, config.verificationUuidLength);
|
uuid = email.body.substr(index + verifyUrlPrefix.length, config.verificationUuidLength);
|
||||||
|
isValidUuid = new RegExp('[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}').test(uuid);
|
||||||
|
if (!isValidUuid) {
|
||||||
|
// there's no valid uuid in the email, so forget about that, too.
|
||||||
|
localCallback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
self._keychain.verifyPublicKey(uuid, function(err) {
|
self._keychain.verifyPublicKey(uuid, function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
localCallback({
|
localCallback({
|
||||||
|
@ -14,7 +14,15 @@ define(function() {
|
|||||||
this._restDao.get({
|
this._restDao.get({
|
||||||
uri: uri,
|
uri: uri,
|
||||||
type: 'text'
|
type: 'text'
|
||||||
}, callback);
|
}, function(err, res, status) {
|
||||||
|
if (err && err.code === 400) {
|
||||||
|
// there was an attempt to verify a non-existing public key
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(err, res, status);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,6 +15,7 @@ define(function(require) {
|
|||||||
|
|
||||||
var emailAddress, passphrase, asymKeySize, mockkeyId, dummyEncryptedMail,
|
var emailAddress, passphrase, asymKeySize, mockkeyId, dummyEncryptedMail,
|
||||||
dummyDecryptedMail, mockKeyPair, account, publicKey, verificationMail, verificationUuid,
|
dummyDecryptedMail, mockKeyPair, account, publicKey, verificationMail, verificationUuid,
|
||||||
|
corruptedVerificationMail, corruptedVerificationUuid,
|
||||||
nonWhitelistedMail;
|
nonWhitelistedMail;
|
||||||
|
|
||||||
beforeEach(function(done) {
|
beforeEach(function(done) {
|
||||||
@ -35,7 +36,7 @@ define(function(require) {
|
|||||||
unread: false,
|
unread: false,
|
||||||
answered: false
|
answered: false
|
||||||
};
|
};
|
||||||
verificationUuid = 'OMFG_FUCKING_BASTARD_UUID_FROM_HELL!';
|
verificationUuid = '9A858952-17EE-4273-9E74-D309EAFDFAFB';
|
||||||
verificationMail = {
|
verificationMail = {
|
||||||
from: [{
|
from: [{
|
||||||
name: 'Whiteout Test',
|
name: 'Whiteout Test',
|
||||||
@ -49,6 +50,20 @@ define(function(require) {
|
|||||||
unread: true,
|
unread: true,
|
||||||
answered: false
|
answered: false
|
||||||
};
|
};
|
||||||
|
corruptedVerificationUuid = 'OMFG_FUCKING_BASTARD_UUID_FROM_HELL!';
|
||||||
|
corruptedVerificationMail = {
|
||||||
|
from: [{
|
||||||
|
name: 'Whiteout Test',
|
||||||
|
address: 'whiteout.test@t-online.de'
|
||||||
|
}], // sender address
|
||||||
|
to: [{
|
||||||
|
address: 'safewithme.testuser@gmail.com'
|
||||||
|
}], // list of receivers
|
||||||
|
subject: "[whiteout] New public key uploaded", // Subject line
|
||||||
|
body: 'yadda yadda bla blabla foo bar https://keys.whiteout.io/verify/' + corruptedVerificationUuid, // plaintext body
|
||||||
|
unread: true,
|
||||||
|
answered: false
|
||||||
|
};
|
||||||
dummyDecryptedMail = {
|
dummyDecryptedMail = {
|
||||||
uid: 1234,
|
uid: 1234,
|
||||||
from: [{
|
from: [{
|
||||||
@ -193,7 +208,9 @@ define(function(require) {
|
|||||||
|
|
||||||
// initFolders
|
// initFolders
|
||||||
listFolderStub = sinon.stub(dao, '_imapListFolders');
|
listFolderStub = sinon.stub(dao, '_imapListFolders');
|
||||||
listFolderStub.yields({code:42});
|
listFolderStub.yields({
|
||||||
|
code: 42
|
||||||
|
});
|
||||||
|
|
||||||
dao.init({
|
dao.init({
|
||||||
account: account
|
account: account
|
||||||
@ -1666,7 +1683,6 @@ define(function(require) {
|
|||||||
dao.sync({
|
dao.sync({
|
||||||
folder: folder
|
folder: folder
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
|
|
||||||
if (invocations === 0) {
|
if (invocations === 0) {
|
||||||
expect(err).to.not.exist;
|
expect(err).to.not.exist;
|
||||||
expect(dao._account.busy).to.be.true;
|
expect(dao._account.busy).to.be.true;
|
||||||
@ -1714,7 +1730,6 @@ define(function(require) {
|
|||||||
dao.sync({
|
dao.sync({
|
||||||
folder: folder
|
folder: folder
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
|
|
||||||
if (invocations === 0) {
|
if (invocations === 0) {
|
||||||
expect(err).to.not.exist;
|
expect(err).to.not.exist;
|
||||||
expect(dao._account.busy).to.be.true;
|
expect(dao._account.busy).to.be.true;
|
||||||
@ -1761,7 +1776,6 @@ define(function(require) {
|
|||||||
dao.sync({
|
dao.sync({
|
||||||
folder: folder
|
folder: folder
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
|
|
||||||
if (invocations === 0) {
|
if (invocations === 0) {
|
||||||
expect(err).to.not.exist;
|
expect(err).to.not.exist;
|
||||||
expect(dao._account.busy).to.be.true;
|
expect(dao._account.busy).to.be.true;
|
||||||
@ -1814,6 +1828,59 @@ define(function(require) {
|
|||||||
markReadStub = sinon.stub(dao, '_imapMark');
|
markReadStub = sinon.stub(dao, '_imapMark');
|
||||||
imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage');
|
imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage');
|
||||||
|
|
||||||
|
dao.sync({
|
||||||
|
folder: folder
|
||||||
|
}, function(err) {
|
||||||
|
if (invocations === 0) {
|
||||||
|
expect(err).to.not.exist;
|
||||||
|
expect(dao._account.busy).to.be.true;
|
||||||
|
invocations++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(err).to.not.exist;
|
||||||
|
expect(dao._account.busy).to.be.false;
|
||||||
|
expect(dao._account.folders[0].messages).to.be.empty;
|
||||||
|
expect(localListStub.calledOnce).to.be.true;
|
||||||
|
expect(imapSearchStub.calledThrice).to.be.true;
|
||||||
|
expect(imapGetStub.calledOnce).to.be.true;
|
||||||
|
expect(keychainStub.verifyPublicKey.called).to.be.false;
|
||||||
|
expect(markReadStub.called).to.be.false;
|
||||||
|
expect(imapDeleteStub.called).to.be.false;
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not bother about corrupted authentication mails', function(done) {
|
||||||
|
var invocations, folder, localListStub, imapSearchStub, imapGetStub, markReadStub, imapDeleteStub;
|
||||||
|
|
||||||
|
invocations = 0;
|
||||||
|
folder = 'FOLDAAAA';
|
||||||
|
dao._account.folders = [{
|
||||||
|
type: 'Folder',
|
||||||
|
path: folder,
|
||||||
|
messages: []
|
||||||
|
}];
|
||||||
|
|
||||||
|
localListStub = sinon.stub(dao, '_localListMessages').yields(null, []);
|
||||||
|
imapSearchStub = sinon.stub(dao, '_imapSearch');
|
||||||
|
imapSearchStub.withArgs({
|
||||||
|
folder: folder
|
||||||
|
}).yields(null, [corruptedVerificationMail.uid]);
|
||||||
|
imapSearchStub.withArgs({
|
||||||
|
folder: folder,
|
||||||
|
unread: true
|
||||||
|
}).yields(null, []);
|
||||||
|
imapSearchStub.withArgs({
|
||||||
|
folder: folder,
|
||||||
|
answered: true
|
||||||
|
}).yields(null, []);
|
||||||
|
|
||||||
|
imapGetStub = sinon.stub(dao, '_imapGetMessage').yields(null, corruptedVerificationMail);
|
||||||
|
markReadStub = sinon.stub(dao, '_imapMark');
|
||||||
|
imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage');
|
||||||
|
|
||||||
dao.sync({
|
dao.sync({
|
||||||
folder: folder
|
folder: folder
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
@ -1838,7 +1905,7 @@ define(function(require) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not bother about corrupted authentication mails', function(done) {
|
it('should not bother about corrupted authentication mails no verification link', function(done) {
|
||||||
var invocations, folder, localListStub, imapSearchStub,
|
var invocations, folder, localListStub, imapSearchStub,
|
||||||
imapGetStub, markReadStub, imapDeleteStub;
|
imapGetStub, markReadStub, imapDeleteStub;
|
||||||
|
|
||||||
|
@ -49,12 +49,23 @@ define(function(require) {
|
|||||||
it('should fail', function(done) {
|
it('should fail', function(done) {
|
||||||
restDaoStub.get.yields(42);
|
restDaoStub.get.yields(42);
|
||||||
|
|
||||||
pubkeyDao.get('id', function(err) {
|
pubkeyDao.verify('id', function(err) {
|
||||||
expect(err).to.exist;
|
expect(err).to.exist;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not error for 400', function(done) {
|
||||||
|
restDaoStub.get.yields({
|
||||||
|
code: 400
|
||||||
|
});
|
||||||
|
|
||||||
|
pubkeyDao.verify('id', function(err) {
|
||||||
|
expect(err).to.not.exist;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should work', function(done) {
|
it('should work', function(done) {
|
||||||
var uuid = 'c621e328-8548-40a1-8309-adf1955e98a9';
|
var uuid = 'c621e328-8548-40a1-8309-adf1955e98a9';
|
||||||
restDaoStub.get.yields(null);
|
restDaoStub.get.yields(null);
|
||||||
|
Loading…
Reference in New Issue
Block a user