author | zautrix <zautrix> | 2005-03-18 20:17:03 (UTC) |
---|---|---|
committer | zautrix <zautrix> | 2005-03-18 20:17:03 (UTC) |
commit | 9e549686b23b6dffdcbd09c9b10dc2cb795fbcdf (patch) (unidiff) | |
tree | 2528e6cc740225ca0f47d5ac8ff70f7d3bb10621 /libetpan/src/low-level/smtp | |
parent | 9319998f20f03dcc217fbb39656755dc65226276 (diff) | |
download | kdepimpi-9e549686b23b6dffdcbd09c9b10dc2cb795fbcdf.zip kdepimpi-9e549686b23b6dffdcbd09c9b10dc2cb795fbcdf.tar.gz kdepimpi-9e549686b23b6dffdcbd09c9b10dc2cb795fbcdf.tar.bz2 |
Initial revision
-rw-r--r-- | libetpan/src/low-level/smtp/TODO | 1 | ||||
-rw-r--r-- | libetpan/src/low-level/smtp/mailsmtp.c | 984 | ||||
-rw-r--r-- | libetpan/src/low-level/smtp/mailsmtp.h | 94 | ||||
-rw-r--r-- | libetpan/src/low-level/smtp/mailsmtp_helper.c | 228 | ||||
-rw-r--r-- | libetpan/src/low-level/smtp/mailsmtp_helper.h | 74 | ||||
-rw-r--r-- | libetpan/src/low-level/smtp/mailsmtp_socket.c | 99 | ||||
-rw-r--r-- | libetpan/src/low-level/smtp/mailsmtp_socket.h | 56 | ||||
-rw-r--r-- | libetpan/src/low-level/smtp/mailsmtp_ssl.c | 74 | ||||
-rw-r--r-- | libetpan/src/low-level/smtp/mailsmtp_ssl.h | 55 | ||||
-rw-r--r-- | libetpan/src/low-level/smtp/mailsmtp_types.h | 126 |
10 files changed, 1791 insertions, 0 deletions
diff --git a/libetpan/src/low-level/smtp/TODO b/libetpan/src/low-level/smtp/TODO new file mode 100644 index 0000000..96f44c6 --- a/dev/null +++ b/libetpan/src/low-level/smtp/TODO | |||
@@ -0,0 +1 @@ | |||
- STARTTLS | |||
diff --git a/libetpan/src/low-level/smtp/mailsmtp.c b/libetpan/src/low-level/smtp/mailsmtp.c new file mode 100644 index 0000000..85659e9 --- a/dev/null +++ b/libetpan/src/low-level/smtp/mailsmtp.c | |||
@@ -0,0 +1,984 @@ | |||
1 | /* | ||
2 | * libEtPan! -- a mail stuff library | ||
3 | * | ||
4 | * Copyright (C) 2001, 2005 - DINH Viet Hoa, | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * SMTP AUTH support by Juergen Graf | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * 2. Redistributions in binary form must reproduce the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer in the | ||
16 | * documentation and/or other materials provided with the distribution. | ||
17 | * 3. Neither the name of the libEtPan! project nor the names of its | ||
18 | * contributors may be used to endorse or promote products derived | ||
19 | * from this software without specific prior written permission. | ||
20 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
31 | * SUCH DAMAGE. | ||
32 | */ | ||
33 | |||
34 | /* | ||
35 | * $Id$ | ||
36 | */ | ||
37 | |||
38 | #include "mailsmtp.h" | ||
39 | #include "connect.h" | ||
40 | #include "md5.h" | ||
41 | #include "base64.h" | ||
42 | #include "mail.h" | ||
43 | |||
44 | #include <netinet/in.h> | ||
45 | #include <string.h> | ||
46 | #include <stdlib.h> | ||
47 | #include <unistd.h> | ||
48 | #include <stdio.h> | ||
49 | |||
50 | |||
51 | /* | ||
52 | RFC 2821 : SMTP | ||
53 | RFC 1891 : SMTP Service Extension for Delivery Status Notifications | ||
54 | |||
55 | RFC 1428 : Transition of Internet Mail from Just-Send-8 to 8bit-SMTP/MIME | ||
56 | RFC 1652 : SMTP Service Extension for 8bit-MIMEtransport | ||
57 | RFC 1845 : SMTP Service Extension for Checkpoint/Restart | ||
58 | RFC 1846 : SMTP 521 Reply Code | ||
59 | RFC 1870 : SMTP Service Extension for Message Size Declaration | ||
60 | RFC 1985 : SMTP Service Extension for Remote Message Queue Starting | ||
61 | RFC 2034 : SMTP Service Extension for Returning Enhanced Error Codes | ||
62 | RFC 2442 : The Batch SMTP Media Type | ||
63 | RFC 2487 : SMTP Service Extension for Secure SMTP over TLS | ||
64 | RFC 2505 : Anti-Spam Recommendations for SMTP MTAs | ||
65 | RFC 2554 : SMTP Service Extension for Authentication | ||
66 | RFC 2645 : ON-DEMAND MAIL RELAY (ODMR) SMTP with Dynamic IP Addresses | ||
67 | RFC 2852 : Deliver By SMTP Service Extension | ||
68 | RFC 2920 : SMTP Service Extension for Command Pipelining | ||
69 | RFC 3030 : SMTP Service Extensions for Transmission of Large and Binary MIME | ||
70 | Messages | ||
71 | */ | ||
72 | |||
73 | #define SMTP_STATUS_CONTINUE 0x1000 | ||
74 | |||
75 | mailsmtp * mailsmtp_new(size_t progr_rate, | ||
76 | progress_function * progr_fun) | ||
77 | { | ||
78 | mailsmtp * session; | ||
79 | |||
80 | session = malloc(sizeof(* session)); | ||
81 | if (session == NULL) | ||
82 | goto err; | ||
83 | |||
84 | session->stream = NULL; | ||
85 | |||
86 | session->progr_rate = progr_rate; | ||
87 | session->progr_fun = progr_fun; | ||
88 | |||
89 | session->response = NULL; | ||
90 | |||
91 | session->line_buffer = mmap_string_new(""); | ||
92 | if (session->line_buffer == NULL) | ||
93 | goto free_session; | ||
94 | |||
95 | session->response_buffer = mmap_string_new(""); | ||
96 | if (session->response_buffer == NULL) | ||
97 | goto free_line_buffer; | ||
98 | |||
99 | session->esmtp = 0; | ||
100 | session->auth = MAILSMTP_AUTH_NOT_CHECKED; | ||
101 | |||
102 | return session; | ||
103 | |||
104 | free_line_buffer: | ||
105 | mmap_string_free(session->line_buffer); | ||
106 | free_session: | ||
107 | free(session); | ||
108 | err: | ||
109 | return NULL; | ||
110 | } | ||
111 | |||
112 | void mailsmtp_free(mailsmtp * session) | ||
113 | { | ||
114 | if (session->stream) | ||
115 | mailsmtp_quit(session); | ||
116 | |||
117 | mmap_string_free(session->line_buffer); | ||
118 | mmap_string_free(session->response_buffer); | ||
119 | free(session); | ||
120 | } | ||
121 | |||
122 | static int send_command(mailsmtp * f, char * command); | ||
123 | |||
124 | static int read_response(mailsmtp * session); | ||
125 | |||
126 | /* smtp operations */ | ||
127 | |||
128 | int mailsmtp_connect(mailsmtp * session, mailstream * s) | ||
129 | { | ||
130 | int code; | ||
131 | |||
132 | session->stream = s; | ||
133 | |||
134 | code = read_response(session); | ||
135 | |||
136 | switch (code) { | ||
137 | case 220: | ||
138 | return MAILSMTP_NO_ERROR; | ||
139 | |||
140 | case 554: | ||
141 | session->stream = NULL; | ||
142 | mailstream_close(s); | ||
143 | return MAILSMTP_ERROR_SERVICE_NOT_AVAILABLE; | ||
144 | |||
145 | default: | ||
146 | session->stream = NULL; | ||
147 | mailstream_close(s); | ||
148 | return MAILSMTP_ERROR_UNEXPECTED_CODE; | ||
149 | } | ||
150 | } | ||
151 | |||
152 | |||
153 | #define SMTP_STRING_SIZE 513 | ||
154 | |||
155 | int mailsmtp_quit(mailsmtp * session) | ||
156 | { | ||
157 | char command[SMTP_STRING_SIZE]; | ||
158 | int r; | ||
159 | |||
160 | snprintf(command, SMTP_STRING_SIZE, "QUIT\r\n"); | ||
161 | r = send_command(session, command); | ||
162 | if (r == -1) | ||
163 | return MAILSMTP_ERROR_STREAM; | ||
164 | r = read_response(session); | ||
165 | if (r == 0) | ||
166 | return MAILSMTP_ERROR_STREAM; | ||
167 | mailstream_close(session->stream); | ||
168 | session->stream = NULL; | ||
169 | |||
170 | return MAILSMTP_NO_ERROR; | ||
171 | } | ||
172 | |||
173 | |||
174 | |||
175 | #define HOSTNAME_SIZE 256 | ||
176 | |||
177 | int mailsmtp_helo(mailsmtp * session) | ||
178 | { | ||
179 | int r; | ||
180 | char hostname[HOSTNAME_SIZE]; | ||
181 | char command[SMTP_STRING_SIZE]; | ||
182 | |||
183 | r = gethostname(hostname, HOSTNAME_SIZE); | ||
184 | if (r < 0) | ||
185 | return MAILSMTP_ERROR_HOSTNAME; | ||
186 | |||
187 | snprintf(command, SMTP_STRING_SIZE, "HELO %s\r\n", hostname); | ||
188 | r = send_command(session, command); | ||
189 | if (r == -1) | ||
190 | return MAILSMTP_ERROR_STREAM; | ||
191 | r = read_response(session); | ||
192 | |||
193 | switch (r) { | ||
194 | case 250: | ||
195 | session->esmtp = 0; | ||
196 | session->auth = MAILSMTP_AUTH_NOT_CHECKED; | ||
197 | return MAILSMTP_NO_ERROR; | ||
198 | |||
199 | case 504: | ||
200 | return MAILSMTP_ERROR_NOT_IMPLEMENTED; | ||
201 | |||
202 | case 550: | ||
203 | return MAILSMTP_ERROR_ACTION_NOT_TAKEN; | ||
204 | |||
205 | case 0: | ||
206 | return MAILSMTP_ERROR_STREAM; | ||
207 | |||
208 | default: | ||
209 | return MAILSMTP_ERROR_UNEXPECTED_CODE; | ||
210 | } | ||
211 | } | ||
212 | |||
213 | int mailsmtp_mail(mailsmtp * session, const char * from) | ||
214 | { | ||
215 | int r; | ||
216 | char command[SMTP_STRING_SIZE]; | ||
217 | |||
218 | snprintf(command, SMTP_STRING_SIZE, "MAIL FROM:<%s>\r\n", from); | ||
219 | r = send_command(session, command); | ||
220 | if (r == -1) | ||
221 | return MAILSMTP_ERROR_STREAM; | ||
222 | r = read_response(session); | ||
223 | |||
224 | switch (r) { | ||
225 | case 250: | ||
226 | return MAILSMTP_NO_ERROR; | ||
227 | |||
228 | case 552: | ||
229 | return MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION; | ||
230 | |||
231 | case 451: | ||
232 | return MAILSMTP_ERROR_IN_PROCESSING; | ||
233 | |||
234 | case 452: | ||
235 | return MAILSMTP_ERROR_INSUFFICIENT_SYSTEM_STORAGE; | ||
236 | |||
237 | case 550: | ||
238 | return MAILSMTP_ERROR_MAILBOX_UNAVAILABLE; | ||
239 | |||
240 | case 553: | ||
241 | return MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED; | ||
242 | |||
243 | case 503: | ||
244 | return MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND; | ||
245 | |||
246 | case 0: | ||
247 | return MAILSMTP_ERROR_STREAM; | ||
248 | |||
249 | default: | ||
250 | return MAILSMTP_ERROR_UNEXPECTED_CODE; | ||
251 | } | ||
252 | } | ||
253 | |||
254 | int mailsmtp_rcpt(mailsmtp * session, const char * to) | ||
255 | { | ||
256 | return mailesmtp_rcpt(session, to, 0, NULL); | ||
257 | } | ||
258 | |||
259 | int mailsmtp_data(mailsmtp * session) | ||
260 | { | ||
261 | int r; | ||
262 | char command[SMTP_STRING_SIZE]; | ||
263 | |||
264 | snprintf(command, SMTP_STRING_SIZE, "DATA\r\n"); | ||
265 | r = send_command(session, command); | ||
266 | if (r == -1) | ||
267 | return MAILSMTP_ERROR_STREAM; | ||
268 | r = read_response(session); | ||
269 | |||
270 | switch (r) { | ||
271 | case 354: | ||
272 | return MAILSMTP_NO_ERROR; | ||
273 | |||
274 | case 451: | ||
275 | return MAILSMTP_ERROR_IN_PROCESSING; | ||
276 | |||
277 | case 554: | ||
278 | return MAILSMTP_ERROR_TRANSACTION_FAILED; | ||
279 | |||
280 | case 503: | ||
281 | return MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND; | ||
282 | |||
283 | default: | ||
284 | return MAILSMTP_ERROR_UNEXPECTED_CODE; | ||
285 | } | ||
286 | } | ||
287 | |||
288 | static int send_data(mailsmtp * session, const char * message, size_t size); | ||
289 | |||
290 | int mailsmtp_data_message(mailsmtp * session, | ||
291 | const char * message, | ||
292 | size_t size) | ||
293 | { | ||
294 | int r; | ||
295 | |||
296 | r = send_data(session, message, size); | ||
297 | if (r == -1) | ||
298 | return MAILSMTP_ERROR_STREAM; | ||
299 | |||
300 | r = read_response(session); | ||
301 | |||
302 | switch(r) { | ||
303 | case 250: | ||
304 | return MAILSMTP_NO_ERROR; | ||
305 | |||
306 | case 552: | ||
307 | return MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION; | ||
308 | |||
309 | case 554: | ||
310 | return MAILSMTP_ERROR_TRANSACTION_FAILED; | ||
311 | |||
312 | case 451: | ||
313 | return MAILSMTP_ERROR_IN_PROCESSING; | ||
314 | |||
315 | case 452: | ||
316 | return MAILSMTP_ERROR_INSUFFICIENT_SYSTEM_STORAGE; | ||
317 | |||
318 | case 0: | ||
319 | return MAILSMTP_ERROR_STREAM; | ||
320 | |||
321 | default: | ||
322 | return MAILSMTP_ERROR_UNEXPECTED_CODE; | ||
323 | } | ||
324 | } | ||
325 | |||
326 | /* esmtp operations */ | ||
327 | |||
328 | |||
329 | /** | ||
330 | * called during mailesmtp_ehlo | ||
331 | * checks EHLO answer for server extensions and sets flags | ||
332 | * in session->esmtp | ||
333 | * checks AUTH methods in session->response and sets flags | ||
334 | * in session->auth | ||
335 | */ | ||
336 | #define isdelim(x) ((x) == ' ' || (x) == '\r' || (x) == '\n' || (x) == '\0') | ||
337 | |||
338 | int mailesmtp_parse_ehlo(mailsmtp * session) | ||
339 | { | ||
340 | char * response; | ||
341 | |||
342 | /* restore data */ | ||
343 | session->esmtp = MAILSMTP_ESMTP; | ||
344 | session->auth = MAILSMTP_AUTH_CHECKED; | ||
345 | |||
346 | response = session->response; | ||
347 | |||
348 | /* ESMTP supported extensions : | ||
349 | DSN | ||
350 | EXPN | ||
351 | 8BITMIME | ||
352 | SIZE [<n>] | ||
353 | ETRN | ||
354 | STARTTLS | ||
355 | AUTH <mechanisms...> | ||
356 | */ | ||
357 | while (response != NULL) { | ||
358 | if (!strncasecmp(response, "EXPN", 4) && isdelim(response[4])) | ||
359 | session->esmtp |= MAILSMTP_ESMTP_EXPN; | ||
360 | else if (!strncasecmp(response, "ETRN", 4) && isdelim(response[4])) | ||
361 | session->esmtp |= MAILSMTP_ESMTP_ETRN; | ||
362 | else if (!strncasecmp(response, "DSN", 3) && isdelim(response[3])) | ||
363 | session->esmtp |= MAILSMTP_ESMTP_DSN; | ||
364 | else if (!strncasecmp(response, "8BITMIME", 8) && isdelim(response[8])) | ||
365 | session->esmtp |= MAILSMTP_ESMTP_8BITMIME; | ||
366 | else if (!strncasecmp(response, "STARTTLS", 8) && isdelim(response[8])) | ||
367 | session->esmtp |= MAILSMTP_ESMTP_STARTTLS; | ||
368 | else if (!strncasecmp(response, "SIZE", 4) && isdelim(response[4])) { | ||
369 | session->esmtp |= MAILSMTP_ESMTP_SIZE; | ||
370 | /* TODO: grab optionnal max size */ | ||
371 | } else if (!strncasecmp(response, "AUTH ", 5)) { | ||
372 | response += 5; /* remove "AUTH " */ | ||
373 | while (response[0] != '\n' && response[0] != '\0') { | ||
374 | while (response[0] == ' ') response++; | ||
375 | if (strncasecmp(response, "LOGIN", 5) == 0) { | ||
376 | session->auth |= MAILSMTP_AUTH_LOGIN; | ||
377 | response += 5; | ||
378 | } else if (strncasecmp(response, "CRAM-MD5", 8) == 0) { | ||
379 | session->auth |= MAILSMTP_AUTH_CRAM_MD5; | ||
380 | response += 8; | ||
381 | } else if (strncasecmp(response, "PLAIN", 5) == 0) { | ||
382 | session->auth |= MAILSMTP_AUTH_PLAIN; | ||
383 | response += 5; | ||
384 | } else { | ||
385 | /* unknown auth method - jump to next word or eol */ | ||
386 | while (!isdelim(response[0]) || response[0] == '\r') | ||
387 | response++; | ||
388 | } | ||
389 | } | ||
390 | } | ||
391 | response = strpbrk(response, "\n"); | ||
392 | if (response != NULL) | ||
393 | response++; | ||
394 | } | ||
395 | |||
396 | return MAILSMTP_NO_ERROR; | ||
397 | } | ||
398 | |||
399 | |||
400 | int mailesmtp_ehlo(mailsmtp * session) | ||
401 | { | ||
402 | int r; | ||
403 | char hostname[HOSTNAME_SIZE]; | ||
404 | char command[SMTP_STRING_SIZE]; | ||
405 | |||
406 | r = gethostname(hostname, HOSTNAME_SIZE); | ||
407 | if (r != 0) | ||
408 | return MAILSMTP_ERROR_HOSTNAME; | ||
409 | |||
410 | snprintf(command, SMTP_STRING_SIZE, "EHLO %s\r\n", hostname); | ||
411 | r = send_command(session, command); | ||
412 | if (r == -1) | ||
413 | return MAILSMTP_ERROR_STREAM; | ||
414 | r = read_response(session); | ||
415 | |||
416 | switch (r) { | ||
417 | case 250: | ||
418 | return mailesmtp_parse_ehlo(session); | ||
419 | |||
420 | case 504: | ||
421 | return MAILSMTP_ERROR_NOT_IMPLEMENTED; | ||
422 | |||
423 | case 550: | ||
424 | return MAILSMTP_ERROR_ACTION_NOT_TAKEN; | ||
425 | |||
426 | case 0: | ||
427 | return MAILSMTP_ERROR_STREAM; | ||
428 | |||
429 | default: | ||
430 | return MAILSMTP_ERROR_UNEXPECTED_CODE; | ||
431 | } | ||
432 | } | ||
433 | |||
434 | /* | ||
435 | if return_full is TRUE, the entire message is returned on error | ||
436 | envid can be NULL | ||
437 | */ | ||
438 | |||
439 | |||
440 | int mailesmtp_mail(mailsmtp * session, | ||
441 | const char * from, | ||
442 | int return_full, | ||
443 | const char * envid) | ||
444 | { | ||
445 | int r; | ||
446 | char command[SMTP_STRING_SIZE]; | ||
447 | char *body = ""; | ||
448 | |||
449 | #if notyet | ||
450 | /* TODO: figure out a way for the user to explicity enable this or not */ | ||
451 | if (session->esmtp & MAILSMTP_ESMTP_8BITMIME) | ||
452 | body = " BODY=8BITMIME"; | ||
453 | #endif | ||
454 | |||
455 | if (session->esmtp & MAILSMTP_ESMTP_DSN) { | ||
456 | if (envid) | ||
457 | snprintf(command, SMTP_STRING_SIZE, "MAIL FROM:<%s> RET=%s ENVID=%s%s\r\n", | ||
458 | from, return_full ? "FULL" : "HDRS", envid, body); | ||
459 | else | ||
460 | snprintf(command, SMTP_STRING_SIZE, "MAIL FROM:<%s> RET=%s%s\r\n", | ||
461 | from, return_full ? "FULL" : "HDRS", body); | ||
462 | } else | ||
463 | snprintf(command, SMTP_STRING_SIZE, "MAIL FROM:<%s>%s\r\n", | ||
464 | from, body); | ||
465 | |||
466 | r = send_command(session, command); | ||
467 | if (r == -1) | ||
468 | return MAILSMTP_ERROR_STREAM; | ||
469 | r = read_response(session); | ||
470 | |||
471 | switch (r) { | ||
472 | case 250: | ||
473 | return MAILSMTP_NO_ERROR; | ||
474 | |||
475 | case 552: | ||
476 | return MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION; | ||
477 | |||
478 | case 451: | ||
479 | return MAILSMTP_ERROR_IN_PROCESSING; | ||
480 | |||
481 | case 452: | ||
482 | return MAILSMTP_ERROR_INSUFFICIENT_SYSTEM_STORAGE; | ||
483 | |||
484 | case 550: | ||
485 | return MAILSMTP_ERROR_MAILBOX_UNAVAILABLE; | ||
486 | |||
487 | case 553: | ||
488 | return MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED; | ||
489 | |||
490 | case 503: | ||
491 | return MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND; | ||
492 | |||
493 | case 0: | ||
494 | return MAILSMTP_ERROR_STREAM; | ||
495 | |||
496 | default: | ||
497 | return MAILSMTP_ERROR_UNEXPECTED_CODE; | ||
498 | } | ||
499 | } | ||
500 | |||
501 | int mailesmtp_rcpt(mailsmtp * session, | ||
502 | const char * to, | ||
503 | int notify, | ||
504 | const char * orcpt) | ||
505 | { | ||
506 | int r; | ||
507 | char command[SMTP_STRING_SIZE]; | ||
508 | char notify_str[30] = ""; | ||
509 | char notify_info_str[30] = ""; | ||
510 | |||
511 | if (notify != 0 && session->esmtp & MAILSMTP_ESMTP_DSN) { | ||
512 | if (notify & MAILSMTP_DSN_NOTIFY_SUCCESS) | ||
513 | strcat(notify_info_str, ",SUCCESS"); | ||
514 | if (notify & MAILSMTP_DSN_NOTIFY_FAILURE) | ||
515 | strcat(notify_info_str, ",FAILURE"); | ||
516 | if (notify & MAILSMTP_DSN_NOTIFY_DELAY) | ||
517 | strcat(notify_info_str, ",DELAY"); | ||
518 | |||
519 | if (notify & MAILSMTP_DSN_NOTIFY_NEVER) | ||
520 | strcpy(notify_info_str, ",NEVER"); | ||
521 | |||
522 | notify_info_str[0] = '='; | ||
523 | |||
524 | strcpy(notify_str, " NOTIFY"); | ||
525 | strcat(notify_str, notify_info_str); | ||
526 | } | ||
527 | |||
528 | if (orcpt && session->esmtp & MAILSMTP_ESMTP_DSN) | ||
529 | snprintf(command, SMTP_STRING_SIZE, "RCPT TO:<%s>%s ORCPT=%s\r\n", | ||
530 | to, notify_str, orcpt); | ||
531 | else | ||
532 | snprintf(command, SMTP_STRING_SIZE, "RCPT TO:<%s>%s\r\n", to, notify_str); | ||
533 | |||
534 | r = send_command(session, command); | ||
535 | if (r == -1) | ||
536 | return MAILSMTP_ERROR_STREAM; | ||
537 | r = read_response(session); | ||
538 | |||
539 | switch (r) { | ||
540 | case 250: | ||
541 | return MAILSMTP_NO_ERROR; | ||
542 | |||
543 | case 251: /* not local user, will be forwarded */ | ||
544 | return MAILSMTP_NO_ERROR; | ||
545 | |||
546 | case 550: | ||
547 | case 450: | ||
548 | return MAILSMTP_ERROR_MAILBOX_UNAVAILABLE; | ||
549 | |||
550 | case 551: | ||
551 | return MAILSMTP_ERROR_USER_NOT_LOCAL; | ||
552 | |||
553 | case 552: | ||
554 | return MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION; | ||
555 | |||
556 | case 553: | ||
557 | return MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED; | ||
558 | |||
559 | case 451: | ||
560 | return MAILSMTP_ERROR_IN_PROCESSING; | ||
561 | |||
562 | case 452: | ||
563 | return MAILSMTP_ERROR_INSUFFICIENT_SYSTEM_STORAGE; | ||
564 | |||
565 | case 503: | ||
566 | return MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND; | ||
567 | |||
568 | case 0: | ||
569 | return MAILSMTP_ERROR_STREAM; | ||
570 | |||
571 | default: | ||
572 | return MAILSMTP_ERROR_UNEXPECTED_CODE; | ||
573 | } | ||
574 | } | ||
575 | |||
576 | int auth_map_errors(int err) | ||
577 | { | ||
578 | switch (err) { | ||
579 | case 235: | ||
580 | return MAILSMTP_NO_ERROR; /* AUTH successfull */ | ||
581 | case 334: | ||
582 | return MAILSMTP_NO_ERROR; /* AUTH in progress */ | ||
583 | case 432: | ||
584 | return MAILSMTP_ERROR_AUTH_TRANSITION_NEEDED; | ||
585 | case 454: | ||
586 | return MAILSMTP_ERROR_AUTH_TEMPORARY_FAILTURE; | ||
587 | case 504: | ||
588 | return MAILSMTP_ERROR_AUTH_NOT_SUPPORTED; | ||
589 | case 530: | ||
590 | return MAILSMTP_ERROR_AUTH_REQUIRED; | ||
591 | case 534: | ||
592 | return MAILSMTP_ERROR_AUTH_TOO_WEAK; | ||
593 | case 538: | ||
594 | return MAILSMTP_ERROR_AUTH_ENCRYPTION_REQUIRED; | ||
595 | default: | ||
596 | /* opportunistic approach ;) */ | ||
597 | return MAILSMTP_NO_ERROR; | ||
598 | } | ||
599 | } | ||
600 | |||
601 | static int mailsmtp_auth_login(mailsmtp * session, | ||
602 | const char * user, const char * pass) | ||
603 | { | ||
604 | int err; | ||
605 | char command[SMTP_STRING_SIZE]; | ||
606 | char * user64, * pass64; | ||
607 | |||
608 | user64 = NULL; | ||
609 | pass64 = NULL; | ||
610 | |||
611 | user64 = encode_base64(user, strlen(user)); | ||
612 | if (user64 == NULL) { | ||
613 | err = MAILSMTP_ERROR_MEMORY; | ||
614 | goto err_free; | ||
615 | } | ||
616 | |||
617 | pass64 = encode_base64(pass, strlen(pass)); | ||
618 | if (pass64 == NULL) { | ||
619 | err = MAILSMTP_ERROR_MEMORY; | ||
620 | goto err_free; | ||
621 | } | ||
622 | |||
623 | snprintf(command, SMTP_STRING_SIZE, "%s\r\n", user64); | ||
624 | err = send_command(session, command); | ||
625 | if (err == -1) { | ||
626 | err = MAILSMTP_ERROR_STREAM; | ||
627 | goto err_free; | ||
628 | } | ||
629 | err = read_response(session); | ||
630 | err = auth_map_errors(err); | ||
631 | if (err != MAILSMTP_NO_ERROR) | ||
632 | goto err_free; | ||
633 | |||
634 | snprintf(command, SMTP_STRING_SIZE, "%s\r\n", pass64); | ||
635 | err = send_command(session, command); | ||
636 | if (err == -1) { | ||
637 | err = MAILSMTP_ERROR_STREAM; | ||
638 | goto err_free; | ||
639 | } | ||
640 | err = read_response(session); | ||
641 | err = auth_map_errors(err); | ||
642 | |||
643 | err_free: | ||
644 | free(user64); | ||
645 | free(pass64); | ||
646 | |||
647 | return err; | ||
648 | } | ||
649 | |||
650 | static int mailsmtp_auth_plain(mailsmtp * session, | ||
651 | const char * user, const char * pass) | ||
652 | { | ||
653 | int err, len; | ||
654 | char command[SMTP_STRING_SIZE]; | ||
655 | char * plain, * plain64; | ||
656 | |||
657 | len = strlen(user) + strlen(pass) + 3; | ||
658 | plain = (char *) malloc(len); | ||
659 | if (plain == NULL) { | ||
660 | err = MAILSMTP_ERROR_MEMORY; | ||
661 | goto err; | ||
662 | } | ||
663 | |||
664 | snprintf(plain, len, "%c%s%c%s", '\0', user, '\0', pass); | ||
665 | plain64 = encode_base64(plain, len - 1); | ||
666 | |||
667 | snprintf(command, SMTP_STRING_SIZE, "%s\r\n", plain64); | ||
668 | err = send_command(session, command); | ||
669 | if (err == -1) { | ||
670 | err = MAILSMTP_ERROR_STREAM; | ||
671 | goto err_free; | ||
672 | } | ||
673 | |||
674 | err = read_response(session); | ||
675 | err = auth_map_errors(err); | ||
676 | |||
677 | err_free: | ||
678 | free(plain64); | ||
679 | free(plain); | ||
680 | |||
681 | err: | ||
682 | return err; | ||
683 | } | ||
684 | |||
685 | static char * convert_hex(unsigned char *in, int len) | ||
686 | { | ||
687 | static char hex[] = "0123456789abcdef"; | ||
688 | char * out; | ||
689 | int i; | ||
690 | |||
691 | out = (char *) malloc(len * 2 + 1); | ||
692 | if (out == NULL) | ||
693 | return NULL; | ||
694 | |||
695 | for (i = 0; i < len; i++) { | ||
696 | out[i * 2] = hex[in[i] >> 4]; | ||
697 | out[i * 2 + 1] = hex[in[i] & 15]; | ||
698 | } | ||
699 | |||
700 | out[i*2] = 0; | ||
701 | |||
702 | return out; | ||
703 | } | ||
704 | |||
705 | static char * hash_md5(const char * sec_key, const char * data, int len) | ||
706 | { | ||
707 | char key[65], digest[24]; | ||
708 | char * hash_hex; | ||
709 | |||
710 | int sec_len, i; | ||
711 | |||
712 | sec_len = strlen(sec_key); | ||
713 | |||
714 | if (sec_len < 64) { | ||
715 | memcpy(key, sec_key, sec_len); | ||
716 | for (i = sec_len; i < 64; i++) { | ||
717 | key[i] = 0; | ||
718 | } | ||
719 | } else { | ||
720 | memcpy(key, sec_key, 64); | ||
721 | } | ||
722 | |||
723 | hmac_md5(data, len, key, 64, digest); | ||
724 | hash_hex = convert_hex(digest, 16); | ||
725 | |||
726 | return hash_hex; | ||
727 | } | ||
728 | |||
729 | static int mailsmtp_auth_cram_md5(mailsmtp * session, | ||
730 | const char * user, const char * pass) | ||
731 | { | ||
732 | int err; | ||
733 | char command[SMTP_STRING_SIZE]; | ||
734 | char *response, *auth_hex, *auth; | ||
735 | |||
736 | response = decode_base64(session->response, strlen(session->response)); | ||
737 | if (response == NULL) return MAILSMTP_ERROR_MEMORY; | ||
738 | |||
739 | auth_hex = hash_md5(pass, response, strlen(response)); | ||
740 | if (auth_hex == NULL) { | ||
741 | err = MAILSMTP_ERROR_MEMORY; | ||
742 | goto err_free_response; | ||
743 | } | ||
744 | |||
745 | snprintf(command, SMTP_STRING_SIZE, "%s %s", user, auth_hex); | ||
746 | |||
747 | auth = encode_base64(command, strlen(command)); | ||
748 | if (auth == NULL) { | ||
749 | err = MAILSMTP_ERROR_MEMORY; | ||
750 | goto err_free_auth_hex; | ||
751 | } | ||
752 | |||
753 | snprintf(command, SMTP_STRING_SIZE, "%s\r\n", auth); | ||
754 | err = send_command(session, command); | ||
755 | if (err == -1) { | ||
756 | err = MAILSMTP_ERROR_STREAM; | ||
757 | goto err_free; | ||
758 | } | ||
759 | |||
760 | err = read_response(session); | ||
761 | err = auth_map_errors(err); | ||
762 | |||
763 | err_free: | ||
764 | free(auth); | ||
765 | err_free_auth_hex: | ||
766 | free(auth_hex); | ||
767 | err_free_response: | ||
768 | free(response); | ||
769 | return err; | ||
770 | } | ||
771 | |||
772 | int mailsmtp_auth_type(mailsmtp * session, | ||
773 | const char * user, const char * pass, int type) | ||
774 | { | ||
775 | int err; | ||
776 | char command[SMTP_STRING_SIZE]; | ||
777 | |||
778 | if (session->auth == MAILSMTP_AUTH_NOT_CHECKED) | ||
779 | return MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND; | ||
780 | |||
781 | if ( !(session->auth & type) ) return MAILSMTP_ERROR_AUTH_NOT_SUPPORTED; | ||
782 | |||
783 | switch (type) { | ||
784 | case MAILSMTP_AUTH_LOGIN: | ||
785 | snprintf(command, SMTP_STRING_SIZE, "AUTH LOGIN\r\n"); | ||
786 | break; | ||
787 | case MAILSMTP_AUTH_PLAIN: | ||
788 | snprintf(command, SMTP_STRING_SIZE, "AUTH PLAIN\r\n"); | ||
789 | break; | ||
790 | case MAILSMTP_AUTH_CRAM_MD5: | ||
791 | snprintf(command, SMTP_STRING_SIZE, "AUTH CRAM-MD5\r\n"); | ||
792 | break; | ||
793 | default: | ||
794 | return MAILSMTP_ERROR_NOT_IMPLEMENTED; | ||
795 | } | ||
796 | |||
797 | err = send_command(session, command); | ||
798 | if (err == -1) return MAILSMTP_ERROR_STREAM; | ||
799 | |||
800 | err = read_response(session); | ||
801 | err = auth_map_errors(err); | ||
802 | if (err != MAILSMTP_NO_ERROR) return err; | ||
803 | |||
804 | switch (type) { | ||
805 | case MAILSMTP_AUTH_LOGIN: | ||
806 | return mailsmtp_auth_login(session, user, pass); | ||
807 | case MAILSMTP_AUTH_PLAIN: | ||
808 | return mailsmtp_auth_plain(session, user, pass); | ||
809 | case MAILSMTP_AUTH_CRAM_MD5: | ||
810 | return mailsmtp_auth_cram_md5(session, user, pass); | ||
811 | default: | ||
812 | return MAILSMTP_ERROR_NOT_IMPLEMENTED; | ||
813 | } | ||
814 | } | ||
815 | |||
816 | |||
817 | int mailsmtp_auth(mailsmtp * session, const char * user, const char * pass) | ||
818 | { | ||
819 | if (session->auth == MAILSMTP_AUTH_NOT_CHECKED) | ||
820 | return MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND; | ||
821 | |||
822 | if (session->auth & MAILSMTP_AUTH_CRAM_MD5) { | ||
823 | return mailsmtp_auth_type(session, user, pass, MAILSMTP_AUTH_CRAM_MD5); | ||
824 | } else if (session->auth & MAILSMTP_AUTH_PLAIN) { | ||
825 | return mailsmtp_auth_type(session, user, pass, MAILSMTP_AUTH_PLAIN); | ||
826 | } else if (session->auth & MAILSMTP_AUTH_LOGIN) { | ||
827 | return mailsmtp_auth_type(session, user, pass, MAILSMTP_AUTH_LOGIN); | ||
828 | } else { | ||
829 | return MAILSMTP_ERROR_AUTH_NOT_SUPPORTED; | ||
830 | } | ||
831 | } | ||
832 | |||
833 | /* TODO: add mailesmtp_etrn, mailssmtp_expn */ | ||
834 | |||
835 | int mailesmtp_starttls(mailsmtp * session) { | ||
836 | int r; | ||
837 | |||
838 | if (!(session->esmtp & MAILSMTP_ESMTP_STARTTLS)) | ||
839 | return MAILSMTP_ERROR_STARTTLS_NOT_SUPPORTED; | ||
840 | |||
841 | r = send_command(session, "STARTTLS\r\n"); | ||
842 | if (r == -1) | ||
843 | return MAILSMTP_ERROR_STREAM; | ||
844 | r = read_response(session); | ||
845 | |||
846 | switch (r) { | ||
847 | case 220: | ||
848 | return MAILSMTP_NO_ERROR; | ||
849 | |||
850 | case 454: | ||
851 | return MAILSMTP_ERROR_STARTTLS_TEMPORARY_FAILURE; | ||
852 | |||
853 | default: | ||
854 | return MAILSMTP_ERROR_UNEXPECTED_CODE; | ||
855 | } | ||
856 | } | ||
857 | |||
858 | static int parse_response(mailsmtp * session, | ||
859 | char * response) | ||
860 | { | ||
861 | char * message; | ||
862 | int code; | ||
863 | int cont = 0; | ||
864 | |||
865 | code = strtol(response, &message, 10); | ||
866 | if (* message == ' ') | ||
867 | mmap_string_append(session->response_buffer, message + 1); | ||
868 | else if (* message == '-') { | ||
869 | cont = SMTP_STATUS_CONTINUE; | ||
870 | mmap_string_append(session->response_buffer, message + 1); | ||
871 | } | ||
872 | else | ||
873 | mmap_string_append(session->response_buffer, message); | ||
874 | |||
875 | return code | cont; | ||
876 | } | ||
877 | |||
878 | static char * read_line(mailsmtp * session) | ||
879 | { | ||
880 | return mailstream_read_line_remove_eol(session->stream, | ||
881 | session->line_buffer); | ||
882 | } | ||
883 | |||
884 | static int read_response(mailsmtp * session) | ||
885 | { | ||
886 | char * line; | ||
887 | int code; | ||
888 | |||
889 | mmap_string_assign(session->response_buffer, ""); | ||
890 | |||
891 | do { | ||
892 | line = read_line(session); | ||
893 | |||
894 | if (line != NULL) { | ||
895 | code = parse_response(session, line); | ||
896 | mmap_string_append_c(session->response_buffer, '\n'); | ||
897 | } | ||
898 | else | ||
899 | code = 0; | ||
900 | } | ||
901 | while ((code & SMTP_STATUS_CONTINUE) != 0); | ||
902 | |||
903 | session->response = session->response_buffer->str; | ||
904 | |||
905 | return code; | ||
906 | } | ||
907 | |||
908 | |||
909 | |||
910 | |||
911 | |||
912 | static int send_command(mailsmtp * f, char * command) | ||
913 | { | ||
914 | ssize_t r; | ||
915 | |||
916 | r = mailstream_write(f->stream, command, strlen(command)); | ||
917 | if (r == -1) | ||
918 | return -1; | ||
919 | |||
920 | r = mailstream_flush(f->stream); | ||
921 | if (r == -1) | ||
922 | return -1; | ||
923 | |||
924 | return 0; | ||
925 | } | ||
926 | |||
927 | static int send_data(mailsmtp * session, const char * message, size_t size) | ||
928 | { | ||
929 | if (mailstream_send_data(session->stream, message, size, | ||
930 | session->progr_rate, session->progr_fun) == -1) | ||
931 | return -1; | ||
932 | |||
933 | if (mailstream_flush(session->stream) == -1) | ||
934 | return -1; | ||
935 | |||
936 | return 0; | ||
937 | } | ||
938 | |||
939 | |||
940 | const char * mailsmtp_strerror(int errnum) | ||
941 | { | ||
942 | switch (errnum) { | ||
943 | case MAILSMTP_NO_ERROR: | ||
944 | return "No error"; | ||
945 | case MAILSMTP_ERROR_UNEXPECTED_CODE: | ||
946 | return "Unexpected error code"; | ||
947 | case MAILSMTP_ERROR_SERVICE_NOT_AVAILABLE: | ||
948 | return "Service not available"; | ||
949 | case MAILSMTP_ERROR_STREAM: | ||
950 | return "Stream error"; | ||
951 | case MAILSMTP_ERROR_HOSTNAME: | ||
952 | return "gethostname() failed"; | ||
953 | case MAILSMTP_ERROR_NOT_IMPLEMENTED: | ||
954 | return "Not implemented"; | ||
955 | case MAILSMTP_ERROR_ACTION_NOT_TAKEN: | ||
956 | return "Error, action not taken"; | ||
957 | case MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION: | ||
958 | return "Data exceeds storage allocation"; | ||
959 | case MAILSMTP_ERROR_IN_PROCESSING: | ||
960 | return "Error in processing"; | ||
961 | case MAILSMTP_ERROR_INSUFFICIENT_SYSTEM_STORAGE: | ||
962 | return "Insufficient system storage"; | ||
963 | case MAILSMTP_ERROR_MAILBOX_UNAVAILABLE: | ||
964 | return "Mailbox unavailable"; | ||
965 | case MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED: | ||
966 | return "Mailbox name not allowed"; | ||
967 | case MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND: | ||
968 | return "Bad command sequence"; | ||
969 | case MAILSMTP_ERROR_USER_NOT_LOCAL: | ||
970 | return "User not local"; | ||
971 | case MAILSMTP_ERROR_TRANSACTION_FAILED: | ||
972 | return "Transaction failed"; | ||
973 | case MAILSMTP_ERROR_MEMORY: | ||
974 | return "Memory error"; | ||
975 | case MAILSMTP_ERROR_CONNECTION_REFUSED: | ||
976 | return "Connection refused"; | ||
977 | case MAILSMTP_ERROR_STARTTLS_TEMPORARY_FAILURE: | ||
978 | return "TLS not available on server for temporary reason"; | ||
979 | case MAILSMTP_ERROR_STARTTLS_NOT_SUPPORTED: | ||
980 | return "TLS not supported by server"; | ||
981 | default: | ||
982 | return "Unknown error code"; | ||
983 | } | ||
984 | } | ||
diff --git a/libetpan/src/low-level/smtp/mailsmtp.h b/libetpan/src/low-level/smtp/mailsmtp.h new file mode 100644 index 0000000..72e1786 --- a/dev/null +++ b/libetpan/src/low-level/smtp/mailsmtp.h | |||
@@ -0,0 +1,94 @@ | |||
1 | /* | ||
2 | * libEtPan! -- a mail stuff library | ||
3 | * | ||
4 | * Copyright (C) 2001, 2005 - DINH Viet Hoa | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * 1. Redistributions of source code must retain the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer. | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in the | ||
14 | * documentation and/or other materials provided with the distribution. | ||
15 | * 3. Neither the name of the libEtPan! project nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived | ||
17 | * from this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND | ||
20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE | ||
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
29 | * SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | /* | ||
33 | * $Id$ | ||
34 | */ | ||
35 | |||
36 | #ifndef MAILSMTP_H | ||
37 | |||
38 | #define MAILSMTP_H | ||
39 | |||
40 | #ifdef __cplusplus | ||
41 | extern "C" { | ||
42 | #endif | ||
43 | |||
44 | #include <libetpan/mailsmtp_types.h> | ||
45 | #include <libetpan/mailsmtp_helper.h> | ||
46 | #include <libetpan/mailsmtp_socket.h> | ||
47 | #include <libetpan/mailsmtp_ssl.h> | ||
48 | |||
49 | |||
50 | mailsmtp * mailsmtp_new(size_t progr_rate, | ||
51 | progress_function * progr_fun); | ||
52 | void mailsmtp_free(mailsmtp * session); | ||
53 | |||
54 | int mailsmtp_connect(mailsmtp * session, mailstream * s); | ||
55 | int mailsmtp_quit(mailsmtp * session); | ||
56 | |||
57 | /** | ||
58 | * Tries AUTH with detected method - "better" method first: | ||
59 | * CRAM-MD5 -> PLAIN -> LOGIN | ||
60 | */ | ||
61 | int mailsmtp_auth(mailsmtp * session, const char * user, const char * pass); | ||
62 | |||
63 | /** | ||
64 | * tries to autenticate with the server using given auth-type | ||
65 | * returns MAILSMTP_NO_ERROR on success | ||
66 | */ | ||
67 | int mailsmtp_auth_type(mailsmtp * session, | ||
68 | const char * user, const char * pass, int type); | ||
69 | |||
70 | int mailsmtp_helo(mailsmtp * session); | ||
71 | int mailsmtp_mail(mailsmtp * session, const char * from); | ||
72 | int mailsmtp_rcpt(mailsmtp * session, const char * to); | ||
73 | int mailsmtp_data(mailsmtp * session); | ||
74 | int mailsmtp_data_message(mailsmtp * session, | ||
75 | const char * message, | ||
76 | size_t size); | ||
77 | int mailesmtp_ehlo(mailsmtp * session); | ||
78 | int mailesmtp_mail(mailsmtp * session, | ||
79 | const char * from, | ||
80 | int return_full, | ||
81 | const char * envid); | ||
82 | int mailesmtp_rcpt(mailsmtp * session, | ||
83 | const char * to, | ||
84 | int notify, | ||
85 | const char * orcpt); | ||
86 | int mailesmtp_starttls(mailsmtp * session); | ||
87 | |||
88 | const char * mailsmtp_strerror(int errnum); | ||
89 | |||
90 | #ifdef __cplusplus | ||
91 | } | ||
92 | #endif | ||
93 | |||
94 | #endif | ||
diff --git a/libetpan/src/low-level/smtp/mailsmtp_helper.c b/libetpan/src/low-level/smtp/mailsmtp_helper.c new file mode 100644 index 0000000..69b73cc --- a/dev/null +++ b/libetpan/src/low-level/smtp/mailsmtp_helper.c | |||
@@ -0,0 +1,228 @@ | |||
1 | /* | ||
2 | * libEtPan! -- a mail stuff library | ||
3 | * | ||
4 | * Copyright (C) 2001, 2005 - DINH Viet Hoa | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * 1. Redistributions of source code must retain the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer. | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in the | ||
14 | * documentation and/or other materials provided with the distribution. | ||
15 | * 3. Neither the name of the libEtPan! project nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived | ||
17 | * from this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND | ||
20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE | ||
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
29 | * SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | /* | ||
33 | * $Id$ | ||
34 | */ | ||
35 | |||
36 | #include "mailsmtp.h" | ||
37 | #include <string.h> | ||
38 | #include <stdlib.h> | ||
39 | #include "mail.h" | ||
40 | |||
41 | int mailsmtp_init(mailsmtp * session) | ||
42 | { | ||
43 | int r; | ||
44 | |||
45 | r = mailesmtp_ehlo(session); | ||
46 | |||
47 | if (r == MAILSMTP_NO_ERROR) | ||
48 | return MAILSMTP_NO_ERROR; | ||
49 | |||
50 | r = mailsmtp_helo(session); | ||
51 | if (r == MAILSMTP_NO_ERROR) | ||
52 | return MAILSMTP_NO_ERROR; | ||
53 | |||
54 | return r; | ||
55 | } | ||
56 | |||
57 | |||
58 | |||
59 | int mailesmtp_send(mailsmtp * session, | ||
60 | const char * from, | ||
61 | int return_full, | ||
62 | const char * envid, | ||
63 | clist * addresses, | ||
64 | const char * message, size_t size) | ||
65 | { | ||
66 | int r; | ||
67 | clistiter * l; | ||
68 | |||
69 | if (!session->esmtp) | ||
70 | return mailsmtp_send(session, from, addresses, message, size); | ||
71 | |||
72 | r = mailesmtp_mail(session, from, return_full, envid); | ||
73 | if (r != MAILSMTP_NO_ERROR) | ||
74 | return r; | ||
75 | |||
76 | for(l = clist_begin(addresses) ; l != NULL; l = clist_next(l)) { | ||
77 | struct esmtp_address * addr; | ||
78 | |||
79 | addr = clist_content(l); | ||
80 | |||
81 | r = mailesmtp_rcpt(session, addr->address, addr->notify, addr->orcpt); | ||
82 | if (r != MAILSMTP_NO_ERROR) | ||
83 | return r; | ||
84 | } | ||
85 | |||
86 | r = mailsmtp_data(session); | ||
87 | if (r != MAILSMTP_NO_ERROR) | ||
88 | return r; | ||
89 | |||
90 | r = mailsmtp_data_message(session, message, size); | ||
91 | if (r != MAILSMTP_NO_ERROR) | ||
92 | return r; | ||
93 | |||
94 | return MAILSMTP_NO_ERROR; | ||
95 | } | ||
96 | |||
97 | int mailsmtp_send(mailsmtp * session, | ||
98 | const char * from, | ||
99 | clist * addresses, | ||
100 | const char * message, size_t size) | ||
101 | { | ||
102 | int r; | ||
103 | clistiter * l; | ||
104 | |||
105 | r = mailsmtp_mail(session, from); | ||
106 | if (r != MAILSMTP_NO_ERROR) | ||
107 | return r; | ||
108 | |||
109 | for(l = clist_begin(addresses) ; l != NULL; l = clist_next(l)) { | ||
110 | struct esmtp_address * addr; | ||
111 | |||
112 | addr = clist_content(l); | ||
113 | |||
114 | r = mailsmtp_rcpt(session, addr->address); | ||
115 | if (r != MAILSMTP_NO_ERROR) | ||
116 | return r; | ||
117 | } | ||
118 | |||
119 | r = mailsmtp_data(session); | ||
120 | if (r != MAILSMTP_NO_ERROR) | ||
121 | return r; | ||
122 | |||
123 | r = mailsmtp_data_message(session, message, size); | ||
124 | if (r != MAILSMTP_NO_ERROR) | ||
125 | return r; | ||
126 | |||
127 | return MAILSMTP_NO_ERROR; | ||
128 | } | ||
129 | |||
130 | |||
131 | |||
132 | |||
133 | |||
134 | |||
135 | |||
136 | |||
137 | |||
138 | |||
139 | |||
140 | |||
141 | |||
142 | /* esmtp addresses and smtp addresses */ | ||
143 | |||
144 | static struct esmtp_address * esmtp_address_new(char * addr, | ||
145 | int notify, char * orcpt) | ||
146 | { | ||
147 | struct esmtp_address * esmtpa; | ||
148 | |||
149 | esmtpa = malloc(sizeof(* esmtpa)); | ||
150 | if (esmtpa == NULL) | ||
151 | return NULL; | ||
152 | |||
153 | esmtpa->address = strdup(addr); | ||
154 | if (esmtpa->address == NULL) { | ||
155 | free(esmtpa); | ||
156 | return NULL; | ||
157 | } | ||
158 | |||
159 | if (orcpt != NULL) { | ||
160 | esmtpa->orcpt = strdup(orcpt); | ||
161 | if (esmtpa->orcpt == NULL) { | ||
162 | free(esmtpa->address); | ||
163 | free(esmtpa); | ||
164 | return NULL; | ||
165 | } | ||
166 | } | ||
167 | else | ||
168 | esmtpa->orcpt = NULL; | ||
169 | |||
170 | esmtpa->notify = notify; | ||
171 | |||
172 | return esmtpa; | ||
173 | } | ||
174 | |||
175 | static void esmtp_address_free(struct esmtp_address * addr) | ||
176 | { | ||
177 | if (addr->orcpt) | ||
178 | free(addr->orcpt); | ||
179 | if (addr->address) | ||
180 | free(addr->address); | ||
181 | |||
182 | free(addr); | ||
183 | } | ||
184 | |||
185 | clist * esmtp_address_list_new() | ||
186 | { | ||
187 | return clist_new(); | ||
188 | } | ||
189 | |||
190 | void esmtp_address_list_free(clist * l) | ||
191 | { | ||
192 | clist_foreach(l, (clist_func) esmtp_address_free, NULL); | ||
193 | clist_free(l); | ||
194 | } | ||
195 | |||
196 | int esmtp_address_list_add(clist * list, char * address, | ||
197 | int notify, char * orcpt) | ||
198 | { | ||
199 | struct esmtp_address * esmtpa; | ||
200 | int r; | ||
201 | |||
202 | esmtpa = esmtp_address_new(address, notify, orcpt); | ||
203 | if (esmtpa == NULL) | ||
204 | return -1; | ||
205 | |||
206 | r = clist_append(list, esmtpa); | ||
207 | if (r < 0) { | ||
208 | esmtp_address_free(esmtpa); | ||
209 | return -1; | ||
210 | } | ||
211 | |||
212 | return 0; | ||
213 | } | ||
214 | |||
215 | clist * smtp_address_list_new() | ||
216 | { | ||
217 | return esmtp_address_list_new(); | ||
218 | } | ||
219 | |||
220 | int smtp_address_list_add(clist * list, char * address) | ||
221 | { | ||
222 | return esmtp_address_list_add(list, address, 0, NULL); | ||
223 | } | ||
224 | |||
225 | void smtp_address_list_free(clist * l) | ||
226 | { | ||
227 | esmtp_address_list_free(l); | ||
228 | } | ||
diff --git a/libetpan/src/low-level/smtp/mailsmtp_helper.h b/libetpan/src/low-level/smtp/mailsmtp_helper.h new file mode 100644 index 0000000..2178d50 --- a/dev/null +++ b/libetpan/src/low-level/smtp/mailsmtp_helper.h | |||
@@ -0,0 +1,74 @@ | |||
1 | /* | ||
2 | * libEtPan! -- a mail stuff library | ||
3 | * | ||
4 | * Copyright (C) 2001, 2005 - DINH Viet Hoa | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * 1. Redistributions of source code must retain the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer. | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in the | ||
14 | * documentation and/or other materials provided with the distribution. | ||
15 | * 3. Neither the name of the libEtPan! project nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived | ||
17 | * from this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND | ||
20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE | ||
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
29 | * SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | /* | ||
33 | * $Id$ | ||
34 | */ | ||
35 | |||
36 | #ifndef MAILSMTP_HELPER_H | ||
37 | |||
38 | #define MAILSMTP_HELPER_H | ||
39 | |||
40 | #ifdef __cplusplus | ||
41 | extern "C" { | ||
42 | #endif | ||
43 | |||
44 | #include "mailsmtp_types.h" | ||
45 | #include "clist.h" | ||
46 | |||
47 | int mailsmtp_init(mailsmtp * session); | ||
48 | |||
49 | int mailesmtp_send(mailsmtp * session, | ||
50 | const char * from, | ||
51 | int return_full, | ||
52 | const char * envid, | ||
53 | clist * addresses, | ||
54 | const char * message, size_t size); | ||
55 | |||
56 | int mailsmtp_send(mailsmtp * session, | ||
57 | const char * from, | ||
58 | clist * addresses, | ||
59 | const char * message, size_t size); | ||
60 | |||
61 | clist * esmtp_address_list_new(); | ||
62 | int esmtp_address_list_add(clist * list, char * address, | ||
63 | int notify, char * orcpt); | ||
64 | void esmtp_address_list_free(clist * l); | ||
65 | |||
66 | clist * smtp_address_list_new(); | ||
67 | int smtp_address_list_add(clist * list, char * address); | ||
68 | void smtp_address_list_free(clist * l); | ||
69 | |||
70 | #ifdef __cplusplus | ||
71 | } | ||
72 | #endif | ||
73 | |||
74 | #endif | ||
diff --git a/libetpan/src/low-level/smtp/mailsmtp_socket.c b/libetpan/src/low-level/smtp/mailsmtp_socket.c new file mode 100644 index 0000000..6b8d81a --- a/dev/null +++ b/libetpan/src/low-level/smtp/mailsmtp_socket.c | |||
@@ -0,0 +1,99 @@ | |||
1 | /* | ||
2 | * libEtPan! -- a mail stuff library | ||
3 | * | ||
4 | * Copyright (C) 2001, 2005 - DINH Viet Hoa | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * 1. Redistributions of source code must retain the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer. | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in the | ||
14 | * documentation and/or other materials provided with the distribution. | ||
15 | * 3. Neither the name of the libEtPan! project nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived | ||
17 | * from this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND | ||
20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE | ||
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
29 | * SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | /* | ||
33 | * $Id$ | ||
34 | */ | ||
35 | |||
36 | #include "mailsmtp_socket.h" | ||
37 | |||
38 | #include "mailsmtp.h" | ||
39 | |||
40 | #include "connect.h" | ||
41 | #include <netinet/in.h> | ||
42 | #include <unistd.h> | ||
43 | |||
44 | #define DEFAULT_SMTP_PORT 25 | ||
45 | #define SERVICE_NAME_SMTP "smtp" | ||
46 | #define SERVICE_TYPE_TCP "tcp" | ||
47 | |||
48 | int mailsmtp_socket_connect(mailsmtp * session, | ||
49 | const char * server, uint16_t port) | ||
50 | { | ||
51 | int s; | ||
52 | mailstream * stream; | ||
53 | |||
54 | if (port == 0) { | ||
55 | port = mail_get_service_port(SERVICE_NAME_SMTP, SERVICE_TYPE_TCP); | ||
56 | if (port == 0) | ||
57 | port = DEFAULT_SMTP_PORT; | ||
58 | port = ntohs(port); | ||
59 | } | ||
60 | |||
61 | /* Connection */ | ||
62 | |||
63 | s = mail_tcp_connect(server, port); | ||
64 | if (s == -1) | ||
65 | return MAILSMTP_ERROR_CONNECTION_REFUSED; | ||
66 | |||
67 | stream = mailstream_socket_open(s); | ||
68 | if (stream == NULL) { | ||
69 | close(s); | ||
70 | return MAILSMTP_ERROR_MEMORY; | ||
71 | } | ||
72 | |||
73 | return mailsmtp_connect(session, stream); | ||
74 | } | ||
75 | |||
76 | int mailsmtp_socket_starttls(mailsmtp * session) { | ||
77 | int r; | ||
78 | int fd; | ||
79 | mailstream_low * low; | ||
80 | mailstream_low * new_low; | ||
81 | |||
82 | r = mailesmtp_starttls(session); | ||
83 | if (r != MAILSMTP_NO_ERROR) | ||
84 | return r; | ||
85 | |||
86 | low = mailstream_get_low(session->stream); | ||
87 | fd = mailstream_low_get_fd(low); | ||
88 | if (fd == -1) | ||
89 | return MAILSMTP_ERROR_STREAM; | ||
90 | |||
91 | new_low = mailstream_low_ssl_open(fd); | ||
92 | if (new_low == NULL) | ||
93 | return MAILSMTP_ERROR_STREAM; | ||
94 | |||
95 | mailstream_low_free(low); | ||
96 | mailstream_set_low(session->stream, new_low); | ||
97 | |||
98 | return MAILSMTP_NO_ERROR; | ||
99 | } | ||
diff --git a/libetpan/src/low-level/smtp/mailsmtp_socket.h b/libetpan/src/low-level/smtp/mailsmtp_socket.h new file mode 100644 index 0000000..2726c1d --- a/dev/null +++ b/libetpan/src/low-level/smtp/mailsmtp_socket.h | |||
@@ -0,0 +1,56 @@ | |||
1 | /* | ||
2 | * libEtPan! -- a mail stuff library | ||
3 | * | ||
4 | * Copyright (C) 2001, 2005 - DINH Viet Hoa | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * 1. Redistributions of source code must retain the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer. | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in the | ||
14 | * documentation and/or other materials provided with the distribution. | ||
15 | * 3. Neither the name of the libEtPan! project nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived | ||
17 | * from this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND | ||
20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE | ||
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
29 | * SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | /* | ||
33 | * $Id$ | ||
34 | */ | ||
35 | |||
36 | #ifndef MAILSMTP_SOCKET_H | ||
37 | |||
38 | #define MAILSMTP_SOCKET_H | ||
39 | |||
40 | #ifdef __cplusplus | ||
41 | extern "C" { | ||
42 | #endif | ||
43 | |||
44 | #include <inttypes.h> | ||
45 | |||
46 | #include <libetpan/mailsmtp_types.h> | ||
47 | |||
48 | int mailsmtp_socket_connect(mailsmtp * session, | ||
49 | const char * server, uint16_t port); | ||
50 | int mailsmtp_socket_starttls(mailsmtp * session); | ||
51 | |||
52 | #ifdef __cplusplus | ||
53 | } | ||
54 | #endif | ||
55 | |||
56 | #endif | ||
diff --git a/libetpan/src/low-level/smtp/mailsmtp_ssl.c b/libetpan/src/low-level/smtp/mailsmtp_ssl.c new file mode 100644 index 0000000..4a42326 --- a/dev/null +++ b/libetpan/src/low-level/smtp/mailsmtp_ssl.c | |||
@@ -0,0 +1,74 @@ | |||
1 | /* | ||
2 | * libEtPan! -- a mail stuff library | ||
3 | * | ||
4 | * Copyright (C) 2001, 2005 - DINH Viet Hoa | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * 1. Redistributions of source code must retain the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer. | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in the | ||
14 | * documentation and/or other materials provided with the distribution. | ||
15 | * 3. Neither the name of the libEtPan! project nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived | ||
17 | * from this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND | ||
20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE | ||
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
29 | * SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | /* | ||
33 | * $Id$ | ||
34 | */ | ||
35 | |||
36 | #include "mailsmtp_socket.h" | ||
37 | |||
38 | #include "mailsmtp.h" | ||
39 | |||
40 | #include "connect.h" | ||
41 | #include <netinet/in.h> | ||
42 | #include <unistd.h> | ||
43 | |||
44 | #define DEFAULT_SMTPS_PORT 465 | ||
45 | #define SERVICE_NAME_SMTPS "smtps" | ||
46 | #define SERVICE_TYPE_TCP "tcp" | ||
47 | |||
48 | int mailsmtp_ssl_connect(mailsmtp * session, | ||
49 | const char * server, uint16_t port) | ||
50 | { | ||
51 | int s; | ||
52 | mailstream * stream; | ||
53 | |||
54 | if (port == 0) { | ||
55 | port = mail_get_service_port(SERVICE_NAME_SMTPS, SERVICE_TYPE_TCP); | ||
56 | if (port == 0) | ||
57 | port = DEFAULT_SMTPS_PORT; | ||
58 | port = ntohs(port); | ||
59 | } | ||
60 | |||
61 | /* Connection */ | ||
62 | |||
63 | s = mail_tcp_connect(server, port); | ||
64 | if (s == -1) | ||
65 | return MAILSMTP_ERROR_CONNECTION_REFUSED; | ||
66 | |||
67 | stream = mailstream_ssl_open(s); | ||
68 | if (stream == NULL) { | ||
69 | close(s); | ||
70 | return MAILSMTP_ERROR_CONNECTION_REFUSED; | ||
71 | } | ||
72 | |||
73 | return mailsmtp_connect(session, stream); | ||
74 | } | ||
diff --git a/libetpan/src/low-level/smtp/mailsmtp_ssl.h b/libetpan/src/low-level/smtp/mailsmtp_ssl.h new file mode 100644 index 0000000..01f4683 --- a/dev/null +++ b/libetpan/src/low-level/smtp/mailsmtp_ssl.h | |||
@@ -0,0 +1,55 @@ | |||
1 | /* | ||
2 | * libEtPan! -- a mail stuff library | ||
3 | * | ||
4 | * Copyright (C) 2001, 2005 - DINH Viet Hoa | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * 1. Redistributions of source code must retain the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer. | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in the | ||
14 | * documentation and/or other materials provided with the distribution. | ||
15 | * 3. Neither the name of the libEtPan! project nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived | ||
17 | * from this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND | ||
20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE | ||
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
29 | * SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | /* | ||
33 | * $Id$ | ||
34 | */ | ||
35 | |||
36 | #ifndef MAILSMTP_SSL_H | ||
37 | |||
38 | #define MAILSMTP_SSL_H | ||
39 | |||
40 | #ifdef __cplusplus | ||
41 | extern "C" { | ||
42 | #endif | ||
43 | |||
44 | #include <inttypes.h> | ||
45 | |||
46 | #include <libetpan/mailsmtp_types.h> | ||
47 | |||
48 | int mailsmtp_ssl_connect(mailsmtp * session, | ||
49 | const char * server, uint16_t port); | ||
50 | |||
51 | #ifdef __cplusplus | ||
52 | } | ||
53 | #endif | ||
54 | |||
55 | #endif | ||
diff --git a/libetpan/src/low-level/smtp/mailsmtp_types.h b/libetpan/src/low-level/smtp/mailsmtp_types.h new file mode 100644 index 0000000..0aa2617 --- a/dev/null +++ b/libetpan/src/low-level/smtp/mailsmtp_types.h | |||
@@ -0,0 +1,126 @@ | |||
1 | /* | ||
2 | * libEtPan! -- a mail stuff library | ||
3 | * | ||
4 | * Copyright (C) 2001, 2005 - DINH Viet Hoa | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * 1. Redistributions of source code must retain the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer. | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in the | ||
14 | * documentation and/or other materials provided with the distribution. | ||
15 | * 3. Neither the name of the libEtPan! project nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived | ||
17 | * from this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND | ||
20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE | ||
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
29 | * SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | /* | ||
33 | * $Id$ | ||
34 | */ | ||
35 | |||
36 | #ifndef MAILSMTP_TYPES_H | ||
37 | |||
38 | #define MAILSMTP_TYPES_H | ||
39 | |||
40 | #ifdef __cplusplus | ||
41 | extern "C" { | ||
42 | #endif | ||
43 | |||
44 | #include "mailstream.h" | ||
45 | #include "mmapstring.h" | ||
46 | |||
47 | enum { | ||
48 | MAILSMTP_NO_ERROR = 0, | ||
49 | MAILSMTP_ERROR_UNEXPECTED_CODE, | ||
50 | MAILSMTP_ERROR_SERVICE_NOT_AVAILABLE, | ||
51 | MAILSMTP_ERROR_STREAM, | ||
52 | MAILSMTP_ERROR_HOSTNAME, | ||
53 | MAILSMTP_ERROR_NOT_IMPLEMENTED, | ||
54 | MAILSMTP_ERROR_ACTION_NOT_TAKEN, | ||
55 | MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION, | ||
56 | MAILSMTP_ERROR_IN_PROCESSING, | ||
57 | MAILSMTP_ERROR_INSUFFICIENT_SYSTEM_STORAGE, | ||
58 | MAILSMTP_ERROR_MAILBOX_UNAVAILABLE, | ||
59 | MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED, | ||
60 | MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND, | ||
61 | MAILSMTP_ERROR_USER_NOT_LOCAL, | ||
62 | MAILSMTP_ERROR_TRANSACTION_FAILED, | ||
63 | MAILSMTP_ERROR_MEMORY, | ||
64 | MAILSMTP_ERROR_AUTH_NOT_SUPPORTED, | ||
65 | MAILSMTP_ERROR_AUTH_LOGIN, | ||
66 | MAILSMTP_ERROR_AUTH_REQUIRED, | ||
67 | MAILSMTP_ERROR_AUTH_TOO_WEAK, | ||
68 | MAILSMTP_ERROR_AUTH_TRANSITION_NEEDED, | ||
69 | MAILSMTP_ERROR_AUTH_TEMPORARY_FAILTURE, | ||
70 | MAILSMTP_ERROR_AUTH_ENCRYPTION_REQUIRED, | ||
71 | MAILSMTP_ERROR_STARTTLS_TEMPORARY_FAILURE, | ||
72 | MAILSMTP_ERROR_STARTTLS_NOT_SUPPORTED, | ||
73 | MAILSMTP_ERROR_CONNECTION_REFUSED | ||
74 | }; | ||
75 | |||
76 | enum { | ||
77 | MAILSMTP_AUTH_NOT_CHECKED = 0, | ||
78 | MAILSMTP_AUTH_CHECKED = 1, | ||
79 | MAILSMTP_AUTH_CRAM_MD5 = 2, | ||
80 | MAILSMTP_AUTH_PLAIN = 4, | ||
81 | MAILSMTP_AUTH_LOGIN = 8 | ||
82 | }; | ||
83 | |||
84 | enum { | ||
85 | MAILSMTP_ESMTP = 1, | ||
86 | MAILSMTP_ESMTP_EXPN = 2, | ||
87 | MAILSMTP_ESMTP_8BITMIME = 4, | ||
88 | MAILSMTP_ESMTP_SIZE = 8, | ||
89 | MAILSMTP_ESMTP_ETRN = 16, | ||
90 | MAILSMTP_ESMTP_STARTTLS = 32, | ||
91 | MAILSMTP_ESMTP_DSN = 64, | ||
92 | }; | ||
93 | |||
94 | struct mailsmtp { | ||
95 | mailstream * stream; | ||
96 | |||
97 | size_t progr_rate; | ||
98 | progress_function * progr_fun; | ||
99 | |||
100 | char * response; | ||
101 | |||
102 | MMAPString * line_buffer; | ||
103 | MMAPString * response_buffer; | ||
104 | |||
105 | int esmtp; // contains flags MAILSMTP_ESMTP_* | ||
106 | int auth; // contains flags MAILSMTP_AUTH_* | ||
107 | }; | ||
108 | |||
109 | typedef struct mailsmtp mailsmtp; | ||
110 | |||
111 | #define MAILSMTP_DSN_NOTIFY_SUCCESS 1 | ||
112 | #define MAILSMTP_DSN_NOTIFY_FAILURE 2 | ||
113 | #define MAILSMTP_DSN_NOTIFY_DELAY 4 | ||
114 | #define MAILSMTP_DSN_NOTIFY_NEVER 8 | ||
115 | |||
116 | struct esmtp_address { | ||
117 | char * address; | ||
118 | int notify; | ||
119 | char * orcpt; | ||
120 | }; | ||
121 | |||
122 | #ifdef __cplusplus | ||
123 | } | ||
124 | #endif | ||
125 | |||
126 | #endif | ||