diff options
author | Vladimir Dronnikov <dronnikov@gmail.com> | 2009-10-15 23:50:48 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-10-15 23:50:48 +0200 |
commit | 944d275175bd712d7a97241c762acc9e3bcd8a2a (patch) | |
tree | 8c60614d8c362e60b658bb516e686534773623cf /mailutils/sendmail.c | |
parent | f5a295d5a82297a5c13289c2e43256f20c172ddf (diff) | |
download | busybox-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.c | 53 |
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 | |||
12 | static int smtp_checkp(const char *fmt, const char *param, int code) | 16 | static 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 | ||
56 | static void rcptto(const char *s) | 60 | static 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 | ||
61 | int sendmail_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 67 | int 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 |