mirror of
https://github.com/jambonz/sbc-inbound.git
synced 2025-12-18 20:27: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,
|
||||
getApplicationForDidAndCarrier,
|
||||
getOutboundGatewayForRefer,
|
||||
getApplicationBySid
|
||||
getApplicationBySid,
|
||||
lookupAuthCarriersForAccountAndSP
|
||||
} = require('./lib/db-utils')(srf, logger);
|
||||
srf.locals = {
|
||||
...srf.locals,
|
||||
@@ -139,7 +140,8 @@ srf.locals = {
|
||||
getApplicationForDidAndCarrier,
|
||||
getOutboundGatewayForRefer,
|
||||
getFeatureServer: require('./lib/fs-tracking')(srf, logger),
|
||||
getApplicationBySid
|
||||
getApplicationBySid,
|
||||
lookupAuthCarriersForAccountAndSP
|
||||
};
|
||||
const activeCallIds = srf.locals.activeCallIds;
|
||||
|
||||
@@ -148,7 +150,8 @@ const {
|
||||
handleSipRec,
|
||||
identifyAccount,
|
||||
checkLimits,
|
||||
challengeDeviceCalls
|
||||
challengeDeviceCalls,
|
||||
identifyAuthTrunk
|
||||
} = require('./lib/middleware')(srf, logger);
|
||||
const CallSession = require('./lib/call-session');
|
||||
|
||||
@@ -236,7 +239,9 @@ srf.use('invite', [
|
||||
handleSipRec,
|
||||
identifyAccount,
|
||||
checkLimits,
|
||||
challengeDeviceCalls
|
||||
challengeDeviceCalls,
|
||||
// challengeDeviceCalls will detect auth_trunk or device calls, identifyAuthTrunk have to be after that
|
||||
identifyAuthTrunk
|
||||
]);
|
||||
|
||||
srf.invite((req, res) => {
|
||||
|
||||
@@ -65,6 +65,16 @@ AND vc.is_active = 1
|
||||
AND vc.register_sip_realm = ?
|
||||
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 = `
|
||||
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
|
||||
@@ -579,12 +589,33 @@ module.exports = (srf, logger) => {
|
||||
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 {
|
||||
wasOriginatedFromCarrier,
|
||||
getApplicationForDidAndCarrier,
|
||||
getApplicationForDidAndCarriers,
|
||||
getOutboundGatewayForRefer,
|
||||
getSPForAccount,
|
||||
getApplicationBySid
|
||||
getApplicationBySid,
|
||||
lookupAuthCarriersForAccountAndSP
|
||||
};
|
||||
};
|
||||
|
||||
@@ -28,9 +28,9 @@ module.exports = function(srf, logger) {
|
||||
lookupAccountBySipRealm,
|
||||
lookupAccountBySid,
|
||||
lookupAccountCapacitiesBySid,
|
||||
queryCallLimits
|
||||
queryCallLimits,
|
||||
} = srf.locals.dbHelpers;
|
||||
const {stats, writeCdrs} = srf.locals;
|
||||
const {stats, writeCdrs, lookupAuthCarriersForAccountAndSP, getApplicationForDidAndCarrier} = srf.locals;
|
||||
|
||||
const initLocals = (req, res, next) => {
|
||||
const callId = req.get('Call-ID');
|
||||
@@ -191,6 +191,10 @@ module.exports = function(srf, logger) {
|
||||
res.send(404);
|
||||
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 (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_password: account.registration_hook.password
|
||||
}),
|
||||
...(auth_trunks?.length && {auth_trunks}),
|
||||
...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) => {
|
||||
try {
|
||||
/* TODO: check if this is a gateway that we have an ACL for */
|
||||
@@ -383,6 +420,7 @@ module.exports = function(srf, logger) {
|
||||
handleSipRec,
|
||||
challengeDeviceCalls,
|
||||
identifyAccount,
|
||||
identifyAuthTrunk,
|
||||
checkLimits
|
||||
};
|
||||
};
|
||||
|
||||
@@ -748,4 +748,4 @@ ALTER TABLE accounts ADD FOREIGN KEY device_calling_application_sid_idxfk (devic
|
||||
|
||||
ALTER TABLE accounts ADD FOREIGN KEY siprec_hook_sid_idxfk (siprec_hook_sid) REFERENCES applications (application_sid);
|
||||
|
||||
SET FOREIGN_KEY_CHECKS=0;
|
||||
SET FOREIGN_KEY_CHECKS=0;
|
||||
Reference in New Issue
Block a user