diff options
Diffstat (limited to 'scripts/identd.perl5')
-rwxr-xr-x | scripts/identd.perl5 | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/scripts/identd.perl5 b/scripts/identd.perl5 new file mode 100755 index 0000000..32626d8 --- /dev/null +++ b/scripts/identd.perl5 @@ -0,0 +1,131 @@ +#!/usr/local/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 <kchowksey@hss.hns.com> +################################################################### + +use Socket; +require 'getopts.pl'; + +# Set path to lsof. + +if (($LSOF = &isexec("../lsof")) eq "") { # Try .. first + if (($LSOF = &isexec("lsof")) eq "") { # Then try . and $PATH + print "can't execute $LSOF\n"; exit 1 + } +} + +# 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 = <STDIN>; + 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(LSOFP,"$LSOF -nPDi -T -FLn -iTCP@".$peer_addr.":".$cli_port."|"); + +$user = "UNKNOWN"; +while ($a_line = <LSOFP>) { + # 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"; + + +## isexec($path) -- is $path executable +# +# $path = absolute or relative path to file to test for executabiity. +# Paths that begin with neither '/' nor '.' that arent't found as +# simple references are also tested with the path prefixes of the +# PATH environment variable. + +sub +isexec { + my ($path) = @_; + my ($i, @P, $PATH); + + $path =~ s/^\s+|\s+$//g; + if ($path eq "") { return(""); } + if (($path =~ m#^[\/\.]#)) { + if (-x $path) { return($path); } + return(""); + } + $PATH = $ENV{PATH}; + @P = split(":", $PATH); + for ($i = 0; $i <= $#P; $i++) { + if (-x "$P[$i]/$path") { return("$P[$i]/$path"); } + } + return(""); +} |