mirror of
https://github.com/sheumann/hush.git
synced 2024-09-12 00:55:11 +00:00
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
This commit is contained in:
parent
bc2fd37227
commit
c94d3564c2
@ -630,6 +630,7 @@ void qsort_string_vector(char **sv, unsigned count) FAST_FUNC;
|
|||||||
int safe_poll(struct pollfd *ufds, nfds_t nfds, int timeout_ms) FAST_FUNC;
|
int safe_poll(struct pollfd *ufds, nfds_t nfds, int timeout_ms) FAST_FUNC;
|
||||||
|
|
||||||
char *safe_gethostname(void) FAST_FUNC;
|
char *safe_gethostname(void) FAST_FUNC;
|
||||||
|
char *safe_getdomainname(void) FAST_FUNC;
|
||||||
|
|
||||||
/* Convert each alpha char in str to lower-case */
|
/* Convert each alpha char in str to lower-case */
|
||||||
char* str_tolower(char *str) FAST_FUNC;
|
char* str_tolower(char *str) FAST_FUNC;
|
||||||
|
@ -48,6 +48,19 @@ char* FAST_FUNC safe_gethostname(void)
|
|||||||
|
|
||||||
/* Uname can fail only if you pass a bad pointer to it. */
|
/* Uname can fail only if you pass a bad pointer to it. */
|
||||||
uname(&uts);
|
uname(&uts);
|
||||||
|
return xstrndup(!uts.nodename[0] ? "?" : uts.nodename, sizeof(uts.nodename));
|
||||||
return xstrndup(!*(uts.nodename) ? "?" : uts.nodename, sizeof(uts.nodename));
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On success return the current malloced and NUL terminated domainname.
|
||||||
|
* On error return malloced and NUL terminated string "?".
|
||||||
|
* This is an illegal first character for a domainname.
|
||||||
|
* The returned malloced string must be freed by the caller.
|
||||||
|
*/
|
||||||
|
char* FAST_FUNC safe_getdomainname(void)
|
||||||
|
{
|
||||||
|
struct utsname uts;
|
||||||
|
|
||||||
|
uname(&uts);
|
||||||
|
return xstrndup(!uts.domainname[0] ? "?" : uts.domainname, sizeof(uts.domainname));
|
||||||
}
|
}
|
||||||
|
@ -839,7 +839,7 @@ static void RunJob(const char *user, CronLine *line)
|
|||||||
|
|
||||||
if (mailFd >= 0) {
|
if (mailFd >= 0) {
|
||||||
line->cl_MailFlag = 1;
|
line->cl_MailFlag = 1;
|
||||||
fdprintf(mailFd, "To: %s\nSubject: cron: %s\n\n", user,
|
fdprintf(mailFd, "To: %s\nSubject: cron: %s\n\n", line->cl_MailTo,
|
||||||
line->cl_Shell);
|
line->cl_Shell);
|
||||||
line->cl_MailPos = lseek(mailFd, 0, SEEK_CUR);
|
line->cl_MailPos = lseek(mailFd, 0, SEEK_CUR);
|
||||||
} else {
|
} else {
|
||||||
|
@ -305,6 +305,7 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv)
|
|||||||
OPTS_i = 1 << 7, // sendmail: ignore lone dots in message body (implied)
|
OPTS_i = 1 << 7, // sendmail: ignore lone dots in message body (implied)
|
||||||
|
|
||||||
OPTS_N = 1 << 8, // sendmail: request notification
|
OPTS_N = 1 << 8, // sendmail: request notification
|
||||||
|
OPTS_f = 1 << 9, // sendmail: sender address
|
||||||
};
|
};
|
||||||
const char *options;
|
const char *options;
|
||||||
int opts;
|
int opts;
|
||||||
@ -317,7 +318,7 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv)
|
|||||||
// and is NOT NULL if we are called as sendmail
|
// and is NOT NULL if we are called as sendmail
|
||||||
if (!ENABLE_FETCHMAIL || 's' == applet_name[0]) {
|
if (!ENABLE_FETCHMAIL || 's' == applet_name[0]) {
|
||||||
// SENDMAIL
|
// SENDMAIL
|
||||||
// save initial stdin (body or attachements can be piped!)
|
// save initial stdin since body is piped!
|
||||||
xdup2(STDIN_FILENO, INITIAL_STDIN_FILENO);
|
xdup2(STDIN_FILENO, INITIAL_STDIN_FILENO);
|
||||||
opt_complementary = "w+:a::";
|
opt_complementary = "w+:a::";
|
||||||
options = "w:H:St" "s:c:a:iN:f:";
|
options = "w:H:St" "s:c:a:iN:f:";
|
||||||
@ -337,9 +338,9 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv)
|
|||||||
argv += optind;
|
argv += optind;
|
||||||
|
|
||||||
// connect to server
|
// connect to server
|
||||||
// host[:port] not specified ? -> use $HOST. no $HOST ? -> use localhost
|
// host[:port] not specified ? -> use $HOSTNAME. no $HOSTNAME ? -> use localhost
|
||||||
if (!(opts & OPT_H)) {
|
if (!(opts & OPT_H)) {
|
||||||
opt_connect = getenv("HOST");
|
opt_connect = getenv("HOSTNAME");
|
||||||
if (!opt_connect)
|
if (!opt_connect)
|
||||||
opt_connect = "127.0.0.1";
|
opt_connect = "127.0.0.1";
|
||||||
}
|
}
|
||||||
@ -349,6 +350,12 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv)
|
|||||||
opt_connect = parse_url((char*)opt_connect, &opt_user, &opt_pass);
|
opt_connect = parse_url((char*)opt_connect, &opt_user, &opt_pass);
|
||||||
// bb_error_msg("H[%s] U[%s] P[%s]", opt_connect, opt_user, opt_pass);
|
// bb_error_msg("H[%s] U[%s] P[%s]", opt_connect, opt_user, opt_pass);
|
||||||
|
|
||||||
|
// username must be defined!
|
||||||
|
if (!opt_user) {
|
||||||
|
// N.B. IMHO getenv("USER") can be way easily spoofed!
|
||||||
|
opt_user = bb_getpwuid(NULL, -1, getuid());
|
||||||
|
}
|
||||||
|
|
||||||
// SSL ordered? ->
|
// SSL ordered? ->
|
||||||
if (opts & OPT_S) {
|
if (opts & OPT_S) {
|
||||||
// ... use openssl helper
|
// ... use openssl helper
|
||||||
@ -384,12 +391,6 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv)
|
|||||||
argv++;
|
argv++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we didn't use SSL helper? ->
|
|
||||||
if (!(opts & OPT_S)) {
|
|
||||||
// ... wait for initial server OK
|
|
||||||
smtp_check(NULL, 220);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if -t specified or no recipients specified -> enter all-included mode
|
// if -t specified or no recipients specified -> enter all-included mode
|
||||||
// i.e. scan stdin for To: and Subject: lines ...
|
// i.e. scan stdin for To: and Subject: lines ...
|
||||||
// ... and then use the rest of stdin as message body
|
// ... and then use the rest of stdin as message body
|
||||||
@ -402,7 +403,10 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv)
|
|||||||
while ((s = xmalloc_reads(INITIAL_STDIN_FILENO, NULL, NULL)) != NULL) {
|
while ((s = xmalloc_reads(INITIAL_STDIN_FILENO, NULL, NULL)) != NULL) {
|
||||||
if (0 == strncmp("To: ", s, 4)) {
|
if (0 == strncmp("To: ", s, 4)) {
|
||||||
llist_add_to_end(&opt_recipients, s+4);
|
llist_add_to_end(&opt_recipients, s+4);
|
||||||
} else if (0 == strncmp("Subject: ", s, 9)) {
|
/* } else if (0 == strncmp("From: ", s, 6)) {
|
||||||
|
opt_from = s+6;
|
||||||
|
opts |= OPTS_f;
|
||||||
|
*/ } else if (0 == strncmp("Subject: ", s, 9)) {
|
||||||
opt_subject = s+9;
|
opt_subject = s+9;
|
||||||
opts |= OPTS_s;
|
opts |= OPTS_s;
|
||||||
} else {
|
} else {
|
||||||
@ -414,7 +418,21 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// got no sender address? -> use username as a resort
|
||||||
|
if (!(opts & OPTS_f)) {
|
||||||
|
char *domain = safe_getdomainname();
|
||||||
|
opt_from = xasprintf("%s@%s", opt_user, domain);
|
||||||
|
free(domain);
|
||||||
|
}
|
||||||
|
|
||||||
// introduce to server
|
// introduce to server
|
||||||
|
|
||||||
|
// we didn't use SSL helper? ->
|
||||||
|
if (!(opts & OPT_S)) {
|
||||||
|
// ... wait for initial server OK
|
||||||
|
smtp_check(NULL, 220);
|
||||||
|
}
|
||||||
|
|
||||||
// we should start with modern EHLO
|
// we should start with modern EHLO
|
||||||
if (250 != smtp_checkp("EHLO %s", sane(opt_from), -1)) {
|
if (250 != smtp_checkp("EHLO %s", sane(opt_from), -1)) {
|
||||||
smtp_checkp("HELO %s", opt_from, 250);
|
smtp_checkp("HELO %s", opt_from, 250);
|
||||||
@ -427,16 +445,8 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv)
|
|||||||
// first try softly without authentication
|
// first try softly without authentication
|
||||||
while (250 != smtp_checkp("MAIL FROM:<%s>", opt_from, code)) {
|
while (250 != smtp_checkp("MAIL FROM:<%s>", opt_from, code)) {
|
||||||
// MAIL FROM failed -> authentication needed
|
// MAIL FROM failed -> authentication needed
|
||||||
// have we got username?
|
|
||||||
if (!opt_user) {
|
|
||||||
// no! fetch it from "from" option
|
|
||||||
opt_user = xstrdup(opt_from);
|
|
||||||
*strchrnul(opt_user, '@') = '\0';
|
|
||||||
}
|
|
||||||
// now we've got username
|
|
||||||
// so try to authenticate
|
|
||||||
if (334 == smtp_check("AUTH LOGIN", -1)) {
|
if (334 == smtp_check("AUTH LOGIN", -1)) {
|
||||||
uuencode(NULL, opt_user);
|
uuencode(NULL, opt_user); // opt_user != NULL
|
||||||
smtp_check("", 334);
|
smtp_check("", 334);
|
||||||
uuencode(NULL, opt_pass);
|
uuencode(NULL, opt_pass);
|
||||||
smtp_check("", 235);
|
smtp_check("", 235);
|
||||||
@ -552,10 +562,7 @@ int sendgetmail_main(int argc ATTRIBUTE_UNUSED, char **argv)
|
|||||||
*fargs = *argv;
|
*fargs = *argv;
|
||||||
|
|
||||||
// authenticate
|
// authenticate
|
||||||
if (!opt_user) {
|
|
||||||
// N.B. IMHO getenv("USER") can be way easily spoofed!
|
|
||||||
opt_user = bb_getpwuid(NULL, -1, getuid());
|
|
||||||
}
|
|
||||||
// password is mandatory
|
// password is mandatory
|
||||||
if (!opt_pass) {
|
if (!opt_pass) {
|
||||||
bb_error_msg_and_die("no password");
|
bb_error_msg_and_die("no password");
|
||||||
|
Loading…
Reference in New Issue
Block a user