#!/usr/bin/perl

# prenviron - print the script's Unix running environment; CGI
# Steve Kinzler, steve@kinzler.com, Sep 94/Aug 00
# https://kinzler.com/me/home.html#webadm

if (0) {
	$out = "/tmp/prenviron$$";
	open(OUT, "> $out");
	select OUT;
	$seefile = "See $out";
}

print STDOUT "Content-type: text/plain\n\n$seefile";

print $0;
($arg = shift) =~ s/'/'\\''/g, print " '$arg'" while @ARGV;
print "\n";

chop($cwd = `pwd`);
$umask    = sprintf("%03o", umask);
$ruser    = (getpwuid($<))[0] || $<;
$euser    = ($> == $<) ? $ruser : (getpwuid($>))[0] || $>;
$rgroups  = &gids2groups($();
$egroups  = &gids2groups($));

print "\n", <<EOF;
cwd              = $cwd
umask            = $umask
real user        = $ruser
effective user   = $euser
real groups      = $rgroups
effective groups = $egroups
EOF

print "\n";
foreach (sort keys %ENV) {
	print "$_=$ENV{$_}\n";
}

if ($ENV{'REQUEST_METHOD'} =~ /^POST$/i) {
	read(STDIN, $post, $ENV{'CONTENT_LENGTH'});
	print "\nPOST data on STDIN:\n", $post, "\n";
}

if ($ENV{'REQUEST_METHOD'} =~ /^POST$/i || exists $ENV{'QUERY_STRING'}) {
	print "\nCGI data:\n";
	$cgi = (defined $post) ? $post : $ENV{'QUERY_STRING'};
	foreach (split(/&/, $cgi)) {
		s/\+/ /g;
		($key, $val) = split(/=/, $_, 2);
		$key =~ s/%([\da-f]{2})/pack('C', hex $1)/gie;
		$val =~ s/%([\da-f]{2})/pack('C', hex $1)/gie;
		$key =~ s/(\r\n|\n\r)/\n/g; $key =~ s/\r/\n/g;
		$val =~ s/(\r\n|\n\r)/\n/g; $val =~ s/\r/\n/g;
		$cgi{$key} .= ((defined $cgi{$key}) ? "\0" : '') . $val;
	}
	foreach (sort keys %cgi) {
		print '(multivalue) ' if $cgi{$_} =~ s/\0/\\0/g;
		print "$_=$cgi{$_}\n";
	}
}

@cgib64 = ('SAMLResponse');
if (grep(/./, @cgi{@cgib64})) {
	print "\nSome Base64-decoded CGI data:\n";
	foreach (@cgib64) {
		print "$_=", &decode_base64($cgi{$_}), "\n" if $cgi{$_} =~ /./;
	}
}

###############################################################################

sub gids2groups {
	local(@gids)	       = @_;
	local($group, $groups) = ('', '');

	foreach (split(/\s+/, join(' ', @_))) {
		$group   = $gid{$_} || (getgrgid($_))[0] || $_;
		$gid{$_} = $group;
		$groups .= ($groups eq '') ? $group : " $group";
	}

	return $groups;
}

sub decode_base64 {
	use integer;
	local($s, $u, $i, $l) = (shift, '');

	$s =~ tr/A-Za-z0-9+=\///cd;
	$s =~ s/=+$//;
	$s =~ tr/A-Za-z0-9+\// -_/;
	return '' unless length $s;

	$l = length($s) - 60;
	for ($i = 0; $i <= $l; $i += 60) {
		$u .= 'M' . substr($s, $i, 60);
	}
	$s  = substr($s, $i);
	$u .= chr(32 + length($s) * 3 / 4) . $s if $s ne '';
	return unpack ('u', $u);
}
