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