#!/usr/bin/perl -w
#
# module EliminateExpired.pl
#
# parameter: cert for CRL  class1 or class3 
#
# Eliminates certificate-records from file index.txt for CRL, which
# are revoked at least for 100 days and their expirationdate also older than 100 days
#
# if a certificate is revoked, it remains at index.txt
#	max{expirationDate,revokationDate} + 100 days
#
# this has to be proofed against the parameters of the openssl - config files
# for next update of the CRL
#
# also $fileNameStart has to be checked agains the config files
# /etc/ssl/CA for class1 
# /etc/ssl/class3 for class3
#

use strict;
use warnings;

use POSIX;
use open qw< :encoding(UTF-8) >;

#
# initializing
#

my $debuglvl = 0;
my $lz       = "\n";

# Counters

my $countInput      = 0;
my $countOutput     = 0;
my $countEliminated = 0;

#
# Date handling
#

my $actualDate = time();
my $actualDateS = strftime( "%Y-%m-%d", gmtime($actualDate) );

my $eliminationDateLimit = $actualDate - 100 * 24 * 60 * 60;    #subtract 100 days from current time
my $eliminationDateLimitS = strftime( "%Y-%m-%d", gmtime($eliminationDateLimit) );
my $eliminateDate =
    substr( $eliminationDateLimitS, 2, 2 )
  . substr( $eliminationDateLimitS, 5, 2 )
  . substr( $eliminationDateLimitS, 8, 2 );

#
#Logging functions:
#

my $lastdate = "";

sub SysLog($) {
	return if ( not defined( $_[0] ) );
	my $timestamp = strftime( "%Y-%m-%d %H:%M:%S", gmtime );
	my $currdate = substr( $timestamp, 0, 10 );
	if ( $lastdate ne $currdate ) {
		close LOG if ( $lastdate ne "" );
		$lastdate = $currdate;
		open LOG, ">logfile$lastdate.txt";
	}
	print LOG "$timestamp $_[0]";
	flush LOG;
}

#
# Handling filenames and parameters
#

my $filenameInput      = undef;
my $filenameOutput     = undef;
my $filenameEliminated = undef;
my $filenameSave       = undef;

sub SelectFilenames {

	my $cert          = "";
	my $fileNameStart = undef;

	if ( not defined $ARGV[0] ) {
		$cert = "class3";
	}
	else {
		$cert = $ARGV[0];
	}
	if ( $cert eq "class1" ) {
		$fileNameStart = "/etc/ssl/CA/";
	}
	else {
		$fileNameStart = "/etc/ssl/class3/";
	}
	$filenameInput      = $fileNameStart . "index.txt";
	$filenameOutput     = $fileNameStart . "index.temp.new";
	$filenameEliminated = $fileNameStart . "index.elim.$actualDateS";

	SysLog( "File to read from -> $filenameInput" . $lz );
	SysLog( "File to write kept lines -> $filenameOutput" . $lz );
	SysLog( "File to save the removed lines -> $filenameEliminated" . $lz );

	if ( $debuglvl > 8 ) {
		$fileNameStart = "/home/GuKKDevel/bug-1306/tmp/";
		$filenameInput = $fileNameStart . "index.txt";
		print "File to read from -> $filenameInput" . $lz;
		$filenameOutput = $fileNameStart . "index.temp.new";
		print "File to write kept lines -> $filenameOutput" . $lz;
		$filenameEliminated = $fileNameStart . "index.elim.$actualDateS";
		print "File to save the removed lines -> $filenameEliminated" . $lz;
		SysLog( "DEBUGGING:File to read from -> $filenameInput" . $lz );
		SysLog( "DEBUGGING:File to write kept lines -> $filenameOutput" . $lz );
		SysLog( "DEBUGGING:File to save the removed lines -> $filenameEliminated" . $lz );
	}
}
#
# open the neccessary files
#

SysLog( "Start of program\n");
SysLog( "Removing all revoked certificates expired and revoked before: $eliminationDateLimitS\n");
SysLog( "Allocating files\n");
SelectFilenames();

my $fileInput = undef;
open( $fileInput, "<", "$filenameInput" )
  || die "$0: can't open $filenameInput for reading: $!";

my $fileOutput = undef;
open( $fileOutput, ">", "$filenameOutput" )
  || die "$0: can't open $filenameOutput for reading: $!";

my $fileEliminated = undef;
open( $fileEliminated, ">", "$filenameEliminated" )
  || die "$0: can't open $filenameEliminated for reading: $!";

SysLog( "Start reading\n");
while (<$fileInput>) {
	my $record = $_;
	my @field  = split /\s+/, $record;
	my $flag   = $field[0];
	$countInput++;

	if ( $flag ne "R" ) {

		# certificate is unrevoked
		print $fileOutput $record;
		$countOutput++;
	}
	else {
		# certificate is revoked
		my $expirationDate = $field[1];
		my $revokationDate = $field[2];
		if ( $expirationDate lt $eliminateDate and $revokationDate lt $eliminateDate) {
			print $fileEliminated $record;
			$countEliminated++;
		}
		else {
			print $fileOutput $record;
			$countOutput++;
		}
	}
}
if ($!) {
	die "unexpected error while reading from $fileInput: $!";
}
SysLog( "End reading" . $lz );
SysLog( "Closing files" . $lz );
close $fileInput;
close $fileOutput;
close $fileEliminated;

SysLog( "STATISTICS" . $lz );
SysLog( "Read lines: " . $countInput . $lz );
SysLog( "Kept lines: " . $countOutput . $lz );
SysLog( "Eliminated: " . $countEliminated . $lz );
SysLog( "End of program");
