HEX
Server: Apache
System: Linux info 3.0 #1337 SMP Tue Jan 01 00:00:00 CEST 2000 all GNU/Linux
User: u80650282 (6669564)
PHP: 8.0.30
Disabled: NONE
Upload Files
File: //bin/interpreter
#!/usr/bin/perl -w
# This is a PERL script
# Please call explicitly with /path/to/perl /path/to/interpreter arguments,
# where arguments are:
#   [ -h /path/to/homedir ]
#   [ -n /path/to/nice ]
#   [ -p /path/to/perl ]
#   [ -q /path/to/quota ]
#   [ -ql /path/to/quotaget ]  where quotaget is the binary generated
#                              from ../quota_linux/quotaget.c
#   [ -f /path/to/fstab ]

$| = 1;

$perl = "/usr/bin/perl";
$quota = "/usr/bin/quota";
$quotalinux = '';
$nice = "/usr/bin/nice";
$home = '';
$fstab = '/proc/mounts';

$tmpdir = "/tmp";
$tmpname = $tmpdir . "/" . "interpreter.tmp." . $$ . "." . $<;

while (1) {
	last if (scalar (@ARGV) == 0);
	if (scalar(@ARGV) >= 2 && $ARGV[0] eq '-p') {
		$perl = $ARGV[1];
		shift @ARGV;
		shift @ARGV;
	} elsif (scalar(@ARGV) >= 2 && $ARGV[0] eq '-q') {
		$quota = $ARGV[1];
		shift @ARGV;
		shift @ARGV;
	} elsif (scalar(@ARGV) >= 2 && $ARGV[0] eq '-ql') {
		$quotalinux = $ARGV[1];
		shift @ARGV;
		shift @ARGV;
	} elsif (scalar(@ARGV) >= 2 && $ARGV[0] eq '-h') {
		$home = $ARGV[1];
		shift @ARGV;
		shift @ARGV;
	} elsif (scalar(@ARGV) >= 2 && $ARGV[0] eq '-n') {
		$nice = $ARGV[1];
		shift @ARGV;
		shift @ARGV;
	} elsif (scalar(@ARGV) >= 2 && $ARGV[0] eq '-f') {
		$fstab = $ARGV[1];
		shift @ARGV;
		shift @ARGV;
	} else {
		die "- Interpreter usage error\r\n";
	}
}

print "+ Interpreter OK\r\n";

while (<STDIN>) {
	tr/\r\n//d;
	if (/^\s*quota\s*$/) {
		&do_quota();
	} elsif (/^\s*perlc\s+(\S+)\s*$/) {
		&do_perlc($1);
	} elsif (/^\s*cgi\s+(\S+)(\s.*)?$/) {
		my ($prog, $rest) = ($1, $2);
		$rest =~ s/^\s*//;
		$rest =~ s/\s*$//;
		&do_cgi($prog, $rest);
	} elsif (/^\s*close\s*$/) {
		print "+ OK, Closing connection\r\n";
		exit 0;
	} elsif (/^\s*mkdir\s+(\S+)\s*$/) {
		my $path = $1;
		&do_mkdir($path);
	} else {
		print "- Command error\r\n";
		exit 1;
	}
}
exit 0;

sub do_quota {
	if ($quotalinux ne '') {
		&do_quota_linux();
	} else {
		&do_quota_portab();
	}
}

sub ql {
	my ($device) = @_;
	$device =~ s/\'/\'\\\'\'/g;
	$device = "\'" . $device . "\'";
	if (open (IN, "$quotalinux $device 2>&1 |")) {
		my ($read) = <IN>;
		close (IN);
		$read =~ tr/\r\n//d;
		return (($?, $read));
	}
	return (undef);
}

