#!/usr/bin/perl
#
# bin/printer.saint
#
# Report vulnerable lpd servers.
#
require 'config/saint.cf';
require 'config/paths.pl';
require 'perl/misc.pl';
require 'perllib/getopts.pl';

print "BEGIN\n";
$usage = "usage $0 hosttype target";
 
$argptr = $#ARGV;
if ($ARGV[$argptr] eq "FW" ||
    $ARGV[$argptr] eq ".PLUS" ||
    $ARGV[$argptr] eq "FW.PLUS") {
	$argptr--;
}
die usage if $argptr < 0;
$target = $ARGV[$argptr];

if (--$argptr >= 0) {
    $type = join(' ', @ARGV[0..$argptr]);
} else {
    $type = "UNKNOWN";
}

$port = 515;
$status = "a";
$service = "lpd";
$trusted = "ANY@$target";
$trustee = "ANY@$target";

$args = "-bs \"\006saint saint status\n\" $target $port";

open(TCP_SCAN, "$TCP_SCAN $args |")
	|| die "$0: cannot run $TCP_SCAN";

while(<TCP_SCAN>) {
	chop;
	if (/Spooling Jobs/i) {
		$severity = "zcio";
		$service_output = "LPRng vulnerability";
		$text = "possible vulnerability in LPRng";
		&saint_print();
		$service_output = "groff vulnerability";
		$text = "possible vulnerability in groff through LPRng";
		&saint_print;
	}
	elsif (/Invalid protocol request \(6/) {
	    if ($type =~ /SunOS 5\.[678]/ ||
		$type =~ /Solaris 2\.[678]/ ||
		$type =~ /Solaris [78]/) {
		$severity = "bo";
		$service_output = "Sun lpd";
		$text = "possible vulnerability in Sun lpd";
		&saint_print;
	    } elsif ($type eq "UNKNOWN" ||
		     $type eq "SunOS" ||
		     $type eq "SunOS 5") {
		$severity = "zcio";
		$service_output = "Sun lpd";
		$text = "possible vulnerability in Sun lpd";
		&saint_print;
	    }
	}
	# All BSD types have version numbers in
	# rules/hosttype, so don't worry about the
	# generic case
	elsif (($type =~ /OpenBSD (\d+)\.(\d+)/i
		  && ($1<3 || ($1==3 && $2==0))) ||
		($type =~ /NetBSD 1\.(\d+)\.?(\d*)/i
		  && ($1<5 || ($1==5 && $2<=1))) ||
		($type =~ /FreeBSD (\d+)\.(\d+)/i
		  && ($1<4 || ($1==4 && $2<=3))) ||
		($type =~ /BSDI (\d+)\.(\d+)/i
		  && ($1<4 || ($1==4 && $2<=1))) ||
		($type =~ /OpenServer (\d+)\.?([\d\.]*)/i
		  && ($1<5 || ($1==5 && $2<=0.6))) ||
		($type eq "SCO") ||
		($type =~ /IRIX 6\.5\.?(\d*)/i && $1<=13) ||
		($type eq "IRIX 6" || $type eq "IRIX") ||
		($type eq "UNKNOWN"
		  && /Illegal service request/)) {
		$severity = "zcio";
		$service_output = "BSD lpd";
		$text = "possible vulnerability in BSD lpd";
		&saint_print;
	}
	elsif ($type =~ /Linux/i) {
		$severity = "zcio";
		$service_output = "Linux lpd";
		$text = "possible vulnerability in Linux lpd";
		&saint_print;
		$service_output = "groff vulnerability";
		$text = "possible vulnerability in groff through lpd";
		&saint_print;
	}
	elsif ($type eq "HP-UX" ||
	       ($type =~ /HP-UX [AB]?\.?(\d+\.\d+)/ &&
		$1 >= 10.00 && $1 <= 11.20)) {
		$severity = "zcio";
		$service_output = "HPUX rlpdaemon";
		$text = "possible vulnerability in HP-UX rlpdaemon";
		&saint_print;
	}
	elsif (($type =~ /AIX (\d+)\.?([\d\.]*)/ &&
		($1<5 || ($1==5 && $2<=1))) ||
	       $type eq "AIX") {
		$severity = "zcio";
		$service_output = "AIX lpd";
		$text = "possible vulnerabilities in AIX lpd";
		&saint_print;
	}
}
close (TCP_SCAN);
