#!/usr/bin/perl ################################################################### # identd.perl5 : An implementation of RFC 1413 Ident Server # using Vic Abell's lsof. # # - Started from inetd with 'nowait' option. This entry in # /etc/inetd.conf will suffice : # # ident stream tcp nowait root /usr/local/bin/identd.perl5 -t200 # # - Multiple instances of the server are not a performance penalty # since they shall use lsof's cacheing mechanism. (compare with # Peter Eriksson's pidentd) # - assumes 'lsof' binary in /usr/local/sbin # - Command line arguments : # -t TIMEOUT Number of seconds to wait for a query before aborting. # Default is 120. # # Kapil Chowksey ################################################################### use Socket; require 'getopts.pl'; # redirect lsof's warnings/errors to /dev/null close(STDERR); open(STDERR, ">/dev/null"); $Timeout = "120"; &Getopts('t:'); if ($opt_t) { $Timeout = $opt_t; } ($port, $iaddr) = sockaddr_in(getpeername(STDIN)); $peer_addr = inet_ntoa($iaddr); # read ident-query from socket (STDIN) with a timeout. $timeout = int($Timeout); eval { local $SIG{ALRM} = sub { die "alarm\n" }; alarm $timeout; $query = ; alarm 0; }; die if $@ && $@ ne "alarm\n"; if ($@) { # timed out exit; } # remove all white-spaces from query $query =~ s/\s//g; $serv_port = ""; $cli_port = ""; ($serv_port,$cli_port) = split(/,/,$query); if ($serv_port =~ /^[0-9]+$/) { if (int($serv_port) < 1 || int($serv_port) > 65535) { print $query." : ERROR : INVALID-PORT"."\n"; exit; } } else { print $query." : ERROR : INVALID-PORT"."\n"; exit; } if ($cli_port =~ /^[0-9]+$/) { if (int($cli_port) < 1 || int($cli_port) > 65535) { print $query." : ERROR : INVALID-PORT"."\n"; exit; } } else { print $query." : ERROR : INVALID-PORT"."\n"; exit; } open(LSOF,"/usr/local/sbin/lsof -nPDi -T -FLn -iTCP@".$peer_addr.":".$cli_port."|"); $user = "UNKNOWN"; while ($a_line = ) { # extract user name. if ($a_line =~ /^L.*/) { ($user) = ($a_line =~ /^L(.*)/); } # make sure local port matches. if ($a_line =~ /^n.*:\Q$serv_port->/) { print $serv_port.", ".$cli_port." : USERID : UNIX :".$user."\n"; exit; } } print $serv_port.", ".$cli_port." : ERROR : NO-USER"."\n";