X-Git-Url: https://code.wpia.club/?a=blobdiff_plain;f=src%2Fapps%2Fclient.cpp;h=80422b3bc0e13046ee40dee913a5e7f3648b7aa3;hb=HEAD;hp=92a2369f471465e273cbeebce0119092f0ffff92;hpb=9c88683457862a86656172dfba127717bf41b86a;p=cassiopeia.git diff --git a/src/apps/client.cpp b/src/apps/client.cpp index 92a2369..80422b3 100644 --- a/src/apps/client.cpp +++ b/src/apps/client.cpp @@ -17,6 +17,8 @@ #include "io/slipBio.h" #include "config.h" #include +#include +#include #ifdef NO_DAEMON #define DAEMON false @@ -34,10 +36,7 @@ void checkCRLs( std::shared_ptr sign ) { logger::note( "Signing CRLs" ); for( auto& x : CAs ) { - logger::notef( "Checking: %s ...", x.first ); - if( !x.second->crlNeedsResign() ) { - logger::warnf( "Skipping Resigning CRL: %s ...", x.second->name ); continue; } @@ -52,6 +51,91 @@ void checkCRLs( std::shared_ptr sign ) { } } +bool pathExists( const std::string& name ) { + struct stat buffer; + return stat( name.c_str(), &buffer ) == 0; +} + +void signOCSP( std::shared_ptr sign, std::string profileName, std::string req, std::string crtName, std::string failName ) { + auto cert = std::make_shared(); + cert->ocspCA = profileName; + cert->wishFrom = "now"; + cert->wishTo = "1y"; + cert->md = "sha512"; + + logger::note( "INFO: Message Digest: ", cert->md ); + + cert->csr_content = req; + cert->csr_type = "CSR"; + auto nAVA = std::make_shared(); + nAVA->name = "CN"; + nAVA->value = "OCSP Responder"; + cert->AVAs.push_back( nAVA ); + + std::shared_ptr res = sign->sign( cert ); + + if( !res ) { + writeFile( failName, "failed" ); + logger::error( "OCSP Cert signing failed." ); + return; + } + + writeFile( crtName, res->certificate ); + logger::notef( "Cert log: %s", res->log ); +} + +void checkOCSP( std::shared_ptr sign ) { + std::unique_ptr> dp( opendir( "ca" ), []( DIR * d ) { + closedir( d ); + } ); + + // When opendir fails and returns 0 the unique_ptr will be considered unintialized and will not call closedir. + // Even if closedir would be called, according to POSIX it MAY handle nullptr properly (for glibc it does). + if( !dp ) { + logger::error( "CA directory not found" ); + return; + } + + struct dirent *ep; + + while( ( ep = readdir( dp.get() ) ) ) { + if( ep->d_name[0] == '.' ) { + continue; + } + + std::string profileName( ep->d_name ); + std::string csr = "ca/" + profileName + "/ocsp.csr"; + + if( ! pathExists( csr ) ) { + continue; + } + + std::string crtName = "ca/" + profileName + "/ocsp.crt"; + + if( pathExists( crtName ) ) { + continue; + } + + std::string failName = "ca/" + profileName + "/ocsp.fail"; + + if( pathExists( failName ) ) { + continue; + } + + logger::notef( "Discovered OCSP CSR that needs action: %s", csr ); + std::string req = readFile( csr ); + std::shared_ptr parsed = X509Req::parseCSR( req ); + + if( parsed->verify() <= 0 ) { + logger::errorf( "Invalid CSR for %s", profileName ); + continue; + } + + signOCSP( sign, profileName, req, crtName, failName ); + } +} + + int main( int argc, const char *argv[] ) { bool once = false; bool resetOnly = false; @@ -114,6 +198,8 @@ int main( int argc, const char *argv[] ) { lastCRLCheck = current; } + checkOCSP( sign ); + std::shared_ptr job; try { @@ -127,12 +213,10 @@ int main( int argc, const char *argv[] ) { continue; } - std::shared_ptr logPtr = openLogfile( std::string( "logs/" ) + job->id + std::string( "_" ) + job->warning + std::string( ".log" ) ); - - logger::logger_set log_set( {logger::log_target( *logPtr, logger::level::debug )}, logger::auto_register::on ); + logger::logger_set log_set( {logger::log_target( job->log, logger::level::debug )}, logger::auto_register::on ); logger::note( "TASK ID: ", job->id ); - logger::note( "TRY: ", job->warning ); + logger::note( "TRY: ", job->attempt ); logger::note( "TARGET: ", job->target ); logger::note( "TASK: ", job->task ); @@ -159,8 +243,6 @@ int main( int argc, const char *argv[] ) { logger::notef( "INFO: AVA %s: %s", AVA->name, AVA->value ); } - logger::notef( "FINE: Found the CSR at '%s'", cert->csr ); - cert->csr_content = readFile( keyDir + "/../" + cert->csr ); logger::note( "FINE: CSR content:\n", cert->csr_content ); std::shared_ptr res = sign->sign( cert ); @@ -174,30 +256,14 @@ int main( int argc, const char *argv[] ) { logger::note( "FINE: CERTIFICATE LOG:\n", res->log, "FINE: CERTIFICATE:\n", res->certificate ); - std::string fn = writeBackFile( job->target.c_str(), res->certificate, keyDir ); - - if( fn.empty() ) { - logger::error( "ERROR: Writeback of the certificate failed." ); - jp->failJob( job ); - continue; - } - - res->crt_name = fn; jp->writeBack( job, res ); //! \FIXME: Check return value logger::note( "FINE: signing done." ); if( DAEMON ) { jp->finishJob( job ); } - - continue; } catch( std::exception& c ) { - logger::error( "ERROR: ", c.what() ); - } - - try { jp->failJob( job ); - } catch( std::exception& c ) { logger::error( "ERROR: ", c.what() ); } } else if( job->task == "revoke" ) { @@ -214,7 +280,9 @@ int main( int argc, const char *argv[] ) { jp->writeBackRevocation( job, timeToString( time ) ); jp->finishJob( job ); + continue; } catch( const std::exception& c ) { + jp->failJob( job ); logger::error( "Exception: ", c.what() ); } } else {