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