summaryrefslogtreecommitdiffabout
path: root/kmicromail/libetpan/smtp
authorzautrix <zautrix>2004-07-03 16:33:12 (UTC)
committer zautrix <zautrix>2004-07-03 16:33:12 (UTC)
commite3b89230f065c48c84b48c88edb6eb088374c487 (patch) (unidiff)
tree162ea2ef909a6f82ccfcedf45d80d6c821174912 /kmicromail/libetpan/smtp
parent2dd6ac0b2d24c91d35ce674a6c26351352df2b15 (diff)
downloadkdepimpi-e3b89230f065c48c84b48c88edb6eb088374c487.zip
kdepimpi-e3b89230f065c48c84b48c88edb6eb088374c487.tar.gz
kdepimpi-e3b89230f065c48c84b48c88edb6eb088374c487.tar.bz2
Initial revision
Diffstat (limited to 'kmicromail/libetpan/smtp') (more/less context) (ignore whitespace changes)
-rw-r--r--kmicromail/libetpan/smtp/.libs/libmailsmtp.abin0 -> 49200 bytes
-rw-r--r--kmicromail/libetpan/smtp/TODO1
-rw-r--r--kmicromail/libetpan/smtp/mailsmtp.c982
-rw-r--r--kmicromail/libetpan/smtp/mailsmtp.h94
-rw-r--r--kmicromail/libetpan/smtp/mailsmtp_helper.c232
-rw-r--r--kmicromail/libetpan/smtp/mailsmtp_helper.h74
-rw-r--r--kmicromail/libetpan/smtp/mailsmtp_socket.c99
-rw-r--r--kmicromail/libetpan/smtp/mailsmtp_socket.h56
-rw-r--r--kmicromail/libetpan/smtp/mailsmtp_ssl.c74
-rw-r--r--kmicromail/libetpan/smtp/mailsmtp_ssl.h55
-rw-r--r--kmicromail/libetpan/smtp/mailsmtp_types.h126
11 files changed, 1793 insertions, 0 deletions
diff --git a/kmicromail/libetpan/smtp/.libs/libmailsmtp.a b/kmicromail/libetpan/smtp/.libs/libmailsmtp.a
new file mode 100644
index 0000000..b856a73
--- a/dev/null
+++ b/kmicromail/libetpan/smtp/.libs/libmailsmtp.a
Binary files differ
diff --git a/kmicromail/libetpan/smtp/TODO b/kmicromail/libetpan/smtp/TODO
new file mode 100644
index 0000000..96f44c6
--- a/dev/null
+++ b/kmicromail/libetpan/smtp/TODO
@@ -0,0 +1 @@
- STARTTLS
diff --git a/kmicromail/libetpan/smtp/mailsmtp.c b/kmicromail/libetpan/smtp/mailsmtp.c
new file mode 100644
index 0000000..b3be432
--- a/dev/null
+++ b/kmicromail/libetpan/smtp/mailsmtp.c
@@ -0,0 +1,982 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - 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 REGENTS 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 REGENTS 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
75mailsmtp * 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
112void 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
122static int send_command(mailsmtp * f, char * command);
123
124static int read_response(mailsmtp * session);
125
126/* smtp operations */
127
128int 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
155int 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
177int 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 return MAILSMTP_NO_ERROR;
196
197 case 504:
198 return MAILSMTP_ERROR_NOT_IMPLEMENTED;
199
200 case 550:
201 return MAILSMTP_ERROR_ACTION_NOT_TAKEN;
202
203 case 0:
204 return MAILSMTP_ERROR_STREAM;
205
206 default:
207 return MAILSMTP_ERROR_UNEXPECTED_CODE;
208 }
209}
210
211int mailsmtp_mail(mailsmtp * session, const char * from)
212{
213 int r;
214 char command[SMTP_STRING_SIZE];
215
216 snprintf(command, SMTP_STRING_SIZE, "MAIL FROM:<%s>\r\n", from);
217 r = send_command(session, command);
218 if (r == -1)
219 return MAILSMTP_ERROR_STREAM;
220 r = read_response(session);
221
222 switch (r) {
223 case 250:
224 return MAILSMTP_NO_ERROR;
225
226 case 552:
227 return MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION;
228
229 case 451:
230 return MAILSMTP_ERROR_IN_PROCESSING;
231
232 case 452:
233 return MAILSMTP_ERROR_INSUFFICIENT_SYSTEM_STORAGE;
234
235 case 550:
236 return MAILSMTP_ERROR_MAILBOX_UNAVAILABLE;
237
238 case 553:
239 return MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED;
240
241 case 503:
242 return MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND;
243
244 case 0:
245 return MAILSMTP_ERROR_STREAM;
246
247 default:
248 return MAILSMTP_ERROR_UNEXPECTED_CODE;
249 }
250}
251
252int mailsmtp_rcpt(mailsmtp * session, const char * to)
253{
254 return mailesmtp_rcpt(session, to, 0, NULL);
255}
256
257int mailsmtp_data(mailsmtp * session)
258{
259 int r;
260 char command[SMTP_STRING_SIZE];
261
262 snprintf(command, SMTP_STRING_SIZE, "DATA\r\n");
263 r = send_command(session, command);
264 if (r == -1)
265 return MAILSMTP_ERROR_STREAM;
266 r = read_response(session);
267
268 switch (r) {
269 case 354:
270 return MAILSMTP_NO_ERROR;
271
272 case 451:
273 return MAILSMTP_ERROR_IN_PROCESSING;
274
275 case 554:
276 return MAILSMTP_ERROR_TRANSACTION_FAILED;
277
278 case 503:
279 return MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND;
280
281 default:
282 return MAILSMTP_ERROR_UNEXPECTED_CODE;
283 }
284}
285
286static int send_data(mailsmtp * session, const char * message, size_t size);
287
288int mailsmtp_data_message(mailsmtp * session,
289 const char * message,
290 size_t size)
291{
292 int r;
293
294 r = send_data(session, message, size);
295 if (r == -1)
296 return MAILSMTP_ERROR_STREAM;
297
298 r = read_response(session);
299
300 switch(r) {
301 case 250:
302 return MAILSMTP_NO_ERROR;
303
304 case 552:
305 return MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION;
306
307 case 554:
308 return MAILSMTP_ERROR_TRANSACTION_FAILED;
309
310 case 451:
311 return MAILSMTP_ERROR_IN_PROCESSING;
312
313 case 452:
314 return MAILSMTP_ERROR_INSUFFICIENT_SYSTEM_STORAGE;
315
316 case 0:
317 return MAILSMTP_ERROR_STREAM;
318
319 default:
320 return MAILSMTP_ERROR_UNEXPECTED_CODE;
321 }
322}
323
324/* esmtp operations */
325
326
327/**
328 * called during mailesmtp_ehlo
329 * checks EHLO answer for server extensions and sets flags
330 * in session->esmtp
331 * checks AUTH methods in session->response and sets flags
332 * in session->auth
333 */
334#define isdelim(x) ((x) == ' ' || (x) == '\r' || (x) == '\n' || (x) == '\0')
335
336int mailesmtp_parse_ehlo(mailsmtp * session)
337{
338 char * response;
339
340 /* restore data */
341 session->esmtp = MAILSMTP_ESMTP;
342 session->auth = MAILSMTP_AUTH_CHECKED;
343
344 response = session->response;
345
346 /* ESMTP supported extensions :
347 DSN
348 EXPN
349 8BITMIME
350 SIZE [<n>]
351 ETRN
352 STARTTLS
353 AUTH <mechanisms...>
354 */
355 while (response != NULL) {
356 if (!strncasecmp(response, "EXPN", 4) && isdelim(response[4]))
357 session->esmtp |= MAILSMTP_ESMTP_EXPN;
358 else if (!strncasecmp(response, "ETRN", 4) && isdelim(response[4]))
359 session->esmtp |= MAILSMTP_ESMTP_ETRN;
360 else if (!strncasecmp(response, "DSN", 3) && isdelim(response[3]))
361 session->esmtp |= MAILSMTP_ESMTP_DSN;
362 else if (!strncasecmp(response, "8BITMIME", 8) && isdelim(response[8]))
363 session->esmtp |= MAILSMTP_ESMTP_8BITMIME;
364 else if (!strncasecmp(response, "STARTTLS", 8) && isdelim(response[8]))
365 session->esmtp |= MAILSMTP_ESMTP_STARTTLS;
366 else if (!strncasecmp(response, "SIZE", 4) && isdelim(response[4])) {
367 session->esmtp |= MAILSMTP_ESMTP_SIZE;
368 /* TODO: grab optionnal max size */
369 } else if (!strncasecmp(response, "AUTH ", 5)) {
370 response += 5; /* remove "AUTH " */
371 while (response[0] != '\n' && response[0] != '\0') {
372 while (response[0] == ' ') response++;
373 if (strncasecmp(response, "LOGIN", 5) == 0) {
374 session->auth |= MAILSMTP_AUTH_LOGIN;
375 response += 5;
376 } else if (strncasecmp(response, "CRAM-MD5", 8) == 0) {
377 session->auth |= MAILSMTP_AUTH_CRAM_MD5;
378 response += 8;
379 } else if (strncasecmp(response, "PLAIN", 5) == 0) {
380 session->auth |= MAILSMTP_AUTH_PLAIN;
381 response += 5;
382 } else {
383 /* unknown auth method - jump to next word or eol */
384 while (!isdelim(response[0]) || response[0] == '\r')
385 response++;
386 }
387 }
388 }
389 response = strpbrk(response, "\n");
390 if (response != NULL)
391 response++;
392 }
393
394 return MAILSMTP_NO_ERROR;
395}
396
397
398int mailesmtp_ehlo(mailsmtp * session)
399{
400 int r;
401 char hostname[HOSTNAME_SIZE];
402 char command[SMTP_STRING_SIZE];
403
404 r = gethostname(hostname, HOSTNAME_SIZE);
405 if (r != 0)
406 return MAILSMTP_ERROR_HOSTNAME;
407
408 snprintf(command, SMTP_STRING_SIZE, "EHLO %s\r\n", hostname);
409 r = send_command(session, command);
410 if (r == -1)
411 return MAILSMTP_ERROR_STREAM;
412 r = read_response(session);
413
414 switch (r) {
415 case 250:
416 return mailesmtp_parse_ehlo(session);
417
418 case 504:
419 return MAILSMTP_ERROR_NOT_IMPLEMENTED;
420
421 case 550:
422 return MAILSMTP_ERROR_ACTION_NOT_TAKEN;
423
424 case 0:
425 return MAILSMTP_ERROR_STREAM;
426
427 default:
428 return MAILSMTP_ERROR_UNEXPECTED_CODE;
429 }
430}
431
432/*
433 if return_full is TRUE, the entire message is returned on error
434 envid can be NULL
435*/
436
437
438int mailesmtp_mail(mailsmtp * session,
439 const char * from,
440 int return_full,
441 const char * envid)
442{
443 int r;
444 char command[SMTP_STRING_SIZE];
445 char *body = "";
446
447#if notyet
448 /* TODO: figure out a way for the user to explicity enable this or not */
449 if (session->esmtp & MAILSMTP_ESMTP_8BITMIME)
450 body = " BODY=8BITMIME";
451#endif
452
453 if (session->esmtp & MAILSMTP_ESMTP_DSN) {
454 if (envid)
455 snprintf(command, SMTP_STRING_SIZE, "MAIL FROM:<%s> RET=%s ENVID=%s%s\r\n",
456 from, return_full ? "FULL" : "HDRS", envid, body);
457 else
458 snprintf(command, SMTP_STRING_SIZE, "MAIL FROM:<%s> RET=%s%s\r\n",
459 from, return_full ? "FULL" : "HDRS", body);
460 } else
461 snprintf(command, SMTP_STRING_SIZE, "MAIL FROM:<%s>%s\r\n",
462 from, body);
463
464 r = send_command(session, command);
465 if (r == -1)
466 return MAILSMTP_ERROR_STREAM;
467 r = read_response(session);
468
469 switch (r) {
470 case 250:
471 return MAILSMTP_NO_ERROR;
472
473 case 552:
474 return MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION;
475
476 case 451:
477 return MAILSMTP_ERROR_IN_PROCESSING;
478
479 case 452:
480 return MAILSMTP_ERROR_INSUFFICIENT_SYSTEM_STORAGE;
481
482 case 550:
483 return MAILSMTP_ERROR_MAILBOX_UNAVAILABLE;
484
485 case 553:
486 return MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED;
487
488 case 503:
489 return MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND;
490
491 case 0:
492 return MAILSMTP_ERROR_STREAM;
493
494 default:
495 return MAILSMTP_ERROR_UNEXPECTED_CODE;
496 }
497}
498
499int mailesmtp_rcpt(mailsmtp * session,
500 const char * to,
501 int notify,
502 const char * orcpt)
503{
504 int r;
505 char command[SMTP_STRING_SIZE];
506 char notify_str[30] = "";
507 char notify_info_str[30] = "";
508
509 if (notify != 0 && session->esmtp & MAILSMTP_ESMTP_DSN) {
510 if (notify & MAILSMTP_DSN_NOTIFY_SUCCESS)
511 strcat(notify_info_str, ",SUCCESS");
512 if (notify & MAILSMTP_DSN_NOTIFY_FAILURE)
513 strcat(notify_info_str, ",FAILURE");
514 if (notify & MAILSMTP_DSN_NOTIFY_DELAY)
515 strcat(notify_info_str, ",DELAY");
516
517 if (notify & MAILSMTP_DSN_NOTIFY_NEVER)
518 strcpy(notify_info_str, ",NEVER");
519
520 notify_info_str[0] = '=';
521
522 strcpy(notify_str, " NOTIFY");
523 strcat(notify_str, notify_info_str);
524 }
525
526 if (orcpt && session->esmtp & MAILSMTP_ESMTP_DSN)
527 snprintf(command, SMTP_STRING_SIZE, "RCPT TO:<%s>%s ORCPT=%s\r\n",
528 to, notify_str, orcpt);
529 else
530 snprintf(command, SMTP_STRING_SIZE, "RCPT TO:<%s>%s\r\n", to, notify_str);
531
532 r = send_command(session, command);
533 if (r == -1)
534 return MAILSMTP_ERROR_STREAM;
535 r = read_response(session);
536
537 switch (r) {
538 case 250:
539 return MAILSMTP_NO_ERROR;
540
541 case 251: /* not local user, will be forwarded */
542 return MAILSMTP_NO_ERROR;
543
544 case 550:
545 case 450:
546 return MAILSMTP_ERROR_MAILBOX_UNAVAILABLE;
547
548 case 551:
549 return MAILSMTP_ERROR_USER_NOT_LOCAL;
550
551 case 552:
552 return MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION;
553
554 case 553:
555 return MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED;
556
557 case 451:
558 return MAILSMTP_ERROR_IN_PROCESSING;
559
560 case 452:
561 return MAILSMTP_ERROR_INSUFFICIENT_SYSTEM_STORAGE;
562
563 case 503:
564 return MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND;
565
566 case 0:
567 return MAILSMTP_ERROR_STREAM;
568
569 default:
570 return MAILSMTP_ERROR_UNEXPECTED_CODE;
571 }
572}
573
574int auth_map_errors(int err)
575{
576 switch (err) {
577 case 235:
578 return MAILSMTP_NO_ERROR; /* AUTH successfull */
579 case 334:
580 return MAILSMTP_NO_ERROR; /* AUTH in progress */
581 case 432:
582 return MAILSMTP_ERROR_AUTH_TRANSITION_NEEDED;
583 case 454:
584 return MAILSMTP_ERROR_AUTH_TEMPORARY_FAILTURE;
585 case 504:
586 return MAILSMTP_ERROR_AUTH_NOT_SUPPORTED;
587 case 530:
588 return MAILSMTP_ERROR_AUTH_REQUIRED;
589 case 534:
590 return MAILSMTP_ERROR_AUTH_TOO_WEAK;
591 case 538:
592 return MAILSMTP_ERROR_AUTH_ENCRYPTION_REQUIRED;
593 default:
594 /* opportunistic approach ;) */
595 return MAILSMTP_NO_ERROR;
596 }
597}
598
599static int mailsmtp_auth_login(mailsmtp * session,
600 const char * user, const char * pass)
601{
602 int err;
603 char command[SMTP_STRING_SIZE];
604 char * user64, * pass64;
605
606 user64 = NULL;
607 pass64 = NULL;
608
609 user64 = encode_base64(user, strlen(user));
610 if (user64 == NULL) {
611 err = MAILSMTP_ERROR_MEMORY;
612 goto err_free;
613 }
614
615 pass64 = encode_base64(pass, strlen(pass));
616 if (pass64 == NULL) {
617 err = MAILSMTP_ERROR_MEMORY;
618 goto err_free;
619 }
620
621 snprintf(command, SMTP_STRING_SIZE, "%s\r\n", user64);
622 err = send_command(session, command);
623 if (err == -1) {
624 err = MAILSMTP_ERROR_STREAM;
625 goto err_free;
626 }
627 err = read_response(session);
628 err = auth_map_errors(err);
629 if (err != MAILSMTP_NO_ERROR)
630 goto err_free;
631
632 snprintf(command, SMTP_STRING_SIZE, "%s\r\n", pass64);
633 err = send_command(session, command);
634 if (err == -1) {
635 err = MAILSMTP_ERROR_STREAM;
636 goto err_free;
637 }
638 err = read_response(session);
639 err = auth_map_errors(err);
640
641 err_free:
642 free(user64);
643 free(pass64);
644
645 return err;
646}
647
648static int mailsmtp_auth_plain(mailsmtp * session,
649 const char * user, const char * pass)
650{
651 int err, len;
652 char command[SMTP_STRING_SIZE];
653 char * plain, * plain64;
654
655 len = strlen(user) + strlen(pass) + 3;
656 plain = (char *) malloc(len);
657 if (plain == NULL) {
658 err = MAILSMTP_ERROR_MEMORY;
659 goto err;
660 }
661
662 snprintf(plain, len, "%c%s%c%s", '\0', user, '\0', pass);
663 plain64 = encode_base64(plain, len - 1);
664
665 snprintf(command, SMTP_STRING_SIZE, "%s\r\n", plain64);
666 err = send_command(session, command);
667 if (err == -1) {
668 err = MAILSMTP_ERROR_STREAM;
669 goto err_free;
670 }
671
672 err = read_response(session);
673 err = auth_map_errors(err);
674
675err_free:
676 free(plain64);
677 free(plain);
678
679 err:
680 return err;
681}
682
683static char * convert_hex(unsigned char *in, int len)
684{
685 static char hex[] = "0123456789abcdef";
686 char * out;
687 int i;
688
689 out = (char *) malloc(len * 2 + 1);
690 if (out == NULL)
691 return NULL;
692
693 for (i = 0; i < len; i++) {
694 out[i * 2] = hex[in[i] >> 4];
695 out[i * 2 + 1] = hex[in[i] & 15];
696 }
697
698 out[i*2] = 0;
699
700 return out;
701}
702
703static char * hash_md5(const char * sec_key, const char * data, int len)
704{
705 char key[65], digest[24];
706 char * hash_hex;
707
708 int sec_len, i;
709
710 sec_len = strlen(sec_key);
711
712 if (sec_len < 64) {
713 memcpy(key, sec_key, sec_len);
714 for (i = sec_len; i < 64; i++) {
715 key[i] = 0;
716 }
717 } else {
718 memcpy(key, sec_key, 64);
719 }
720
721 hmac_md5(data, len, key, 64, digest);
722 hash_hex = convert_hex(digest, 16);
723
724 return hash_hex;
725}
726
727static int mailsmtp_auth_cram_md5(mailsmtp * session,
728 const char * user, const char * pass)
729{
730 int err;
731 char command[SMTP_STRING_SIZE];
732 char *response, *auth_hex, *auth;
733
734 response = decode_base64(session->response, strlen(session->response));
735 if (response == NULL) return MAILSMTP_ERROR_MEMORY;
736
737 auth_hex = hash_md5(pass, response, strlen(response));
738 if (auth_hex == NULL) {
739 err = MAILSMTP_ERROR_MEMORY;
740 goto err_free_response;
741 }
742
743 snprintf(command, SMTP_STRING_SIZE, "%s %s", user, auth_hex);
744
745 auth = encode_base64(command, strlen(command));
746 if (auth == NULL) {
747 err = MAILSMTP_ERROR_MEMORY;
748 goto err_free_auth_hex;
749 }
750
751 snprintf(command, SMTP_STRING_SIZE, "%s\r\n", auth);
752 err = send_command(session, command);
753 if (err == -1) {
754 err = MAILSMTP_ERROR_STREAM;
755 goto err_free;
756 }
757
758 err = read_response(session);
759 err = auth_map_errors(err);
760
761err_free:
762 free(auth);
763err_free_auth_hex:
764 free(auth_hex);
765err_free_response:
766 free(response);
767 return err;
768}
769
770int mailsmtp_auth_type(mailsmtp * session,
771 const char * user, const char * pass, int type)
772{
773 int err;
774 char command[SMTP_STRING_SIZE];
775
776 if (session->auth == MAILSMTP_AUTH_NOT_CHECKED)
777 return MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND;
778
779 if ( !(session->auth & type) ) return MAILSMTP_ERROR_AUTH_NOT_SUPPORTED;
780
781 switch (type) {
782 case MAILSMTP_AUTH_LOGIN:
783 snprintf(command, SMTP_STRING_SIZE, "AUTH LOGIN\r\n");
784 break;
785 case MAILSMTP_AUTH_PLAIN:
786 snprintf(command, SMTP_STRING_SIZE, "AUTH PLAIN\r\n");
787 break;
788 case MAILSMTP_AUTH_CRAM_MD5:
789 snprintf(command, SMTP_STRING_SIZE, "AUTH CRAM-MD5\r\n");
790 break;
791 default:
792 return MAILSMTP_ERROR_NOT_IMPLEMENTED;
793 }
794
795 err = send_command(session, command);
796 if (err == -1) return MAILSMTP_ERROR_STREAM;
797
798 err = read_response(session);
799 err = auth_map_errors(err);
800 if (err != MAILSMTP_NO_ERROR) return err;
801
802 switch (type) {
803 case MAILSMTP_AUTH_LOGIN:
804 return mailsmtp_auth_login(session, user, pass);
805 case MAILSMTP_AUTH_PLAIN:
806 return mailsmtp_auth_plain(session, user, pass);
807 case MAILSMTP_AUTH_CRAM_MD5:
808 return mailsmtp_auth_cram_md5(session, user, pass);
809 default:
810 return MAILSMTP_ERROR_NOT_IMPLEMENTED;
811 }
812}
813
814
815int mailsmtp_auth(mailsmtp * session, const char * user, const char * pass)
816{
817 if (session->auth == MAILSMTP_AUTH_NOT_CHECKED)
818 return MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND;
819
820 if (session->auth & MAILSMTP_AUTH_CRAM_MD5) {
821 return mailsmtp_auth_type(session, user, pass, MAILSMTP_AUTH_CRAM_MD5);
822 } else if (session->auth & MAILSMTP_AUTH_PLAIN) {
823 return mailsmtp_auth_type(session, user, pass, MAILSMTP_AUTH_PLAIN);
824 } else if (session->auth & MAILSMTP_AUTH_LOGIN) {
825 return mailsmtp_auth_type(session, user, pass, MAILSMTP_AUTH_LOGIN);
826 } else {
827 return MAILSMTP_ERROR_AUTH_NOT_SUPPORTED;
828 }
829}
830
831/* TODO: add mailesmtp_etrn, mailssmtp_expn */
832
833int mailesmtp_starttls(mailsmtp * session) {
834 int r;
835
836 if (!(session->esmtp & MAILSMTP_ESMTP_STARTTLS))
837 return MAILSMTP_ERROR_STARTTLS_NOT_SUPPORTED;
838
839 r = send_command(session, "STARTTLS\r\n");
840 if (r == -1)
841 return MAILSMTP_ERROR_STREAM;
842 r = read_response(session);
843
844 switch (r) {
845 case 220:
846 return MAILSMTP_NO_ERROR;
847
848 case 454:
849 return MAILSMTP_ERROR_STARTTLS_TEMPORARY_FAILURE;
850
851 default:
852 return MAILSMTP_ERROR_UNEXPECTED_CODE;
853 }
854}
855
856static int parse_response(mailsmtp * session,
857 char * response)
858{
859 char * message;
860 int code;
861 int cont = 0;
862
863 code = strtol(response, &message, 10);
864 if (* message == ' ')
865 mmap_string_append(session->response_buffer, message + 1);
866 else if (* message == '-') {
867 cont = SMTP_STATUS_CONTINUE;
868 mmap_string_append(session->response_buffer, message + 1);
869 }
870 else
871 mmap_string_append(session->response_buffer, message);
872
873 return code | cont;
874}
875
876static char * read_line(mailsmtp * session)
877{
878 return mailstream_read_line_remove_eol(session->stream,
879 session->line_buffer);
880}
881
882static int read_response(mailsmtp * session)
883{
884 char * line;
885 int code;
886
887 mmap_string_assign(session->response_buffer, "");
888
889 do {
890 line = read_line(session);
891
892 if (line != NULL) {
893 code = parse_response(session, line);
894 mmap_string_append_c(session->response_buffer, '\n');
895 }
896 else
897 code = 0;
898 }
899 while ((code & SMTP_STATUS_CONTINUE) != 0);
900
901 session->response = session->response_buffer->str;
902
903 return code;
904}
905
906
907
908
909
910static int send_command(mailsmtp * f, char * command)
911{
912 ssize_t r;
913
914 r = mailstream_write(f->stream, command, strlen(command));
915 if (r == -1)
916 return -1;
917
918 r = mailstream_flush(f->stream);
919 if (r == -1)
920 return -1;
921
922 return 0;
923}
924
925static int send_data(mailsmtp * session, const char * message, size_t size)
926{
927 if (mailstream_send_data(session->stream, message, size,
928 session->progr_rate, session->progr_fun) == -1)
929 return -1;
930
931 if (mailstream_flush(session->stream) == -1)
932 return -1;
933
934 return 0;
935}
936
937
938const char * mailsmtp_strerror(int errnum)
939{
940 switch (errnum) {
941 case MAILSMTP_NO_ERROR:
942 return "No error";
943 case MAILSMTP_ERROR_UNEXPECTED_CODE:
944 return "Unexpected error code";
945 case MAILSMTP_ERROR_SERVICE_NOT_AVAILABLE:
946 return "Service not available";
947 case MAILSMTP_ERROR_STREAM:
948 return "Stream error";
949 case MAILSMTP_ERROR_HOSTNAME:
950 return "gethostname() failed";
951 case MAILSMTP_ERROR_NOT_IMPLEMENTED:
952 return "Not implemented";
953 case MAILSMTP_ERROR_ACTION_NOT_TAKEN:
954 return "Error, action not taken";
955 case MAILSMTP_ERROR_EXCEED_STORAGE_ALLOCATION:
956 return "Data exceeds storage allocation";
957 case MAILSMTP_ERROR_IN_PROCESSING:
958 return "Error in processing";
959 case MAILSMTP_ERROR_INSUFFICIENT_SYSTEM_STORAGE:
960 return "Insufficient system storage";
961 case MAILSMTP_ERROR_MAILBOX_UNAVAILABLE:
962 return "Mailbox unavailable";
963 case MAILSMTP_ERROR_MAILBOX_NAME_NOT_ALLOWED:
964 return "Mailbox name not allowed";
965 case MAILSMTP_ERROR_BAD_SEQUENCE_OF_COMMAND:
966 return "Bad command sequence";
967 case MAILSMTP_ERROR_USER_NOT_LOCAL:
968 return "User not local";
969 case MAILSMTP_ERROR_TRANSACTION_FAILED:
970 return "Transaction failed";
971 case MAILSMTP_ERROR_MEMORY:
972 return "Memory error";
973 case MAILSMTP_ERROR_CONNECTION_REFUSED:
974 return "Connection refused";
975 case MAILSMTP_ERROR_STARTTLS_TEMPORARY_FAILURE:
976 return "TLS not available on server for temporary reason";
977 case MAILSMTP_ERROR_STARTTLS_NOT_SUPPORTED:
978 return "TLS not supported by server";
979 default:
980 return "Unknown error code";
981 }
982}
diff --git a/kmicromail/libetpan/smtp/mailsmtp.h b/kmicromail/libetpan/smtp/mailsmtp.h
new file mode 100644
index 0000000..548a5b7
--- a/dev/null
+++ b/kmicromail/libetpan/smtp/mailsmtp.h
@@ -0,0 +1,94 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - 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 REGENTS 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 REGENTS 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
41extern "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
50mailsmtp * mailsmtp_new(size_t progr_rate,
51 progress_function * progr_fun);
52void mailsmtp_free(mailsmtp * session);
53
54int mailsmtp_connect(mailsmtp * session, mailstream * s);
55int mailsmtp_quit(mailsmtp * session);
56
57/**
58 * Tries AUTH with detected method - "better" method first:
59 * CRAM-MD5 -> PLAIN -> LOGIN
60 */
61int 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 */
67int mailsmtp_auth_type(mailsmtp * session,
68 const char * user, const char * pass, int type);
69
70int mailsmtp_helo(mailsmtp * session);
71int mailsmtp_mail(mailsmtp * session, const char * from);
72int mailsmtp_rcpt(mailsmtp * session, const char * to);
73int mailsmtp_data(mailsmtp * session);
74int mailsmtp_data_message(mailsmtp * session,
75 const char * message,
76 size_t size);
77int mailesmtp_ehlo(mailsmtp * session);
78int mailesmtp_mail(mailsmtp * session,
79 const char * from,
80 int return_full,
81 const char * envid);
82int mailesmtp_rcpt(mailsmtp * session,
83 const char * to,
84 int notify,
85 const char * orcpt);
86int mailesmtp_starttls(mailsmtp * session);
87
88const char * mailsmtp_strerror(int errnum);
89
90#ifdef __cplusplus
91}
92#endif
93
94#endif
diff --git a/kmicromail/libetpan/smtp/mailsmtp_helper.c b/kmicromail/libetpan/smtp/mailsmtp_helper.c
new file mode 100644
index 0000000..32d6564
--- a/dev/null
+++ b/kmicromail/libetpan/smtp/mailsmtp_helper.c
@@ -0,0 +1,232 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - 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 REGENTS 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 REGENTS 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
41int mailsmtp_init(mailsmtp * session)
42{
43 int r;
44 session->esmtp = 0;
45 r = mailesmtp_ehlo(session);
46
47 if (r == MAILSMTP_NO_ERROR) {
48 // session->esmtp = TRUE;
49 return MAILSMTP_NO_ERROR;
50 }
51
52 r = mailsmtp_helo(session);
53 /* if (r == MAILSMTP_NO_ERROR) { */
54/* session->esmtp = FALSE; */
55/* return MAILSMTP_NO_ERROR; */
56/* } */
57
58 return r;
59}
60
61
62
63int mailesmtp_send(mailsmtp * session,
64 const char * from,
65 int return_full,
66 const char * envid,
67 clist * addresses,
68 const char * message, size_t size)
69{
70 int r;
71 clistiter * l;
72
73 if (!session->esmtp)
74 return mailsmtp_send(session, from, addresses, message, size);
75
76 r = mailesmtp_mail(session, from, return_full, envid);
77 if (r != MAILSMTP_NO_ERROR)
78 return r;
79
80 for(l = clist_begin(addresses) ; l != NULL; l = clist_next(l)) {
81 struct esmtp_address * addr;
82
83 addr = clist_content(l);
84
85 r = mailesmtp_rcpt(session, addr->address, addr->notify, addr->orcpt);
86 if (r != MAILSMTP_NO_ERROR)
87 return r;
88 }
89
90 r = mailsmtp_data(session);
91 if (r != MAILSMTP_NO_ERROR)
92 return r;
93
94 r = mailsmtp_data_message(session, message, size);
95 if (r != MAILSMTP_NO_ERROR)
96 return r;
97
98 return MAILSMTP_NO_ERROR;
99}
100
101int mailsmtp_send(mailsmtp * session,
102 const char * from,
103 clist * addresses,
104 const char * message, size_t size)
105{
106 int r;
107 clistiter * l;
108
109 r = mailsmtp_mail(session, from);
110 if (r != MAILSMTP_NO_ERROR)
111 return r;
112
113 for(l = clist_begin(addresses) ; l != NULL; l = clist_next(l)) {
114 struct esmtp_address * addr;
115
116 addr = clist_content(l);
117
118 r = mailsmtp_rcpt(session, addr->address);
119 if (r != MAILSMTP_NO_ERROR)
120 return r;
121 }
122
123 r = mailsmtp_data(session);
124 if (r != MAILSMTP_NO_ERROR)
125 return r;
126
127 r = mailsmtp_data_message(session, message, size);
128 if (r != MAILSMTP_NO_ERROR)
129 return r;
130
131 return MAILSMTP_NO_ERROR;
132}
133
134
135
136
137
138
139
140
141
142
143
144
145
146/* esmtp addresses and smtp addresses */
147
148static struct esmtp_address * esmtp_address_new(char * addr,
149 int notify, char * orcpt)
150{
151 struct esmtp_address * esmtpa;
152
153 esmtpa = malloc(sizeof(* esmtpa));
154 if (esmtpa == NULL)
155 return NULL;
156
157 esmtpa->address = strdup(addr);
158 if (esmtpa->address == NULL) {
159 free(esmtpa);
160 return NULL;
161 }
162
163 if (orcpt != NULL) {
164 esmtpa->orcpt = strdup(orcpt);
165 if (esmtpa->orcpt == NULL) {
166 free(esmtpa->address);
167 free(esmtpa);
168 return NULL;
169 }
170 }
171 else
172 esmtpa->orcpt = NULL;
173
174 esmtpa->notify = notify;
175
176 return esmtpa;
177}
178
179static void esmtp_address_free(struct esmtp_address * addr)
180{
181 if (addr->orcpt)
182 free(addr->orcpt);
183 if (addr->address)
184 free(addr->address);
185
186 free(addr);
187}
188
189clist * esmtp_address_list_new()
190{
191 return clist_new();
192}
193
194void esmtp_address_list_free(clist * l)
195{
196 clist_foreach(l, (clist_func) esmtp_address_free, NULL);
197 clist_free(l);
198}
199
200int esmtp_address_list_add(clist * list, char * address,
201 int notify, char * orcpt)
202{
203 struct esmtp_address * esmtpa;
204 int r;
205
206 esmtpa = esmtp_address_new(address, notify, orcpt);
207 if (esmtpa == NULL)
208 return -1;
209
210 r = clist_append(list, esmtpa);
211 if (r < 0) {
212 esmtp_address_free(esmtpa);
213 return -1;
214 }
215
216 return 0;
217}
218
219clist * smtp_address_list_new()
220{
221 return esmtp_address_list_new();
222}
223
224int smtp_address_list_add(clist * list, char * address)
225{
226 return esmtp_address_list_add(list, address, 0, NULL);
227}
228
229void smtp_address_list_free(clist * l)
230{
231 esmtp_address_list_free(l);
232}
diff --git a/kmicromail/libetpan/smtp/mailsmtp_helper.h b/kmicromail/libetpan/smtp/mailsmtp_helper.h
new file mode 100644
index 0000000..6bbe3c9
--- a/dev/null
+++ b/kmicromail/libetpan/smtp/mailsmtp_helper.h
@@ -0,0 +1,74 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - 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 REGENTS 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 REGENTS 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
41extern "C" {
42#endif
43
44#include "mailsmtp_types.h"
45#include "clist.h"
46
47int mailsmtp_init(mailsmtp * session);
48
49int 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
56int mailsmtp_send(mailsmtp * session,
57 const char * from,
58 clist * addresses,
59 const char * message, size_t size);
60
61clist * esmtp_address_list_new();
62int esmtp_address_list_add(clist * list, char * address,
63 int notify, char * orcpt);
64void esmtp_address_list_free(clist * l);
65
66clist * smtp_address_list_new();
67int smtp_address_list_add(clist * list, char * address);
68void smtp_address_list_free(clist * l);
69
70#ifdef __cplusplus
71}
72#endif
73
74#endif
diff --git a/kmicromail/libetpan/smtp/mailsmtp_socket.c b/kmicromail/libetpan/smtp/mailsmtp_socket.c
new file mode 100644
index 0000000..b847bf2
--- a/dev/null
+++ b/kmicromail/libetpan/smtp/mailsmtp_socket.c
@@ -0,0 +1,99 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - 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 REGENTS 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 REGENTS 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
48int 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
76int 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/kmicromail/libetpan/smtp/mailsmtp_socket.h b/kmicromail/libetpan/smtp/mailsmtp_socket.h
new file mode 100644
index 0000000..6691d9e
--- a/dev/null
+++ b/kmicromail/libetpan/smtp/mailsmtp_socket.h
@@ -0,0 +1,56 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - 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 REGENTS 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 REGENTS 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
41extern "C" {
42#endif
43
44#include <inttypes.h>
45
46#include <libetpan/mailsmtp_types.h>
47
48int mailsmtp_socket_connect(mailsmtp * session,
49 const char * server, uint16_t port);
50int mailsmtp_socket_starttls(mailsmtp * session);
51
52#ifdef __cplusplus
53}
54#endif
55
56#endif
diff --git a/kmicromail/libetpan/smtp/mailsmtp_ssl.c b/kmicromail/libetpan/smtp/mailsmtp_ssl.c
new file mode 100644
index 0000000..eea31de
--- a/dev/null
+++ b/kmicromail/libetpan/smtp/mailsmtp_ssl.c
@@ -0,0 +1,74 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - 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 REGENTS 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 REGENTS 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
48int 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/kmicromail/libetpan/smtp/mailsmtp_ssl.h b/kmicromail/libetpan/smtp/mailsmtp_ssl.h
new file mode 100644
index 0000000..9de9732
--- a/dev/null
+++ b/kmicromail/libetpan/smtp/mailsmtp_ssl.h
@@ -0,0 +1,55 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - 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 REGENTS 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 REGENTS 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
41extern "C" {
42#endif
43
44#include <inttypes.h>
45
46#include <libetpan/mailsmtp_types.h>
47
48int 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/kmicromail/libetpan/smtp/mailsmtp_types.h b/kmicromail/libetpan/smtp/mailsmtp_types.h
new file mode 100644
index 0000000..b63d5ea
--- a/dev/null
+++ b/kmicromail/libetpan/smtp/mailsmtp_types.h
@@ -0,0 +1,126 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - 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 REGENTS 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 REGENTS 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
41extern "C" {
42#endif
43
44#include "mailstream.h"
45#include "mmapstring.h"
46
47enum {
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
76enum {
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
84enum {
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
94struct 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
109typedef 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
116struct esmtp_address {
117 char * address;
118 int notify;
119 char * orcpt;
120};
121
122#ifdef __cplusplus
123}
124#endif
125
126#endif