ACC SHELL
#!/usr/bin/perl -w
# SuSEfirewall2-rpcinfo - helper script for SuSEfirewall2
# Copyright (C) 2004 SUSE Linux AG
# Copyright (C) 2005 SUSE Linux Products GmbH
#
# Author: Ludwig Nussel
#
# Please send feedback via http://www.suse.de/feedback
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# version 2 as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# determine ports of RPC services specified on the command line and print them
# as iptables command line parameters. Only services that are actually running
# and are running as root are printed.
use strict;
#use Data::Dumper;
if ($#ARGV < 0)
{
print STDERR "Usage: $0 <service ...>\n\n";
exit 1;
}
# {
# 'ypbind' => [
# {
# 'udp' => [
# 979
# ],
# 'tcp' => [
# 982
# ],
# 'sport' => '666:777',
# 'net' => '10.10.0.1/32'
# },
# }
my %services;
foreach my $service (@ARGV)
{
my @a = split(/,/,$service);
if( $#a == 0)
{
push @{$services{$service}}, {};
}
elsif ($#a >= 2 && $a[1] eq '_rpc_')
{
my %h = ();
$h{'net'} = $a[0] if($a[0] && length($a[0]));
$h{'sport'} = $a[3] if($a[3] && length($a[3]));
push @{$services{$a[2]}}, \%h;
}
}
my %udpports = ();
my %tcpports = ();
# collect registered rpc services
open (RPCINFO, '/usr/sbin/rpcinfo -p localhost|') or die;
<RPCINFO>; # header line
while(<RPCINFO>)
{
chomp;
my @line = split;
next if($#line < 4);
next unless (exists $services{$line[4]});
if($line[2] eq 'udp')
{
$udpports{$line[3]} = $line[4];
}
elsif($line[2] eq 'tcp')
{
$tcpports{$line[3]} = $line[4];
}
}
close RPCINFO;
# @param file
# @param hashref
sub getportsfor($$)
{
my ($proto, $href) = @_;
# check if the registered ports are actually used and whether they are
# owned by a process running as root
open (FILE, '<', "/proc/net/$proto") or die;
<FILE>; # header line
my $ret = 0;
while(<FILE>)
{
chomp;
my @line = split;
next if($line[7] != 0); # only root allowed
my ($addr, $port) = split(/:/, $line[1], 2);
$port = pack('H*', $port); # "007B" => "\x00\x7B"
$port = unpack('n', $port); # "\x00\x7B" => 0x007B
if(exists $href->{$port})
{
++$ret;
foreach my $h (@{$services{$href->{$port}}})
{
push @{$h->{$proto}}, $port;
}
}
}
close FILE;
# always also add portmapper
if($ret && !exists $services{'portmapper'})
{
push @{$services{'portmapper'}}, { tcp => [111], udp => [111] };
}
}
getportsfor('udp', \%udpports);
getportsfor('tcp', \%tcpports);
#print Dumper(\%services);
foreach my $l (values %services)
{
foreach my $h (@$l)
{
foreach my $proto (('udp', 'tcp'))
{
if(exists($h->{$proto}))
{
foreach my $port (@{$h->{$proto}})
{
print "-p $proto --dport $port";
print " --sport ".$h->{'sport'} if exists $h->{'sport'};
print " -s ".$h->{'net'} if exists $h->{'net'};
print "\n";
}
}
}
}
}
ACC SHELL 2018