X-Git-Url: https://code.wpia.club/?a=blobdiff_plain;f=src%2Futil.cpp;h=c16ba1c6c8d541164fc5ff7fd540aadb74d1e7fa;hb=ea0b37d1586c82d6be3f8e3951f8d6a6bfef4cec;hp=f04c4ae036bd9833a971c3d64993f2310296deb8;hpb=9e866a1a2facc8cb1565cd660c6b6d482f18ecb1;p=cassiopeia.git diff --git a/src/util.cpp b/src/util.cpp index f04c4ae..c16ba1c 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -3,6 +3,10 @@ #include #include +#include +#include +#include +#include void writeFile( const std::string& name, const std::string& content ) { std::ofstream file; @@ -10,6 +14,8 @@ void writeFile( const std::string& name, const std::string& content ) { file.open( name ); file << content; file.close(); + + //! \FIXME: Error checking } std::string readFile( const std::string& name ) { @@ -21,10 +27,28 @@ std::string readFile( const std::string& name ) { } std::string writeBackFile( const std::string& serial, const std::string& cert, const std::string& keydir ) { + errno = 0; + std::string filename = keydir; - mkdir( filename.c_str(), 0755 ); + + if( 0 != mkdir( filename.c_str(), 0755 ) ) { + if( EEXIST != errno ) { + return ""; + } + + //! \FIXME: Check this is a directory + } + filename += "/crt"; - mkdir( filename.c_str(), 0755 ); + + if( 0 != mkdir( filename.c_str(), 0755 ) ) { + if( EEXIST != errno ) { + return ""; + } + + //! \FIXME: Check this is a directory + } + std::string first; if( serial.length() < 3 ) { @@ -34,9 +58,144 @@ std::string writeBackFile( const std::string& serial, const std::string& cert, c } filename += "/" + first; - mkdir( filename.c_str(), 0755 ); + + if( 0 != mkdir( filename.c_str(), 0755 ) ) { + if( EEXIST != errno ) { + return ""; + } + + //! \FIXME: Check this is a directory + } + filename += "/" + serial + ".crt"; writeFile( filename, cert ); return filename; } + +bool isDigit( char c ) { + return ( c >= '0' ) && ( c <= '9' ); +} + +std::pair parseDate( const std::string& date ) { + if( date.size() != 10 || date[4] != '-' || date[7] != '-' ) { + return std::pair( false, 0 ); + } + + if( !isDigit( date[0] ) + || !isDigit( date[1] ) + || !isDigit( date[2] ) + || !isDigit( date[3] ) + || !isDigit( date[5] ) + || !isDigit( date[6] ) + || !isDigit( date[8] ) + || !isDigit( date[9] ) ) { + return std::pair( false, 0 ); + } + + std::tm t; + t.tm_sec = 0; + t.tm_min = 0; + t.tm_hour = 0; + t.tm_year = std::stoi( date.substr( 0, 4 ) ) - 1900; + t.tm_mon = std::stoi( date.substr( 5, 2 ) ) - 1; + t.tm_mday = std::stoi( date.substr( 8, 2 ) ); + setenv( "TZ", "UTC", 1 ); + tzset(); + std::time_t res = mktime( &t ); + char check[11]; + std::size_t siz = strftime( check, 11, "%Y-%m-%d", &t ); + + if( siz != 10 ) { + return std::pair( false, 0 ); // NO-COVERAGE (by contract of strftime) + } + + std::string checkS( check, siz ); + + if( checkS != date ) { + return std::pair( false, 0 ); + } + + return std::pair( true, res ); +} + +std::pair addMonths( std::time_t t, int32_t count ) { + std::tm* parsed = gmtime( &t ); + + if( !parsed || count <= 0 || count > 24 ) { // FIXED MAX-Validity-Length + return std::pair( false, 0 ); + } + + parsed->tm_mon += count; + int oldday = parsed->tm_mday; + setenv( "TZ", "UTC", 1 ); + tzset(); + std::time_t res = mktime( parsed ); + + if( parsed->tm_mday != oldday ) { + parsed->tm_mday = 0; + res = mktime( parsed ); + } + + return std::pair( true, res ); + +} + +std::pair parseMonthInterval( std::time_t t, const std::string& date ) { + if( date[date.size() - 1] != 'm' ) { + return std::pair( false, 0 ); + } + + try { + size_t end = 0; + int num = std::stoi( date.substr( 0, date.size() - 1 ) , &end ); + + if( end != date.size() - 1 ) { + return std::pair( false, 0 ); + } + + return addMonths( t, num ); + } catch( const std::invalid_argument& a ) { + return std::pair( false, 0 ); + } catch( const std::out_of_range& a ) { + return std::pair( false, 0 ); + } +} +std::pair parseYearInterval( std::time_t t, const std::string& date ) { + if( date[date.size() - 1] != 'y' ) { + return std::pair( false, 0 ); + } + + try { + size_t end = 0; + int num = std::stoi( date.substr( 0, date.size() - 1 ), &end ); + + if( end != date.size() - 1 ) { + return std::pair( false, 0 ); + } + + return addMonths( t, num * 12 ); + } catch( std::invalid_argument& a ) { + return std::pair( false, 0 ); + } catch( std::out_of_range& a ) { + return std::pair( false, 0 ); + } +} + +std::shared_ptr openLogfile( const std::string name) { + struct stat buffer; + std::string tname = name; + int ctr = 2; + while(stat (tname.c_str(), &buffer) == 0) { + tname = name + "_" + std::to_string(ctr++); + } + auto res = std::shared_ptr(new std::ofstream( tname ), + [](std::ofstream *p){ + p->close(); + delete p; + }); + if(! res->good() ){ + throw std::string("Failed to open file for logging: ") + name; + } + return res; +}