sub do_quota_linux {
	my (@devices);
	if (open (IN, "< /proc/mounts")) {
		while (<IN>) {
			if (/^(\S+)\s*(\S+)\s*(\S+)\s*(\S+)/) {
				my ($dev, $mnt, $fstyp, $opt) = ($1,$2,$3,$4);
				my (@opts);
				# skip tmp FS
				next if $mnt =~ /tmp/;
				@opts = split(/,/, $opt);
				# local filesystems
				if ( (0 != (grep {/^(usrquota|usrjquota)=?.*$/} @opts)) ) { #  && ( $dev =~ "^\/\S+")
					push @devices, $dev unless grep "$dev", @devices;
				}
				# NFSv4 filesystems
				if ( ($fstyp eq "nfs4") && ($mnt =~ "homepages") ) {
				  push @devices, $mnt;
				}
			}
		}
		close (IN);
	} else {
		print "- Can\'t open fstab file\r\n";
		return;
	}
	my ($dev);
	my ($blkcur, $blklim, $filcur, $fillim);
	$blkcur = 0;
	$blklim = 0;
	$filcur = 0;
	$fillim = 0;
	for $dev (@devices) {
		my ($status, $result) = &ql($dev);
		if ( (($status&255) != 0) && (($status&255) != 1) ) { # return code 1 if over quota
			print "- quota_linux error: ", $result, "\r\n";
			return;
		}
		if ($result =~
		    /^(\d+):(\d+):(\d+):(\d+):(\d+):(\d+):-?\d+:-?\d+$/) {
			my ($bh, $bs, $bc, $ih, $is, $ic) =
			    ($1, $2, $3, $4, $5, $6);
			if ($bh != $bs || $ih != $is) {
				print "- quota_linux output error\r\n";
				return;
			}
			$blkcur += $bc;
			$blklim += $bh;
			$filcur += $ic;
			$fillim += $ih;
		} else {
			print "- quota_linux output error: $result \r\n";
			return;
		}
	}
	print "+ $blkcur:$blklim:$filcur:$fillim\r\n";
}

