]> WPIA git - cassiopeia.git/blob - src/config.cpp
a4d32848ecb7de4e3e4609adc5a83e997d927d47
[cassiopeia.git] / src / config.cpp
1 #include <iostream>
2 #include <vector>
3 #include <fstream>
4 #include <dirent.h>
5 #include <unordered_map>
6
7 #include "crypto/sslUtil.h"
8
9 #include "log/logger.hpp"
10
11 std::string keyDir;
12 std::unordered_map<std::string, Profile> profiles;
13 std::unordered_map<std::string, std::shared_ptr<CAConfig>> CAs;
14 std::string sqlHost, sqlUser, sqlPass, sqlDB;
15 std::string serialPath;
16 std::string crlPrefix;
17 std::string crtPrefix;
18
19 std::shared_ptr<std::unordered_map<std::string, std::string>> parseConf( std::string path ) {
20     auto map = std::make_shared<std::unordered_map<std::string, std::string>>();
21     std::ifstream config;
22     config.open( path );
23
24     if( !config.is_open() ) {
25         logger::notef( "Where is \"%s\"?", path );
26         throw std::runtime_error( "Config missing" );
27     }
28
29     std::string line1;
30
31     while( std::getline( config, line1 ) ) {
32         if( line1[0] == '#' || line1.size() == 0 ) {
33             continue;
34         }
35
36         int splitter = line1.find( "=" );
37
38         if( splitter == -1 ) {
39             logger::warn( "Ignoring malformed config line: ", line1 );
40             continue;
41         }
42
43         std::string key = line1.substr( 0, splitter );
44         std::string value = line1.substr( splitter + 1 );
45         map->emplace( key, value );
46     }
47
48     config.close();
49
50     return map;
51 }
52
53 int parseProfiles() {
54     CAs = std::unordered_map<std::string, std::shared_ptr<CAConfig>>();
55
56     DIR* dp;
57     struct dirent* ep;
58     dp = opendir( "profiles" );
59
60     if( dp == NULL ) {
61         logger::error( "Profiles directory not found" );
62         return -1;
63     }
64
65     while( ( ep = readdir( dp ) ) ) {
66         if( ep->d_name[0] == '.' ) {
67             continue;
68         }
69
70         std::string profileName( ep->d_name );
71
72         int splitter = profileName.find( "-" );
73
74         if( splitter == -1 ) {
75             logger::warn( "Ignoring malformed profile: ", profileName );
76             continue;
77         }
78
79         std::string id = profileName.substr( 0, splitter );
80
81         if( profileName.substr( profileName.size() - 4 ) != ".cfg" ) {
82             logger::warn( "Ignoring malformed profile: ", profileName );
83             continue;
84         }
85
86         auto map = parseConf( std::string( "profiles/" ) + profileName );
87
88         profileName = profileName.substr( 0, profileName.size() - 4 );
89
90         Profile prof;
91         prof.id = std::stoi( id );
92         prof.eku = map->at( "eku" );
93         prof.ku = map->at( "ku" );
94         prof.maxValidity = std::stoi( map->at( "days" ) ) * /* DAYS */24 * 60 * 60;
95
96         std::string cas = map->at( "ca" );
97
98         DIR* dir;
99         struct dirent* ent;
100
101         if( ( dir = opendir( "ca" ) ) != NULL ) {
102             while( ( ent = readdir( dir ) ) != NULL ) {
103                 std::string caName = std::string( ent->d_name );
104
105                 if( caName.find( cas ) != 0 ) {
106                     continue;
107                 }
108
109                 if( CAs.find( caName ) == CAs.end() ) {
110                     auto ca = std::make_shared<CAConfig>( caName );
111                     CAs.emplace( caName, ca );
112                 }
113
114                 prof.ca.push_back( CAs.at( caName ) );
115                 logger::note( "Adding CA: ", caName );
116             }
117
118             closedir( dir );
119         } else {
120             throw std::runtime_error( "Directory with CAConfigs not found" );
121         }
122
123         profiles.emplace( profileName, prof );
124         logger::notef( "Profile: \"%s\" up and running.", profileName );
125     }
126
127     ( void ) closedir( dp );
128
129     logger::notef( "%s profiles loaded.", profiles.size() );
130
131     return 0;
132 }
133
134 int parseConfig( std::string path ) {
135     auto masterConf = parseConf( path );
136
137     keyDir = masterConf->at( "key.directory" );
138     sqlHost = masterConf->at( "sql.host" );
139     sqlUser = masterConf->at( "sql.user" );
140     sqlPass = masterConf->at( "sql.password" );
141     sqlDB = masterConf->at( "sql.database" );
142     serialPath = masterConf->at( "serialPath" );
143     crlPrefix = masterConf->at( "crlPrefix" );
144     crtPrefix = masterConf->at( "crtPrefix" );
145
146     if( keyDir == "" ) {
147         logger::error( "Missing config property key.directory" );
148         return -1;
149     }
150
151     if( parseProfiles() != 0 ) {
152         return -1;
153     }
154
155     return 0;
156 }