]> WPIA git - cassiopeia.git/blob - src/util.cpp
fix: Properly check for success to create the necessary directories
[cassiopeia.git] / src / util.cpp
1 #include "util.h"
2
3 #include <sys/stat.h>
4
5 #include <fstream>
6 #include <iostream>
7 #include <sstream>
8 #include <time.h>
9 #include <stdexcept>
10
11 void writeFile( const std::string& name, const std::string& content ) {
12     std::ofstream file;
13
14     file.open( name );
15     file << content;
16     file.close();
17 }
18
19 std::string readFile( const std::string& name ) {
20     std::ifstream t( name );
21     std::string res = std::string( std::istreambuf_iterator<char>( t ), std::istreambuf_iterator<char>() );
22     t.close();
23
24     return res;
25 }
26
27 std::string writeBackFile( const std::string& serial, const std::string& cert, const std::string& keydir ) {
28     errno = 0;
29
30     std::string filename = keydir;
31     if( 0 != mkdir( filename.c_str(), 0755 ) ) {
32         return "";
33     }
34
35     filename += "/crt";
36     if( 0 != mkdir( filename.c_str(), 0755 ) ) {
37         return "";
38     }
39     std::string first;
40
41     if( serial.length() < 3 ) {
42         first = "0";
43     } else {
44         first = serial.substr( 0, serial.length() - 3 );
45     }
46
47     filename += "/" + first;
48     if( 0 != mkdir( filename.c_str(), 0755 ) ) {
49         return "";
50     }
51     filename += "/" + serial + ".crt";
52     writeFile( filename, cert );
53
54     return filename;
55 }
56
57 bool isDigit( char c ) {
58     return ( c >= '0' ) && ( c <= '9' );
59 }
60
61 std::pair<bool, time_t> parseDate( const std::string& date ) {
62     if( date.size() != 10 || date[4] != '-' || date[7] != '-' ) {
63         return std::pair<bool, time_t>( false, 0 );
64     }
65
66     if( !isDigit( date[0] )
67             || !isDigit( date[1] )
68             || !isDigit( date[2] )
69             || !isDigit( date[3] )
70             || !isDigit( date[5] )
71             || !isDigit( date[6] )
72             || !isDigit( date[8] )
73             || !isDigit( date[9] ) ) {
74         return std::pair<bool, time_t>( false, 0 );
75     }
76
77     std::tm t;
78     t.tm_sec = 0;
79     t.tm_min = 0;
80     t.tm_hour = 0;
81     t.tm_year = std::stoi( date.substr( 0, 4 ) ) - 1900;
82     t.tm_mon = std::stoi( date.substr( 5, 2 ) ) - 1;
83     t.tm_mday = std::stoi( date.substr( 8, 2 ) );
84     setenv( "TZ", "UTC", 1 );
85     tzset();
86     std::time_t res = mktime( &t );
87     char check[11];
88     std::size_t siz = strftime( check, 11, "%Y-%m-%d", &t );
89
90     if( siz != 10 ) {
91         return std::pair<bool, time_t>( false, 0 ); // NO-COVERAGE (by contract of strftime)
92     }
93
94     std::string checkS( check, siz );
95
96     if( checkS != date ) {
97         return std::pair<bool, time_t>( false, 0 );
98     }
99
100     return std::pair<bool, time_t>( true, res );
101 }
102
103 std::pair<bool, time_t> addMonths( std::time_t t, int32_t count ) {
104     std::tm* parsed = gmtime( &t );
105
106     if( !parsed || count <= 0 || count > 24 ) { // FIXED MAX-Validity-Length
107         return std::pair<bool, time_t>( false, 0 );
108     }
109
110     parsed->tm_mon += count;
111     int oldday = parsed->tm_mday;
112     setenv( "TZ", "UTC", 1 );
113     tzset();
114     std::time_t res = mktime( parsed );
115
116     if( parsed->tm_mday != oldday ) {
117         parsed->tm_mday = 0;
118         res = mktime( parsed );
119     }
120
121     return std::pair<bool, time_t>( true, res );
122
123 }
124
125 std::pair<bool, time_t> parseMonthInterval( std::time_t t, const std::string& date ) {
126     if( date[date.size() - 1] != 'm' ) {
127         return  std::pair<bool, time_t>( false, 0 );
128     }
129
130     try {
131         size_t end = 0;
132         int num = std::stoi( date.substr( 0, date.size() - 1 ) , &end );
133
134         if( end != date.size() - 1 ) {
135             return  std::pair<bool, time_t>( false, 0 );
136         }
137
138         return addMonths( t, num );
139     } catch( const std::invalid_argument& a ) {
140         return std::pair<bool, time_t>( false, 0 );
141     } catch( const std::out_of_range& a ) {
142         return std::pair<bool, time_t>( false, 0 );
143     }
144 }
145 std::pair<bool, time_t> parseYearInterval( std::time_t t, const std::string& date ) {
146     if( date[date.size() - 1] != 'y' ) {
147         return  std::pair<bool, time_t>( false, 0 );
148     }
149
150     try {
151         size_t end = 0;
152         int num = std::stoi( date.substr( 0, date.size() - 1 ), &end );
153
154         if( end != date.size() - 1 ) {
155             return  std::pair<bool, time_t>( false, 0 );
156         }
157
158         return addMonths( t, num * 12 );
159     } catch( std::invalid_argument& a ) {
160         return std::pair<bool, time_t>( false, 0 );
161     } catch( std::out_of_range& a ) {
162         return std::pair<bool, time_t>( false, 0 );
163     }
164 }