package NGCP::Panel::Utils::Security; use Sipwise::Base; use XML::LibXML; use URI::Encode; use NGCP::Panel::Utils::XMLDispatcher; use NGCP::Panel::Utils::DateTime; sub list_banned_ips { my ( $c, %params ) = @_; my $xml_parser = XML::LibXML->new(); my $ip_xml = <<'EOF'; htable.dump ipban EOF my $ip_res = NGCP::Panel::Utils::XMLDispatcher::dispatch($c, "loadbalancer", 1, 1, $ip_xml); my @ips = (); XML_RESULTS_LOOP: for my $host (grep {$$_[1]} @$ip_res) { my $xmlDoc = $xml_parser->parse_string($host->[2]); foreach my $node ($xmlDoc->findnodes('//member')) { my $name = $node->findvalue('./name'); my $value = $node->findvalue('./value/string'); if ($name eq 'name') { if (!defined $params{id} || $params{id} eq $value) { push @ips, { ip => $value, id => $value, }; if (defined $params{id}) { last XML_RESULTS_LOOP; } } } } } return \@ips; } sub list_banned_users { my ( $c, %params ) = @_; my $xml_parser = XML::LibXML->new(); my $user_xml = <<'EOF'; htable.dump auth EOF my $user_res = NGCP::Panel::Utils::XMLDispatcher::dispatch($c, "loadbalancer", 1, 1, $user_xml); my @users = (); my $usr = {}; for my $host (grep {$$_[1]} @$user_res) { 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/(?.*)::(?.*)/; $username = $+{user}; $key = $+{key}; } elsif ($name eq 'value' && $username && $key) { # there should not 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 $config_failed_auth_attempts = $c->config->{security}->{failed_auth_attempts} // 3; #in case we requested to filter by username, we will use it as the only possible key my @user_ids; if (defined $params{id}) { if (exists $usr->{$params{id}}) { @user_ids = ($params{id}); } } else { @user_ids = (keys %{ $usr }); } for my $key (@user_ids) { my $last_auth = $usr->{$key}->{last_auth} ? NGCP::Panel::Utils::DateTime::epoch_local($usr->{$key}->{last_auth}) : undef; if ($last_auth) { $last_auth->set_time_zone($c->session->{user_tz}) if $c->session->{user_tz}; $last_auth = $last_auth->ymd.' '. $last_auth->hms; } if( defined $usr->{$key}->{auth_count} && $usr->{$key}->{auth_count} >= $config_failed_auth_attempts ) { push @users, { username => $key, id => $key, auth_count => $usr->{$key}->{auth_count}, last_auth => $last_auth, }; } } return \@users; } sub ip_unban { my ( $c, $ip ) = @_; my $decoder = URI::Encode->new; $ip = $decoder->decode($ip); my $xml = <<"EOF"; htable.delete ipban $ip EOF NGCP::Panel::Utils::XMLDispatcher::dispatch($c, "loadbalancer", 1, 1, $xml); } sub user_unban { my ( $c, $user ) = @_; my $decoder = URI::Encode->new; $user = $decoder->decode($user); my @keys = ($user.'::auth_count', $user.'::last_auth'); foreach my $key (@keys) { my $xml = <<"EOF"; htable.delete auth $key EOF NGCP::Panel::Utils::XMLDispatcher::dispatch($c, "loadbalancer", 1, 1, $xml); } } 1; # vim: set tabstop=4 expandtab: