mirror of
https://github.com/jambonz/sbc-inbound.git
synced 2025-12-19 04:37:43 +00:00
support auth trunk for incoming call (#213)
* support auth trunk for incoming call * wip * wip * wip * update digest-utils version * update sql file from api-server * update sql file from api-server * wip
This commit is contained in:
13
app.js
13
app.js
@@ -130,7 +130,8 @@ const {
|
|||||||
wasOriginatedFromCarrier,
|
wasOriginatedFromCarrier,
|
||||||
getApplicationForDidAndCarrier,
|
getApplicationForDidAndCarrier,
|
||||||
getOutboundGatewayForRefer,
|
getOutboundGatewayForRefer,
|
||||||
getApplicationBySid
|
getApplicationBySid,
|
||||||
|
lookupAuthCarriersForAccountAndSP
|
||||||
} = require('./lib/db-utils')(srf, logger);
|
} = require('./lib/db-utils')(srf, logger);
|
||||||
srf.locals = {
|
srf.locals = {
|
||||||
...srf.locals,
|
...srf.locals,
|
||||||
@@ -139,7 +140,8 @@ srf.locals = {
|
|||||||
getApplicationForDidAndCarrier,
|
getApplicationForDidAndCarrier,
|
||||||
getOutboundGatewayForRefer,
|
getOutboundGatewayForRefer,
|
||||||
getFeatureServer: require('./lib/fs-tracking')(srf, logger),
|
getFeatureServer: require('./lib/fs-tracking')(srf, logger),
|
||||||
getApplicationBySid
|
getApplicationBySid,
|
||||||
|
lookupAuthCarriersForAccountAndSP
|
||||||
};
|
};
|
||||||
const activeCallIds = srf.locals.activeCallIds;
|
const activeCallIds = srf.locals.activeCallIds;
|
||||||
|
|
||||||
@@ -148,7 +150,8 @@ const {
|
|||||||
handleSipRec,
|
handleSipRec,
|
||||||
identifyAccount,
|
identifyAccount,
|
||||||
checkLimits,
|
checkLimits,
|
||||||
challengeDeviceCalls
|
challengeDeviceCalls,
|
||||||
|
identifyAuthTrunk
|
||||||
} = require('./lib/middleware')(srf, logger);
|
} = require('./lib/middleware')(srf, logger);
|
||||||
const CallSession = require('./lib/call-session');
|
const CallSession = require('./lib/call-session');
|
||||||
|
|
||||||
@@ -236,7 +239,9 @@ srf.use('invite', [
|
|||||||
handleSipRec,
|
handleSipRec,
|
||||||
identifyAccount,
|
identifyAccount,
|
||||||
checkLimits,
|
checkLimits,
|
||||||
challengeDeviceCalls
|
challengeDeviceCalls,
|
||||||
|
// challengeDeviceCalls will detect auth_trunk or device calls, identifyAuthTrunk have to be after that
|
||||||
|
identifyAuthTrunk
|
||||||
]);
|
]);
|
||||||
|
|
||||||
srf.invite((req, res) => {
|
srf.invite((req, res) => {
|
||||||
|
|||||||
@@ -65,6 +65,16 @@ AND vc.is_active = 1
|
|||||||
AND vc.register_sip_realm = ?
|
AND vc.register_sip_realm = ?
|
||||||
AND vc.register_username = ?`;
|
AND vc.register_username = ?`;
|
||||||
|
|
||||||
|
const sqlSelectAuthCarriersForAccountAndSP = `
|
||||||
|
SELECT * FROM voip_carriers
|
||||||
|
WHERE trunk_type = 'auth'
|
||||||
|
AND is_active = 1
|
||||||
|
AND (
|
||||||
|
(account_sid = ?)
|
||||||
|
OR
|
||||||
|
(service_provider_sid = ? AND account_sid IS NULL)
|
||||||
|
)`;
|
||||||
|
|
||||||
const sqlSelectGatewaysByVoipCarrierSids = `
|
const sqlSelectGatewaysByVoipCarrierSids = `
|
||||||
SELECT sg.sip_gateway_sid, sg.voip_carrier_sid, vc.name, vc.service_provider_sid,
|
SELECT sg.sip_gateway_sid, sg.voip_carrier_sid, vc.name, vc.service_provider_sid,
|
||||||
vc.account_sid, vc.application_sid, sg.inbound, sg.outbound, sg.is_active, sg.ipv4, sg.netmask, sg.pad_crypto
|
vc.account_sid, vc.application_sid, sg.inbound, sg.outbound, sg.is_active, sg.ipv4, sg.netmask, sg.pad_crypto
|
||||||
@@ -579,12 +589,33 @@ module.exports = (srf, logger) => {
|
|||||||
return failure;
|
return failure;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves voip_carriers with trunk_type 'auth' that belong to either:
|
||||||
|
* 1. The specified account (account_sid matches), OR
|
||||||
|
* 2. The service provider but with null account_sid (shared across service provider)
|
||||||
|
*
|
||||||
|
* @param {string} account_sid - The SID of the account
|
||||||
|
* @param {string} service_provider_sid - The SID of the service provider
|
||||||
|
* @returns {Promise<Array>} Array of voip_carrier records matching the criteria
|
||||||
|
* @throws {Error} Database errors or other unexpected errors
|
||||||
|
*/
|
||||||
|
const lookupAuthCarriersForAccountAndSP = async(account_sid, service_provider_sid) => {
|
||||||
|
try {
|
||||||
|
const [rows] = await pp.query(sqlSelectAuthCarriersForAccountAndSP, [account_sid, service_provider_sid]);
|
||||||
|
return rows;
|
||||||
|
} catch (err) {
|
||||||
|
logger.error({err, account_sid, service_provider_sid}, 'lookupAuthCarriersForAccountAndSP');
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
wasOriginatedFromCarrier,
|
wasOriginatedFromCarrier,
|
||||||
getApplicationForDidAndCarrier,
|
getApplicationForDidAndCarrier,
|
||||||
getApplicationForDidAndCarriers,
|
getApplicationForDidAndCarriers,
|
||||||
getOutboundGatewayForRefer,
|
getOutboundGatewayForRefer,
|
||||||
getSPForAccount,
|
getSPForAccount,
|
||||||
getApplicationBySid
|
getApplicationBySid,
|
||||||
|
lookupAuthCarriersForAccountAndSP
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ module.exports = function(srf, logger) {
|
|||||||
lookupAccountBySipRealm,
|
lookupAccountBySipRealm,
|
||||||
lookupAccountBySid,
|
lookupAccountBySid,
|
||||||
lookupAccountCapacitiesBySid,
|
lookupAccountCapacitiesBySid,
|
||||||
queryCallLimits
|
queryCallLimits,
|
||||||
} = srf.locals.dbHelpers;
|
} = srf.locals.dbHelpers;
|
||||||
const {stats, writeCdrs} = srf.locals;
|
const {stats, writeCdrs, lookupAuthCarriersForAccountAndSP, getApplicationForDidAndCarrier} = srf.locals;
|
||||||
|
|
||||||
const initLocals = (req, res, next) => {
|
const initLocals = (req, res, next) => {
|
||||||
const callId = req.get('Call-ID');
|
const callId = req.get('Call-ID');
|
||||||
@@ -191,6 +191,10 @@ module.exports = function(srf, logger) {
|
|||||||
res.send(404);
|
res.send(404);
|
||||||
return req.srf.endSession(req);
|
return req.srf.endSession(req);
|
||||||
}
|
}
|
||||||
|
const auth_trunks = await lookupAuthCarriersForAccountAndSP(
|
||||||
|
account.account_sid,
|
||||||
|
account.service_provider_sid
|
||||||
|
);
|
||||||
|
|
||||||
/* if this is a dedicated SBC (static IP) only take calls for that account's sip realm */
|
/* if this is a dedicated SBC (static IP) only take calls for that account's sip realm */
|
||||||
if (process.env.SBC_ACCOUNT_SID && account.account_sid !== process.env.SBC_ACCOUNT_SID) {
|
if (process.env.SBC_ACCOUNT_SID && account.account_sid !== process.env.SBC_ACCOUNT_SID) {
|
||||||
@@ -214,6 +218,7 @@ module.exports = function(srf, logger) {
|
|||||||
registration_hook_username: account.registration_hook.username,
|
registration_hook_username: account.registration_hook.username,
|
||||||
registration_hook_password: account.registration_hook.password
|
registration_hook_password: account.registration_hook.password
|
||||||
}),
|
}),
|
||||||
|
...(auth_trunks?.length && {auth_trunks}),
|
||||||
...req.locals
|
...req.locals
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -365,6 +370,38 @@ module.exports = function(srf, logger) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const identifyAuthTrunk = async(req, res, next) => {
|
||||||
|
try {
|
||||||
|
if (req.authorization) {
|
||||||
|
const {grant} = req.authorization;
|
||||||
|
if (grant && grant.status === 'ok' && grant.auth_trunk) {
|
||||||
|
// we have successfully authenticated the call for an auth_trunk
|
||||||
|
const application_sid = await getApplicationForDidAndCarrier(req, grant.auth_trunk.voip_carrier_sid);
|
||||||
|
|
||||||
|
req.locals = {
|
||||||
|
...req.locals,
|
||||||
|
originator: 'trunk',
|
||||||
|
carrier: grant.auth_trunk.name,
|
||||||
|
gateway: grant.auth_trunk,
|
||||||
|
voip_carrier_sid: grant.auth_trunk.voip_carrier_sid,
|
||||||
|
application_sid: application_sid || grant.auth_trunk.application_sid,
|
||||||
|
};
|
||||||
|
// as call from auth carrier, clean req.authorization that impact on legacy logic for authenticated user
|
||||||
|
delete req.authorization;
|
||||||
|
|
||||||
|
logger.debug({callId: req.locals.callId, auth_trunk: grant.auth_trunk.name},
|
||||||
|
'identifyAuthTrunk: call authenticated for auth trunk');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
} catch (err) {
|
||||||
|
stats.increment('sbc.terminations', ['sipStatus:500']);
|
||||||
|
logger.error(err, `${req.get('Call-ID')} Error challenging auth trunk`);
|
||||||
|
res.send(500);
|
||||||
|
req.srf.endSession(req);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const challengeDeviceCalls = async(req, res, next) => {
|
const challengeDeviceCalls = async(req, res, next) => {
|
||||||
try {
|
try {
|
||||||
/* TODO: check if this is a gateway that we have an ACL for */
|
/* TODO: check if this is a gateway that we have an ACL for */
|
||||||
@@ -383,6 +420,7 @@ module.exports = function(srf, logger) {
|
|||||||
handleSipRec,
|
handleSipRec,
|
||||||
challengeDeviceCalls,
|
challengeDeviceCalls,
|
||||||
identifyAccount,
|
identifyAccount,
|
||||||
|
identifyAuthTrunk,
|
||||||
checkLimits
|
checkLimits
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user