#!/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 # puts the resulting file of kept records in place of the original index.txt # # 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 $cert = ""; # Counters my $countInput = 0; my $countOutput = 0; my $countRevokedUnexpired = 0; my $countRevokedExpired = 0; my $countUnrevokedUnexpired = 0; my $countUnrevokedExpired = 0; my $countEliminated = 0; # Filenames my $filenameInput = undef; my $filenameOutput = undef; my $filenameEliminated = undef; my $filenameSave = undef; my $filenameTemp = undef; my $fileNameStart = undef; # # 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]"; print "$timestamp $_[0]" if ( $debuglvl > 0 ); flush LOG; } # # Handling filenames and parameters # # getParameters allowed: class1, class3, test # getFilename returns te next valid name of a specific file # selectFilenames depending on given arguments sub getParameters () { if ( not defined $ARGV[0] ) { $cert = "test"; } else { $cert = $ARGV[0]; } if ( ( $cert ne "test" ) and ( $cert ne "class1" ) and ( $cert ne "class3" ) ) { dieOut( "no valid parameter $cert allowed are 'class1', 'class3' and 'test'\n" ); } } sub getFilename($$) { my $name = $_[0]; my $qualif = $_[1]; my $namepart = $name . $qualif; if ( -f $fileNameStart . $namepart . $actualDateS ) { while ( -f $fileNameStart . $namepart . $actualDateS ) { $namepart .= $qualif; } } return $namepart . $actualDateS; } sub SelectFilenames { if ( $cert eq "class1" ) { $fileNameStart = "/etc/ssl/CA/"; } else { if ( $cert eq "class3" ) { $fileNameStart = "/etc/ssl/class3/"; } else { $fileNameStart = "/home/GuKKDevel/bug-1306/tmp/"; } } $filenameInput = $fileNameStart . "index.txt"; $filenameOutput = $fileNameStart . getFilename( "index.", "kept." ); $filenameEliminated = $fileNameStart . getFilename( "index.", "elim." ); $filenameSave = $fileNameStart . getFilename( "index.", "save." ); $filenameTemp = $fileNameStart . "index.temp"; SysLog("File to read from -> $filenameInput\n"); SysLog("File to write kept lines -> $filenameOutput\n"); SysLog("File to save the removed lines -> $filenameEliminated\n"); } # # Pre-/Post-processing # # StartStopDemon stopping and starting the signer-demon # dieOut Start the signer-demon before die # preProcessing stopping the signer-demon # postProcessing renaming the kept-file as new index.txt-file my $restartDemon = 0; sub startStopDemon($) { if ( $_[0] eq "Stop" ) { # Stop demon SysLog("Stopping signer-demon\n"); system("service commmodule-signer stop"); if ($!) { die("$0: Couldn't stop signer"); } SysLog("Signer-demon stopped"); $restartDemon = 1; } else { # Start demon SysLog("Restarting signer-demon\n"); system("service commmodule-signer start"); if ($!) { die("$0: Couldn't start signer"); } SysLog("Signer-demon started"); } } sub dieOut ($) { SysLog( $_[0] ); if ($restartDemon) { startStopDemon("Start"); } die( $_[0] ); } sub preProcessing () { SysLog("\n"); SysLog("Start Pre-prossessing\n"); startStopDemon("Stop"); SysLog("End Pre-processing\n"); SysLog("\n"); } sub postProcessing () { SysLog("\n"); SysLog("Start Post-processing\n"); SysLog("Copying $filenameOutput to \n"); SysLog("$filenameTemp\n"); system("cp $filenameOutput $filenameTemp"); if ($!) { dieOut("$0: can' t copy $filenameOutput to $filenameTemp: $! \n "); } SysLog(" Copying done \n "); SysLog(" Copying $filenameInput to \n "); SysLog("$filenameSave \n "); system(" cp $filenameInput $filenameSave "); if ($!) { dieOut("$0 : can't copy $filenameInput to $filenameSave \n "); } SysLog(" Copying done \n "); SysLog(" Renaming $filenameTemp to \n "); SysLog("$filenameInput \n "); # now the index.txt file will be replaced # whilst Error server-demon MUST BE NOT RESTARTED $restartDemon = 0; system(" mv $filenameTemp $filenameInput "); if ($!) { dieOut("$0 : can't replace $filenameInput by $filenameTemp \n "); } SysLog(" Renaming done \n "); # restart demon $restartDemon = 1; startStopDemon(" Start "); SysLog(" End Post-processing \n "); SysLog(" \n "); } # # start of the main structure # # open the neccessary files # SysLog(" Start of program \n "); SysLog(" Reading the parameters \n "); getParameters(); SysLog( " Remove all revoked certificates, issued by $cert -certificate, expired and revoked before : $eliminationDateLimitS \n " ); preProcessing(); SysLog(" Allocating files \n "); SelectFilenames(); my $fileInput = undef; open( $fileInput, " < ", "$filenameInput " ) || dieOut("$0 : can't open $filenameInput for reading : $! \n "); my $fileOutput = undef; open( $fileOutput, " > ", "$filenameOutput " ) || dieOut("$0 : can't open $filenameOutput for writing : $! \n "); my $fileEliminated = undef; open( $fileEliminated, " > ", "$filenameEliminated " ) || dieOut("$0 : can't open $filenameEliminated for writing : $! \n "); SysLog(" Start reading \n "); while (<$fileInput>) { my $record = $_; my @field = split /\s+/, $record; my $flag = $field[0]; my $expirationDate = $field[1]; $countInput++; if ( $flag ne " R " ) { # certificate is unrevoked print $fileOutput $record; $countOutput++; if ( $expirationDate lt $eliminateDate ) { $countUnrevokedExpired++; } else { $countUnrevokedUnexpired++; } } else { # certificate is revoked my $revokationDate = $field[2]; if ( $expirationDate lt $eliminateDate and $revokationDate lt $eliminateDate ) { print $fileEliminated $record; $countEliminated++; $countRevokedExpired++; } else { print $fileOutput $record; $countOutput++; $countRevokedUnexpired++; } } } if ($!) { dieOut(" unexpected error while reading from $fileInput: $! "); } SysLog(" End reading \n "); SysLog(" Closing files \n "); close $fileInput; close $fileOutput; close $fileEliminated; postProcessing(); SysLog(" \n "); SysLog(" STATISTICS \n "); SysLog(" Read lines : $countInput \n "); SysLog(" Kept lines : $countOutput \n "); SysLog(" unrevoked and unexpired : $countUnrevokedUnexpired \n "); SysLog(" unrevoked but expired : $countUnrevokedExpired \n "); SysLog(" revoked but unexpired : $countRevokedUnexpired \n "); SysLog(" Eliminated : $countEliminated \n "); SysLog(" revoked and expired : $countRevokedExpired \n "); SysLog(" End of program \n ");