fix issue where apps can sendmail with any username
a valid password is still required for this to work
This commit is contained in:
33
src/ldap.js
33
src/ldap.js
@@ -634,16 +634,35 @@ function userSearchSftp(req, res, next) {
|
||||
});
|
||||
}
|
||||
|
||||
function verifyAppMailboxPassword(addonId, username, password, callback) {
|
||||
assert.strictEqual(typeof addonId, 'string');
|
||||
assert.strictEqual(typeof username, 'string');
|
||||
assert.strictEqual(typeof password, 'string');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
const pattern = addonId === 'sendmail' ? 'MAIL_SMTP' : 'MAIL_IMAP';
|
||||
appdb.getAppIdByAddonConfigValue(addonId, `%${pattern}_PASSWORD`, password, function (error, appId) { // search by password because this is unique for each app
|
||||
if (error) return callback(error);
|
||||
|
||||
appdb.getAddonConfig(appId, addonId, function (error, result) {
|
||||
if (error) return callback(error);
|
||||
|
||||
if (!result.some(r => r.name.endsWith(`${pattern}_USERNAME`) && r.value === username)) return callback(new BoxError(BoxError.INVALID_CREDENTIALS));
|
||||
|
||||
callback(null);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function authenticateMailAddon(req, res, next) {
|
||||
debug('mail addon auth: %s (from %s)', req.dn.toString(), req.connection.ldap.id);
|
||||
|
||||
if (!req.dn.rdns[0].attrs.cn) return next(new ldap.NoSuchObjectError(req.dn.toString()));
|
||||
|
||||
var email = req.dn.rdns[0].attrs.cn.value.toLowerCase();
|
||||
var parts = email.split('@');
|
||||
if (parts.length !== 2) return next(new ldap.NoSuchObjectError(req.dn.toString()));
|
||||
|
||||
const addonId = req.dn.rdns[1].attrs.ou.value.toLowerCase(); // 'sendmail' or 'recvmail'
|
||||
if (addonId !== 'sendmail' && addonId !== 'recvmail') return next(new ldap.OperationsError('Invalid DN'));
|
||||
|
||||
mail.getDomain(parts[1], function (error, domain) {
|
||||
if (error && error.reason === BoxError.NOT_FOUND) return next(new ldap.NoSuchObjectError(req.dn.toString()));
|
||||
@@ -651,15 +670,11 @@ function authenticateMailAddon(req, res, next) {
|
||||
|
||||
if (addonId === 'recvmail' && !domain.enabled) return next(new ldap.NoSuchObjectError(req.dn.toString()));
|
||||
|
||||
let namePattern; // manifest v2 has a CLOUDRON_ prefix for names
|
||||
if (addonId === 'sendmail') namePattern = '%MAIL_SMTP_PASSWORD';
|
||||
else if (addonId === 'recvmail') namePattern = '%MAIL_IMAP_PASSWORD';
|
||||
else return next(new ldap.OperationsError('Invalid DN'));
|
||||
verifyAppMailboxPassword(addonId, email, req.credentials || '', function (error) {
|
||||
if (!error) return res.end(); // validated as app
|
||||
|
||||
// note: with sendmail addon, apps can send mail without a mailbox (unlike users)
|
||||
appdb.getAppIdByAddonConfigValue(addonId, namePattern, req.credentials || '', function (error, appId) {
|
||||
if (error && error.reason === BoxError.INVALID_CREDENTIALS) return next(new ldap.InvalidCredentialsError(req.dn.toString()));
|
||||
if (error && error.reason !== BoxError.NOT_FOUND) return next(new ldap.OperationsError(error.message));
|
||||
if (appId) return res.end();
|
||||
|
||||
mailboxdb.getMailbox(parts[0], parts[1], function (error, mailbox) {
|
||||
if (error && error.reason === BoxError.NOT_FOUND) return next(new ldap.NoSuchObjectError(req.dn.toString()));
|
||||
|
||||
Reference in New Issue
Block a user