.
authordev <dev>
Sat, 22 Aug 2026 12:45:22 +0000 (12:45 +0000)
committerdev <dev>
Sat, 22 Aug 2026 12:45:22 +0000 (12:45 +0000)
CGI/cgi-bin/black-white.pl [new file with mode: 0755]

diff --git a/CGI/cgi-bin/black-white.pl b/CGI/cgi-bin/black-white.pl
new file mode 100755 (executable)
index 0000000..b320a66
--- /dev/null
@@ -0,0 +1,287 @@
+#!/usr/bin/perl
+
+####################################################################################
+#  Asterisk Black/White List Entry CGI (AMI)
+#
+#  $Id: black-white.pl,v 1.1 2026/08/22 12:45:22 dev Exp $
+#
+####################################################################################
+
+use warnings;
+use strict;
+use utf8;
+use Config::Simple '-strict';
+use CGI;
+use Telephony::Asterisk::AMI;
+use HTML::Template;
+use Encode;
+
+# Settings
+my $debug        = 0;
+my $ami_def_user = 'user0001';
+my $ami_def_pass = 'password';
+my $cnf_def_path = '/var/www/asterisk/black_whitelist.ini';
+my $html_tmpl    = '/var/www/asterisk/black_whitelist.tmpl';
+
+my $h_title  = 'Asterisk Black/White List'; 
+my $h_lang   = 'ja'; 
+my $h_enc    = 'UTF-8'; 
+my $h_css  = [
+               { 'href' => 'https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css',
+                 'integrity' => 'sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB',
+                 'crossorigin' => 'anonymous'
+               },
+               { 'href' => 'https://cdn.jsdelivr.net/npm/bootstrap-table@1.27.3/dist/bootstrap-table.min.css',
+                 'integrity' => '',
+                 'crossorigin' => 'anonymous'
+               }
+             ];
+my $h_js   = [
+               { 'href' => 'https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js',
+                 'integrity' => 'sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI',
+                 'crossorigin' => 'anonymous'
+               },
+               { 'href' => 'https://code.jquery.com/jquery-3.7.1.min.js',
+                 'integrity' => 'sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=',
+                 'crossorigin' => 'anonymous'
+               }
+             ];
+
+# Init
+my ( $cfg, $ami_user, $ami_pass );
+my ( $response, $output, $res_stat, $stat_flg, $stat_msg );
+my ( $tab_1, $tab_2 );
+my ( $err_flg, $err_msg );
+my ( $cmd_f, $cmd_l );
+my ( $dmy, $telno );
+my ( $i, $line );
+my $hd_act  = '';
+my $hd_cate = '';
+my $hd_telno= '';
+my $hd_desc = '';
+my $cate    = '';
+my $desc    = '';
+my $bid = 0;
+my $wid = 0;
+undef my @blacklist;
+undef my @whitelist;
+
+$err_flg = 0;
+
+if ( -f $cnf_def_path ){
+    $cfg      = new Config::Simple($cnf_def_path); 
+    $ami_user = $cfg->param("AMI.user"); 
+    $ami_pass = $cfg->param("AMI.pass"); 
+    $html_tmpl= $cfg->param("COM.template"); 
+    $debug    = $cfg->param("COM.debug_flg"); 
+} 
+else{
+    $ami_user = $ami_def_user;
+    $ami_pass = $ami_def_pass;
+}
+
+if ( $debug ) {
+    require Data::Dumper;
+    Data::Dumper->import( qw(Dumper) );
+    require CGI::Carp;
+    CGI::Carp->import( qw(fatalsToBrowser) );
+}
+#use if $debug, CGI::Carp => qw(fatalsToBrowser);
+
+my $ami_obj = Telephony::Asterisk::AMI->new(
+    Username => $ami_user,
+    Secret   => $ami_pass
+);
+
+my $template = HTML::Template->new( filename => $html_tmpl, utf8 => 1 );
+my $cgi      = new CGI;
+my $own_fn   = $cgi->url;
+if ( defined $cgi->param('act') )  { $hd_act   = $cgi->param('act'); }
+if ( defined $cgi->param('cate') ) { $hd_cate  = $cgi->param('cate'); }
+if ( defined $cgi->param('telno') ){ $hd_telno = $cgi->param('telno'); }
+if ( defined $cgi->param('desc') ) { $hd_desc  = $cgi->param('desc'); }
+
+$hd_telno =~ s/^\s+//;
+$hd_telno =~ s/\s+$//;
+$hd_telno =~ s/-//;
+
+### Main ###
+
+# POSTデータ(追加/削除ボタン押下時) astdb処理
+if ( $hd_act eq 'addnumber' or $hd_act eq 'delnumber' ){
+    $cmd_f = 0;
+    if ( $hd_act eq 'addnumber' ){
+        ($err_flg, $err_msg) = &telno_chk($hd_telno);
+
+        if ( $err_flg == 0 ){
+            if ( $hd_cate eq 'blacklist' ){
+                $cmd_f = 1;
+                $cmd_l = qq(database put blacklist $hd_telno "$hd_desc");
+            }
+            elsif ( $hd_cate eq 'whitelist' ){
+                $cmd_f = 1;
+                $cmd_l = qq(database put whitelist $hd_telno "$hd_desc");
+            }
+            else{
+                $err_flg = 1;
+                $err_msg = 'Illegal DataError';
+            }
+        }
+    }
+    elsif ( $hd_act eq 'delnumber' ){
+        ($err_flg, $err_msg) = &telno_chk($hd_telno);
+
+        if ( $err_flg == 0 ){
+            if ( $hd_cate eq 'blacklist' ){
+                $cmd_f = 1;
+                $cmd_l = qq(database del blacklist $hd_telno);
+            }
+            elsif ( $hd_cate eq 'whitelist' ){
+                $cmd_f = 1;
+                $cmd_l = qq(database del whitelist $hd_telno);
+            }
+            else{
+                $err_flg = 1;
+                $err_msg = 'Illegal DataError';
+            }
+        }
+    }
+    else{
+        $err_flg = 1;
+        $err_msg = 'Illegal DataError';
+    }
+
+    if ( $cmd_f == 1 ){
+        $ami_obj->connect or die $ami_obj->error;
+        my $response = $ami_obj->action({ Action => 'Command',
+                                          Command => "$cmd_l"
+                                        });
+        $ami_obj->disconnect or die $ami_obj->error;
+        $res_stat = $response->{'Response'};
+        if ( $res_stat eq 'Success' and $hd_act eq 'addnumber' ){
+            $stat_flg = 1;
+            $stat_msg = '登録しました';
+        }
+        elsif ( $res_stat eq 'Success' and $hd_act eq 'delnumber' ){
+            $stat_flg = 1;
+            $stat_msg = '削除しました';
+        }
+        else {
+          $err_flg = 1;
+          $err_msg = 'Illegal DataError';
+        }
+    }
+}
+
+# HTML::Template 変数入力の前処理
+#   追加/削除押下時のアクティブタブ 押下後も維持
+if ( $hd_cate eq 'blacklist' ){
+    $tab_1 = 'active';
+    $tab_2 = '';
+}
+elsif ( $hd_cate eq 'whitelist' ){
+    $tab_1 = '';
+    $tab_2 = 'active';
+}
+else{
+    $tab_1 = 'active';
+    $tab_2 = '';
+}
+
+# Asterisk astdbへブラックリスト/ホワイトリスト電話番号を取得
+$ami_obj->connect or die $ami_obj->error;
+$response = $ami_obj->action({ Action => 'Command',
+                               Command => 'database show'
+                             });
+$ami_obj->disconnect or die $ami_obj->error;
+
+for ( $i = 0;  $i < @{$response->{'Output'}} ; $i++ ){
+    $line = $response->{'Output'}->[$i];
+    if ( $line =~ m!/blacklist/! or $line =~ m!/whitelist/! ){
+        ($dmy, $cate, $telno) = split(/\//, (split(/:/, $line))[0]);
+        $desc = (split(/:/, $line))[1];
+        $desc =~ s/\s+$//;
+        if ( $cate eq 'blacklist' and $telno =~ m/^([0-9]+)\s+$/ ){
+            $bid++;
+            $telno = $1;
+            push( @blacklist, {'bid' => $bid, 'telno' => $telno, 'desc' => $desc} );
+        }
+        elsif ( $cate eq 'whitelist' and $telno =~ m/^([0-9]+)\s+$/ ){
+           $wid++;
+            $telno = $1;
+            push( @whitelist, {'wid' => $wid, 'telno' => $telno, 'desc' => $desc} );
+           $wid++;
+        }
+    }
+}
+
+# HTML::Templateで使用する変数を定義
+$template->param( BLIST  => \@blacklist );
+$template->param( WLIST  => \@whitelist );
+$template->param( BNUM   => $bid );
+$template->param( WNUM   => $wid );
+$template->param( OWNPRG => $own_fn );
+$template->param( TAB_BL => $tab_1 );
+$template->param( TAB_WH => $tab_2 );
+$template->param( ERRFLG => $err_flg );
+$template->param( ERRMSG => $err_msg );
+$template->param( STAFLG => $stat_flg );
+$template->param( STAMSG => $stat_msg );
+$output = $template->output();
+
+# HTML 出力
+print $cgi->header( -type=>'text/html', -charset=> $h_enc ); 
+print $cgi->start_html( 
+        -title=> $h_title, 
+        -lang => $h_lang, 
+        -encoding => $h_enc, 
+        -meta => {'name'=>'robots',
+                  'content' => 'noindex',
+        },
+        -style  => [
+            { 'src'         => $h_css->[0]->{'href'}, 
+              'integrity'   => $h_css->[0]->{'integrity'},
+              'crossorigin' => $h_css->[0]->{'crossorigin'}
+            },
+            { 'src'         => $h_css->[1]->{'href'},
+              'integrity'   => $h_css->[1]->{'integrity'},
+              'crossorigin' => $h_css->[1]->{'crossorigin'}
+            },
+          ], 
+        ); 
+print qq(<script src="$h_js->[0]->{'href'}" integrity="$h_js->[0]->{'integrity'}" crossorigin="$h_js->[0]->{'crossorigin'}">);
+print qq(</script>\n);
+print qq(<script src="$h_js->[1]->{'href'}" integrity="$h_js->[1]->{'integrity'}" crossorigin="$h_js->[1]->{'crossorigin'}">);
+print qq(</script>\n);
+print Encode::encode( 'UTF-8', $output );
+
+### SubRoutine ###
+sub telno_chk {
+    my ($t1) = @_;
+    my ($t_flg, $t_msg);
+
+    if ( $t1 =~ m/^0[0-9]{9,9}$/ or $t1 =~ m/^0[6-9]0[1-9]{8,8}$/ ){
+        return (0,'');
+    }
+    elsif ( $t1 =~ m/^0[1-9][0-9]+$/ ){
+        $t_flg = 1;
+        $t_msg = '入力された桁数が規定と異なります。';
+    }
+    elsif ( $t1 =~ m/^[1-9][0-9]+$/ ){
+        $t_flg = 1;
+        $t_msg = '先頭文字は0から始まる必要があります。海外電話番号の入力は出来ません。';
+    }
+    elsif ( $t1 =~ m/\D/ ){
+        $t_flg = 1;
+        $t_msg = '数字以外の文字が入力されました。';
+    }
+    elsif ( $t1 eq '' ){
+        $t_flg = 1;
+        $t_msg = '電話番号が入力されていません。';
+    }
+    else {
+        $t_flg = 1;
+        $t_msg = 'Unknown Error';
+    }
+    return ($t_flg, "$t_msg");
+}