#!/usr/bin/perl
#Local Access Protection Deprotector And No Cash Expected
#lapdance.pl V1.0 Copyright (C) 2012
#SecQuest Information Security Ltd. www.secquest.co.uk
#Use of this script is at your own risk.
use Getopt::Std;
use Term::Cap;

$version="";
$title="";
$enc="";
$char="";
$l1="";
$l2="";

getopts('idphf:') or usage();

if ($opt_h or (!$opt_i or !$opt_f)) { 
	usage();
}

print "Local Access Protection Deprotector And No Cash Expected\n";
print "--------------------------------------------------------\n\n";
print "  Getting info for ".$opt_f."\n";

#Files under 5? MB have the flag @ $1A4 and $2C4, over that the flag is $2C4 only

open(NSF, "<$opt_f") or die "\n\nError: Cannot open ".$opt_f;
binmode NSF;
#Get ODS version
seek(NSF,6,0);
#For some reason ord(sysread(NSF, $char, 1)) returns value+1?!!?
sysread(NSF, $char, 1);
$version=ord($char);

#Get database title
seek(NSF,200,0);
sysread NSF, $char, 1;
while (ord($char) ne 0 and ord($char) ne 10) {
  $title=$title.$char;
	sysread NSF, $char, 1;
}

#Check local access protection
seek(NSF,420,0); #$1A4
sysread(NSF, $char, 1);
$l1=ord($char);
seek(NSF,708,0); #$2C4
sysread(NSF, $char, 1);
$l2=ord($char);

#Get encryption status
seek(NSF,642,0);
sysread(NSF, $char, 1);
$enc=ord($char);

#Done
close(NSF);

print "  Database title: ".$title."\n";

if ($version eq 16) {
	print "  Database ODS version 16, Notes V2\n";
} elsif ($version eq 17) {
	print "  Database ODS version 17, Notes V3\n";
} elsif ($version eq 20) {
	print "  Database ODS version 20, Notes V4\n";
} elsif ($version eq 41) {
	print "  Database ODS version 41, Notes V5\n";
} elsif ($version eq 43) {
	print "  Database ODS version 43, Notes V6+\n";
} elsif ($version eq 48) {
	print "  Database ODS version 48, Notes V8\n";
} elsif ($version eq 51) {
	print "  Database ODS version 51, Notes V8.5\n";
} else {
	print "  Unknown ODS version (".$version.") - please tell us about it.\n";
}

if ($enc eq 1) {
	print "  Database is encrypted\n";
}

if($l1 == 32 or $l2 == 32) {
	print "  Database has local access protection\n";
}

#Deprotect file..
if($opt_d) {
	if($l1 == 32 or $l2 == 32) {
		print "  Removing local access protection..";
		open(NSF, "+<$opt_f") or die "\n\nError: Cannot open ".$opt_f;
		binmode NSF;
		#Change 2 bytes to deprotect file, saves working out sizing..
		seek(NSF,420,0);
		syswrite(NSF, chr(00)) or die "\n\nError: changing protection failed: $!\n";
		seek(NSF,708,0);
		syswrite(NSF, chr(00)) or die "\n\nError: changing protection failed: $!\n";
		close(NSF);
		print " done\n";
	} else {
		print "\n  Database isn't protected, nothing to change.\n";
	}
}

#Protect file..
if($opt_p) {
	if($l1 == 0 and $l2 == 0) {
		print "  Adding local access protection..";
		open(NSF, "+<$opt_f") or die "\n\nError: Cannot open ".$opt_f;
		binmode NSF;
		#Change 2 bytes to protect file, saves working out sizing..
		seek(NSF,420,0);
		syswrite(NSF, chr(32)) or die "\n\nError: changing protection failed: $!\n";
		seek(NSF,708,0);
		syswrite(NSF, chr(32)) or die "\n\nError: changing protection failed: $!\n";
		close(NSF);
		print " done\n";
	} else {
		print "\n  Database is already protected, nothing to change.\n";
	}
}

sub usage()
{
	print STDERR << "END";
Local Access Protection Deprotector And No Cash Expected!

SecQuest Information Security Ltd. 2012

Tool to display information about a Lotus Domino NSF file
and toggle database local access protection.

Usage: $0 [-idp] -f database.nsf 

 -i : Display info about the NSF only
 -d : Remove local access protection
 -p : Add local access protection
 -h : This info

example: $0 -d -f protected-db.nsf
END
exit 1;
}