]>
Commit | Line | Data |
---|---|---|
95d2589c CT |
1 | /* |
2 | * $Id$ | |
3 | */ | |
4 | ||
5 | #include "config.h" | |
fb2178bb | 6 | #include "ssl/gadgets.h" |
95d2589c CT |
7 | #include "ssl/crtd_message.h" |
8 | #if HAVE_CSTDLIB | |
9 | #include <cstdlib> | |
10 | #endif | |
11 | #if HAVE_CSTRING | |
12 | #include <cstring> | |
13 | #endif | |
14 | ||
15 | Ssl::CrtdMessage::CrtdMessage() | |
16 | : body_size(0), state(BEFORE_CODE) | |
17 | {} | |
18 | ||
19 | Ssl::CrtdMessage::ParseResult Ssl::CrtdMessage::parse(const char * buffer, size_t len) | |
20 | { | |
21 | char const *current_pos = buffer; | |
22 | while (current_pos != buffer + len && state != END) { | |
23 | switch (state) { | |
24 | case BEFORE_CODE: { | |
25 | if (xisspace(*current_pos)) { | |
26 | current_pos++; | |
27 | break; | |
28 | } | |
29 | if (xisalpha(*current_pos)) { | |
30 | state = CODE; | |
31 | break; | |
32 | } | |
33 | clear(); | |
34 | return ERROR; | |
35 | } | |
36 | case CODE: { | |
37 | if (xisalnum(*current_pos) || *current_pos == '_') { | |
38 | current_block += *current_pos; | |
39 | current_pos++; | |
40 | break; | |
41 | } | |
42 | if (xisspace(*current_pos)) { | |
43 | code = current_block; | |
44 | current_block.clear(); | |
45 | state = BEFORE_LENGTH; | |
46 | break; | |
47 | } | |
48 | clear(); | |
49 | return ERROR; | |
50 | } | |
51 | case BEFORE_LENGTH: { | |
52 | if (xisspace(*current_pos)) { | |
53 | current_pos++; | |
54 | break; | |
55 | } | |
56 | if (xisdigit(*current_pos)) { | |
57 | state = LENGTH; | |
58 | break; | |
59 | } | |
60 | clear(); | |
61 | return ERROR; | |
62 | } | |
63 | case LENGTH: { | |
64 | if (xisdigit(*current_pos)) { | |
65 | current_block += *current_pos; | |
66 | current_pos++; | |
67 | break; | |
68 | } | |
69 | if (xisspace(*current_pos)) { | |
70 | body_size = atoi(current_block.c_str()); | |
71 | current_block.clear(); | |
72 | state = BEFORE_BODY; | |
73 | break; | |
74 | } | |
75 | clear(); | |
76 | return ERROR; | |
77 | } | |
78 | case BEFORE_BODY: { | |
79 | if (body_size == 0) { | |
80 | state = END; | |
81 | break; | |
82 | } | |
83 | if (xisspace(*current_pos)) { | |
84 | current_pos++; | |
85 | break; | |
86 | } else { | |
87 | state = BODY; | |
88 | break; | |
89 | } | |
90 | } | |
91 | case BODY: { | |
92 | size_t body_len = (static_cast<size_t>(buffer + len - current_pos) >= body_size - current_block.length()) | |
93 | ? body_size - current_block.length() | |
94 | : static_cast<size_t>(buffer + len - current_pos); | |
95 | current_block += std::string(current_pos, body_len); | |
96 | current_pos += body_len; | |
97 | if (current_block.length() == body_size) { | |
98 | body = current_block; | |
99 | state = END; | |
100 | } | |
101 | if (current_block.length() > body_size) { | |
102 | clear(); | |
103 | return ERROR; | |
104 | } | |
105 | break; | |
106 | } | |
107 | case END: { | |
108 | return OK; | |
109 | } | |
110 | } | |
111 | } | |
112 | if (state != END) return INCOMPLETE; | |
113 | return OK; | |
114 | } | |
115 | ||
116 | std::string const & Ssl::CrtdMessage::getBody() const { return body; } | |
117 | ||
118 | std::string const & Ssl::CrtdMessage::getCode() const { return code; } | |
119 | ||
120 | void Ssl::CrtdMessage::setBody(std::string const & aBody) { body = aBody; } | |
121 | ||
122 | void Ssl::CrtdMessage::setCode(std::string const & aCode) { code = aCode; } | |
123 | ||
124 | ||
125 | std::string Ssl::CrtdMessage::compose() const | |
126 | { | |
127 | if (code.empty()) return std::string(); | |
128 | char buffer[10]; | |
129 | snprintf(buffer, sizeof(buffer), "%zd", body.length()); | |
0af9303a | 130 | return code + ' ' + buffer + ' ' + body; |
95d2589c CT |
131 | } |
132 | ||
133 | void Ssl::CrtdMessage::clear() | |
134 | { | |
135 | body_size = 0; | |
136 | state = BEFORE_CODE; | |
137 | body.clear(); | |
138 | code.clear(); | |
139 | current_block.clear(); | |
140 | } | |
141 | ||
142 | void Ssl::CrtdMessage::parseBody(CrtdMessage::BodyParams & map, std::string & other_part) const | |
143 | { | |
144 | other_part.clear(); | |
145 | // Copy string for using it as temp buffer. | |
146 | std::string temp_body(body.c_str(), body.length()); | |
147 | char * buffer = const_cast<char *>(temp_body.c_str()); | |
148 | char * token = strtok(buffer, "\r\n"); | |
149 | while (token != NULL) { | |
150 | std::string current_string(token); | |
151 | size_t equal_pos = current_string.find('='); | |
152 | if (equal_pos == std::string::npos) { | |
153 | size_t offset_body_part = token - temp_body.c_str(); | |
154 | other_part = std::string(body.c_str() + offset_body_part, body.length() - offset_body_part); | |
155 | break; | |
156 | } else { | |
157 | std::string param(current_string.c_str(), current_string.c_str() + equal_pos); | |
158 | std::string value(current_string.c_str() + equal_pos + 1); | |
159 | map.insert(std::make_pair(param, value)); | |
160 | } | |
161 | token = strtok(NULL, "\r\n"); | |
162 | } | |
163 | } | |
164 | ||
165 | void Ssl::CrtdMessage::composeBody(CrtdMessage::BodyParams const & map, std::string const & other_part) | |
166 | { | |
167 | body.clear(); | |
168 | for (BodyParams::const_iterator i = map.begin(); i != map.end(); i++) { | |
169 | if (i != map.begin()) | |
170 | body += "\n"; | |
171 | body += i->first + "=" + i->second; | |
172 | } | |
173 | if (!other_part.empty()) | |
4e903d59 | 174 | body += '\n' + other_part; |
95d2589c CT |
175 | } |
176 | ||
177 | const std::string Ssl::CrtdMessage::code_new_certificate("new_certificate"); | |
178 | const std::string Ssl::CrtdMessage::param_host("host"); | |
fb2178bb CT |
179 | const std::string Ssl::CrtdMessage::param_SetValidAfter(Ssl::CertAdaptAlgorithmStr[algSetValidAfter]); |
180 | const std::string Ssl::CrtdMessage::param_SetValidBefore(Ssl::CertAdaptAlgorithmStr[algSetValidBefore]); | |
181 | const std::string Ssl::CrtdMessage::param_SetCommonName(Ssl::CertAdaptAlgorithmStr[algSetCommonName]); |