summaryrefslogtreecommitdiff
path: root/scripts/identd.perl5
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/identd.perl5')
-rwxr-xr-xscripts/identd.perl5131
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("");
+}