#include <iostream>
#include <vector>
#include <fstream>
+#include <dirent.h>
+#include <unordered_map>
-#include "sslUtil.h"
+#include "crypto/sslUtil.h"
+
+#include "log/logger.hpp"
std::string keyDir;
-std::vector<Profile> profiles;
+std::unordered_map<std::string, Profile> profiles;
+std::unordered_map<std::string, std::shared_ptr<CAConfig>> CAs;
std::string sqlHost, sqlUser, sqlPass, sqlDB;
std::string serialPath;
+std::string crlPrefix;
+std::string crtPrefix;
-int parseConfig( std::string path ) {
+std::shared_ptr<std::unordered_map<std::string, std::string>> parseConf( std::string path ) {
+ auto map = std::make_shared<std::unordered_map<std::string, std::string>>();
std::ifstream config;
config.open( path );
if( !config.is_open() ) {
- std::cerr << "config missing" << std::endl;
- return 1;
+ logger::notef( "Where is \"%s\"?", path );
+ throw std::runtime_error("Config missing");
}
std::string line1;
int splitter = line1.find( "=" );
if( splitter == -1 ) {
- std::cerr << "Ignoring malformed config line: " << line1 << std::endl;
+ logger::warn( "Ignoring malformed config line: ", line1 );
continue;
}
std::string key = line1.substr( 0, splitter );
std::string value = line1.substr( splitter + 1 );
+ map->emplace( key, value );
+ }
+
+ config.close();
+
+ return map;
+}
+
+int parseProfiles() {
+ CAs = std::unordered_map<std::string, std::shared_ptr<CAConfig>>();
+
+ DIR* dp;
+ struct dirent* ep;
+ dp = opendir( "profiles" );
+
+ if( dp == NULL ) {
+ logger::error( "Profiles directory not found" );
+ return -1;
+ }
- if( key == "key.directory" ) {
- keyDir = value;
+ while( ( ep = readdir( dp ) ) ) {
+ if( ep->d_name[0] == '.' ) {
continue;
- } else if( key == "sql.host" ) {
- sqlHost = value;
- } else if( key == "sql.user" ) {
- sqlUser = value;
- } else if( key == "sql.password" ) {
- sqlPass = value;
- } else if( key == "sql.database" ) {
- sqlDB = value;
- } else if( key == "serialPath" ) {
- serialPath = value;
- } else if( key.compare( 0, 8, "profile." ) == 0 ) {
- int numE = key.find( ".", 9 );
-
- if( numE == 0 ) {
- std::cout << "invalid line: " << line1 << std::endl;
- continue;
- }
+ }
- unsigned int i = atoi( key.substr( 8, numE - 8 ).c_str() );
- std::string rest = key.substr( numE + 1 );
+ std::string profileName( ep->d_name );
- if( i + 1 > profiles.size() ) {
- profiles.resize( i + 1 );
- }
+ int splitter = profileName.find( "-" );
- if( rest == "key" ) {
- profiles[i].key = value;
- } else if( rest == "cert" ) {
- profiles[i].cert = value;
- } else if( rest == "ku" ) {
- profiles[i].ku = value;
- } else if( rest == "eku" ) {
- profiles[i].eku = value;
- } else {
- std::cout << "invalid line: " << line1 << std::endl;
- continue;
- }
+ if( splitter == -1 ) {
+ logger::warn( "Ignoring malformed profile: ", profileName );
+ continue;
}
- }
- for( auto& prof : profiles ) {
- if( prof.cert != "" && prof.key != "" ) {
- std::cout << "Loading profile... " << std::endl;
- prof.ca = loadX509FromFile( prof.cert );
- prof.caKey = loadPkeyFromFile( prof.key );
+ std::string id = profileName.substr( 0, splitter );
+
+ if( profileName.substr( profileName.size() - 4 ) != ".cfg" ) {
+ logger::warn( "Ignoring malformed profile: ", profileName );
+ continue;
}
+
+ auto map = parseConf( std::string( "profiles/" ) + profileName );
+
+ profileName = profileName.substr( 0, profileName.size() - 4 );
+
+ Profile prof;
+ prof.id = std::stoi( id );
+ prof.eku = map->at( "eku" );
+ prof.ku = map->at( "ku" );
+ prof.maxValidity = std::stoi( map->at( "days" ) ) * /* DAYS */24 * 60 * 60;
+
+ std::string cas = map->at( "ca" );
+
+ DIR* dir;
+ struct dirent* ent;
+
+ if( ( dir = opendir( "ca" ) ) != NULL ) {
+ while( ( ent = readdir( dir ) ) != NULL ) {
+ std::string caName = std::string( ent->d_name );
+
+ if( caName.find( cas ) != 0 ) {
+ continue;
+ }
+
+ if( CAs.find( caName ) == CAs.end() ) {
+ auto ca = std::make_shared<CAConfig>( caName );
+ CAs.emplace( caName, ca );
+ }
+
+ prof.ca.push_back( CAs.at( caName ) );
+ logger::note( "Adding CA: ", caName );
+ }
+
+ closedir( dir );
+ } else {
+ throw std::runtime_error("Directory with CAConfigs not found");
+ }
+
+ profiles.emplace( profileName, prof );
+ logger::notef( "Profile: \"%s\" up and running.", profileName );
}
- std::cout << profiles.size() << " profiles loaded." << std::endl;
+ ( void ) closedir( dp );
+
+ logger::notef( "%s profiles loaded.", profiles.size() );
+
+ return 0;
+}
+
+int parseConfig( std::string path ) {
+ auto masterConf = parseConf( path );
+
+ keyDir = masterConf->at( "key.directory" );
+ sqlHost = masterConf->at( "sql.host" );
+ sqlUser = masterConf->at( "sql.user" );
+ sqlPass = masterConf->at( "sql.password" );
+ sqlDB = masterConf->at( "sql.database" );
+ serialPath = masterConf->at( "serialPath" );
+ crlPrefix = masterConf->at( "crlPrefix" );
+ crtPrefix = masterConf->at( "crtPrefix" );
if( keyDir == "" ) {
- std::cerr << "Missing config property key.directory" << std::endl;
+ logger::error( "Missing config property key.directory" );
+ return -1;
+ }
+
+ if( parseProfiles() != 0 ) {
return -1;
}
- config.close();
return 0;
}