aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-06-30 13:30:21 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-06-30 13:30:21 +0000
commitc94d3564c2b0584804fd4bab0a03f9160aa39720 (patch)
treec77f63cc4f0d406ebd0faee44cd508fa09482a0a
parentbc2fd372272e4917909358473c07e19c1ce450cc (diff)
downloadbusybox-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.h1
-rw-r--r--libbb/safe_gethostname.c15
-rw-r--r--miscutils/crond.c2
-rw-r--r--networking/sendmail.c53
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;
630int safe_poll(struct pollfd *ufds, nfds_t nfds, int timeout_ms) FAST_FUNC; 630int safe_poll(struct pollfd *ufds, nfds_t nfds, int timeout_ms) FAST_FUNC;
631 631
632char *safe_gethostname(void) FAST_FUNC; 632char *safe_gethostname(void) FAST_FUNC;
633char *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 */
635char* str_tolower(char *str) FAST_FUNC; 636char* 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 */
60char* 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");