#!/usr/bin/perl #!/usr/bin/perl ############################################################# ############################################################# # # # Perl agi Script for Authenticate caller via RADIUS or DBA D # Perl agi Script for Authenticate caller via RADIUS or DBA D # # # Switzernet(c)2011 # Switzernet(c)2011 # # ############################################################# ############################################################# # my modules # my modules use Crypt::CBC; use Crypt::CBC; use Asterisk::AGI; use Asterisk::AGI; use Authen::Radius; use Authen::Radius; use Sys::Syslog; use Sys::Syslog; use Switch; use Switch; use List::Util; use List::Util; use Config::IniFiles; use Config::IniFiles; use Date::Format; use Date::Format; use Time::HiRes qw/gettimeofday/; use Time::HiRes qw/gettimeofday/; use DBI; use DBI; use Data::Dumper; use Data::Dumper; use constant ROUTING => "SIP"; use constant ROUTING => "SIP"; #Disable debug | #1 to enable debug use constant DEBUG => 0; use constant DEBUG => 0; use constant {H323_CONTINUE => 0, use constant {H323_CONTINUE => 0, H323_INVALID_ACC => 1, H323_INVALID_ACC => 1, H323_MAX_SIMUL_CALLS => 3, H323_MAX_SIMUL_CALLS => 3, H323_ACC_EXPIRED => 5, H323_ACC_EXPIRED => 5, H323_CREDIT_LIMIT => 6, H323_CREDIT_LIMIT => 6, H323_ACC_BLOCKED => 7, H323_ACC_BLOCKED => 7, H323_TECH_PROB => 8, H323_TECH_PROB => 8, H323_DEST_BLOCKED => 9, H323_DEST_BLOCKED => 9, H323_FREE_CALL => 13 | H323_FREE_CALL => 13, > H323_INVALID_NUMBER => 14 }; }; use constant {CONTACT_PREFIX => 1, use constant {CONTACT_PREFIX => 1, CONTACT_IP => 0}; CONTACT_IP => 0}; use constant CONFIG_DIR => "/etc/astrad/config"; use constant CONFIG_DIR => "/etc/astrad/config"; | local $Data::Dumper::Indent = 0; ############################################################# ############################################################# # Globals # Globals my $radius_auth = 0; #0 for RADIUS authentication/1 for MySQL my $radius_auth = 0; #0 for RADIUS authentication/1 for MySQL my $credit_time = -1; my $credit_time = -1; my $hangup = 1; my $hangup = 1; my $numroutes = 0; my $numroutes = 0; my $skip_route = 0; my $skip_route = 0; my $iexpires = 0; my $iexpires = 0; my $return_code; my $return_code; my @routes; my @routes; my @Expire; my @Expire; my @Join_Expire; my @Join_Expire; my %expires; my %expires; my $auth_cli; my $auth_cli; my $dial_info = ''; my $dial_info = ''; my $ii; my $ii; my $xtot; my $xtot; my $dnid; my $dnid; my $pbcld; | my $pbcld = ''; my $nroutes; my $nroutes; my $sip_username; my $sip_username; > my $usedauth = 0; my $activeprivacy = 0; my $activeprivacy = 0; my $activeprivacycode; my $activeprivacycode; my $activefollowme = 0; my $activefollowme = 0; my $typefollowme = 0; my $typefollowme = 0; my $fromaccount = 0; my $fromaccount = 0; my $radiusstatus; my $radiusstatus; my $language; my $language; my $calllimit; my $calllimit; my @routeslist; my @routeslist; my @XSUM; my @XSUM; < my $toE164; my $toE164; my $max_duration = 7200; my $max_duration = 7200; my $date_format = "%Y-%m-%d %T"; my $date_format = "%Y-%m-%d %T"; my ($setuptime1,$setupms1) = gettimeofday(); my ($setuptime1,$setupms1) = gettimeofday(); my ($setuptime2,$setupms2); my ($setuptime2,$setupms2); my ($setuptime3,$setupms3); my ($setuptime3,$setupms3); ############################################################# ############################################################# # Database # Database my $dbh; my $dbh; my $LOCAL_HOST; my $LOCAL_HOST; my $DB_NAME1; my $DB_NAME1; my $DB_NAME2; my $DB_NAME2; my $DB_HOST; my $DB_HOST; my $DB_USER; my $DB_USER; my $DB_PASS; my $DB_PASS; ############################################################# ############################################################# # FUNCTION # FUNCTION ############################################################# ############################################################# # Load config # Load config sub load_config { sub load_config { my $conf=Config::IniFiles->new(-file => CONFIG_DIR ."/swi my $conf=Config::IniFiles->new(-file => CONFIG_DIR ."/swi return 0 if !defined $conf ; return 0 if !defined $conf ; $LOCAL_HOST = $conf->val('GLOBAL','NAS_IP'); $LOCAL_HOST = $conf->val('GLOBAL','NAS_IP'); $DB_NAME1 = $conf->val('DB3','DB_NAME1'); $DB_NAME1 = $conf->val('DB3','DB_NAME1'); $DB_NAME2 = $conf->val('DB3','DB_NAME2'); $DB_NAME2 = $conf->val('DB3','DB_NAME2'); $DB_HOST = $conf->val('DB3','DB_HOST'); $DB_HOST = $conf->val('DB3','DB_HOST'); $DB_USER = $conf->val('DB3','DB_USER'); $DB_USER = $conf->val('DB3','DB_USER'); $DB_PASS = $conf->val('DB3','DB_PASS'); $DB_PASS = $conf->val('DB3','DB_PASS'); return 1; return 1; } } sub unescape { sub unescape { shift() if ref($_[0]); shift() if ref($_[0]); my $todecode = shift; my $todecode = shift; return undef unless defined($todecode); return undef unless defined($todecode); #$todecode =~ tr/+/ /; # pluses become spaces #$todecode =~ tr/+/ /; # pluses become spaces $todecode =~ s/%([0-9a-fA-F]{2})/pack("c",hex($1))/ge; $todecode =~ s/%([0-9a-fA-F]{2})/pack("c",hex($1))/ge; return $todecode; return $todecode; } } sub set_asterisk_variables { sub set_asterisk_variables { $max_duration=$credit_time if ($credit_time > 0 && $credit_ $max_duration=$credit_time if ($credit_time > 0 && $credit_ $AGI->set_variable('II', $ii); $AGI->set_variable('II', $ii); $AGI->set_variable('XTOT', $xtot); $AGI->set_variable('XTOT', $xtot); $AGI->set_variable('DNID', $dnid) if $dnid ne ''; $AGI->set_variable('DNID', $dnid) if $dnid ne ''; $AGI->set_variable('PBCLD',$pbcld) if $pbcld ne ''; $AGI->set_variable('PBCLD',$pbcld) if $pbcld ne ''; $AGI->set_variable('NumRoutes', $nroutes); $AGI->set_variable('NumRoutes', $nroutes); $AGI->set_variable('SIP_Username', $sip_username) if $sip_ $AGI->set_variable('SIP_Username', $sip_username) if $sip_ $AGI->set_variable('ActivePrivacy', $activeprivacy) if $act $AGI->set_variable('ActivePrivacy', $activeprivacy) if $act $AGI->set_variable('RADIUS_Status', $radiusstatus); $AGI->set_variable('RADIUS_Status', $radiusstatus); $AGI->set_variable('ActiveFolloMe', $activefollowme) if $ac $AGI->set_variable('ActiveFolloMe', $activefollowme) if $ac $AGI->set_variable('h323-return-code', $return_code); $AGI->set_variable('h323-return-code', $return_code); $AGI->set_variable('Dial_Info', $dial_info) if $dial_info n $AGI->set_variable('Dial_Info', $dial_info) if $dial_info n $AGI->set_variable('CALL_LIMIT', "L(".$max_duration."000:12 $AGI->set_variable('CALL_LIMIT', "L(".$max_duration."000:12 $AGI->set_variable('LIMIT_PLAYAUDIO_CALLER', 'yes'); $AGI->set_variable('LIMIT_PLAYAUDIO_CALLER', 'yes'); if ($language eq "en" || $language eq "de" || $language eq if ($language eq "en" || $language eq "de" || $language eq $AGI->set_variable('CHANNEL(language)',$language); $AGI->set_variable('CHANNEL(language)',$language); $AGI->verbose("SV SET LANGUAGE = ".$language,5) if $AGI->verbose("SV SET LANGUAGE = ".$language,5) if } else { } else { $AGI->verbose("SV DESIRED LANGUAGE= ".$language,5) $AGI->verbose("SV DESIRED LANGUAGE= ".$language,5) } } if (DEBUG) { if (DEBUG) { $AGI->verbose("SV II = ".$ii,5); $AGI->verbose("SV II = ".$ii,5); $AGI->verbose("SV DNID = ".$dnid,5); $AGI->verbose("SV DNID = ".$dnid,5); $AGI->verbose("SV XTOT = ".$xtot,5); $AGI->verbose("SV XTOT = ".$xtot,5); $AGI->verbose("SV PBCLD = ".$pbcld,5); $AGI->verbose("SV PBCLD = ".$pbcld,5); $AGI->verbose("SV Dial_Info = ".$dial_info,5); $AGI->verbose("SV Dial_Info = ".$dial_info,5); $AGI->verbose("SV NumRoutes = ".$nroutes,5); $AGI->verbose("SV NumRoutes = ".$nroutes,5); $AGI->verbose("SV SIP_Username = ".$sip_username,5); $AGI->verbose("SV SIP_Username = ".$sip_username,5); $AGI->verbose("SV ActivePrivacy= ".$activeprivacy,5); $AGI->verbose("SV ActivePrivacy= ".$activeprivacy,5); $AGI->verbose("SV ActiveFolloMe= ".$activefollowme,5); $AGI->verbose("SV ActiveFolloMe= ".$activefollowme,5); $AGI->verbose("SV RADIUS_Status= ".$radiusstatus,5); $AGI->verbose("SV RADIUS_Status= ".$radiusstatus,5); $AGI->verbose("SV CALL_LIMIT = L(".$max_duration."000:1 $AGI->verbose("SV CALL_LIMIT = L(".$max_duration."000:1 $AGI->verbose("SV h323-return-code=".$return_code,5); $AGI->verbose("SV h323-return-code=".$return_code,5); $AGI->verbose("SV LIMIT_PLAYAUDIO_CALLER=yes",5); $AGI->verbose("SV LIMIT_PLAYAUDIO_CALLER=yes",5); } } syslog('info', "Ast-Aut: II = ".$ii); syslog('info', "Ast-Aut: II = ".$ii); syslog('info', "Ast-Aut: XTOT = ".$xtot); syslog('info', "Ast-Aut: XTOT = ".$xtot); syslog('info', "Ast-Aut: AGI dial info = ".$dial_info); syslog('info', "Ast-Aut: AGI dial info = ".$dial_info); syslog('info', "Ast-Aut: return_code = ".$return_code); syslog('info', "Ast-Aut: return_code = ".$return_code); syslog('info', "Ast-Aut: PortaBilling_Auth_Reseller_CLD=".$ syslog('info', "Ast-Aut: PortaBilling_Auth_Reseller_CLD=".$ $AGI->hangup() if $return_code != 0 && $return_code != 13 & $AGI->hangup() if $return_code != 0 && $return_code != 13 & } } ############################################################# ############################################################# # # # Authenticate the client using db2 instead of Radius # Authenticate the client using db2 instead of Radius # Also return client data. # Also return client data. # # # params : - username of client # params : - username of client # # # return : - h323-return-code : # return : - h323-return-code : # o H323_TECH_PROB if database is unavailable # o H323_TECH_PROB if database is unavailable # o H323_INVALID_ACC if acc doesn't exist in db # o H323_INVALID_ACC if acc doesn't exist in db # o H323_ACC_BLOCKED if acc or customer is blocked # o H323_ACC_BLOCKED if acc or customer is blocked # o H323_ACC_EXPIRED if acc is expired # o H323_ACC_EXPIRED if acc is expired # o H323_MAX_SIMUL_CALLS if call limitation reache # o H323_MAX_SIMUL_CALLS if call limitation reache # o H323_CONTINUE else # o H323_CONTINUE else # # # - credit state : # - credit state : # o 1 if client has credits # o 1 if client has credits # o 0 else # o 0 else # # sub alternative_acc_auth { sub alternative_acc_auth { my $cli = @_[0]; my $cli = @_[0]; if (not defined $dbh){ if (not defined $dbh){ # Not available # Not available syslog('err', "Ast-Aut: Could not connect to database syslog('err', "Ast-Aut: Could not connect to database return (H323_TECH_PROB); return (H323_TECH_PROB); } } ######################################################### ######################################################### # # # Check the caller to know if he is allowed to call or if # Check the caller to know if he is allowed to call or if # # my $request="SELECT c.balance < c.credit_limit AS 'has_cr my $request="SELECT c.balance < c.credit_limit AS 'has_cr ." (c.blocked = 'Y' OR a.blocked = 'Y') AS ." (c.blocked = 'Y' OR a.blocked = 'Y') AS ." (a.expiration_date < CURDATE()) or fals ." (a.expiration_date < CURDATE()) or fals ." a.iso_639_1 as language, " ." a.iso_639_1 as language, " ." c.cld_translation_rule as transrule, " ." c.cld_translation_rule as transrule, " ." a.follow_me_enabled, " ." a.follow_me_enabled, " ." a.i_customer, i_account "; ." a.i_customer, i_account "; if (DEBUG) { if (DEBUG) { # if in debug mode request more details # if in debug mode request more details $request .=", c.balance AS 'balance', c.credit_limit $request .=", c.balance AS 'balance', c.credit_limit ." c.blocked AS 'cust_blocked', a.blocked ." c.blocked AS 'cust_blocked', a.blocked ." a.expiration_date AS 'expires', CURDATE ." a.expiration_date AS 'expires', CURDATE } } $request .=" FROM Accounts a " $request .=" FROM Accounts a " ." INNER JOIN Customers c " ." INNER JOIN Customers c " ." ON (a.i_customer = c.i_customer) " ." ON (a.i_customer = c.i_customer) " ." WHERE a.id='$cli';"; ." WHERE a.id='$cli';"; my $sth = $dbh->prepare($request); my $sth = $dbh->prepare($request); $sth->execute(); $sth->execute(); | $AGI->verbose(Dumper($request),5) if (DEBUG); my @data1; my @data1; return (H323_INVALID_ACC) unless(@data1 = $sth->fetchrow( return (H323_INVALID_ACC) unless(@data1 = $sth->fetchrow( $language = $data1[3]; $language = $data1[3]; $toE164 = $data1[4]; $toE164 = $data1[4]; $activefollowme = 1 if ($data1[5] eq 'Y'); $activefollowme = 1 if ($data1[5] eq 'Y'); my $customerid = $data1[6]; my $customerid = $data1[6]; my $accountid = $data1[7]; my $accountid = $data1[7]; if ($fromaccount == 1) { if ($fromaccount == 1) { #Call from a customers account #Call from a customers account # Checks if the customer has CID hiding configured or s # Checks if the customer has CID hiding configured or s # TODO with this query it is not possible to see if the # TODO with this query it is not possible to see if the # see how to differentiate options use default and no f # see how to differentiate options use default and no f my $request2 = "SELECT sav.i_sattribute, sav.value " my $request2 = "SELECT sav.i_sattribute, sav.value " ."FROM Service_Attribute_Values sav " ."FROM Service_Attribute_Values sav " ."WHERE (sav.i_foreign = '".$customerid." ."WHERE (sav.i_foreign = '".$customerid." ."OR (sav.i_foreign = '".$accountid."' AN ."OR (sav.i_foreign = '".$accountid."' AN my $sth = $dbh->prepare($request2); my $sth = $dbh->prepare($request2); $sth->execute(); $sth->execute(); > $AGI->verbose(Dumper($request2),5) if (DEBUG); while (my $data2 = $sth->fetchrow_hashref()) { while (my $data2 = $sth->fetchrow_hashref()) { if (defined($data2->{value})) { if (defined($data2->{value})) { switch ($data2->{i_sattribute}) { switch ($data2->{i_sattribute}) { # Sets simultanous call limit # Sets simultanous call limit case 1 { case 1 { $calllimit = $data2->{value} if ($data2->{value $calllimit = $data2->{value} if ($data2->{value } } # Sets hide cli code # Sets hide cli code case 5 { case 5 { $data2->{value} =~ m/hide=(.*)/; $data2->{value} =~ m/hide=(.*)/; $activeprivacycode = $1 if ($1 ne ''); $activeprivacycode = $1 if ($1 ne ''); } } case 6 { case 6 { $data2->{value} =~ m/hide=(.*)/; $data2->{value} =~ m/hide=(.*)/; $activeprivacycode = $1 if ($1 ne '' && !define $activeprivacycode = $1 if ($1 ne '' && !define } } } } } } } } if ($calllimit > 0) { if ($calllimit > 0) { my $request3 = "SELECT count(*) AS total " my $request3 = "SELECT count(*) AS total " ."FROM Active_Calls where CLI='".$cli." ."FROM Active_Calls where CLI='".$cli." my $sth = $dbh->prepare($request3); my $sth = $dbh->prepare($request3); } } if (my $data2 = $sth->fetchrow_hashref() && $data2->{to if (my $data2 = $sth->fetchrow_hashref() && $data2->{to return (H323_MAX_SIMUL_CALLS,undef,@data1); return (H323_MAX_SIMUL_CALLS,undef,@data1); } } } } #Call from a node to a customers account #Call from a node to a customers account #Follow me #Follow me #TODO this should be in the route function #TODO this should be in the route function if ($activefollowme) { if ($activefollowme) { my $request4 = "SELECT mode, sequence, timeout " my $request4 = "SELECT mode, sequence, timeout " ."FROM Follow_Me where i_account='".$acco ."FROM Follow_Me where i_account='".$acco my $sth = $dbh->prepare($request4); my $sth = $dbh->prepare($request4); if (my $data2 = $sth->fetchrow_hashref()) { if (my $data2 = $sth->fetchrow_hashref()) { #Modes: Never, Always, Unavail #Modes: Never, Always, Unavail #Sequence: Order, Random, Simultaneous #Sequence: Order, Random, Simultaneous if ($data2->{mode} eq 'Never') { if ($data2->{mode} eq 'Never') { $activefollowme = 0; $activefollowme = 0; } else { } else { $activefollowme = 2 if ($data2->{mode} eq 'Always') $activefollowme = 2 if ($data2->{mode} eq 'Always') $typefollowme = 1 if ($data2->{sequence} eq 'Rand $typefollowme = 1 if ($data2->{sequence} eq 'Rand $typefollowme = 2 if ($data2->{sequence} eq 'Simu $typefollowme = 2 if ($data2->{sequence} eq 'Simu } } } } } } # Account or customer is blocked # Account or customer is blocked return (H323_ACC_BLOCKED,undef,@data1) if ($data1[1]); return (H323_ACC_BLOCKED,undef,@data1) if ($data1[1]); # Account is expired # Account is expired return (H323_ACC_EXPIRED,undef,@data1) if ($data1[2]); return (H323_ACC_EXPIRED,undef,@data1) if ($data1[2]); return (H323_CONTINUE,$data1[0],@data1); return (H323_CONTINUE,$data1[0],@data1); } } ############################################################# ############################################################# # # # Authenticate a node using db2 instead of Radius # Authenticate a node using db2 instead of Radius # # # params : - ip of node # params : - ip of node # # # return : - h323-return-code : # return : - h323-return-code : # o H323_TECH_PROB if database is unavailable # o H323_TECH_PROB if database is unavailable # o H323_INVALID_ACC if acc doesn't exist in db # o H323_INVALID_ACC if acc doesn't exist in db # o H323_ACC_BLOCKED if acc or customer is blocked # o H323_ACC_BLOCKED if acc or customer is blocked # o H323_ACC_EXPIRED if acc is expired # o H323_ACC_EXPIRED if acc is expired # o H323_CONTINUE else # o H323_CONTINUE else # # # - credit state : # - credit state : # o 1 if client has credits # o 1 if client has credits # o 0 else # o 0 else # # sub alternative_ip_auth { sub alternative_ip_auth { my $node = @_[0]; my $node = @_[0]; if (not defined $dbh){ if (not defined $dbh){ # Not available # Not available syslog('err', "Ast-Aut: Could not connect to database syslog('err', "Ast-Aut: Could not connect to database return (H323_TECH_PROB); return (H323_TECH_PROB); } } ######################################################### ######################################################### # # # Check if the node is allowed to call # Check if the node is allowed to call # # #TODO use local table sipdevices where context fromhost i #TODO use local table sipdevices where context fromhost i my $request="SELECT ip,name my $request="SELECT ip,name FROM Nodes FROM Nodes WHERE ip = '$node' WHERE ip = '$node' AND i_env=1 AND i_env=1 AND i_node_type=11 AND i_node_type=11 AND name not like '%[Deleted]%'"; AND name not like '%[Deleted]%'"; my $sth = $dbh->prepare($request); my $sth = $dbh->prepare($request); $sth->execute(); $sth->execute(); return H323_INVALID_ACC unless (my $result1 = $sth->fetch return H323_INVALID_ACC unless (my $result1 = $sth->fetch return H323_CONTINUE; return H323_CONTINUE; } } ############################################################# ############################################################# # # # Define the route to destinations # Define the route to destinations # # # params : - destination # params : - destination # # # # # return : - h323 return code # return : - h323 return code # - formated destination # - formated destination # - a list of ip to contact for routing # - a list of ip to contact for routing # # sub define_routing_params { sub define_routing_params { # return values # return values my ($return_code, $dest, @contacts); my ($return_code, $dest, @contacts); my $dest = @_[0]; my $dest = @_[0]; ######################################################### ######################################################### # Do the regexp rules depending on number called # Do the regexp rules depending on number called # It is important to match a format like +cc num # It is important to match a format like +cc num # If it begins by the national prefix (0) replace it by 4 # If it begins by the national prefix (0) replace it by 4 my $prefix_international = '00'; my $prefix_international = '00'; my $prefix_domestic = '0'; my $prefix_domestic = '0'; my $country_code = '41'; my $country_code = '41'; if ($toE164 ne '') { if ($toE164 ne '') { #User as defined rules #User as defined rules if($toE164 =~ m/#.* dp.([\d]+) .*/) { if($toE164 =~ m/#.* dp.([\d]+) .*/) { $prefix_domestic = $1; $prefix_domestic = $1; } else { } else { $prefix_domestic = ''; $prefix_domestic = ''; } } if($toE164 =~ m/#.* ip.([\d]+) .*/) { if($toE164 =~ m/#.* ip.([\d]+) .*/) { $prefix_international = $1 if ($1 ne ''); $prefix_international = $1 if ($1 ne ''); } } if($toE164 =~ m/#.* cc.([\d]+) .*/) { if($toE164 =~ m/#.* cc.([\d]+) .*/) { $country_code = $1 if ($1 ne ''); $country_code = $1 if ($1 ne ''); } } } else { } else { $country_code = '' if ($dest =~ m/^$country_code/); $country_code = '' if ($dest =~ m/^$country_code/); } } $AGI->verbose("OriginalDest=$dest",5) if (DEBUG); $AGI->verbose("OriginalDest=$dest",5) if (DEBUG); if (defined($activeprivacycode)) { if (defined($activeprivacycode)) { # User has a privacy code enabled # User has a privacy code enabled $activeprivacycode =~ s/([*+]{1})/\\$1/m; $activeprivacycode =~ s/([*+]{1})/\\$1/m; $AGI->verbose("Activeprivacycode=$activeprivacycode",6) $AGI->verbose("Activeprivacycode=$activeprivacycode",6) if ($dest =~ m/^$activeprivacycode/) { if ($dest =~ m/^$activeprivacycode/) { $activeprivacy = 1; $activeprivacy = 1; $dest =~ s/^$activeprivacycode//; $dest =~ s/^$activeprivacycode//; } } } } # remove 00 or + and the local prefix and replace it by t # remove 00 or + and the local prefix and replace it by t if ($dest =~ m/^($prefix_international|\+)/) { if ($dest =~ m/^($prefix_international|\+)/) { $dest =~ s/^($prefix_international|\+)//; $dest =~ s/^($prefix_international|\+)//; } else { } else { $dest =~ s/^$prefix_domestic//; $dest =~ s/^$prefix_domestic//; $dest =~ s/^/$country_code/; $dest =~ s/^/$country_code/; } } $AGI->verbose("E164Dest=$dest",5) if (DEBUG); $AGI->verbose("E164Dest=$dest",5) if (DEBUG); ######################################################### ######################################################### # # # Check the dest to know if it is a free call or not # Check the dest to know if it is a free call or not # # my $request="SELECT id FROM Accounts WHERE id='$dest';"; my $request="SELECT id FROM Accounts WHERE id='$dest';"; $sth = $dbh->prepare($request); $sth = $dbh->prepare($request); $sth->execute(); $sth->execute(); my $acc_data = $sth->fetchrow_hashref(); my $acc_data = $sth->fetchrow_hashref(); my $is_outgoing = not defined $acc_data->{id}; my $is_outgoing = not defined $acc_data->{id}; my $join_expire = 1; my $join_expire = 1; my $expire = 300; my $expire = 300; $XSUM[$join_expire] = 0; $XSUM[$join_expire] = 0; if ($is_outgoing) { if ($is_outgoing) { my $forcerates = 1; #Forces fixed routing my $forcerates = 1; #Forces fixed routing if ($forcerates == 0) { if ($forcerates == 0) { #Gets list of vendors from database with outgoing for #Gets list of vendors from database with outgoing for $request="SELECT c.remote_ip,c.cld_translation_rule " $request="SELECT c.remote_ip,c.cld_translation_rule " $request.=",c.description,c.outgoing_cld_translation_ $request.=",c.description,c.outgoing_cld_translation_ $request.="FROM `porta-billing`.Connections c, (" $request.="FROM `porta-billing`.Connections c, (" ."SELECT * FROM (" ."SELECT * FROM (" ."SELECT i_tariff, price_1, preference, ."SELECT i_tariff, price_1, preference, ."FROM Rates " ."FROM Rates " ."WHERE i_dest=(" ."WHERE i_dest=(" ."SELECT i_dest " ."SELECT i_dest " ."FROM Destinations des " ."FROM Destinations des " ."WHERE '".$dest."' LIKE CONCAT(des.de ."WHERE '".$dest."' LIKE CONCAT(des.de ."ORDER BY LENGTH(des.destination) des ."ORDER BY LENGTH(des.destination) des .") AND effective_from < NOW() " .") AND effective_from < NOW() " .") AS tout " .") AS tout " ."GROUP BY tout.i_tariff) r " ."GROUP BY tout.i_tariff) r " ."WHERE c.i_env=1 AND c.remote_ip REGEXP '^( ."WHERE c.i_env=1 AND c.remote_ip REGEXP '^( ."ORDER BY r.preference DESC, r.price_1 ASC; ."ORDER BY r.preference DESC, r.price_1 ASC; $sth = $dbh->prepare($request); $sth = $dbh->prepare($request); $sth->execute(); $sth->execute(); my $append=''; my $append=''; while(my $acc_data2 = $sth->fetchrow_hashref()) { while(my $acc_data2 = $sth->fetchrow_hashref()) { if (not defined $acc_data2->{outgoing_cld_translati if (not defined $acc_data2->{outgoing_cld_translati $acc_data2->{outgoing_cld_translation_rule} = ''; $acc_data2->{outgoing_cld_translation_rule} = ''; $append=''; $append=''; } else { } else { $acc_data2->{outgoing_cld_translation_rule} =~ /^ $acc_data2->{outgoing_cld_translation_rule} =~ /^ $append = $1; $append = $1; $append =~ s/\\//m; $append =~ s/\\//m; } } push(@routeslist, [$join_expire."_".$XSUM[$join_exp push(@routeslist, [$join_expire."_".$XSUM[$join_exp $XSUM[$join_expire]++; $XSUM[$join_expire]++; } } } else { } else { push(@routeslist, ["1_0", ROUTING."/+".$dest.'@212.24 push(@routeslist, ["1_0", ROUTING."/+".$dest.'@212.24 push(@routeslist, ["1_1", ROUTING."/+".$dest.'@212.24 push(@routeslist, ["1_1", ROUTING."/+".$dest.'@212.24 push(@routeslist, ["1_2", ROUTING."/00".$dest.'@212.2 push(@routeslist, ["1_2", ROUTING."/00".$dest.'@212.2 push(@routeslist, ["1_3", ROUTING."/00".$dest.'@217.1 push(@routeslist, ["1_3", ROUTING."/00".$dest.'@217.1 $XSUM[$join_expire]=4; $XSUM[$join_expire]=4; } } $return_code = H323_CONTINUE; $return_code = H323_CONTINUE; } else { } else { # Find and define the right SIP server (only phones r # Find and define the right SIP server (only phones r #TODO Enable Followme in DBA #TODO Enable Followme in DBA my $request="SELECT domain FROM `$DB_NAME2`.location2 my $request="SELECT domain FROM `$DB_NAME2`.location2 ."WHERE username='$dest' ORDER BY receptio ."WHERE username='$dest' ORDER BY receptio my $sth = $dbh->prepare($request); my $sth = $dbh->prepare($request); $sth->execute(); $sth->execute(); my $location = $sth->fetchrow_hashref(); my $location = $sth->fetchrow_hashref(); # dest format unchanged # dest format unchanged push(@routeslist, [$join_expire."_".$XSUM[$join_expir push(@routeslist, [$join_expire."_".$XSUM[$join_expir $XSUM[$join_expire]++; $XSUM[$join_expire]++; $return_code = H323_FREE_CALL; $return_code = H323_FREE_CALL; } } $dnid = $dest; $dnid = $dest; return $return_code; return $return_code; } } sub set_routing_data { sub set_routing_data { > $AGI->set_variable('UsedAuth', $usedauth); for my $i ( 0 .. $#routeslist ) { for my $i ( 0 .. $#routeslist ) { if ($routeslist[$i][1] && $routeslist[$i][2] && $rout if ($routeslist[$i][1] && $routeslist[$i][2] && $rout $nroutes++; $nroutes++; $AGI->set_variable("XROUTE_".$routeslist[$i][0], $AGI->set_variable("XROUTE_".$routeslist[$i][0], $AGI->set_variable("XEXP_".$routeslist[$i][0], $r $AGI->set_variable("XEXP_".$routeslist[$i][0], $r $AGI->set_variable("XCLI_".$routeslist[$i][0], $r $AGI->set_variable("XCLI_".$routeslist[$i][0], $r if (DEBUG) { if (DEBUG) { $AGI->verbose("SV XROUTE_".$routeslist[$i][0] $AGI->verbose("SV XROUTE_".$routeslist[$i][0] $AGI->verbose("SV XEXP_".$routeslist[$i][0]." $AGI->verbose("SV XEXP_".$routeslist[$i][0]." $AGI->verbose("SV XCLI_".$routeslist[$i][0]." $AGI->verbose("SV XCLI_".$routeslist[$i][0]." } } $dial_info .= '&' if $dial_info ne ''; $dial_info .= '&' if $dial_info ne ''; $dial_info .= $routeslist[$i][1]; $dial_info .= $routeslist[$i][1]; syslog('info', "Ast-Aut: XROUTE_".$routeslist[$i] syslog('info', "Ast-Aut: XROUTE_".$routeslist[$i] } } } } my $k = 0; my $k = 0; $ii=0; $ii=0; foreach my $vl (@XSUM) { foreach my $vl (@XSUM) { if ($vl) { if ($vl) { syslog('info', "Ast-Aut: XSUM_$k = $vl"); syslog('info', "Ast-Aut: XSUM_$k = $vl"); $AGI->set_variable("XSUM_$k", $vl); $AGI->set_variable("XSUM_$k", $vl); $AGI->verbose("SV XSUM_".$k." = ".$vl,5) if (DEBU $AGI->verbose("SV XSUM_".$k." = ".$vl,5) if (DEBU $ii=$k if (!$ii); $ii=$k if (!$ii); } } $k++; $k++; } } $k = $k - 1 ; $k = $k - 1 ; $xtot=$k; $xtot=$k; } } sub set_routing_data2 { sub set_routing_data2 { $radiusstatus = 'OK'; $radiusstatus = 'OK'; } } ############################################################# ############################################################# # main() # main() ############################################################# ############################################################# $AGI = new Asterisk::AGI; $AGI = new Asterisk::AGI; my %input = $AGI->ReadParse(); my %input = $AGI->ReadParse(); openlog('ast-auth', 'cons,pid', 'daemon'); openlog('ast-auth', 'cons,pid', 'daemon'); syslog('notice', "Ast-Aut: Script Asterisk Authentication Sta syslog('notice', "Ast-Aut: Script Asterisk Authentication Sta $AGI->verbose("AGI START",0); $AGI->verbose("AGI START",0); my $username; my $username; my %params; my %params; my(@pairs) = split(/[&;]/,$ARGV[0]); my(@pairs) = split(/[&;]/,$ARGV[0]); my($param,$value); my($param,$value); foreach (@pairs) { foreach (@pairs) { ($param,$value) = split('=',$_,2); ($param,$value) = split('=',$_,2); $param = unescape($param); $param = unescape($param); $value = unescape($value); $value = unescape($value); $params{$param}=$value; $params{$param}=$value; } } ############################################################# ############################################################# # Sending auth. radius packet to portaone server # Sending auth. radius packet to portaone server $hangup = 0 if defined $params{'IfFailed'} && $params{'IfFail $hangup = 0 if defined $params{'IfFailed'} && $params{'IfFail my ($a,$b,$c,$d) = ($1,$2,$3,$4) if defined $params{'H323_ID' my ($a,$b,$c,$d) = ($1,$2,$3,$4) if defined $params{'H323_ID' my $h323_id = sprintf("%08X %08X %08X %08X",$a,$b,$c,$d); my $h323_id = sprintf("%08X %08X %08X %08X",$a,$b,$c,$d); $AGI->verbose("H323 hex: $h323_id"); $AGI->verbose("H323 hex: $h323_id"); $max_duration = $AGI->get_variable('max_duration'); $max_duration = $AGI->get_variable('max_duration'); my $r = new Authen::Radius(Host => $AGI->get_variable('RADIUS my $r = new Authen::Radius(Host => $AGI->get_variable('RADIUS if( !defined $r ) { if( !defined $r ) { $AGI->verbose('RADIUS server "'.$AGI->get_variable('R $AGI->verbose('RADIUS server "'.$AGI->get_variable('R $AGI->hangup() if $hangup; $AGI->hangup() if $hangup; syslog('err', "Ast-Aut: Error in Portaone Radius conn syslog('err', "Ast-Aut: Error in Portaone Radius conn closelog; closelog; exit; exit; } } Authen::Radius->load_dictionary; Authen::Radius->load_dictionary; $input{'callerid'} = $1 if defined $input{'callerid'} && $in $input{'callerid'} = $1 if defined $input{'callerid'} && $in $input{'dnid'} = $1 if defined $input{'dnid'} && $input{'dni | $input{'dnid'} = $AGI->get_variable('CALLERID(dnid)') if ($AG | if (!defined $input{'dnid'}) { > $return_code = H323_INVALID_NUMBER; > $AGI->set_variable("VERIFIED_EXTEN", $input{'dnid'}); > set_asterisk_variables (); > closelog; > exit; > } > $input{'dnid'} = $1 if defined $input{'dnid'} && $input{'dni > $AGI->verbose("DNID: ".$input{'dnid'}) if DEBUG; > if ($input{'dnid'} =~ /^([+]*[#*\d]+)$/) { > #TODO Replace + for international prefix defined in database > #TODO Dialing to internacional prefixes using hide callerid c > $input{'dnid'} =~ s/^[+]/00/; > $AGI->verbose("DNID2: $input{'dnid'}") if DEBUG; > #FIXME Adding * to the dialed number is a temporary fix to su > $AGI->set_variable("VERIFIED_EXTEN", "*".$input{'dnid'}); > } else { > $return_code = H323_INVALID_NUMBER; > $AGI->set_variable("VERIFIED_EXTEN", "*".$input{'dnid'}); > set_asterisk_variables (); > closelog; > exit; > } $r->add_attributes ( $r->add_attributes ( { Name => 'NAS-IP-Address', Value => $AGI->get_variable(' { Name => 'NAS-IP-Address', Value => $AGI->get_variable(' { Name => 'NAS-Port-Name', Value => $input{'channel'} }, { Name => 'NAS-Port-Name', Value => $input{'channel'} }, { Name => 'Calling-Station-Id', Value => $input{'callerid { Name => 'Calling-Station-Id', Value => $input{'callerid { Name => 'Called-Station-Id', Value => $input{'dnid'} }, { Name => 'Called-Station-Id', Value => $input{'dnid'} }, { Name => 'Cisco-AVPair', Value => "call-id=$input{'uniqu { Name => 'Cisco-AVPair', Value => "call-id=$input{'uniqu #{ Name => 'Cisco-AVPair', Value => "call-id=$callid" }, #{ Name => 'Cisco-AVPair', Value => "call-id=$callid" }, { Name => 'Cisco-AVPair', Value => "h323-conf-id=$h323_id { Name => 'Cisco-AVPair', Value => "h323-conf-id=$h323_id ); ); if( defined $params{'AuthorizeBy'} && $params{'AuthorizeBy'} if( defined $params{'AuthorizeBy'} && $params{'AuthorizeBy'} my $sip_auth_header = $AGI->get_variable('SIP_Authorizati my $sip_auth_header = $AGI->get_variable('SIP_Authorizati if( !defined $sip_auth_header ) { if( !defined $sip_auth_header ) { $AGI->verbose("ERROR Authorization=SIP requested but $AGI->verbose("ERROR Authorization=SIP requested but $AGI->set_variable('RADIUS_Status', 'ConfigurationErr $AGI->set_variable('RADIUS_Status', 'ConfigurationErr $AGI->hangup() if $hangup; $AGI->hangup() if $hangup; syslog('err', "Ast-Aut: ERROR Authorization=SIP reque syslog('err', "Ast-Aut: ERROR Authorization=SIP reque closelog; closelog; exit; exit; } } $AGI->verbose("sip_auth_header=$sip_auth_header",5); $AGI->verbose("sip_auth_header=$sip_auth_header",5); $sip_auth_header =~ s/\s*Digest\s*//i; $sip_auth_header =~ s/\s*Digest\s*//i; $AGI->verbose("sip_auth_header=$sip_auth_header",5); $AGI->verbose("sip_auth_header=$sip_auth_header",5); my %sip_auth; my %sip_auth; my(@pairs) = split(/,\s?/,$sip_auth_header); my(@pairs) = split(/,\s?/,$sip_auth_header); my($param,$value); my($param,$value); foreach (@pairs) { foreach (@pairs) { ($param,$value) = split('=',$_,2); ($param,$value) = split('=',$_,2); $param = unescape($param); $param = unescape($param); $value = unescape($value); $value = unescape($value); $value =~ s/^"//; $value =~ s/^"//; $value =~ s/"$//; $value =~ s/"$//; $sip_auth{$param}=$value; $sip_auth{$param}=$value; } } $username = $sip_auth{'username'}; $username = $sip_auth{'username'}; $r->add_attributes ( { Name => 'User-Name', Value => $use $r->add_attributes ( { Name => 'User-Name', Value => $use $r->add_attributes ( { Name => 'Digest-Attributes', Value $r->add_attributes ( { Name => 'Digest-Attributes', Value $r->add_attributes ( { Name => 'Digest-Attributes', Value $r->add_attributes ( { Name => 'Digest-Attributes', Value $r->add_attributes ( { Name => 'Digest-Attributes', Value $r->add_attributes ( { Name => 'Digest-Attributes', Value $r->add_attributes ( { Name => 'Digest-Attributes', Value $r->add_attributes ( { Name => 'Digest-Attributes', Value $r->add_attributes ( { Name => 'Digest-Attributes', Value $r->add_attributes ( { Name => 'Digest-Attributes', Value $r->add_attributes ( { Name => 'Digest-Attributes', Value $r->add_attributes ( { Name => 'Digest-Attributes', Value $r->add_attributes ( { Name => 'Digest-Response', Value = $r->add_attributes ( { Name => 'Digest-Response', Value = $sip_username = $username; $sip_username = $username; } else { } else { #TODO looks wrong, check #TODO looks wrong, check $username = $input{'accountcode'}; $username = $input{'accountcode'}; $r->add_attributes ( { Name => 'User-Name', Value => $inp $r->add_attributes ( { Name => 'User-Name', Value => $inp $r->add_attributes ( { Name => 'Password', Value => $para $r->add_attributes ( { Name => 'Password', Value => $para } } $r->add_attributes ( { Name => 'h323-remote-address', Value = | $r->add_attributes ( { Name => 'h323-remote-address' , Value $r->add_attributes ( { Name => 'h323-ivr-out', Value => "Port | $r->add_attributes ( { Name => 'h323-ivr-out' , Value > $r->add_attributes ( { Name => 'Cisco-AVPair' , Value > $r->add_attributes ( { Name => 'h323-ivr-out' , Value if ($radius_auth == 0) { if ($radius_auth == 0) { $r->send_packet (ACCESS_REQUEST) and $type = $r->recv_packe $r->send_packet (ACCESS_REQUEST) and $type = $r->recv_packe } } if( !defined $type || $radius_auth == 1) { if( !defined $type || $radius_auth == 1) { $error = $r->get_error; $error = $r->get_error; ($setuptime2,$setupms2) = gettimeofday(); ($setuptime2,$setupms2) = gettimeofday(); ######################################################### ######################################################### # # # Master is unavailable. Use db2 to authentificate and ro # Master is unavailable. Use db2 to authentificate and ro # # syslog('info', "Ast-Aut: Master not available => Alternat syslog('info', "Ast-Aut: Master not available => Alternat closelog; closelog; $AGI->verbose("Master unavailable. Trying DBA",0); $AGI->verbose("Master unavailable. Trying DBA",0); openlog('ast-auth-alt', 'cons,pid', 'daemon'); openlog('ast-auth-alt', 'cons,pid', 'daemon'); syslog('info', "Ast-Aut-Alt : Call $h323_id"); syslog('info', "Ast-Aut-Alt : Call $h323_id"); my @debug_data; my @debug_data; load_config(); load_config(); $dbh = DBI->connect("DBI:mysql:$DB_NAME1;host=$DB_HOST", $dbh = DBI->connect("DBI:mysql:$DB_NAME1;host=$DB_HOST", #TODO connect locally (needs required data locally) #TODO connect locally (needs required data locally) #TODO if connection fails try another DBA sequentially (o #TODO if connection fails try another DBA sequentially (o if (not defined $dbh){ if (not defined $dbh){ # DBA2 Not available | # DBA Not available syslog('err', "Ast-Aut: Could not connect to database $ syslog('err', "Ast-Aut: Could not connect to database $ $return_code = H323_TECH_PROB; $return_code = H323_TECH_PROB; } else { } else { > $usedauth = 1; $AGI->verbose("Ast-Aut: Connected to database $DB_NAME1 $AGI->verbose("Ast-Aut: Connected to database $DB_NAME1 # Check in which context we are # Check in which context we are $AGI->verbose("sip_auth_header=Auth by ".$params{'Custo $AGI->verbose("sip_auth_header=Auth by ".$params{'Custo switch ($params{'CustomerType'}) { switch ($params{'CustomerType'}) { ##################################### ##################################### # # # SIP Authentication # SIP Authentication # # case("SipAuth") { case("SipAuth") { $fromaccount=1; $fromaccount=1; ($return_code,my $cli_has_credits, @debug_data) = ($return_code,my $cli_has_credits, @debug_data) = $return_code = define_routing_params($input{'dnid $return_code = define_routing_params($input{'dnid $pbcld=$dnid; $pbcld=$dnid; # check if customer has credits in case of non-f # check if customer has credits in case of non-f $return_code = H323_CREDIT_LIMIT if ($return_code $return_code = H323_CREDIT_LIMIT if ($return_code } } ##################################### ##################################### # # # Node Authentication # Node Authentication # # case("PeerAuth") { case("PeerAuth") { $return_code = alternative_ip_auth($username); $return_code = alternative_ip_auth($username); if ($return_code == H323_CONTINUE) { if ($return_code == H323_CONTINUE) { $dnid = $input{'dnid'}; $dnid = $input{'dnid'}; $pbcld=$dnid; $pbcld=$dnid; my $callerid = $AGI->get_variable('CALLERID(n my $callerid = $AGI->get_variable('CALLERID(n push(@routeslist, ["1_0", ROUTING."/".$dnid, push(@routeslist, ["1_0", ROUTING."/".$dnid, $XSUM[1]=1; $XSUM[1]=1; $join_expire = 1; $join_expire = 1; } } } } ##################################### ##################################### # # # IP Authentication # IP Authentication # # case("IpAuth"){ case("IpAuth"){ ($return_code,my $void,@debug_data) = alternative ($return_code,my $void,@debug_data) = alternative $return_code = define_routing_params($input{'dnid $return_code = define_routing_params($input{'dnid } } } } $dbh->disconnect(); $dbh->disconnect(); } } $radiusstatus = 'OK' if ($return_code == H323_CONTINUE or $radiusstatus = 'OK' if ($return_code == H323_CONTINUE or ($setuptime3,$setupms3) = gettimeofday(); ($setuptime3,$setupms3) = gettimeofday(); my $debug_str; my $debug_str; if (defined @debug_data) { if (defined @debug_data) { $debug_str = ""; $debug_str = ""; foreach $d (@debug_data){ foreach $d (@debug_data){ $debug_str.="," unless $debug_str eq ""; $debug_str.="," unless $debug_str eq ""; $debug_str.=$d; $debug_str.=$d; } } } else { } else { # create empty fields # create empty fields $debug_str = ",,,,,"; $debug_str = ",,,,,"; } } # Log Call ID, CLI, CLD, setup time, connection time, err # Log Call ID, CLI, CLD, setup time, connection time, err syslog('notice', ",$h323_id,$input{'callerid'},$username, syslog('notice', ",$h323_id,$input{'callerid'},$username, .time2str($date_format, $setuptime1).".$se .time2str($date_format, $setuptime1).".$se .time2str($date_format, $setuptime2).".$se .time2str($date_format, $setuptime2).".$se .time2str($date_format, $setuptime3).".$se .time2str($date_format, $setuptime3).".$se .$params{H323_RADDR}.",".$params{'Customer .$params{H323_RADDR}.",".$params{'Customer . $debug_str); . $debug_str); set_routing_data(); set_routing_data(); set_asterisk_variables (); set_asterisk_variables (); closelog; closelog; exit; exit; } } ############################################################# ############################################################# # Treatment reply auth. radius packet from portaone server # Treatment reply auth. radius packet from portaone server my ($ActiveFolloMe,$TypeFollowMe); my ($ActiveFolloMe,$TypeFollowMe); my $Pred_expire=0; my $Pred_expire=0; my $ActivePrivacy=0; my $ActivePrivacy=0; for $a ($r->get_attributes) { for $a ($r->get_attributes) { # $AGI->set_variable($a->{'Name'}, $a->{'Value'}); # $AGI->set_variable($a->{'Name'}, $a->{'Value'}); $AGI->verbose("SV ".$a->{'Name'}."=".$a->{'Value'},6) if $AGI->verbose("SV ".$a->{'Name'}."=".$a->{'Value'},6) if $return_code = $a->{'Value'} if $a->{'Name'} eq 'h323-ret $return_code = $a->{'Value'} if $a->{'Name'} eq 'h323-ret $credit_time = List::Util::min($max_duration,$a->{'Value' $credit_time = List::Util::min($max_duration,$a->{'Value' if( $a->{'Name'} eq 'Cisco-AVPair' && $a->{'Value'} =~ /^ if( $a->{'Name'} eq 'Cisco-AVPair' && $a->{'Value'} =~ /^ $AGI->verbose(" -- AGI full route: $a->{'Value'}", 5 $AGI->verbose(" -- AGI full route: $a->{'Value'}", 5 #TODO this regexp is very important, double-check #TODO this regexp is very important, double-check $a->{'Value'} =~ /^h323-ivr-in=PortaBilling_Routing:\ $a->{'Value'} =~ /^h323-ivr-in=PortaBilling_Routing:\ my ($dest, $contact) = ($1, $2); my ($dest, $contact) = ($1, $2); if ($a->{'Value'} =~ /^h323-ivr-in=PortaBilling_Routi if ($a->{'Value'} =~ /^h323-ivr-in=PortaBilling_Routi $ActivePrivacy=1; $ActivePrivacy=1; } } my %route_info; my %route_info; my(@pairs) = split(/[&;]/,$3); my(@pairs) = split(/[&;]/,$3); my($param,$value); my($param,$value); foreach (@pairs) { foreach (@pairs) { ($param,$value) = split('=',$_,2); ($param,$value) = split('=',$_,2); $param = unescape($param); $param = unescape($param); $value = unescape($value); $value = unescape($value); $route_info{$param}=$value; $route_info{$param}=$value; } } my $cipher = Crypt::CBC->new({ 'key' => $A my $cipher = Crypt::CBC->new({ 'key' => $A 'cipher' => 'D 'cipher' => 'D 'iv' => '$ 'iv' => '$ 'regenerate_key' => 1, 'regenerate_key' => 1, 'padding' => 'o 'padding' => 'o 'prepend_iv' => 0 'prepend_iv' => 0 }); }); my ($authuser, $secret) = split(/\0/, $cipher->decryp my ($authuser, $secret) = split(/\0/, $cipher->decryp $ActiveFolloMe=1 if ($route_info{'access-code'} eq 'F $ActiveFolloMe=1 if ($route_info{'access-code'} eq 'F switch ($route_info{'g-hunt'}) { switch ($route_info{'g-hunt'}) { case 'all' { $TypeFollowMe='Simultaneous';} case 'all' { $TypeFollowMe='Simultaneous';} case 'seq' { $TypeFollowMe='Sequential' ;} case 'seq' { $TypeFollowMe='Sequential' ;} } } if ($route_info{'expires'}) { if ($route_info{'expires'}) { $skip_route++; $skip_route++; $Pred_expire=$route_info{'expires'}; $Pred_expire=$route_info{'expires'}; } } if($dest ne '' and $contact ne '' and ($Pred_expire o if($dest ne '' and $contact ne '' and ($Pred_expire o if (!$Pred_expire and $ActivePrivacy){ if (!$Pred_expire and $ActivePrivacy){ $Pred_expire=30; $Pred_expire=30; $skip_route++; $skip_route++; } } @routes[$numroutes]=$params{'Routing'}."/".$dest; @routes[$numroutes]=$params{'Routing'}."/".$dest; @routes[$numroutes].=":$secret" if defined $route @routes[$numroutes].=":$secret" if defined $route @routes[$numroutes].=":$authuser" if defined $rou @routes[$numroutes].=":$authuser" if defined $rou @routes[$numroutes].='@'.$contact; @routes[$numroutes].='@'.$contact; if (defined $route_info{'cli'}) { @clis[$numroute if (defined $route_info{'cli'}) { @clis[$numroute elsif($ActivePrivacy) {@clis[$numroutes]=$usernam elsif($ActivePrivacy) {@clis[$numroutes]=$usernam @Join_Expire[$numroutes]=$skip_route; @Join_Expire[$numroutes]=$skip_route; @Expire[$numroutes]=$Pred_expire; @Expire[$numroutes]=$Pred_expire; $numroutes++; $numroutes++; } else { } else { $AGI->verbose(" -- AGI route skipped",5) if (DEB $AGI->verbose(" -- AGI route skipped",5) if (DEB } } } } if( $a->{'Name'} eq 'Cisco-AVPair' && $a->{'Value'} =~ /^ if( $a->{'Name'} eq 'Cisco-AVPair' && $a->{'Value'} =~ /^ $routing_info = $a->{'Value'}; $routing_info = $a->{'Value'}; $routing_info =~ s/^h323-ivr-in=PortaBilling_Complete $routing_info =~ s/^h323-ivr-in=PortaBilling_Complete $dnid = $routing_info $dnid = $routing_info } } if( $a->{'Name'} eq 'Cisco-AVPair' && $a->{'Value'} =~ /^ if( $a->{'Name'} eq 'Cisco-AVPair' && $a->{'Value'} =~ /^ $routing_info = $a->{'Value'}; $routing_info = $a->{'Value'}; $routing_info =~ s/^h323-ivr-in=PortaBilling_CLI://; $routing_info =~ s/^h323-ivr-in=PortaBilling_CLI://; $auth_cli=$routing_info; $auth_cli=$routing_info; } } > if( $a->{'Name'} eq 'Cisco-AVPair' && $a->{'Value'} =~ /^ > $pbcld=$1; > } if( $a->{'Name'} eq 'Cisco-AVPair' && $a->{'Value'} =~ /^ if( $a->{'Name'} eq 'Cisco-AVPair' && $a->{'Value'} =~ /^ $pbcld=$1; $pbcld=$1; } } #Selects language #Selects language if( $a->{'Name'} eq 'h323-preferred-lang') { if( $a->{'Name'} eq 'h323-preferred-lang') { $language=$a->{'Value'}; $language=$a->{'Value'}; } } } } #Not used yet: #Not used yet: $TypeFollowMe='List' if ($ActiveFolloMe && !$TypeFollowMe); $TypeFollowMe='List' if ($ActiveFolloMe && !$TypeFollowMe); syslog('info', "Ast-Aut: ActiveFolloMe=$ActiveFolloMe -> $Typ syslog('info', "Ast-Aut: ActiveFolloMe=$ActiveFolloMe -> $Typ for ($i=0;$i<$numroutes;$i++) { for ($i=0;$i<$numroutes;$i++) { if (@Join_Expire[$i]) { if (@Join_Expire[$i]) { my $cli=$auth_cli; my $cli=$auth_cli; $cli=@clis[$i] if defined @clis[$i]; $cli=@clis[$i] if defined @clis[$i]; if (@routes[$i] && @Expire[$i] && $cli) { if (@routes[$i] && @Expire[$i] && $cli) { @XSUM[@Join_Expire[$i]]=0 if (!defined @XSUM[@Joi @XSUM[@Join_Expire[$i]]=0 if (!defined @XSUM[@Joi push(@routeslist, [@Join_Expire[$i]."_".@XSUM[@Jo push(@routeslist, [@Join_Expire[$i]."_".@XSUM[@Jo @XSUM[@Join_Expire[$i]]++; @XSUM[@Join_Expire[$i]]++; } } } } } } $radiusstatus = 'OK'; $radiusstatus = 'OK'; $activefollowme = $ActiveFolloMe; $activefollowme = $ActiveFolloMe; $activeprivacy = $ActivePrivacy; $activeprivacy = $ActivePrivacy; set_routing_data(); set_routing_data(); set_asterisk_variables(); set_asterisk_variables(); closelog; closelog; exit; exit; ############################################################# ############################################################# # END # END ############################################################# #############################################################