aboutsummaryrefslogtreecommitdiff
path: root/mailutils/sendmail.c
diff options
context:
space:
mode:
authorVladimir Dronnikov <dronnikov@gmail.com>2009-10-15 23:50:48 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2009-10-15 23:50:48 +0200
commit944d275175bd712d7a97241c762acc9e3bcd8a2a (patch)
tree8c60614d8c362e60b658bb516e686534773623cf /mailutils/sendmail.c
parentf5a295d5a82297a5c13289c2e43256f20c172ddf (diff)
downloadbusybox-w32-944d275175bd712d7a97241c762acc9e3bcd8a2a.tar.gz
busybox-w32-944d275175bd712d7a97241c762acc9e3bcd8a2a.tar.bz2
busybox-w32-944d275175bd712d7a97241c762acc9e3bcd8a2a.zip
sendmail: update by Vladimir
function old new delta sendmail_main 897 939 +42 rcptto 17 40 +23 Signed-off-by: Vladimir Dronnikov <dronnikov@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'mailutils/sendmail.c')
-rw-r--r--mailutils/sendmail.c53
1 files changed, 41 insertions, 12 deletions
diff --git a/mailutils/sendmail.c b/mailutils/sendmail.c
index 014b20dc8..a216d66c1 100644
--- a/mailutils/sendmail.c
+++ b/mailutils/sendmail.c
@@ -9,6 +9,10 @@
9#include "libbb.h" 9#include "libbb.h"
10#include "mail.h" 10#include "mail.h"
11 11
12// limit maximum allowed number of headers to prevent overflows.
13// set to 0 to not limit
14#define MAX_HEADERS 256
15
12static int smtp_checkp(const char *fmt, const char *param, int code) 16static int smtp_checkp(const char *fmt, const char *param, int code)
13{ 17{
14 char *answer; 18 char *answer;
@@ -55,7 +59,9 @@ static char *sane_address(char *str)
55 59
56static void rcptto(const char *s) 60static void rcptto(const char *s)
57{ 61{
58 smtp_checkp("RCPT TO:<%s>", s, 250); 62 // N.B. we don't die if recipient is rejected, for the other recipients may be accepted
63 if (250 != smtp_checkp("RCPT TO:<%s>", s, -1))
64 bb_error_msg("Bad recipient: <%s>", s);
59} 65}
60 66
61int sendmail_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 67int sendmail_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
@@ -66,6 +72,7 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv)
66 char *s; 72 char *s;
67 llist_t *list = NULL; 73 llist_t *list = NULL;
68 char *domain = sane_address(safe_getdomainname()); 74 char *domain = sane_address(safe_getdomainname());
75 unsigned nheaders = 0;
69 int code; 76 int code;
70 77
71 enum { 78 enum {
@@ -197,6 +204,7 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv)
197 // and then use the rest of stdin as message body 204 // and then use the rest of stdin as message body
198 code = 0; // set "analyze headers" mode 205 code = 0; // set "analyze headers" mode
199 while ((s = xmalloc_fgetline(G.fp0)) != NULL) { 206 while ((s = xmalloc_fgetline(G.fp0)) != NULL) {
207 dump:
200 // put message lines doubling leading dots 208 // put message lines doubling leading dots
201 if (code) { 209 if (code) {
202 // escape leading dots 210 // escape leading dots
@@ -215,41 +223,62 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv)
215 // To: or Cc: headers add recipients 223 // To: or Cc: headers add recipients
216 if (0 == strncasecmp("To: ", s, 4) || 0 == strncasecmp("Bcc: " + 1, s, 4)) { 224 if (0 == strncasecmp("To: ", s, 4) || 0 == strncasecmp("Bcc: " + 1, s, 4)) {
217 rcptto(sane_address(s+4)); 225 rcptto(sane_address(s+4));
218// goto addh; 226 goto addheader;
219 llist_add_to_end(&list, s);
220 // Bcc: header adds blind copy (hidden) recipient 227 // Bcc: header adds blind copy (hidden) recipient
221 } else if (0 == strncasecmp("Bcc: ", s, 5)) { 228 } else if (0 == strncasecmp("Bcc: ", s, 5)) {
222 rcptto(sane_address(s+5)); 229 rcptto(sane_address(s+5));
223 free(s); 230 free(s);
224 // N.B. Bcc: vanishes from headers! 231 // N.B. Bcc: vanishes from headers!
225 // other headers go verbatim 232 // other headers go verbatim
226 } else if (s[0]) { 233 // N.B. we allow MAX_HEADERS generic headers at most to prevent attacks
227// addh: 234 } else if (strchr(s, ':')) {
235 addheader:
236 if (MAX_HEADERS && ++nheaders >= MAX_HEADERS)
237 goto bail;
228 llist_add_to_end(&list, s); 238 llist_add_to_end(&list, s);
229 // the empty line stops analyzing headers 239 // a line without ":" (an empty line too, by definition) doesn't look like a valid header
240 // so stop "analyze headers" mode
230 } else { 241 } else {
231 free(s); 242 reenter:
232 // put recipients specified on cmdline 243 // put recipients specified on cmdline
233 while (*argv) { 244 while (*argv) {
234 s = sane_address(*argv); 245 char *t = sane_address(*argv);
235 rcptto(s); 246 rcptto(t);
236 llist_add_to_end(&list, xasprintf("To: %s", s)); 247 //if (MAX_HEADERS && ++nheaders >= MAX_HEADERS)
248 // goto bail;
249 llist_add_to_end(&list, xasprintf("To: %s", t));
237 argv++; 250 argv++;
238 } 251 }
239 // enter "put message" mode 252 // enter "put message" mode
240 smtp_check("DATA", 354); 253 // N.B. DATA fails iff no recipients were accepted (or even provided)
254 // in this case just bail out gracefully
255 if (354 != smtp_check("DATA", -1))
256 goto bail;
241 // dump the headers 257 // dump the headers
242 while (list) { 258 while (list) {
243 printf("%s\r\n", (char *) llist_pop(&list)); 259 printf("%s\r\n", (char *) llist_pop(&list));
244 } 260 }
245 printf("%s\r\n" + 2); // quirk for format string to be reused
246 // stop analyzing headers 261 // stop analyzing headers
247 code++; 262 code++;
263 // N.B. !s means: we read nothing, and nothing to be read in the future.
264 // just dump empty line and break the loop
265 if (!s) {
266 puts("\r");
267 break;
268 }
269 // go dump message body
270 // N.B. "s" already contains the first non-header line, so pretend we read it from input
271 goto dump;
248 } 272 }
249 } 273 }
274 // odd case: we didn't stop "analyze headers" mode -> message body is empty. Reenter the loop
275 // N.B. after reenter code will be > 0
276 if (!code)
277 goto reenter;
250 278
251 // finalize the message 279 // finalize the message
252 smtp_check(".", 250); 280 smtp_check(".", 250);
281 bail:
253 // ... and say goodbye 282 // ... and say goodbye
254 smtp_check("QUIT", 221); 283 smtp_check("QUIT", 221);
255 // cleanup 284 // cleanup