alexandru matei schrieb: > > Hello, > In export-import.lib the function "build_openssl_date" is missing. > Where canI find it?
This function moved from crypto-utils.lib into the module OpenCA::OpenSSL. I attached the fixed library. Michael -- ------------------------------------------------------------------- Michael Bell Email (private): [EMAIL PROTECTED] Rechenzentrum - Datacenter Email: [EMAIL PROTECTED] Humboldt-University of Berlin Tel.: +49 (0)30-2093 2482 Unter den Linden 6 Fax: +49 (0)30-2093 2959 10099 Berlin Germany [OpenCA Core Developer] http://www.openca.org
## export/import library of OpenCA Group ## ## (c) 1998-2001 by OpenCA Group ## the license is the general project license ## (see http://openca.sourceforge.net) ## ## Usage: ## ## Export ## ------ ## $tmp = createStructure (); ## exportXYZ ($tmp); ## exportABC ($tmp); ## createArchive ( $tmp); ## removeDirectory ( $tmp ); ## ## Import ## ------ ## $tmp = createStructure (); ## extractArchive ($tmp); ## importXYZ ($tmp); ## importABC ($tmp); ## removeDirectory ( $tmp ); ## ## export/import functions: ## * CSRs ## * Certs ## * CRRs ## * CRLs ## * CAs ## * Configuration ## * directory (RBAC, OpenSSL, extfiles) ## * file (openssl.cnf) ## * Mails ## * ImportFromCA/ExportToCA ## * ImportFromRAServer/ExportToRAServer ## * DB ## * replayLog (for SQL-DBs only today) ## ## other functions: ## * createDirectory ## * createStructure ## * createArchive ## * extractArchive ## * removeDirectory ## ## directories for the different objects: ## * CA_CERTIFICATE ## * REQUEST ## * CERTIFICATE ## * CRR ## * CRL ## * Configuration ## * RBAC ## * OpenSSL ## * extfiles ## * others (for the rest) ## * Mail ## the variables which start with $exim_ are reserved for this library #################################### ## general function for archiving ## #################################### ## ## createDirectory ## ## this function prepare a temporary directory for the files ## which should be exported ## sub createDirectory { my $exim_tmp_dir; if ( not $_[0] ) { $exim_tmp_dir = getRequired ('TempDir')."/tmp_".$$; } else { $exim_tmp_dir = $_[0]; } if (not mkdir ( $exim_tmp_dir, 0700 )) { ## output is only necessary if something going wrong print addLogSection ("Creating Temporary Directory $exim_tmp_dir ..."); print addErrorLog ("Cannot create temporary directory $exim_tmp_dir!"); print closeLogSection(); return ""; } return $exim_tmp_dir; } ## ## createStructure ## ## this function prepare a temporary directory for the files ## which should be exported ## sub createStructure { ## get the base directory my $dir; if ( not $_[0]) { $dir = createDirectory (); } else { $dir = $_[0]; } if (not defined $dir or not $dir) { return undef; } ## create the subdirectories ## create structure $list = { CERTIFICATE => [ "VALID", "EXPIRED", "REVOKED", "SUSPENDED" ], REQUEST => [ "PENDING", "APPROVED", "ARCHIVIED", "DELETED", "RENEW" ], CA_CERTIFICATE => [ "VALID", "EXPIRED" ], CRL => [ "VALID" ], CRR => [ "PENDING", "APPROVED", "ARCHIVIED", "DELETED" ], LOG => [ "ALL" ], }; foreach $object (keys %{$list}) { return undef if (not createDirectory ( $dir."/".$object )); foreach $status (@{$list->{$object}}) { return undef if (not createDirectory ( $dir."/".$object."/".$status )); } } return $dir; } ## ## createArchive ## ## this function generates an archive from a special directory ## parameters : DIRECTORY as $_[0] ## sub createArchive { my $exim_tmp_dir = $_[0]; print addLogSection ("Creating Archive ..."); print addLogLine ( "" ); print addPreLogLine ("Load required variables ..."); ## Get required parameters from the configuration file my $creat = getRequired( 'CreateArchive' ); my $test = getRequired( 'TestArchive' ); my $dest = getRequired( 'ExportDev' ); ## Build the right $cmd with substitution of the $dest ## with the 'ExportDest' and in 'TestArchive' my $arc = $query->subVar( $creat, '$dest', $dest ); my $test = $query->subVar( $test, '$dest', $dest ); print addPreLogLine ("Changing to directory $exim_tmp_dir ..."); if (not chdir $exim_tmp_dir) { print addErrorLog ( "failed"); print closeLogSection(); return 0; } print addPreLogLine ("Build Archive ..."); $ret = `$arc . 2>&1`; if( $? != 0 ) { print addErrorLog("Archiving Failed to $dest!"); print addLogLine( "$arc ." ); print closeLogSection(); return 0; } print addPreLogLine ("Test Archive ..."); $ret = `$test 2>&1`; if( $? != 0 ) { print addErrorLog("Testing Archive Failed for $dest!"); print addLogLine( "$arc" ); print closeLogSection(); return 0; } print addPreLogLine ("Archive created successfully."); print closeLogSection(); return 1; } ## ## extractArchive ## ## this function extracts an archive from a special media ## parameters : DIRECTORY as $_[0] ## sub extractArchive { my $exim_tmp_dir = $_[0]; ## Get required parameters from the configuration file my $unpack = getRequired( 'UnpackArchive' ); my $test = getRequired( 'TestArchive' ); my $dest = getRequired( 'ImportDev' ); ## Build the right $cmd with substitution of the $dest ## with the 'ExportDest' and in 'TestArchive' my $arc = $query->subVar( $unpack, '$orig', $dest ); my $arc = $query->subVar( $arc, '$dest', $exim_tmp_dir ); my $test = $query->subVar( $test, '$dest', $dest ); if (not chdir $exim_tmp_dir) { print addLogLine ("Changing to directory $exim_tmp_dir ..."); printErrorLog ( "failed"); return 0; } $ret = `$test 2>&1`; if( $? != 0 ) { print addLogSection ("Extracting Archive ..."); print addErrorLog("Testing Archive Failed for $dest!"); print addLogLine( "$arc" ); print closeLogSection (); return 0; } $ret = `$arc . 2>&1`; if( $? != 0 ) { print addLogSection ("Extracting Archive ..."); print addErrorLog("Extracting Archive Failed from $dest!"); print addLogLine( "$arc" ); print closeLogSection (); return 0; } return 1; } ## ## removeArchive ## ## this function remove a temporary directory ## sub removeDirectory { my $exim_tmp_dir = $_[0]; print addLogSection ("Clean up ..."); if ( length ( $exim_tmp_dir ) < 10 ) { print addErrorLog ("Stop removing temporary directory $exim_tmp_dir ". " because the length of it is smaller than 10!"); print closeLogSection(); return 0; } $ret = `rm -rf $exim_tmp_dir`; if( $? != 0 ) { print addErrorLog("Cannot remove temporary directory $exim_tmp_dir"); print addLogLine( "rm -rf $exim_tmp_dir" ); print closeLogSection(); return 0; } print addLogLine( "Ok." ); print closeLogSection(); return 1; } ###################################### ## functions for DB-backup/recovery ## ###################################### ##################################################### ## general warning ## ##################################################### ## * all actions are handled by this function ## ## (except of html-header and -footer) ## ## * use importDB only on an empty DB ## ## * if importDB detects an already existing ## ## object it only signal this event and continue ## ## * every import of an object is documented in ## ## the logs if you use OpenCA::DB and importDB ## ## * replayLog only use the logs and replay all ## ## actions of the CA or RAServer ## ## * if you want to use replayLog you MUST create ## ## the database again to get consistent state, ## ## if you replay on a not newly created database ## ## then the result is undefined ## ##################################################### sub exportDB { ## create initial structure my $dir = createStructure (); if (not defined $dir or not $dir) { return undef; } ## structure $list = { CERTIFICATE => [ "VALID", "EXPIRED", "REVOKED", "SUSPENDED" ], REQUEST => [ "PENDING", "APPROVED", "ARCHIVIED", "DELETED", "RENEW" ], CA_CERTIFICATE => [ "VALID", "EXPIRED" ], CRL => [ "VALID" ], CRR => [ "PENDING", "APPROVED", "ARCHIVIED", "DELETED" ], LOG => [ "ALL" ], }; ## iterate over all types of object foreach my $object (keys %{$list}) { if ( ($object =~ /LOG/) and (getRequired ('DBmodule') !~ /DBI/i) ) { next; } ## iterate over all states foreach my $status (@{$list->{$object}}) { exportObjects ( DATATYPE => $object, STATUS => $status, DIR => $dir ); } } ## create the archive return undef if (not createArchive ( $dir )); ## remove the hole structure return undef if (not removeDirectory ( $dir )); return 1; } sub importDB { ## create initial structure my $dir = createDirectory (); if (not defined $dir or not $dir) { return undef; } ## extract archive if (not extractArchive ( $dir )) { return undef; } ## structure $list = { CERTIFICATE => [ "VALID", "EXPIRED", "REVOKED", "SUSPENDED" ], REQUEST => [ "PENDING", "APPROVED", "ARCHIVIED", "DELETED", "RENEW" ], CA_CERTIFICATE => [ "VALID", "EXPIRED" ], CRL => [ "VALID" ], CRR => [ "PENDING", "APPROVED", "ARCHIVIED", "DELETED" ], LOG => [ "ALL" ], }; ## iterate over all types of object foreach my $object (keys %{$list}) { if ( ($object =~ /LOG/) and (getRequired ('DBmodule') !~ /DBI/i) ) { next; } ## iterate over all states foreach my $status (@{$list->{$object}}) { importObjects ( DATATYPE => $object, STATUS => $status, DIR => $dir ); } } ## remove the hole structure return undef if (not removeDirectory ( $dir )); return 1; } ## this function recovers a database only from the logs! ## so if you want to have a secure replay you can use ## this function (we are doing datalogging) sub replayLog { ## create initial structure my $dir = createDirectory (); if (not defined $dir or not $dir) { print addPreLogLine ( "<FONT COLOR=#FF0000>FAILURE: You can only replay the logs if you are using a SQL-database</FONT>"); print addPreLogLine ( "<FONT COLOR=#FF0000>ABORTING ...</FONT>"); print closeLogSection (); return undef; } ## extract archive if (not extractArchive ( $dir )) { return undef; } ## start output print addLogSection ("Replaying logs (on a new and empty sql-database only) ..."); if ( ($object =~ /LOG/) and (getRequired ('DBmodule') !~ /DBI/i) ) { return undef; } my $directory = $dir."/LOG/ALL"; opendir( DIR, $directory ); my @dirList = grep (/^[^\.]/, readdir( DIR )); closedir( DIR ); if (not scalar @dirList) { print addPreLogLine ("<i>The log is empty.</i>"); } for (my $i=1; $i <= scalar @dirList; $i++) { ## setup filename my $filename = $directory."/".$i.".log"; ## load the file my $content = $tools->getFile ( $filename ); ## load the datatype my ( $object ) = ( $content =~ /^([^\n]*)/ ); $content =~ s/^[^\n]*\n//; ## load the status my ( $status ) = ( $content =~ /^([^\n]*)/ ); $content =~ s/^[^\n]*\n//; ## write back the file ( $filename ) = ( $content =~ /^([^\n]*)/ ); $content =~ s/^[^\n]*\n//; ## write back filename $filename = $dir."/LOG/".$filename; if (not $tools->saveFile (FILENAME => $filename, DATA => $content)) { print addPreLogLine ( "<FONT COLOR=#FF0000>FAILURE: Cannot write file</FONT>"); print addPreLogLine ( "<FONT COLOR=#FF0000>FILE: ".$filename."</FONT>"); print addPreLogLine ( "<FONT COLOR=#FF0000>ABORTING ...</FONT>"); print closeLogSection (); return undef; } ## create object my $db_object; if ($object =~ /CERTIFICATE/) { $db_object = new OpenCA::X509 ( SHELL => $cryptoShell, INFILE => $filename, FORMAT => "PEM" ); } elsif ($object =~ /^(REQUEST|CRR)$/) { $db_object = new OpenCA::REQ ( SHELL => $cryptoShell, INFILE => $filename); } else { $db_object = new OpenCA::CRL ( INFILE => $filename, SHELL => $cryptoShell ); } if (not defined $db_object or not $db_object) { print addPreLogLine ( "<FONT COLOR=#FF0000>FAILURE: Cannot create object from file</FONT>"); print addPreLogLine ( "<FONT COLOR=#FF0000>FILE: ".$filename."</FONT>"); print addPreLogLine ( "<FONT COLOR=#FF0000>ABORTING ...</FONT>"); print closeLogSection (); return undef; } if ( defined $db->storeItem ( DATATYPE => $status."_".$object, OBJECT => $db_object, MODE => "UPDATE" )) { $filename =~ s/.*\///; print addPreLogLine ($status."_".$object." updated from $filename"); } else { if ( defined $db->storeItem ( DATATYPE => $status."_".$object, OBJECT => $db_object, MODE => "INSERT" )) { $filename =~ s/.*\///; print addPreLogLine ($status."_".$object." inserted from $filename"); } else { print addPreLogLine ( "<FONT COLOR=#FF0000>FAILURE: Cannot insert/update object</FONT>"); print addPreLogLine ( "<FONT COLOR=#FF0000>FILE: ".$filename."</FONT>"); print addPreLogLine ( "<FONT COLOR=#FF0000>ABORTING ...</FONT>"); print closeLogSection (); return undef; } } } ## end output print closeLogSection (); ## remove the hole structure return undef if (not removeDirectory ( $dir )); return 1; } ########################### ## functions for objects ## ########################### # Input: DATATYPE and/or STATUS # Output: array with the ex-/imported Objects # determine status and datatype sub eximObjectsGetParams { my $keys = { @_ }; my @result = (); # determine status if ($keys->{STATUS}) { $result [1] = $keys->{STATUS}; } else { $result [1] = $keys->{DATATYPE}; $result [1] =~ s/_.*$//; $result [1] = "" if ($result [1] =~ /^(CA|CERTIFICATE|REQUEST|CRR|CRL|LOG)$/); } # determine datatype $result [0] = $keys->{DATATYPE}; $result [0] =~ s/^$result[1]_// if ($result [1]); return @result; } sub exportObjects { my $keys = { @_ }; my @datatype = eximObjectsGetParams ( @_ ); print addLogSection ( "Exporting ".lc $datatype [1]." ".$datatype [0]." ..." ); ## load objects my @list; if ($datatype [1] and ($datatype [0] !~ /LOG/)) { @list = $db->searchItems ( DATATYPE => $datatype [1]."_".$datatype [0] ); } else { @list = $db->searchItems ( DATATYPE => $datatype [0] ); } ## write objects my @result = (); if (not scalar @list) { print addPreLogLine ("<i>No objects are present.</i>"); } my $count = 0; foreach my $value (@list) { my $txtItem; my $log = 0; if ($datatype [0] =~ /LOG/) { $log = 1; $count++; $datatype [0] = $value-> [0]; $datatype [1] = $value-> [1]; my $h = $value-> [2]; $value = undef; $value = $h; } ## get content and format for file if( $datatype [0] =~ /(REQUEST|CRR)/i ) { $txtItem = $value->getParsed()->{ITEM}; $format = $value->getParsed()->{TYPE}; } else { if ( $datatype [0] =~ /CERTIFICATE/i) { $txtItem = $value->getPEMHeader ()."\n"; } else { $txtItem = "-----BEGIN HEADER-----\n".$value->getHeader ()."-----END HEADER-----\n"; } $txtItem .= $value->getPEM(); $txtItem .= $value->getParsed()->{KEY}; $format = "PEM"; } $format =~ s/\s/_/g; # serial my $serial; if ($datatype [0] =~ /^CERTIFICATE/) { $serial = $value->getParsed()->{SERIAL}; } elsif ($datatype [0] =~ /(REQUEST|CRR)/) { $serial = $value->getParsed()->{DBKEY}; } else { # CRL,CA_CERTIFICATE $serial = $cryptoShell->getDigest ( DATA => $value->getPEM()); } ## corrections for logs if ($log) { # filename $txtItem = $serial.".".(lc $format)."\n".$txtItem; # status $txtItem = $datatype [1]."\n".$txtItem; # datatype $txtItem = $datatype [0]."\n".$txtItem; $datatype [0] = "LOG"; $datatype [1] = "ALL"; $format = "log"; $serial = $count; } ## write file my $filename = $keys->{DIR}."/".$datatype [0]."/".$datatype [1]."/".$serial.".".(lc $format); if ($tools->saveFile (FILENAME => $filename, DATA => $txtItem)) { print addPreLogLine ($serial.".".(lc $format)); push (@result, $serial); } else { print addPreLogLine ( "<FONT COLOR=#FF0000>FAILURE: ".$serial.".".(lc $format)."</FONT>"); print addPreLogLine ( "<FONT COLOR=#FF0000>FILE: ".$filename."</FONT>"); } } print closeLogSection (); return @result; } sub importObjects { my $keys = { @_ }; my @datatype = eximObjectsGetParams ( @_ ); print addLogSection ( "Importing ".lc $datatype [1]." ".$datatype [0]." ..." ); if ( ($datatype [0] =~ /LOG/) and (getRequired ('DBmodule') !~ /DBI/i) ) { print addPreLogLine ("iLogs are only available on SQL-Databases!"); print closeLogSection (); return (); } my $dir = $keys->{DIR}; my $directory = $dir."/".$datatype [0]."/".$datatype [1]; opendir( DIR, $directory ); my @dirList = grep (/^[^\.]/, readdir( DIR )); closedir( DIR ); my @result = (); if (not scalar @dirList) { print addPreLogLine ("<i>No objects are present.</i>"); } foreach my $value (@dirList) { ## setup filename my $filename = $directory."/".$value; ## if we load the the logs we have to do a little bit more my $log = 0; if ($datatype [0] =~ /LOG/) { $log = 1; ## value $value =~ s/\.log$//; ## load the file my $content = $tools->getFile ( $filename ); ## load the datatype ( $datatype [0] ) = ( $content =~ /^([^\n]*)/ ); $content =~ s/^[^\n]*\n//; ## load the status ( $datatype [1] ) = ( $content =~ /^([^\n]*)/ ); $content =~ s/^[^\n]*\n//; ## write back the file ( $filename ) = ( $content =~ /^([^\n]*)/ ); $content =~ s/^[^\n]*\n//; ## write back filename $filename = $dir."/LOG/".$filename; if (not $tools->saveFile (FILENAME => $filename, DATA => $content)) { print addPreLogLine ( "<FONT COLOR=#FF0000>FAILURE: Cannot write file</FONT>"); print addPreLogLine ( "<FONT COLOR=#FF0000>FILE: ".$filename."</FONT>"); next; } } ## create object my $db_object; if ($datatype [0] =~ /CERTIFICATE/) { $db_object = new OpenCA::X509 ( SHELL => $cryptoShell, INFILE => $filename, FORMAT => "PEM" ); } elsif ($datatype [0] =~ /^(REQUEST|CRR)$/) { $db_object = new OpenCA::REQ ( SHELL => $cryptoShell, INFILE => $filename); } else { $db_object = new OpenCA::CRL ( INFILE => $filename, SHELL => $cryptoShell ); } if (not defined $db_object or not $db_object) { print addPreLogLine ( "<FONT COLOR=#FF0000>FAILURE: Cannot create object from file</FONT>"); print addPreLogLine ( "<FONT COLOR=#FF0000>FILE: ".$filename."</FONT>"); next; } ## insert object my $h; my $db_mode = "INSERT"; if ($log) { $h = $db->storeItem ( DATATYPE => "LOG", OBJECT_DATATYPE => $datatype [1]."_".$datatype [0], OBJECT => $db_object, KEY => $value, MODE => $db_mode ); $datatype [0] = "LOG"; $value .= ".log"; $datatype [1] = "ALL"; } else { my @help_list = (); if ($datatype [0] =~ /(CRR|REQUEST)/) { $serial = $db_object->getParsed()->{HEADER}->{SERIAL}; @help_list = $db->searchItems ( DATATYPE => "PENDING_".$datatype [0], KEY => $serial ); } ## request already in the database ? if ( @help_list and scalar @help_list ) { $db_mode = "UPDATE"; } $h = $db->storeItem ( DATATYPE => $datatype [1]."_".$datatype [0], OBJECT => $db_object, MODE => $db_mode ); if ( (not defined $h) and (defined $keys->{ENFORCE} and $keys->{ENFORCE}) and ($db_mode !~ /UPDATE/) ) { $db_mode = "UPDATE"; $h = $db->storeItem ( DATATYPE => $datatype [1]."_".$datatype [0], OBJECT => $db_object, MODE => $db_mode ); } } if (defined $h) { push (@result, $db_object); if ($db_mode =~ /UPDATE/) { print addPreLogLine ($value." updated"); } else { print addPreLogLine ($value." inserted"); } } else { # serial my $serial; if ($datatype [0] =~ /^CERTIFICATE/) { $serial = $db_object->getParsed()->{SERIAL}; } elsif ($datatype [0] =~ /(REQUEST|CRR)/) { $serial = $db_object->getParsed()->{DBKEY}; } else { # CRL,CA_CERTIFICATE $serial = $cryptoShell->getDigest ( DATA => $db_object->getPEM()); } ## advanced information if ($db->searchItems ( DATATYPE => $datatype [0], KEY => $serial )) { if ($db_mode !~ /UPDATE/) { print addPreLogLine ( "<FONT COLOR=#FF0000>WARNING: Cannot insert object but object is present in database</FONT>"); print addPreLogLine ( "<FONT COLOR=#FF0000>FILE: ".$filename."</FONT>"); } else { print addPreLogLine ( "<FONT COLOR=#FF0000>WARNING: Cannot update object but object is present in database</FONT>"); print addPreLogLine ( "<FONT COLOR=#FF0000>FILE: ".$filename."</FONT>"); } } elsif ($db_mode !~ /UPDATE/) { print addPreLogLine ( "<FONT COLOR=#FF0000>FAILURE: Cannot insert object and object is not present in database</FONT>"); print addPreLogLine ( "<FONT COLOR=#FF0000>FILE: ".$filename."</FONT>"); } else { print addPreLogLine ( "<FONT COLOR=#FF0000>FAILURE: Cannot insert and/or update object and object is not present in database</FONT>"); print addPreLogLine ( "<FONT COLOR=#FF0000>FILE: ".$filename."</FONT>"); } } } print closeLogSection (); return @result; } ############################ ## functions for Requests ## ############################ ## the requests are only archived during the import of the certificates ## to handle crashed disks etc. sub exportCSRs { my $exim_tmp_dir = $_[0]; exportObjects ( DATATYPE => "APPROVED_REQUEST", DIR => $exim_tmp_dir ); exportObjects ( DATATYPE => "PENDING_REQUEST", DIR => $exim_tmp_dir ); exportObjects ( DATATYPE => "RENEW_REQUEST", DIR => $exim_tmp_dir ); return 1; } sub importCSRs { my $exim_tmp_dir = $_[0]; importObjects ( DATATYPE => "APPROVED_REQUEST", DIR => $exim_tmp_dir ); importObjects ( DATATYPE => "PENDING_REQUEST", DIR => $exim_tmp_dir ); importObjects ( DATATYPE => "RENEW_REQUEST", DIR => $exim_tmp_dir ); return 1; } ############################### ## functions for Certifcates ## ############################### sub exportCerts { my $exim_tmp_dir = $_[0]; exportObjects ( DATATYPE => "VALID_CERTIFICATE", DIR => $exim_tmp_dir ); exportObjects ( DATATYPE => "ARCHIVIED_REQUEST", DIR => $exim_tmp_dir ); exportObjects ( DATATYPE => "DELETED_REQUEST", DIR => $exim_tmp_dir ); return 1; } sub importCerts { my $keys = { @_ }; my $exim_tmp_dir = $keys->{TMP}; my $certDir = getRequired ( 'CertDir' ); my @list = importObjects ( DATATYPE => "VALID_CERTIFICATE", DIR => $exim_tmp_dir ); importObjects ( DATATYPE => "ARCHIVIED_REQUEST", DIR => $exim_tmp_dir, ENFORCE => 1 ); importObjects ( DATATYPE => "DELETED_REQUEST", DIR => $exim_tmp_dir, ENFORCE => 1 ); my $dir = $exim_tmp_dir."/CERTIFICATE/VALID/"; return 1 if (not $keys->{LDAP}); print addLogSection( "Importing Certificates into ldap ... "); if ( not scalar @list) { print addPreLogLine ("<i>No certificates present.</i>"); } foreach my $data (@list) { my $result = eximObjectToLDAP ( CERTIFICATE => $data ); if ( not $result or not $result->{STATUS} ) { $ret .= "\n<FONT COLOR=#FF0000>Cannot write CERTIFICATE ".$data->getParsed()->{SERIAL}." to LDAP</FONT>"; } else { $ret .= "\nCERTIFICATE ".$data->getParsed()->{SERIAL}." is available via LDAP"; } print addPreLogLine ($ret); } ## what I'm doing here??? ## upating lastImport my $txt = ""; foreach $line (@list) { $txt .= $line->getParsed()->{SERIAL}."\n"; }; unlink( "$certDir/lastImport.txt" ); if (not $tools->saveFile (FILENAME => "$certDir/lastImport.txt", DATA => $txt ) ) { print addPreLogLine ("<FONT COLOR=#FF0000>". "Cannot update file ". $certDir."/lastImport.txt". "with certificates of last import". "</FONT>"); } print closeLogSection(); return 1; } ################################## ## functions for CA-Certifcates ## ################################## sub exportCAs { my $exim_tmp_dir = $_[0]; exportObjects ( DATATYPE => "VALID_CA_CERTIFICATE", DIR => $exim_tmp_dir ); return 1; } sub importCAs { my $keys = { @_ }; my $exim_tmp_dir = $keys->{TMP}; my @list = importObjects ( DATATYPE => "VALID_CA_CERTIFICATE", DIR => $exim_tmp_dir, ENFORCE => 1 ); if ($keys->{LDAP}) { print addLogSection( "Importing CA-Certificates into ldap ... "); foreach my $data (@list) { my $tmpSerial, $tmpFormat; $tmpSerial = $cryptoShell->getDigest ( DATA => $data->getPEM()); ## update LDAP ? my $result = eximObjectToLDAP ( AUTHORITY_CERTIFICATE => $data ); if ( not $result or not $result->{STATUS} ) { print addPreLogLine ("<FONT COLOR=#FF0000>Cannot write CA-Certificate $tmpSerial to LDAP</FONT>" ); } else { print addPreLogLine ("CA-Certificate $tmpSerial is available via LDAP") ; } } print closeLogSection(); } print addLogSection ("Make CA-Certificate available on the server ..."); my @cacerts = $db->searchItems ( DATATYPE => "VALID_CA_CERTIFICATE" ); my $key; my $serial = -1; my $cert_data = ""; foreach my $cert (@cacerts) { if ( $cert->getParsed ()->{SERIAL} > $serial ) { $serial = $cert->getParsed ()->{SERIAL}; $cert_data = $cert->getPEM (); } } $tools->saveFile ( FILENAME => "${exim_tmp_dir}/${key}.pem", DATA => $cert_data); my $CACert = getRequired ( 'CACertificate'); if( not $tools->copyFiles ( SRC => "${exim_tmp_dir}/${key}.pem", DEST => $CACert ) ) { print addLogLine ( "FAILED." ); print addPreLogLine( "<FONT COLOR=#FF0000>". "Copying latest ca-certificate into ". "the RAServer failed ". "(from ${exim_tmp_dir}/${key}.pem ". "to $CACert)!</FONT>"); print closeLogSection (); return 0; } print addLogLine ("OK."); print closeLogSection (); # Now we copy the CA's certificate to the chain dir my $cacertCRT = gteRequired ('CACertificateCRT'); if (not $tools->copyFiles( SRC => $CACert, DEST => $cacertCRT )) { print addLogSection( "<FONT COLOR=#FF0000>". "Copying latest ca-certificate into ". "chain's directory failed ". "(from $CACert ". "to ${cacertCRT})!</FONT>"); print closeLogSection (); return 0; } # Let's make Chain verification print addLogSection("Re-Building CA Chain ... "); my $chainDir = getRequired ( 'ChainDir' ); chdir( "${chainDir}" ); ## what for command? my $makeCmd = getRequired ('MakePath'); $ret = `$makeCmd clean ; $makeCmd 2>&1`; if ( $? ) { print addLogLine ("<FONT COLOR=#FF0000>FAILED</FONT>"); print closeLogSection(); return 0; } else { print addLogLine("Ok."); } print closeLogSection(); return 1; } ######################## ## functions for CRRs ## ######################## sub exportCRRs { my $exim_tmp_dir = $_[0]; exportObjects ( DATATYPE => "APPROVED_CRR", DIR => $exim_tmp_dir ); exportObjects ( DATATYPE => "PENDING_CRR", DIR => $exim_tmp_dir ); return 1; } sub importCRRs { my $exim_tmp_dir = $_[0]; my @list = importObjects ( DATATYPE => "APPROVED_CRR", DIR => $exim_tmp_dir ); push (@list, importObjects ( DATATYPE => "PENDING_CRR", DIR => $exim_tmp_dir )); print addLogSection ("Updating certificates status ..."); foreach my $data (@list) { if ($db->updateStatus ( DATATYPE => "VALID_CERTIFICATE", NEWTYPE => "SUSPENDED_CERTIFICATE", OBJECT => $db->getItem ( DATATYPE => "VALID_CERTIFICATE", KEY => $data->getParsed()->{REVOKE_CERTIFICATE_SERIAL} ) )) { print addPreLogLine ("Changed the status of the certificate <I>" . $data->getParsed()->{REVOKE_CERTIFICATE_DN} . " (" . $data->getParsed()->{REVOKE_CERTIFICATE_SERIAL} . ")</I>"); } else { print addPreLogLine ("<FONT COLOR=##FF0000>". "Cannot change the status of the certificate <I>" . $data->getParsed()->{REVOKE_CERTIFICATE_DN} . " (" . $data->getParsed->{REVOKE_CERTIFICATE_SERIAL} . ")</I>". "</FONT>"); } } print closeLogSection(); return 1; } ######################## ## functions for CRLs ## ######################## sub exportCRLs { my $exim_tmp_dir = $_[0]; exportObjects ( DATATYPE => "VALID_CRL", DIR => $exim_tmp_dir ); exportObjects ( DATATYPE => "ARCHIVIED_CRR", DIR => $exim_tmp_dir ); exportObjects ( DATATYPE => "REVOKED_CERTIFICATE", DIR => $exim_tmp_dir ); return 1; } sub importCRLs { my $keys = { @_ }; my $exim_tmp_dir = $keys->{TMP}; my @list = importObjects ( DATATYPE => "VALID_CRL", DIR => $exim_tmp_dir, ENFORCE => 1 ); importObjects ( DATATYPE => "ARCHIVIED_CRR", DIR => $exim_tmp_dir, ENFORCE => 1 ); importObjects ( DATATYPE => "DELETED_CRR", DIR => $exim_tmp_dir, ENFORCE => 1 ); importObjects ( DATATYPE => "REVOKED_CERTIFICATE", DIR => $exim_tmp_dir, ENFORCE => 1 ); return 1 if (not defined @list or not scalar @list); if ( $keys->{LDAP} ) { print addLogSection("Importing CRL into LDAP ... "); foreach my $data (@list) { my $result = eximObjectToLDAP ( CRL => $data ); if ( not $result or not $result->{STATUS} ) { print addPreLogLine ( "<FONT COLOR=#FF0000>". "Cannot write CRL to LDAP\n\tLast Update: ". $data->getParsed()->{LAST_UPDATE} ."\n" . "\tNext Update: " . $data->getParsed()->{NEXT_UPDATE} . "\n". "</FONT>"); } else { print addPreLogLine ( "Added CRL to LDAP\n\tLast Update: " . $data->getParsed()->{LAST_UPDATE} ."\n" . "\tNext Update: " . $data->getParsed()->{NEXT_UPDATE} . "\n"); } } print closeLogSection (); } my $crlDir = getRequired ( 'CRLDir'); print addLogSection("Importing CRL into servers ... "); my $serial = 0; my $data; foreach my $tmpCRL (@list) { if ($cryptoShell->getNumericDate ($tmpCRL->getParsed()->{LAST_UPDATE}) > $serial) { $serial = $cryptoShell->getNumericDate ($tmpCRL->getParsed()->{LAST_UPDATE}); $data = $tmpCRL; } } ## RAServer if (not $tools->saveFile ( FILENAME=>"$crlDir/cacrl.pem", DATA=>$data->getPEM())) { print addPreLogLine ( "<FONT COLOR=#FF0000>". "Cannot update CRL on RAServer. FILE: $crlDir/cacrl.pem". "</FONT>"); } if (not $tools->saveFile ( FILENAME=>"$crlDir/cacrl.der", DATA=>$data->getDER())) { print addPreLogLine ( "<FONT COLOR=#FF0000>". "Cannot update CRL on RAServer. FILE: $crlDir/cacrl.der". "</FONT>"); } if (not $tools->saveFile ( FILENAME=>"$crlDir/cacrl.crl", DATA=>$data->getDER())) { print addPreLogLine ( "<FONT COLOR=#FF0000>". "Cannot update CRL on RAServer. FILE: $crlDir/cacrl.crl". "</FONT>"); } if (not $tools->saveFile ( FILENAME=>"$crlDir/cacrl.txt", DATA=>$data->getTXT())) { print addPreLogLine ( "<FONT COLOR=#FF0000>". "Cannot update CRL on RAServer. FILE: $crlDir/cacrl.txt". "</FONT>"); } print addPreLogLine ( "Added CRL to servers\n\tLast Update: " . $data->getParsed()->{LAST_UPDATE} ."\n" . "\tNext Update: " . $data->getParsed()->{NEXT_UPDATE} . "\n"); print closeLogSection(); return 1; } ################################# ## functions for Configuration ## ################################# sub exportConfiguration { my $exim_tmp_dir = $_[0]; my $dir = $exim_tmp_dir."/Configuration"; if ( not createDirectory ($dir) ) { return 0; } # my $openssl = getRequired ( 'sslconfig' ); my $rbac_dir = getRequired ( 'RBAC_DIR' ); # my $openssl_dir = getRequired ( 'OPENSSL_DIR' ); # my $ext_dir = getRequired ( 'EXT_DIR' ); my $config_dir = $rbac_dir; $config_dir =~ s/\/[^\/]*$//; $rbac_dir =~ s/^.*\///g; # $openssl_dir =~ s/^.*\///g; # $ext_dir =~ s/^.*\///g; my $tmpdir = $dir; if( not chdir( "$tmpdir" )) { print addErrorLog( "Failed changing dir to $tmpdir" ); print closeLogSection (); return 0; } # ## bring openssl.cnf to tmp-dir # # print addLogSection("Exporting the OpenSSL-configurationfile of the CA ... "); # $ret = `cp $openssl . 2>&1`; # if( $? != 0 ) { # print addErrorLog("Cannot copy $openssl to $tmpdir!"); # print addLogLine( "cp $openssl ." ); # print closeLogSection (); # return 0; # } # print addLogLine( "Ok." ); # print closeLogSection (); ## bring RBAC/ to tmp-dir print addLogSection("Exporting the RBAC-configuration ... "); $ret = `cd $config_dir; tar -c $rbac_dir | tar -x -C $tmpdir 2>&1`; if( $? != 0 ) { print addErrorLog("Cannot copy $rbac_dir to $tmpdir!"); print addLogLine( "cd $config_dir; tar -c $rbac_dir | tar -x -C $tmpdir" ); print closeLogSection (); return 0; } print addLogLine( "Ok." ); print closeLogSection (); # ## bring OpenSSL/ to tmp-dir # # print addLogSection("Exporting the OpenSSL-configuration of the roles ... "); # $ret = `cd $config_dir; tar -c $openssl_dir | tar -x -C $tmpdir 2>&1`; # if( $? != 0 ) { # print addErrorLog("Cannot copy $openssl_dir to $tmpdir!"); # print addLogLine( "cd $config_dir; tar -c $openssl_dir | tar -x -C $tmpdir" ); # print closeLogSection (); # return 0; # } # print addLogLine( "Ok." ); # print closeLogSection (); # ## bring extfiles/ to tmp-dir # # print addLogSection("Exporting the configuration of the extensions of the roles ... "); # $ret = `cd $config_dir; tar -c $ext_dir | tar -x -C $tmpdir 2>&1`; # if( $? != 0 ) { # print addErrorLog("Cannot copy $ext_dir to $tmpdir!"); # print addLogLine( "cd $config_dir; tar -c $ext_dir | tar -x -C $tmpdir" ); # print closeLogSection (); # return 0; # } # print addLogLine( "Ok." ); # print closeLogSection (); return 1; } sub importConfiguration { my $exim_tmp_dir = $_[0]; my $dir = $exim_tmp_dir."/Configuration"; # my $openssl = getRequired ( 'sslconfig' ); my $rbac_dir = getRequired ( 'RBAC_DIR' ); # my $openssl_dir = getRequired ( 'OPENSSL_DIR' ); # my $ext_dir = getRequired ( 'EXT_DIR' ); my $config_dir = $rbac_dir; $config_dir =~ s/\/[^\/]*$//; $rbac_dir =~ s/^.*\///g; # $openssl_dir =~ s/^.*\///g; # $ext_dir =~ s/^.*\///g; my ( @lastExport ); my $tmpdir = $dir; if (not chdir ( $tmpdir ) ) { print addErrorLog("Cannot change directory to $tmpdir!"); print closeLogSection (); return 0; } # ## importing openssl.cnf # # my $sslconfig = $openssl; # $sslconfig =~ s/.*\///g; # print addLogSection("Importing the OpenSSL-configurationfile of the CA ... "); # $ret = `cp $sslconfig $openssl 2>&1`; # if( $? != 0 ) { # print addErrorLog("Cannot copy $sslconfig to $openssl!"); # print addLogLine( "cp $sslconfig $openssl" ); # print closeLogSection (); # return 0; # } # print addLogLine( "Ok." ); # print closeLogSection (); ## importing RBAC/ print addLogSection("Importing the RBAC-configuration ... "); $ret = `tar -c $rbac_dir | tar -x -C $config_dir 2>&1`; if( $? != 0 ) { print addErrorLog("Cannot copy $rbac_dir to $config_dir!"); print addLogLine( "tar -c $rbac_dir | tar -x -C $config_dir" ); print closeLogSection (); return 0; } print addLogLine( "Ok." ); print closeLogSection (); # ## importing OpenSSL/ # # print addLogSection("Importing the OpenSSL-configuration of the roles ... "); # $ret = `tar -c $openssl_dir | tar -x -C $config_dir 2>&1`; # if( $? != 0 ) { # print addErrorLog("Cannot copy $openssl_dir to $config_dir!"); # print addLogLine( "tar -c $openssl_dir | tar -x -C $config_dir" ); # print closeLogSection (); # return 0; # } # print addLogLine( "Ok." ); # print closeLogSection (); # ## importing extfiles/ # # print addLogSection("Importing the configuration of the extensions of the roles ... "); # $ret = `tar -c $ext_dir | tar -x -C $config_dir 2>&1`; # if( $? != 0 ) { # print addErrorLog("Cannot copy $ext_dir to $config_dir!"); # print addLogLine( "tar -c $ext_dir | tar -x -C $config_dir" ); # print closeLogSection (); # return 0; # } # print addLogLine( "Ok." ); # print closeLogSection (); return 1; } ######################### ## functions for Mails ## ######################### sub exportMails { my $exim_tmp_dir = $_[0]; my $dir = $exim_tmp_dir."/Mail"; if ( not createDirectory ($dir) ) { return 0; } my $mail_dir = getRequired ( 'MAIL_DIR' ); print addLogSection("Exporting the Mails ... "); $ret = `cd $mail_dir; tar -c * | tar -x -C $dir 2>&1`; if( $? != 0 ) { print addErrorLog("Cannot copy $mail_dir to $dir!"); print addLogLine( "cd $mail_dir; tar -c * | tar -x -C $dir" ); print closeLogSection (); return 0; } print addLogLine( "Ok." ); print closeLogSection (); return 1; } sub importMails { my $exim_tmp_dir = $_[0]; my $dir = $exim_tmp_dir."/Mail"; my $mail_dir = getRequired ( 'MAIL_DIR' ); print addLogSection("Importing the Mails ... "); $ret = `cd $dir; tar -c * | tar -x -C $mail_dir 2>&1`; if( $? != 0 ) { print addErrorLog("Cannot copy $dir to $mail_dir!"); print addLogLine( "cd $dir; tar -c * | tar -x -C $mail_dir" ); print closeLogSection (); return 0; } print addLogLine( "Ok." ); print closeLogSection (); ## perhaps I have to send the mails ? ## coded in mail-utils.lib if (getRequired ('SEND_MAIL_DURING_IMPORT') and (getRequired ('SEND_MAIL_DURING_IMPORT') !~ /^NO$/i)) { sendPreparedMails (); } return 1; } ########################################## ## ldap import and export functionality ## ########################################## sub eximObjectToLDAP { my $keys = { @_ }; ## determine type of object if ( $keys->{CERTIFICATE} ) { ## create object in LDAP my $result = addLDAPobject ( CERTIFICATE => $keys->{CERTIFICATE} ); if ( not $result or not $result->{STATUS} ) { return (0); } ## add attribute return addLDAPattribute ( CERTIFICATE => $keys->{CERTIFICATE}, NOPRINT => 1 ); } elsif ( $keys->{AUTHORITY_CERTIFICATE} ) { ## create object in LDAP my $result = addLDAPobject ( CERTIFICATE => $keys->{AUTHORITY_CERTIFICATE} ); if ( not $result and not $result->{STATUS} ) { return (0); } ## add attribute return addLDAPattribute ( AUTHORITY_CERTIFICATE => $keys->{AUTHORITY_CERTIFICATE}, NOPRINT => 1 ); } elsif ( $keys->{CRL} ) { ## create object in LDAP is not necessary because it is the CA ## add attribute return addLDAPattribute ( CRL => $keys->{CRL}, NOPRINT => 1 ); } elsif ( $keys->{AUTHORITY_CRL} ) { ## create object in LDAP is not necessary because it is the CA ## add attribute return addLDAPattribute ( AUTHORITY_CRL => $keys->{AUTHORITY_CRL}, NOPRINT => 1 ); } else { return (0); } } ###################################### ## full export/import functionality ## ###################################### sub exportToCA { my $tmp = createStructure (); exportCSRs ( $tmp ); exportCRRs ( $tmp ); createArchive ( $tmp ); removeDirectory ( $tmp ); } sub importFromCA { my $keys = { @_ }; my $tmp = createStructure (); extractArchive ( $tmp ); if (withLDAPsupport) { importCerts ( TMP => $tmp, LDAP => "1" ); importCAs ( TMP => $tmp, LDAP => "1" ); importCRLs ( TMP => $tmp, LDAP => "1" ); } else { importCerts ( TMP => $tmp, LDAP => "0" ); importCAs ( TMP => $tmp, LDAP => "0" ); importCRLs ( TMP => $tmp, LDAP => "0" ); } importMails ( $tmp ); importConfiguration ( $tmp ); removeDirectory ( $tmp ); } sub exportToRAServer { my $tmp = createStructure (); exportCerts ( $tmp ); exportCAs ( $tmp ); exportCRLs ( $tmp ); exportMails ( $tmp ); exportConfiguration ( $tmp ); createArchive ( $tmp ); removeDirectory ( $tmp ); } sub importFromRAServer { my $tmp = createStructure (); extractArchive ( $tmp ); importCSRs ( $tmp ); importCRRs ( $tmp ); removeDirectory ( $tmp ); } sub withLDAPsupport { my $ldap = getRequired ('LDAP'); print addLogSection ("LDAP support is "); if ( $ldap =~ /^(off|no)$/i ) { print addLogLine ("deactivated"); print closeLogSection (); return 0; } else { print addLogLine ("activated"); print closeLogSection (); return 1; } } 1;