sub do_quota_portab {
	if (open (IN, "$quota -v 2>&1 |")) {
		my (@spl, $found);
		my ($bv, $bq, $fv, $fq);
		$found = 0;
		while (<IN>) {
			tr/\r\n//d;
			s/^\s*//;
			@spl = split(/\s+/);
			if (scalar (@spl) >= 7 && ($spl[0] =~ /^\//)) {
				shift @spl;
				$bv = 0 + (shift @spl);
				$bq = 0 + (shift @spl);
				my ($bq_tmp);
				$bq_tmp = 0 + (shift @spl);
				if ($spl[0] =~ /^[A-Za-z]+$/) {
					shift @spl;
				}
				if (scalar (@spl) < 3 || $bq != $bq_tmp) {
					close(IN);
					print "- quota output error\r\n";
					return;
				}
				$fv = 0 + (shift @spl);
				$fq = 0 + (shift @spl);
				my ($fq_tmp);
				$fq_tmp = 0 + (shift @spl);
				if ($fq_tmp != $fq) {
					close(IN);
					print "- quota output error\r\n";
					return;
				}
				$found++;
			}
		}
		close(IN);
		if ($found == 1) {
			print "+ $bv:$bq:$fv:$fq\r\n";
		} elsif ($found == 0) {
			print "- No quota records found\r\n";
		} else {
			print "- Too many quota records\r\n";
		}
		# parse output
	} else {
		print "- Executing command failed\r\n";
	}
}

sub do_mkdir {
	my ($path) = @_;
	$path = &my_unescape($path);
	$path =~ s/^\/*//;
	$path = '/' . $path;
	my ($givenpath) = $path;
	$path = $home . $path;
	if ($givenpath =~ /\/\.\.\// || $givenpath =~ /\/\.\.$/) {
		print "- mkdir: No dot-dot reference allowed\r\n";
	} elsif ($givenpath =~ /\/\.\// || $givenpath =~ /\/\.$/) {
		print "- mkdir: No dot reference allowed\r\n";
	} elsif (-e $path) {
		print "- mkdir: Exists\r\n";
	} else {
		if (mkdir ($path, 0755)) {
			print "+ mkdir: OK\r\n";
		} else {
			print "- mkdir: failed: $!\r\n";
		}
	}
}

sub correct_perl {
	my ($path) = @_;
	unless (open (TMPIN, "< $path")) {
		return 0;
	}
	my ($line);
	$line = <TMPIN>;
	my ($ok);
	$ok = 0;
	if ($line) {
		$line =~ tr/\r\n//d;
		if ($line =~ /^\#\![ \t]*([^ \t]+)[ \t]*(([^ \t].*)?)$/) {
			if ($1 eq $perl && $2 eq '') {
				$ok = 1;
			}
		}
	}
	close TMPIN;
	return ($ok);
}

sub do_perlc {
	my ($path) = @_;
	$path =~ s/^\/*//;
	$path = '/' . $path;
	my ($givenpath) = $path;
	$path = $home . $path;
	if ($givenpath =~ /\/\.\.\// || $givenpath =~ /\/\.\.$/) {
		print "- cgi: No dot-dot reference allowed\r\n";
		print "- (no output)\r\n";
	} elsif ($givenpath =~ /\/\.\// || $givenpath =~ /\/\.$/) {
		print "- cgi: No dot reference allowed\r\n";
		print "- (no output)\r\n";
	} elsif (! (-f $path && ! -u $path && ! -g $path && -r $path)) {
		print "- cgi: File not present or has invalid modes\r\n";
		print "- (no output)\r\n";
	} elsif (! -x $path) {
		print "- cgi: File not executable (use chmod +x)\r\n";
		print "- (no output)\r\n";
	} elsif (! -r $path) {
		print "- cgi: File not readable (use chmod +r)\r\n";
		print "- (no output)\r\n";
	} elsif (! &correct_perl($path)) {
		print "- cgi: File has no correct script header (should be #! $perl)\r\n";
		print "- (no output)\r\n";
	} else {
		$path =~ s/\'/\'\\\'\'/g;
		$path = "\'" . $path . "\'";
		system ("$perl -c $path >$tmpname.out 2>$tmpname.err");
		if ($? != 0) {
			print "- ", ($? >> 8) , " perl returned nonzero status\r\n";
			&out('-');
		} else {
			print "+ Check succeeded\r\n";
			&out('+');
		}
	}
}

sub do_cgi {
	my ($path, $query) = @_;
	$path =~ s/^\/*//;
	$path = '/' . $path;
	my ($givenpath) = $path;
	$path = $home . $path;
	if ($givenpath =~ /\/\.\.\// || $givenpath =~ /\/\.\.$/) {
		print "- cgi: No dot-dot reference allowed\r\n";
		print "- (no output)\r\n";
	} elsif ($givenpath =~ /\/\.\// || $givenpath =~ /\/\.$/) {
		print "- cgi: No dot reference allowed\r\n";
		print "- (no output)\r\n";
	} elsif (! (-f $path && ! -u $path && ! -g $path && -r $path)) {
		print "- cgi: File not present or has invalid modes\r\n";
		print "- (no output)\r\n";
	} else {
		$ENV{'SERVER_SOFTWARE'} = 'interpreter/4.7.1.1';
		$ENV{'SERVER_NAME'} = '127.0.0.1';
		$ENV{'GATEWAY_INTERFACE'} = 'CGI/1.1';
		$ENV{'SERVER_PROTOCOL'} = 'HTTP/1.0';
		$ENV{'SERVER_PORT'} = '80';
		$ENV{'REQUEST_METHOD'} = 'GET';
		$ENV{'QUERY_STRING'} = $query;
		$ENV{'SCRIPT_NAME'} = $path;
		$ENV{'REMOTE_ADDR'} = '127.0.0.1';
		if ($home ne '') {
			$ENV{'DOCUMENT_ROOT'} = $home;
		}
		$ENV{'SCRIPT_FILENAME'} = $home . $path;
		# XXX env?!
		# XXX $ENV{'PATH'}
		my ($dir);
		$dir = $path;
		if ($dir =~ /^(.*)\/[^\/]+$/) {
			$dir = $1;
		}
		$path =~ s/\'/\'\\\'\'/g;
		$path = "\'" . $path . "\'";
		my ($arg);
		$arg = '';
		if (($query ne '') && ($query !~ /=/)) {
			$arg = $query;
			$arg =~ s/\'/\'\\\'\'/g;
			$arg = "\'" . $arg . "\'";
		}
		system("( cd $dir && $nice -n 19 $path $arg ) > $tmpname.out 2> $tmpname.err");
		if ($? != 0) {
			print "- ", ($? >> 8) ,
			    " CGI returned nonzero status\r\n";
			&out('-');
		} else {
			print "+ CGI Check succeeded\r\n";
			&out('+');
		}
	}
}

sub out {
	my ($finalchar) = @_;
	my ($outok, $errok) = (1, 1);
	if (open(IN, "< $tmpname.out")) {
		while (<IN>) {
			tr/\r\n//d;
			print "o ", $_, "\r\n";
		}
		close (IN);
		$outok = 1;
	} else {
		$outok = 0;
	}
	if (open(IN, "< $tmpname.err")) {
		while (<IN>) {
			tr/\r\n//d;
			print "e ", $_, "\r\n";
		}
		close(IN);
		$errok = 1;
	} else {
		$errok = 0;
	}
	print $finalchar, " ";
	print ($outok ? "STDOUT OK" : "STDOUT FAILED");
	print " ";
	print ($errok ? "STDERR OK" : "STDERR FAILED");
	print "\r\n";
	unlink("$tmpname.out");
	unlink("$tmpname.err");
}

sub my_unescape {
	my $str = shift;
	return '' if ($str eq '%');
	$str =~ s/\+/\%20/g;
	$str =~ s/\%([0-9A-Fa-f][0-9A-Fa-f])/chr(hex($1))/ge;
	return ($str);
}