Using Dynamic Routes & Pin Sets to Authenticate Caller

This post was shared on reddit which I thought it was really clever. It’s the first time I can recall ever seeing an example of the pinsets module being used for anything other than it’s intent. I immediately wondered how I might incorporate this technique into dynroutes so that no custom dialplan was necessary.

The intent of the Pin Sets module is to restrict access to outbound routes and thus control which local extensions can dial which external numbers. But suppose you need to create a call flow where you want to challenge a caller for a PIN before they can continue (after hours support?). You could use an IVR, but since IVRs are static, that would probably mean sharing PINs across users and it won’t scale beyond a few PINs. Better is to create a Pin Set for this purpose with a complete list of acceptable codes and then refer to that list using a dynroute. Restricting or expanding access in the future is just a matter of editing the Pin Set.

Step 1 - Create a Pin Set

All that’s required is a name and a list of codes. It’s best if all codes are the same length, but not required. For our purposes here the ‘record in CDR’ option will be ignored. Once done, you must determine the index for the Pin Set, when editing note the trailing digit(s) in the URL that follow itemid=. We will use the index in the dynroute, and for this example we’re assuming the index=1.

Step 2 - Create the Dynamic Route

Create a Dynamic Route, enter a name and set “Enable DTMF Input” to yes. Fill out the fields for prompting and validating the input if desired. Set a name in “Saved input variable name”, in this example I’m using dtmf_in. For Source type select Asterisk Variable, Disable Substitutions and set Asterisk variable to:

$[${DB_EXISTS(PINSETS/1/${DYNROUTE_dtmf_in})}]

The above expression checks the AstDB for a PIN in index 1 that matches the caller DTMF input. If your PIn Set is another index, substitute that value. It’s required to disable substitutions for this config, because our Asterisk expression uses square brackets that are not intended to refer to a dynroute variable. Wrapping this in $[] makes it a condition which will return a 0 if false or 1 if true.

Step 3 - Create the Dynamic Route Entries

Create 2 entries, one with a match of 0 and one with a match of 1. Direct each case to the appropriate FreePBX destination, something like this:

Limitations:

The method above as written will only allow the caller a single attempt to enter a PIN. You might want to chain 2-3 dynroutes together to give them multiple attempts. One of the strengths of using Pin Sets is to record the PIN in the CDR for record keeping purposes. If you need that feature, it could be done with more Dynamic Routes, but prob easier just to follow the method linked at the top.

2 Likes

Modification of the above where instead of challenging the caller for a PIN via DTMF, you check to see if the Caller ID is in the Pin Set list.

Don’t enable DTMF input.
Keep substitutions disabled

Asterisk Variable expression, sub the appropriate index number in place of the 1:

$[${DB_EXISTS(PINSETS/1/${CALLERID(number)})}]

Expression will return a 1 if the callers CID number is in the pinset list otherwise will return zero.

This topic was automatically closed 31 days after the last reply. New replies are no longer allowed.