1 |
< |
/* ============================================================================ |
2 |
< |
* Douglas Thrift's Web Contact License |
3 |
< |
* |
4 |
< |
* Copyright (C) 2002, Douglas Thrift. All Rights Reserved. |
5 |
< |
* |
6 |
< |
* Redistribution and use in source and binary forms, with or without |
7 |
< |
* modification, are permitted provided that the following conditions are met: |
8 |
< |
* |
9 |
< |
* 1. Redistributions of source code must retain the above copyright notice, |
10 |
< |
* this list of conditions and the following disclaimer. |
11 |
< |
* |
12 |
< |
* 2. Redistributions in binary form must reproduce the above copyright notice, |
13 |
< |
* this list of conditions and the following disclaimer in the documentation |
14 |
< |
* and/or other materials provided with the distribution. |
15 |
< |
* |
16 |
< |
* 3. The end-user documentation included with the redistribution, if any, must |
17 |
< |
* include the following acknowledgment: |
18 |
< |
* |
19 |
< |
* "This product includes software developed by Douglas Thrift |
20 |
< |
* (http://computers.douglasthrift.net/webcontact.html)." |
21 |
< |
* |
22 |
< |
* Alternately, this acknowledgment may appear in the software itself, if |
23 |
< |
* and wherever such third-party acknowledgments normally appear. |
24 |
< |
* |
25 |
< |
* 4. The names "Douglas Thrift" and "Douglas Thrift's Web Contact" must not be |
26 |
< |
* used to endorse or promote products derived from this software without |
27 |
< |
* specific prior written permission. For written permission, please visit |
28 |
< |
* http://www.douglasthrift.net/contact.html for contact information. |
29 |
< |
* |
30 |
< |
* 5. Products derived from this software may not be called "Douglas Thrift's |
31 |
< |
* Web Contact", nor may "Douglas Thrift's Web Contact" appear in their |
32 |
< |
* name, without prior written permission. |
33 |
< |
* |
34 |
< |
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
35 |
< |
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
36 |
< |
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
37 |
< |
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
38 |
< |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
39 |
< |
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, |
40 |
< |
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
41 |
< |
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
42 |
< |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
43 |
< |
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
44 |
< |
* ============================================================================ |
45 |
< |
*/ |
46 |
< |
// Windows XP FAQ Poll |
1 |
> |
// IMAP Handler |
2 |
|
// |
3 |
|
// Douglas Thrift |
4 |
|
// |
8 |
|
|
9 |
|
IMAPHandler::IMAPHandler(const string& server, bool tls) |
10 |
|
{ |
11 |
+ |
letter = 'a'; |
12 |
+ |
number = 0; |
13 |
+ |
|
14 |
|
this->tls = tls; |
15 |
|
buffer = new char[BUFSIZ + 1]; |
16 |
|
|
86 |
|
} |
87 |
|
} |
88 |
|
|
89 |
< |
string input = getline(); |
132 |
< |
if (debug) cerr << input << "\n"; |
89 |
> |
getline(); |
90 |
|
} |
91 |
|
|
92 |
|
IMAPHandler::~IMAPHandler() |
113 |
|
|
114 |
|
if (success) |
115 |
|
{ |
116 |
< |
// |
116 |
> |
tls = true; |
117 |
> |
|
118 |
> |
SSL_load_error_strings(); |
119 |
> |
SSL_library_init(); |
120 |
> |
|
121 |
> |
char* seed = new char[BUFSIZ + 1]; |
122 |
> |
time_t moment = time(NULL); |
123 |
> |
sprintf(seed, "froofy%sfoofoo", ctime(&moment)); |
124 |
> |
|
125 |
> |
RAND_add(seed, strlen(seed), 0.007456); |
126 |
> |
|
127 |
> |
delete [] seed; |
128 |
> |
|
129 |
> |
ctx = SSL_CTX_new(TLSv1_client_method()); |
130 |
> |
if (ctx == NULL) |
131 |
> |
{ |
132 |
> |
cerr << program << ": SSL CTX New: " << |
133 |
> |
ERR_reason_error_string(ERR_get_error()) << "\n"; |
134 |
> |
exit(1); |
135 |
> |
} |
136 |
> |
|
137 |
> |
ssl = SSL_new(ctx); |
138 |
> |
|
139 |
> |
if (SSL_set_fd(ssl, sock) == 0) |
140 |
> |
{ |
141 |
> |
cerr << program << ": SSL Set FD: " << |
142 |
> |
ERR_reason_error_string(ERR_get_error()) << "\n"; |
143 |
> |
exit(1); |
144 |
> |
} |
145 |
> |
|
146 |
> |
if (int code = SSL_connect(ssl) <= 0) |
147 |
> |
{ |
148 |
> |
error(program + ": SSL Connect", code); |
149 |
> |
exit(1); |
150 |
> |
} |
151 |
|
} |
152 |
|
|
153 |
|
return answer; |
154 |
|
} |
155 |
|
|
156 |
+ |
string IMAPHandler::command() |
157 |
+ |
{ |
158 |
+ |
char buffer[4]; |
159 |
+ |
sprintf(buffer, "%03u", number++); |
160 |
+ |
|
161 |
+ |
string sequence = letter + string(buffer); |
162 |
+ |
|
163 |
+ |
if (number > 999) |
164 |
+ |
{ |
165 |
+ |
letter++; |
166 |
+ |
number = 0; |
167 |
+ |
} |
168 |
+ |
|
169 |
+ |
if (letter > 'z') |
170 |
+ |
{ |
171 |
+ |
letter = 'a'; |
172 |
+ |
} |
173 |
+ |
|
174 |
+ |
return sequence; |
175 |
+ |
} |
176 |
+ |
|
177 |
|
string IMAPHandler::imap(const string& imap) |
178 |
|
{ |
179 |
|
string result; |
180 |
|
|
181 |
< |
// |
181 |
> |
string sequence = command(); |
182 |
> |
putline(sequence + " " + imap); |
183 |
> |
|
184 |
> |
while (true) |
185 |
> |
{ |
186 |
> |
string input = getline(); |
187 |
> |
|
188 |
> |
if (input.find(sequence + " OK") == 0) |
189 |
> |
{ |
190 |
> |
success = true; |
191 |
> |
break; |
192 |
> |
} |
193 |
> |
else if (input.find(sequence + " NO") == 0 || input.find(sequence + |
194 |
> |
" BAD") == 0) |
195 |
> |
{ |
196 |
> |
success = false; |
197 |
> |
break; |
198 |
> |
} |
199 |
> |
else |
200 |
> |
{ |
201 |
> |
result += input + "\n"; |
202 |
> |
} |
203 |
> |
} |
204 |
|
|
205 |
|
return result; |
206 |
|
} |
207 |
|
|
208 |
< |
void IMAPHandler::putline(const string line) |
208 |
> |
string IMAPHandler::imap(const string& imap, const string& args) |
209 |
|
{ |
210 |
< |
sprintf(buffer, "%s\r\n", line.c_str()); |
210 |
> |
string result; |
211 |
|
|
212 |
< |
if (tls) |
212 |
> |
string sequence = command(); |
213 |
> |
putline(sequence + " " + imap + " " + args); |
214 |
> |
|
215 |
> |
while (true) |
216 |
|
{ |
217 |
< |
if (int code = SSL_write(ssl, buffer, strlen(buffer)) <= 0) |
217 |
> |
string input = getline(); |
218 |
> |
|
219 |
> |
if (input.find(sequence + " OK") == 0) |
220 |
|
{ |
221 |
< |
error(program + ": SSL Write", code); |
222 |
< |
exit(1); |
221 |
> |
success = true; |
222 |
> |
break; |
223 |
> |
} |
224 |
> |
else if (input.find(sequence + " NO") == 0 || input.find(sequence + |
225 |
> |
" BAD") == 0) |
226 |
> |
{ |
227 |
> |
success = false; |
228 |
> |
break; |
229 |
> |
} |
230 |
> |
else |
231 |
> |
{ |
232 |
> |
result += input + "\n"; |
233 |
|
} |
234 |
|
} |
235 |
< |
else |
235 |
> |
|
236 |
> |
return result; |
237 |
> |
} |
238 |
> |
|
239 |
> |
string IMAPHandler::imap(const string& imap, const string& args, const string& |
240 |
> |
message) |
241 |
> |
{ |
242 |
> |
string result; |
243 |
> |
|
244 |
> |
string sequence = command(); |
245 |
> |
putline(sequence + " " + imap + " " + args); |
246 |
> |
putline(message); |
247 |
> |
|
248 |
> |
while (true) |
249 |
|
{ |
250 |
< |
if (send(sock, buffer, strlen(buffer), 0) == SOCKET_ERROR) |
250 |
> |
string input = getline(); |
251 |
> |
|
252 |
> |
if (input.find(sequence + " OK") == 0) |
253 |
|
{ |
254 |
< |
error(program + ": Send"); |
255 |
< |
exit(1); |
254 |
> |
success = true; |
255 |
> |
break; |
256 |
> |
} |
257 |
> |
else if (input.find(sequence + " NO") == 0 || input.find(sequence + |
258 |
> |
" BAD") == 0) |
259 |
> |
{ |
260 |
> |
success = false; |
261 |
> |
break; |
262 |
> |
} |
263 |
> |
else |
264 |
> |
{ |
265 |
> |
result += input + "\n"; |
266 |
|
} |
267 |
|
} |
268 |
+ |
|
269 |
+ |
return result; |
270 |
+ |
} |
271 |
+ |
|
272 |
+ |
void IMAPHandler::putline(const string line) |
273 |
+ |
{ |
274 |
+ |
if (debug) cerr << line << "\n"; |
275 |
+ |
|
276 |
+ |
istringstream lines(line); |
277 |
+ |
|
278 |
+ |
while (lines.good()) |
279 |
+ |
{ |
280 |
+ |
string line; |
281 |
+ |
|
282 |
+ |
std::getline(lines, line); |
283 |
+ |
sprintf(buffer, "%s\r\n", line.c_str()); |
284 |
+ |
|
285 |
+ |
if (tls) |
286 |
+ |
{ |
287 |
+ |
if (int code = SSL_write(ssl, buffer, strlen(buffer)) <= 0) |
288 |
+ |
{ |
289 |
+ |
error(program + ": SSL Write", code); |
290 |
+ |
exit(1); |
291 |
+ |
} |
292 |
+ |
} |
293 |
+ |
else |
294 |
+ |
{ |
295 |
+ |
if (send(sock, buffer, strlen(buffer), 0) == SOCKET_ERROR) |
296 |
+ |
{ |
297 |
+ |
error(program + ": Send"); |
298 |
+ |
exit(1); |
299 |
+ |
} |
300 |
+ |
} |
301 |
+ |
|
302 |
+ |
lines.peek(); |
303 |
+ |
} |
304 |
|
} |
305 |
|
|
306 |
|
string IMAPHandler::getline() |
334 |
|
} |
335 |
|
while (byte != '\n'); |
336 |
|
|
337 |
+ |
if (debug) cerr << line << "\n"; |
338 |
+ |
|
339 |
|
return line; |
340 |
|
} |
341 |
|
|