|
|
|
|
@ -3,7 +3,7 @@ use Sipwise::Base;
|
|
|
|
|
|
|
|
|
|
BEGIN { extends 'Catalyst::Controller'; }
|
|
|
|
|
|
|
|
|
|
use XML::Mini::Document;
|
|
|
|
|
use XML::LibXML;
|
|
|
|
|
use URI::Encode;
|
|
|
|
|
use NGCP::Panel::Utils::Navigation;
|
|
|
|
|
use NGCP::Panel::Utils::XMLDispatcher;
|
|
|
|
|
@ -23,6 +23,7 @@ sub root :PathPart('/') :CaptureArgs(0) {
|
|
|
|
|
sub index :Chained('/') :PathPart('security') :Args(0) {
|
|
|
|
|
my ( $self, $c ) = @_;
|
|
|
|
|
my $dispatcher = NGCP::Panel::Utils::XMLDispatcher->new;
|
|
|
|
|
my $xml_parser = XML::LibXML->new();
|
|
|
|
|
|
|
|
|
|
my $ip_xml = <<'EOF';
|
|
|
|
|
<?xml version="1.0" ?>
|
|
|
|
|
@ -38,31 +39,9 @@ EOF
|
|
|
|
|
|
|
|
|
|
my @ips = ();
|
|
|
|
|
for my $host (grep {$$_[1]} @$ip_res) {
|
|
|
|
|
my $xmlDoc = XML::Mini::Document->new();
|
|
|
|
|
$xmlDoc->parse($host->[2]);
|
|
|
|
|
my $xmlHash = $xmlDoc->toHash();
|
|
|
|
|
|
|
|
|
|
# non empty response
|
|
|
|
|
if(defined $xmlHash->{methodResponse}->{params}->{param}->{value} and
|
|
|
|
|
'' ne $xmlHash->{methodResponse}->{params}->{param}->{value} ) {
|
|
|
|
|
|
|
|
|
|
# single IP
|
|
|
|
|
if(ref $xmlHash->{methodResponse}->{params}->{param}->{value}->{struct} eq 'HASH') {
|
|
|
|
|
push @ips, { ip => $xmlHash->{methodResponse}->{params}->{param}->{value}->{struct}->{member}->[2]->{value}->{struct}->{member}->{value}->{struct}->{member}->[0]->{value}->{string} };
|
|
|
|
|
}
|
|
|
|
|
# multiple IPs
|
|
|
|
|
else {
|
|
|
|
|
for my $struct ( @{ $xmlHash->{methodResponse}->{params}->{param}->{value}->{struct} } ) {
|
|
|
|
|
if(ref $struct->{member}->[2]->{value}->{struct}->{member} eq 'HASH') {
|
|
|
|
|
push @ips, { ip => $struct->{member}->[2]->{value}->{struct}->{member}->{value}->{struct}->{member}->[0]->{value}->{string} };
|
|
|
|
|
} else {
|
|
|
|
|
foreach my $member(@{ $struct->{member}->[2]->{value}->{struct}->{member} }) {
|
|
|
|
|
push @ips, { ip => $member->{value}->{struct}->{member}->[0]->{value}->{string} };
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
my $xmlDoc = $xml_parser->parse_string($host->[2]);
|
|
|
|
|
@ips = map { { ip => $_->to_literal } }
|
|
|
|
|
$xmlDoc->findnodes('//member/value/string');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -80,43 +59,33 @@ EOF
|
|
|
|
|
my @users = ();
|
|
|
|
|
my $usr = {};
|
|
|
|
|
for my $host (grep {$$_[1]} @$user_res) {
|
|
|
|
|
my $xmlDoc = XML::Mini::Document->new();
|
|
|
|
|
$xmlDoc->parse($host->[2]);
|
|
|
|
|
my $xmlHash = $xmlDoc->toHash();
|
|
|
|
|
|
|
|
|
|
# non empty response
|
|
|
|
|
if(defined $xmlHash->{methodResponse}->{params}->{param}->{value} and
|
|
|
|
|
'' ne $xmlHash->{methodResponse}->{params}->{param}->{value} ) {
|
|
|
|
|
|
|
|
|
|
for my $struct_ar ( @{ $xmlHash->{methodResponse}->{params}->{param}->{value}->{struct} } ) {
|
|
|
|
|
# possibly buggy behaviour of kamailio to return mutliple entries as one member
|
|
|
|
|
# (array of hashes) instead of seperate members (hashes)
|
|
|
|
|
my $member = ref $struct_ar->{member}->[2]->{value}->{struct}->{member} eq 'HASH'
|
|
|
|
|
? [ $struct_ar->{member}->[2]->{value}->{struct}->{member} ]
|
|
|
|
|
: $struct_ar->{member}->[2]->{value}->{struct}->{member};
|
|
|
|
|
|
|
|
|
|
foreach my $m (@$member) {
|
|
|
|
|
$m->{value}->{struct}->{member}->[0]->{value}->{string} =~ m/(?<user>.*)::(?<key>.*)/;
|
|
|
|
|
my $username = $+{user};
|
|
|
|
|
my $key = $+{key};
|
|
|
|
|
my $value = $m->{value}->{struct}->{member}->[1]->{value}->{int};
|
|
|
|
|
|
|
|
|
|
# there souldn't be any other keys
|
|
|
|
|
$key eq 'auth_count' and $usr->{$username}->{auth_count} = $value;
|
|
|
|
|
$key eq 'last_auth' and $usr->{$username}->{last_auth} = $value;
|
|
|
|
|
}
|
|
|
|
|
my $xmlDoc = $xml_parser->parse_string($host->[2]);
|
|
|
|
|
my $username = '';
|
|
|
|
|
my $key = '';
|
|
|
|
|
foreach my $node ($xmlDoc->findnodes('//member')) {
|
|
|
|
|
my $name = $node->findvalue('./name');
|
|
|
|
|
my $value = $node->findvalue('./value/string') ||
|
|
|
|
|
$node->findvalue('./value/int');
|
|
|
|
|
if ($name eq 'name') {
|
|
|
|
|
$value =~ m/(?<user>.*)::(?<key>.*)/;
|
|
|
|
|
$username = $+{user};
|
|
|
|
|
$key = $+{key};
|
|
|
|
|
} elsif ($name eq 'value' && $username && $key) {
|
|
|
|
|
# there souldn't be any other keys
|
|
|
|
|
$key eq 'auth_count' and $usr->{$username}->{auth_count} = $value;
|
|
|
|
|
$key eq 'last_auth' and $usr->{$username}->{last_auth} = $value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for my $key (keys %{ $usr }) {
|
|
|
|
|
push @users, {
|
|
|
|
|
username => $key,
|
|
|
|
|
auth_count => $usr->{$key}->{auth_count},
|
|
|
|
|
last_auth => NGCP::Panel::Utils::DateTime::epoch_local($usr->{$key}->{last_auth}),
|
|
|
|
|
} if($usr->{$key}->{auth_count} >= $c->config->{security}->{failed_auth_attempts});
|
|
|
|
|
}
|
|
|
|
|
for my $key (keys %{ $usr }) {
|
|
|
|
|
push @users, {
|
|
|
|
|
username => $key,
|
|
|
|
|
auth_count => $usr->{$key}->{auth_count},
|
|
|
|
|
last_auth => NGCP::Panel::Utils::DateTime::epoch_local($usr->{$key}->{last_auth}),
|
|
|
|
|
} if($usr->{$key}->{auth_count} >= $c->config->{security}->{failed_auth_attempts});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$c->stash(
|
|
|
|
|
template => 'security/list.tt',
|
|
|
|
|
banned_ips => \@ips,
|
|
|
|
|
|