#!/usr/bin/perl
#
# bin/finger.saint
#
# version 2, Mon Mar 20 21:30:24 1995, last mod by wietse
# modified 2/25 s.k.  added fact for identified login name
#

# Query the target's finger daemon and report which user logged in from
# which host.  Try to clean up unqualified host names or host names that
# may be truncated. 

$running_under_saint = 1;

require 'config/paths.pl';
require 'perl/fix_hostname.pl';
require 'perl/misc.pl';
require 'perllib/getopts.pl';
 
#
# Parse JCL.
#
print "BEGIN\n";
$usage="Usage: $0 [-u user] [user@]target\n";
$opt_u = ":0:\@:version:\"a b c d e f g h\":root:demo:guest";
&Getopts("u:v");
 
if ($#ARGV < 0) {
    print STDERR $usage;
    exit 1;
}

# If no user is given, iterate over a list of queries that might
# give us some interesting answers.

if ($ARGV[0] =~ /([^@]+)@([^@]+)/) {
    $login = $1;
    $target = $2;
} else {
    $target = $ARGV[0];
    $login = $opt_u;
}

$| = 1;
$service = &basename($0, ".saint");

foreach $query (split(/:/, $login)) {
    print "trying: $SAFE_FINGER -l $query\@$target\n" if $opt_v;
    open (FINGER, "$SAFE_FINGER -l $query\@$target 2>/dev/null|") 
	|| exit 1;
    $user = $query;
    while (<FINGER>) {
	print if $opt_v;
	if (/^ login name: (\S+)/i) { 
	    $user = $1;
	}
	if (/^ login: (\S+)/i) { 
	    $user = $1;
	}
	if (/^ directory: (\S+)/i) { 
	    $home = $1;
	}
	if (/(never logged in|on since|last login)/i) { 
	  if (/(on since|last login).*\s+from\s+([-.A-Za-z]+)/i) { 
	    # Get rid of sync, daemon, localhost, X displays
	    next if ($user eq "sync" || $user eq "daemon");
	    $origin = $2;
	    $origin =~ s/:.*//;
	    # Strip off X display numbers.
	    if ($origin =~ /(.*)@(.*)/) {
		($ruser = $1) || ($ruser = "root");
		$host = $2;
	    } else {
		$ruser = "root";
		$host = $origin;
	    }
	    next if ($host eq "" || $host eq "localhost");
	    if ($fqdn = &fix_hostname($host, $target)) {
		$host = $fqdn;
		$status = "a";
		#removed trust info because finger sometimes returns
		#corrupt hostname
		#$trustee = "$user\@$target";
		#$trusted = "$ruser\@$host";
		$trustee = "";
		$trusted = "";
                $severity = "";
                $service_output = "$user $home $host";
		$text = "identified login $user home $home from $host";
                &saint_print();
	    } else {
		$status = "u";
		#$trustee = "$user\@$target";
		#$trusted = "$ruser\@$host";
		$trustee = "";
		$trusted = "";
                $severity = "";
                $service_output = "$user $home $host";
		$text = "identified login $user home $home from $host, unable to verify hostname";
                &saint_print();
	    }
	  } else {
		$status = "a";
		$trustee = "";
		$trusted = "";
                $severity = "";
                $service_output = "$user $home";
		$text = "identified login $user home $home";
                &saint_print();
	  }
          $trustee = "ANY\@ANY";
          $trusted = "ANY\@ANY";
          $severity = "yi";
	  if ($query =~ /a b c d e f g h/) {
	    $service_output = "finger vulnerabilities";
	    $text = "Solaris fingerd user list disclosure";
	  } else {
            $service_output = "excessive finger info";
            $text = "Excessive finger information";
	  }
          &saint_print();
	}
	if (/Configurable Finger/i && /version (\d+\.\d+)(\.?)(\d*)/i) {
	    if ($1 < 1.4 || ($1==1.4 && $3 < 4)) {
		$status = "a";
		$severity = "zcio";
		$trustee = "ANY\@ANY";
		$trusted = "ANY\@ANY";
		$service_output = "cfingerd vulnerability";
		$text = "possible vulnerability in cfingerd $1$2$3";
		&saint_print();
	    }
	}
    }
    close(FINGER);

    # check for file read vulnerability (FreeBSD 4.1.1)
    open (FINGER, "$SAFE_FINGER /etc/group\@$target 2>/dev/null|") 
	|| exit 1;
    while(<FINGER>) {
	if (/:0:/) {
	    $status = "a";
	    $trusted = "ANY\@ANY";
	    $trustee = "ANY\@ANY";
	    $severity = "nr";
	    $service_output = "finger vulnerabilities";
	    $text = "file read vulnerability in finger";
	    &saint_print();
	}
    }
    close(FINGER);
}
