Simple Call ACL App for FusionPBX

Samael28

Member
Apr 5, 2017
67
20
8
35
Made a simple Call Access Control List application for FusionPBX

Idea is to have a set of rules, that will be match on Caller and Callee number to allow or reject this call.
As an example - simple limit certain extension to call only certain numbers. Or block some callers to call exact this extension.

All is done on regex-like simple patterns.

Screen Shot 2019-03-14 at 17.26.22.png

Rules are applied in order.

This app now is a part of my fork of FusionPBX, but fully compatible with vanilla Fusion version 4.4

To install it

# cd /usr/src
# git clone -b 4.4 https://github.com/samael33/fusionpbx.git fusionpbx-samael
# cp -r fusionpbx-samael/app/call_acl /var/www/fusionpbx/app/
# mkdir -p /var/www/fusionpbx/resources/install/scripts/app/custom
# cp -r fusionpbx-samael/resources/install/scripts/app/custom/call_acl /var/www/fusionpbx/resources/install/scripts/app/custom
# cp -r fusionpbx-samael/resources/install/scripts/app/app_custom.lua /var/www/fusionpbx/resources/install/scripts/app/
# cp -r fusionpbx-samael/app/dialplans/resources/switch/conf/dialplan/041_call_acl.xml /var/www/fusionpbx/app/dialplans/resources/switch/conf/dialplan

(optional)
# chown -R www-data. /var/www/fusionpbx

FusionPBX Menu -> Advanced -> Upgrade -> Schema + App Defaults + Menu Defaults + Permission Defaults

(TBH, not tested on vanilla)

Note, by default in Dialplan Manager call_acl extension by default is disabled. Done this is mainly cause you don't want to enable it on all domains. So, enable it per domain.

For cons - it's really heavy under high load and with big number of rules, cause heavily using regular expressions which are not super fast.
 
  • Like
Reactions: krooney

jfoster911

New Member
Apr 16, 2019
4
0
1
I have installed this on Version 4.4.3, works great.
I was wondering if the Action could be expanded to send call directly to a voicemail account?
I see that call_block has this function.

Thanks
 

Samael28

Member
Apr 5, 2017
67
20
8
35
Hi!
Actually yes, code is open source :)
For now, I don't require these functions, but change is really simple. PR's are welcome.
 

jfoster911

New Member
Apr 16, 2019
4
0
1
Taking a stab at it. What do you think?
I noticed that these changes would be required between call_block and call_acl
Anything else I might have missed?

Thanks, again

** Changes in call_acl_edit.php

//define the call_block_get_extensions function
function call_block_get_extensions($select_extension) {
global $db, $text;

//list voicemail
$sql = "select extension, user_context, description from v_extensions ";
$sql .= "where domain_uuid = '".$_SESSION['domain_uuid']."' ";
$sql .= "and enabled = 'true' ";
$sql .= "order by extension asc ";
$prep_statement = $db->prepare(check_sql($sql));
$prep_statement->execute();
$result = $prep_statement->fetchAll(PDO::FETCH_ASSOC);

echo "<optgroup label='".$text['label-voicemail']."'>\n";
foreach ($result as &$row) {
$extension = $row["extension"];
$context = $row["user_context"];
$description = $row["description"];
if ($extension == $select_extension) $selected = "selected='selected'";
echo " <option value='Voicemail $context $extension' $selected>".$extension." ".$description."</option>\n";
$selected = "";
}
echo "</optgroup>\n";
}

// Show action
echo "<tr>\n";
echo "<td class='vncell' valign='top' align='left' nowrap='nowrap'>\n";
echo " ".$text['label-call_acl_action']."\n";
echo "</td>\n";
echo "<td class='vtable' align='left'>\n";
echo " <select class='formfld' name='call_acl_action'>\n";
if ($call_acl_action == "reject") {
echo " <option value='allow'>".$text['label-allow']."</option>\n";
echo " <option value='reject' selected='selected'>".$text['label-reject']."</option>\n";
} else {
echo " <option value='allow' selected='selected'>".$text['label-allow']."</option>\n";
echo " <option value='reject'>".$text['label-reject']."</option>\n";
}
call_block_get_extensions($extension);
echo " </select>\n";
echo "<br />\n";
echo $text['description-call_acl_action']."\n";
echo "\n";
echo "</td>\n";
echo "</tr>\n";

** Changes in call_acl/index.lua

if (source:find(call_acl_source) and destination:find(call_acl_destination)) then
details = {}
k = 0
for v in string.gmatch(call_acl_action, "[%w%.]+") do
details[k] = v
k = k + 1

log("[" ..source.. "/" .. call_acl_source.. "][" ..destination.. "/" .. call_acl_destination.. "] ACL " .. call_acl_name .. " matched")
if call_acl_action == 'reject' then
log("ACL is reject. Stop process call")
session:execute('hangup', "BEARERCAPABILITY_NOTAUTH")
elseif (details[0] =="Voicemail") then
log("ACL to Voicemail. Stop process call")
session:setAutoHangup(false)
session:execute("transfer", "*99" .. details[2] .. " XML " .. details[1])
elseif
-- We found pattern match and this is allow (means not reject)
log("ACL is allow. Stop process ACLs")
end
return
end
 

DigitalDaz

Administrator
Staff member
Sep 29, 2016
2,300
359
83
A pull request is a github thing. You fork the project then make changes to the fork and in there somewhere is an option to submit a pull request.