diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-06-30 13:30:21 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-06-30 13:30:21 +0000 |
commit | c94d3564c2b0584804fd4bab0a03f9160aa39720 (patch) | |
tree | c77f63cc4f0d406ebd0faee44cd508fa09482a0a | |
parent | bc2fd372272e4917909358473c07e19c1ce450cc (diff) | |
download | busybox-w32-c94d3564c2b0584804fd4bab0a03f9160aa39720.tar.gz busybox-w32-c94d3564c2b0584804fd4bab0a03f9160aa39720.tar.bz2 busybox-w32-c94d3564c2b0584804fd4bab0a03f9160aa39720.zip |
sendmail: from Vladimir:
Here comes the third part of compatibility patch for sendmail.
* Introduced new safe_getdomainname() -- will it be useful?
* Fixed SEGV if sender address is missed. Should snoop for sender address in mail headers?
* More compat: use HOSTNAME instead of HOST when no server is explicitly specified.
* crond: fixed mail recipient address.
function old new delta
safe_getdomainname - 56 +56
sendgetmail_main 1937 1946 +9
grep_file 846 850 +4
crond_main 1423 1425 +2
xstrtoull_range_sfx 295 296 +1
utoa_to_buf 110 108 -2
passwd_main 1053 1049 -4
sv_main 1234 1228 -6
parse_expr 841 833 -8
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 4/4 up/down: 72/-20) Total: 52 bytes
-rw-r--r-- | include/libbb.h | 1 | ||||
-rw-r--r-- | libbb/safe_gethostname.c | 15 | ||||
-rw-r--r-- | miscutils/crond.c | 2 | ||||
-rw-r--r-- | networking/sendmail.c | 53 |
4 files changed, 46 insertions, 25 deletions
diff --git a/include/libbb.h b/include/libbb.h index 7bc0dca2f..54601f87b 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -630,6 +630,7 @@ void qsort_string_vector(char **sv, unsigned count) FAST_FUNC; | |||
630 | int safe_poll(struct pollfd *ufds, nfds_t nfds, int timeout_ms) FAST_FUNC; | 630 | int safe_poll(struct pollfd *ufds, nfds_t nfds, int timeout_ms) FAST_FUNC; |
631 | 631 | ||
632 | char *safe_gethostname(void) FAST_FUNC; | 632 | char *safe_gethostname(void) FAST_FUNC; |
633 | char *safe_getdomainname(void) FAST_FUNC; | ||
633 | 634 | ||
634 | /* Convert each alpha char in str to lower-case */ | 635 | /* Convert each alpha char in str to lower-case */ |
635 | char* str_tolower(char *str) FAST_FUNC; | 636 | char* str_tolower(char *str) FAST_FUNC; |
diff --git a/libbb/safe_gethostname.c b/libbb/safe_gethostname.c index 1f8b2a8fd..7407fb782 100644 --- a/libbb/safe_gethostname.c +++ b/libbb/safe_gethostname.c | |||
@@ -48,6 +48,19 @@ char* FAST_FUNC safe_gethostname(void) | |||
48 | 48 | ||
49 | /* Uname can fail only if you pass a bad pointer to it. */ | 49 | /* Uname can fail only if you pass a bad pointer to it. */ |
50 | uname(&uts); | 50 | uname(&uts); |
51 | return xstrndup(!uts.nodename[0] ? "?" : uts.nodename, sizeof(uts.nodename)); | ||
52 | } | ||
51 | 53 | ||
52 | return xstrndup(!*(uts.nodename) ? "?" : uts.nodename, sizeof(uts.nodename)); | 54 | /* |
55 | * On success return the current malloced and NUL terminated domainname. | ||
56 | * On error return malloced and NUL terminated string "?". | ||
57 | * This is an illegal first character for a domainname. | ||
58 | * The returned malloced string must be freed by the caller. | ||
59 | */ | ||
60 | char* FAST_FUNC safe_getdomainname(void) | ||
61 | { | ||
62 | struct utsname uts; | ||
63 | |||
64 | uname(&uts); | ||
65 | return xstrndup(!uts.domainname[0] ? "?" : uts.domainname, sizeof(uts.domainname)); | ||
53 | } | 66 | } |
diff --git a/miscutils/crond.c b/miscutils/crond.c index 27f24dd85..51b09ece0 100644 --- a/miscutils/crond.c +++ b/miscutils/crond.c | |||
@@ -839,7 +839,7 @@ static void RunJob(const char *user, CronLine *line) | |||
839 | 839 | ||
840 | if (mailFd >= 0) { | 840 | if (mailFd >= 0) { |
841 | line->cl_MailFlag = 1; | 841 | line->cl_MailFlag = 1; |
842 | fdprintf(mailFd, "To: %s\nSubject: cron: %s\n\n", user, | 842 | fdprintf(mailFd, "To: %s\nSubject: cron: %s\n\n", line->cl_MailTo, |
843 | line->cl_Shell); | 843 | line->cl_Shell); |
844 | line->cl_MailPos = lseek(mailFd, 0, SEEK_CUR); | 844 | line->cl_MailPos = lseek(mailFd, 0, SEEK_CUR); |
845 | } else { | 845 | } else { |
diff --git a/networking/sendmail.c b/networking/sendmail.c index b81c8525f..1c23ca290 100644 --- a/networking/sendmail.c +++ b/networking/sendmail.c | |||
@@ -305,6 +305,7 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
305 | OPTS_i = 1 << 7, // sendmail: ignore lone dots in message body (implied) | 305 | OPTS_i = 1 << 7, // sendmail: ignore lone dots in message body (implied) |
306 | 306 | ||
307 | OPTS_N = 1 << 8, // sendmail: request notification | 307 | OPTS_N = 1 << 8, // sendmail: request notification |
308 | OPTS_f = 1 << 9, // sendmail: sender address | ||
308 | }; | 309 | }; |
309 | const char *options; | 310 | const char *options; |
310 | int opts; | 311 | int opts; |
@@ -317,7 +318,7 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
317 | // and is NOT NULL if we are called as sendmail | 318 | // and is NOT NULL if we are called as sendmail |
318 | if (!ENABLE_FETCHMAIL || 's' == applet_name[0]) { | 319 | if (!ENABLE_FETCHMAIL || 's' == applet_name[0]) { |
319 | // SENDMAIL | 320 | // SENDMAIL |
320 | // save initial stdin (body or attachements can be piped!) | 321 | // save initial stdin since body is piped! |
321 | xdup2(STDIN_FILENO, INITIAL_STDIN_FILENO); | 322 | xdup2(STDIN_FILENO, INITIAL_STDIN_FILENO); |
322 | opt_complementary = "w+:a::"; | 323 | opt_complementary = "w+:a::"; |
323 | options = "w:H:St" "s:c:a:iN:f:"; | 324 | options = "w:H:St" "s:c:a:iN:f:"; |
@@ -337,9 +338,9 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
337 | argv += optind; | 338 | argv += optind; |
338 | 339 | ||
339 | // connect to server | 340 | // connect to server |
340 | // host[:port] not specified ? -> use $HOST. no $HOST ? -> use localhost | 341 | // host[:port] not specified ? -> use $HOSTNAME. no $HOSTNAME ? -> use localhost |
341 | if (!(opts & OPT_H)) { | 342 | if (!(opts & OPT_H)) { |
342 | opt_connect = getenv("HOST"); | 343 | opt_connect = getenv("HOSTNAME"); |
343 | if (!opt_connect) | 344 | if (!opt_connect) |
344 | opt_connect = "127.0.0.1"; | 345 | opt_connect = "127.0.0.1"; |
345 | } | 346 | } |
@@ -349,6 +350,12 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
349 | opt_connect = parse_url((char*)opt_connect, &opt_user, &opt_pass); | 350 | opt_connect = parse_url((char*)opt_connect, &opt_user, &opt_pass); |
350 | // bb_error_msg("H[%s] U[%s] P[%s]", opt_connect, opt_user, opt_pass); | 351 | // bb_error_msg("H[%s] U[%s] P[%s]", opt_connect, opt_user, opt_pass); |
351 | 352 | ||
353 | // username must be defined! | ||
354 | if (!opt_user) { | ||
355 | // N.B. IMHO getenv("USER") can be way easily spoofed! | ||
356 | opt_user = bb_getpwuid(NULL, -1, getuid()); | ||
357 | } | ||
358 | |||
352 | // SSL ordered? -> | 359 | // SSL ordered? -> |
353 | if (opts & OPT_S) { | 360 | if (opts & OPT_S) { |
354 | // ... use openssl helper | 361 | // ... use openssl helper |
@@ -384,12 +391,6 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
384 | argv++; | 391 | argv++; |
385 | } | 392 | } |
386 | 393 | ||
387 | // we didn't use SSL helper? -> | ||
388 | if (!(opts & OPT_S)) { | ||
389 | // ... wait for initial server OK | ||
390 | smtp_check(NULL, 220); | ||
391 | } | ||
392 | |||
393 | // if -t specified or no recipients specified -> enter all-included mode | 394 | // if -t specified or no recipients specified -> enter all-included mode |
394 | // i.e. scan stdin for To: and Subject: lines ... | 395 | // i.e. scan stdin for To: and Subject: lines ... |
395 | // ... and then use the rest of stdin as message body | 396 | // ... and then use the rest of stdin as message body |
@@ -402,7 +403,10 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
402 | while ((s = xmalloc_reads(INITIAL_STDIN_FILENO, NULL, NULL)) != NULL) { | 403 | while ((s = xmalloc_reads(INITIAL_STDIN_FILENO, NULL, NULL)) != NULL) { |
403 | if (0 == strncmp("To: ", s, 4)) { | 404 | if (0 == strncmp("To: ", s, 4)) { |
404 | llist_add_to_end(&opt_recipients, s+4); | 405 | llist_add_to_end(&opt_recipients, s+4); |
405 | } else if (0 == strncmp("Subject: ", s, 9)) { | 406 | /* } else if (0 == strncmp("From: ", s, 6)) { |
407 | opt_from = s+6; | ||
408 | opts |= OPTS_f; | ||
409 | */ } else if (0 == strncmp("Subject: ", s, 9)) { | ||
406 | opt_subject = s+9; | 410 | opt_subject = s+9; |
407 | opts |= OPTS_s; | 411 | opts |= OPTS_s; |
408 | } else { | 412 | } else { |
@@ -414,7 +418,21 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
414 | } | 418 | } |
415 | } | 419 | } |
416 | 420 | ||
421 | // got no sender address? -> use username as a resort | ||
422 | if (!(opts & OPTS_f)) { | ||
423 | char *domain = safe_getdomainname(); | ||
424 | opt_from = xasprintf("%s@%s", opt_user, domain); | ||
425 | free(domain); | ||
426 | } | ||
427 | |||
417 | // introduce to server | 428 | // introduce to server |
429 | |||
430 | // we didn't use SSL helper? -> | ||
431 | if (!(opts & OPT_S)) { | ||
432 | // ... wait for initial server OK | ||
433 | smtp_check(NULL, 220); | ||
434 | } | ||
435 | |||
418 | // we should start with modern EHLO | 436 | // we should start with modern EHLO |
419 | if (250 != smtp_checkp("EHLO %s", sane(opt_from), -1)) { | 437 | if (250 != smtp_checkp("EHLO %s", sane(opt_from), -1)) { |
420 | smtp_checkp("HELO %s", opt_from, 250); | 438 | smtp_checkp("HELO %s", opt_from, 250); |
@@ -427,16 +445,8 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
427 | // first try softly without authentication | 445 | // first try softly without authentication |
428 | while (250 != smtp_checkp("MAIL FROM:<%s>", opt_from, code)) { | 446 | while (250 != smtp_checkp("MAIL FROM:<%s>", opt_from, code)) { |
429 | // MAIL FROM failed -> authentication needed | 447 | // MAIL FROM failed -> authentication needed |
430 | // have we got username? | ||
431 | if (!opt_user) { | ||
432 | // no! fetch it from "from" option | ||
433 | opt_user = xstrdup(opt_from); | ||
434 | *strchrnul(opt_user, '@') = '\0'; | ||
435 | } | ||
436 | // now we've got username | ||
437 | // so try to authenticate | ||
438 | if (334 == smtp_check("AUTH LOGIN", -1)) { | 448 | if (334 == smtp_check("AUTH LOGIN", -1)) { |
439 | uuencode(NULL, opt_user); | 449 | uuencode(NULL, opt_user); // opt_user != NULL |
440 | smtp_check("", 334); | 450 | smtp_check("", 334); |
441 | uuencode(NULL, opt_pass); | 451 | uuencode(NULL, opt_pass); |
442 | smtp_check("", 235); | 452 | smtp_check("", 235); |
@@ -552,10 +562,7 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
552 | *fargs = *argv; | 562 | *fargs = *argv; |
553 | 563 | ||
554 | // authenticate | 564 | // authenticate |
555 | if (!opt_user) { | 565 | |
556 | // N.B. IMHO getenv("USER") can be way easily spoofed! | ||
557 | opt_user = bb_getpwuid(NULL, -1, getuid()); | ||
558 | } | ||
559 | // password is mandatory | 566 | // password is mandatory |
560 | if (!opt_pass) { | 567 | if (!opt_pass) { |
561 | bb_error_msg_and_die("no password"); | 568 | bb_error_msg_and_die("no password"); |