diff --git a/src/config/global-config.c b/src/config/global-config.c index 8ee6b2ade..83634264b 100644 --- a/src/config/global-config.c +++ b/src/config/global-config.c @@ -441,10 +441,14 @@ int Read_Global(XML_NODE node, void *configp, void *mailp) } else if (strcmp(node[i]->element, xml_smtpserver) == 0) { #ifndef WIN32 if (Mail && (Mail->mn)) { - Mail->smtpserver = OS_GetHost(node[i]->content, 5); - if (!Mail->smtpserver) { - merror(INVALID_SMTP, __local_name, node[i]->content); - return (OS_INVALID); + if (node[i]->content[0] == '/') { + os_strdup(node[i]->content, Mail->smtpserver); + } else { + Mail->smtpserver = OS_GetHost(node[i]->content, 5); + if (!Mail->smtpserver) { + merror(INVALID_SMTP, __local_name, node[i]->content); + return (OS_INVALID); + } } } #endif diff --git a/src/os_maild/maild.c b/src/os_maild/maild.c index b7529aee7..ef4143319 100644 --- a/src/os_maild/maild.c +++ b/src/os_maild/maild.c @@ -160,18 +160,20 @@ int main(int argc, char **argv) ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno)); } - /* chroot */ - if (Privsep_Chroot(dir) < 0) { - ErrorExit(CHROOT_ERROR, ARGV0, dir, errno, strerror(errno)); + if (mail.smtpserver[0] != '/') { + /* chroot */ + if (Privsep_Chroot(dir) < 0) { + ErrorExit(CHROOT_ERROR, ARGV0, dir, errno, strerror(errno)); + } + nowChroot(); + debug1(CHROOT_MSG, ARGV0, dir); } - nowChroot(); /* Change user */ if (Privsep_SetUser(uid) < 0) { ErrorExit(SETUID_ERROR, ARGV0, user, errno, strerror(errno)); } - debug1(CHROOT_MSG, ARGV0, dir); debug1(PRIVSEP_MSG, ARGV0, user); /* Signal manipulation */ diff --git a/src/os_maild/sendcustomemail.c b/src/os_maild/sendcustomemail.c index 363c8e019..a7851ae6b 100644 --- a/src/os_maild/sendcustomemail.c +++ b/src/os_maild/sendcustomemail.c @@ -47,93 +47,83 @@ int OS_SendCustomEmail(char **to, char *subject, char *smtpserver, char *from, char *idsname, FILE *fp, const struct tm *p) { - int socket, i = 0; + FILE *sendmail = NULL; + int socket = -1, i = 0; char *msg; char snd_msg[128]; char buffer[2049]; buffer[2048] = '\0'; - /* Connect to the SMTP server */ - socket = OS_ConnectTCP(SMTP_DEFAULT_PORT, smtpserver, 0, NULL); - if (socket < 0) { - return (socket); - } - - /* Receive the banner */ - msg = OS_RecvTCP(socket, OS_SIZE_1024); - if ((msg == NULL) || (!OS_Match(VALIDBANNER, msg))) { - merror(BANNER_ERROR); - if (msg) { - free(msg); + if (smtpserver[0] == '/') { + sendmail = popen(smtpserver, "w"); + if (!sendmail) { + return (OS_INVALID); + } + } else { + /* Connect to the SMTP server */ + socket = OS_ConnectTCP(SMTP_DEFAULT_PORT, smtpserver, 0, NULL); + if (socket < 0) { + return (socket); } - close(socket); - return (OS_INVALID); - } - MAIL_DEBUG("DEBUG: Received banner: '%s' %s", msg, ""); - free(msg); - /* Send HELO message */ - OS_SendTCP(socket, HELOMSG); - msg = OS_RecvTCP(socket, OS_SIZE_1024); - if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { - if (msg) { - /* In some cases (with virus scans in the middle) - * we may get two banners. Check for that in here. - */ - if (OS_Match(VALIDBANNER, msg)) { + /* Receive the banner */ + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDBANNER, msg))) { + merror(BANNER_ERROR); + if (msg) { free(msg); + } + close(socket); + return (OS_INVALID); + } + MAIL_DEBUG("DEBUG: Received banner: '%s' %s", msg, ""); + free(msg); - /* Try again */ - msg = OS_RecvTCP(socket, OS_SIZE_1024); - if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { - merror("%s:%s", HELO_ERROR, msg != NULL ? msg : "null"); - if (msg) { - free(msg); + /* Send HELO message */ + OS_SendTCP(socket, HELOMSG); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { + if (msg) { + /* In some cases (with virus scans in the middle) + * we may get two banners. Check for that in here. + */ + if (OS_Match(VALIDBANNER, msg)) { + free(msg); + + /* Try again */ + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { + merror("%s:%s", HELO_ERROR, msg != NULL ? msg : "null"); + if (msg) { + free(msg); + } + close(socket); + return (OS_INVALID); } + } else { + merror("%s:%s", HELO_ERROR, msg); + free(msg); close(socket); return (OS_INVALID); } } else { - merror("%s:%s", HELO_ERROR, msg); - free(msg); + merror("%s:%s", HELO_ERROR, "null"); close(socket); return (OS_INVALID); } - } else { - merror("%s:%s", HELO_ERROR, "null"); - close(socket); - return (OS_INVALID); } - } - - MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", HELOMSG, msg); - free(msg); - /* Build "Mail from" msg */ - memset(snd_msg, '\0', 128); - snprintf(snd_msg, 127, MAILFROM, from); - OS_SendTCP(socket, snd_msg); - msg = OS_RecvTCP(socket, OS_SIZE_1024); - if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { - merror(FROM_ERROR); - if (msg) { - free(msg); - } - close(socket); - return (OS_INVALID); - } - MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); - free(msg); + MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", HELOMSG, msg); + free(msg); - /* Build "RCPT TO" msg */ - while (to[i]) { + /* Build "Mail from" msg */ memset(snd_msg, '\0', 128); - snprintf(snd_msg, 127, RCPTTO, to[i]); + snprintf(snd_msg, 127, MAILFROM, from); OS_SendTCP(socket, snd_msg); msg = OS_RecvTCP(socket, OS_SIZE_1024); if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { - merror(TO_ERROR, to[i]); + merror(FROM_ERROR); if (msg) { free(msg); } @@ -143,31 +133,59 @@ int OS_SendCustomEmail(char **to, char *subject, char *smtpserver, char *from, c MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); free(msg); - i++; - } - - /* Send the "DATA" msg */ - OS_SendTCP(socket, DATAMSG); - msg = OS_RecvTCP(socket, OS_SIZE_1024); - if ((msg == NULL) || (!OS_Match(VALIDDATA, msg))) { - merror(DATA_ERROR); - if (msg) { + /* Build "RCPT TO" msg */ + while (to[i]) { + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, RCPTTO, to[i]); + OS_SendTCP(socket, snd_msg); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { + merror(TO_ERROR, to[i]); + if (msg) { + free(msg); + } + close(socket); + return (OS_INVALID); + } + MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); free(msg); + + i++; } - close(socket); - return (OS_INVALID); + + /* Send the "DATA" msg */ + OS_SendTCP(socket, DATAMSG); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDDATA, msg))) { + merror(DATA_ERROR); + if (msg) { + free(msg); + } + close(socket); + return (OS_INVALID); + } + MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", DATAMSG, msg); + free(msg); } - MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", DATAMSG, msg); - free(msg); /* Build "From" and "To" in the e-mail header */ memset(snd_msg, '\0', 128); snprintf(snd_msg, 127, TO, to[0]); - OS_SendTCP(socket, snd_msg); + + if (sendmail) { + fprintf(sendmail, snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } memset(snd_msg, '\0', 128); snprintf(snd_msg, 127, FROM, from); - OS_SendTCP(socket, snd_msg); + + if (sendmail) { + fprintf(sendmail, snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } /* Add CCs */ if (to[1]) { @@ -179,7 +197,12 @@ int OS_SendCustomEmail(char **to, char *subject, char *smtpserver, char *from, c memset(snd_msg, '\0', 128); snprintf(snd_msg, 127, TO, to[i]); - OS_SendTCP(socket, snd_msg); + + if (sendmail) { + fprintf(sendmail, snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } i++; } @@ -195,47 +218,70 @@ int OS_SendCustomEmail(char **to, char *subject, char *smtpserver, char *from, c strftime(snd_msg, 127, "Date: %a, %d %b %Y %T %z\r\n", p); #endif - OS_SendTCP(socket, snd_msg); + if (sendmail) { + fprintf(sendmail, snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } if (idsname) { /* Send server name header */ memset(snd_msg, '\0', 128); snprintf(snd_msg, 127, XHEADER, idsname); - OS_SendTCP(socket, snd_msg); + + if (sendmail) { + fprintf(sendmail, snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } } /* Send subject */ memset(snd_msg, '\0', 128); snprintf(snd_msg, 127, SUBJECT, subject); - OS_SendTCP(socket, snd_msg); - OS_SendTCP(socket, ENDHEADER); + + if (sendmail) { + fprintf(sendmail, snd_msg); + fprintf(sendmail, ENDHEADER); + } else { + OS_SendTCP(socket, snd_msg); + OS_SendTCP(socket, ENDHEADER); + } /* Send body */ fseek(fp, 0, SEEK_SET); while (fgets(buffer, 2048, fp) != NULL) { - OS_SendTCP(socket, buffer); + if (sendmail) { + fprintf(sendmail, buffer); + } else { + OS_SendTCP(socket, buffer); + } } - /* Send end of data \r\n.\r\n */ - OS_SendTCP(socket, ENDDATA); - msg = OS_RecvTCP(socket, OS_SIZE_1024); + if (sendmail) { + fclose(sendmail); + } else { + /* Send end of data \r\n.\r\n */ + OS_SendTCP(socket, ENDDATA); + msg = OS_RecvTCP(socket, OS_SIZE_1024); - /* Check msg, since it may be null */ - if (msg) { - free(msg); - } + /* Check msg, since it may be null */ + if (msg) { + free(msg); + } - /* Quit and close socket */ - OS_SendTCP(socket, QUITMSG); - msg = OS_RecvTCP(socket, OS_SIZE_1024); + /* Quit and close socket */ + OS_SendTCP(socket, QUITMSG); + msg = OS_RecvTCP(socket, OS_SIZE_1024); - if (msg) { - free(msg); + if (msg) { + free(msg); + } + + close(socket); } memset_secure(snd_msg, '\0', 128); - close(socket); - return (0); } diff --git a/src/os_maild/sendmail.c b/src/os_maild/sendmail.c index e819c7731..510ecd960 100644 --- a/src/os_maild/sendmail.c +++ b/src/os_maild/sendmail.c @@ -48,148 +48,161 @@ int OS_Sendsms(MailConfig *mail, struct tm *p, MailMsg *sms_msg) { - int socket; + FILE *sendmail = NULL; + int socket = -1; size_t final_to_sz; char *msg; char snd_msg[128]; char final_to[512]; - /* Connect to the SMTP server */ - socket = OS_ConnectTCP(SMTP_DEFAULT_PORT, mail->smtpserver, 0, NULL); - if (socket < 0) { - return (socket); - } - - /* Receive the banner */ - msg = OS_RecvTCP(socket, OS_SIZE_1024); - if ((msg == NULL) || (!OS_Match(VALIDBANNER, msg))) { - merror(BANNER_ERROR); - if (msg) { - free(msg); + if (mail->smtpserver[0] == '/') { + sendmail = popen(mail->smtpserver, "w"); + if (!sendmail) { + return (OS_INVALID); } - close(socket); - return (OS_INVALID); - } - MAIL_DEBUG("DEBUG: Received banner: '%s' %s", msg, ""); - free(msg); - - /* Send HELO message */ - memset(snd_msg, '\0', 128); - if (mail->heloserver) { - snprintf(snd_msg, 127, "Helo %s\r\n", mail->heloserver); } else { - snprintf(snd_msg, 127, "Helo %s\r\n", "notify.ossec.net"); - } - OS_SendTCP(socket, snd_msg); - msg = OS_RecvTCP(socket, OS_SIZE_1024); - if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { - if (msg) { - /* In some cases (with virus scans in the middle) - * we may get two banners. Check for that in here. - */ - if (OS_Match(VALIDBANNER, msg)) { + /* Connect to the SMTP server */ + socket = OS_ConnectTCP(SMTP_DEFAULT_PORT, mail->smtpserver, 0, NULL); + if (socket < 0) { + return (socket); + } + + /* Receive the banner */ + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDBANNER, msg))) { + merror(BANNER_ERROR); + if (msg) { free(msg); + } + close(socket); + return (OS_INVALID); + } + MAIL_DEBUG("DEBUG: Received banner: '%s' %s", msg, ""); + free(msg); - /* Try again */ - msg = OS_RecvTCP(socket, OS_SIZE_1024); - if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { - merror("%s:%s", HELO_ERROR, msg != NULL ? msg : "null"); - if (msg) { - free(msg); + /* Send HELO message */ + memset(snd_msg, '\0', 128); + if (mail->heloserver) { + snprintf(snd_msg, 127, "Helo %s\r\n", mail->heloserver); + } else { + snprintf(snd_msg, 127, "Helo %s\r\n", "notify.ossec.net"); + } + OS_SendTCP(socket, snd_msg); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { + if (msg) { + /* In some cases (with virus scans in the middle) + * we may get two banners. Check for that in here. + */ + if (OS_Match(VALIDBANNER, msg)) { + free(msg); + + /* Try again */ + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { + merror("%s:%s", HELO_ERROR, msg != NULL ? msg : "null"); + if (msg) { + free(msg); + } + close(socket); + return (OS_INVALID); } + } else { + merror("%s:%s", HELO_ERROR, msg); + free(msg); close(socket); return (OS_INVALID); } } else { - merror("%s:%s", HELO_ERROR, msg); - free(msg); + merror("%s:%s", HELO_ERROR, "null"); close(socket); return (OS_INVALID); } - } else { - merror("%s:%s", HELO_ERROR, "null"); + } + + MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); + free(msg); + + /* Build "Mail from" msg */ + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, MAILFROM, mail->from); + OS_SendTCP(socket, snd_msg); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { + merror(FROM_ERROR); + if (msg) { + free(msg); + } close(socket); return (OS_INVALID); } - } + MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); + free(msg); - MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); - free(msg); + /* Additional RCPT to */ + final_to[0] = '\0'; + final_to_sz = sizeof(final_to) - 2; - /* Build "Mail from" msg */ - memset(snd_msg, '\0', 128); - snprintf(snd_msg, 127, MAILFROM, mail->from); - OS_SendTCP(socket, snd_msg); - msg = OS_RecvTCP(socket, OS_SIZE_1024); - if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { - merror(FROM_ERROR); - if (msg) { - free(msg); - } - close(socket); - return (OS_INVALID); - } - MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); - free(msg); + if (mail->gran_to) { + int i = 0; + while (mail->gran_to[i] != NULL) { + if (mail->gran_set[i] != SMS_FORMAT) { + i++; + continue; + } + + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, RCPTTO, mail->gran_to[i]); + OS_SendTCP(socket, snd_msg); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { + merror(TO_ERROR, mail->gran_to[i]); + if (msg) { + free(msg); + } + close(socket); + return (OS_INVALID); + } + MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); + free(msg); - /* Additional RCPT to */ - final_to[0] = '\0'; - final_to_sz = sizeof(final_to) - 2; + /* Create header for to */ + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, TO, mail->gran_to[i]); + strncat(final_to, snd_msg, final_to_sz); + final_to_sz -= strlen(snd_msg) + 2; - if (mail->gran_to) { - int i = 0; - while (mail->gran_to[i] != NULL) { - if (mail->gran_set[i] != SMS_FORMAT) { i++; continue; } + } - memset(snd_msg, '\0', 128); - snprintf(snd_msg, 127, RCPTTO, mail->gran_to[i]); - OS_SendTCP(socket, snd_msg); - msg = OS_RecvTCP(socket, OS_SIZE_1024); - if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { - merror(TO_ERROR, mail->gran_to[i]); - if (msg) { - free(msg); - } - close(socket); - return (OS_INVALID); + /* Send the "DATA" msg */ + OS_SendTCP(socket, DATAMSG); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDDATA, msg))) { + merror(DATA_ERROR); + if (msg) { + free(msg); } - MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); - free(msg); - - /* Create header for to */ - memset(snd_msg, '\0', 128); - snprintf(snd_msg, 127, TO, mail->gran_to[i]); - strncat(final_to, snd_msg, final_to_sz); - final_to_sz -= strlen(snd_msg) + 2; - - i++; - continue; + close(socket); + return (OS_INVALID); } - } + MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", DATAMSG, msg); + free(msg); - /* Send the "DATA" msg */ - OS_SendTCP(socket, DATAMSG); - msg = OS_RecvTCP(socket, OS_SIZE_1024); - if ((msg == NULL) || (!OS_Match(VALIDDATA, msg))) { - merror(DATA_ERROR); - if (msg) { - free(msg); - } - close(socket); - return (OS_INVALID); + /* Build "From" and "To" in the e-mail header */ + OS_SendTCP(socket, final_to); } - MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", DATAMSG, msg); - free(msg); - - /* Build "From" and "To" in the e-mail header */ - OS_SendTCP(socket, final_to); memset(snd_msg, '\0', 128); snprintf(snd_msg, 127, FROM, mail->from); - OS_SendTCP(socket, snd_msg); + + if (sendmail) { + fprintf(sendmail, snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } /* Send date */ memset(snd_msg, '\0', 128); @@ -201,50 +214,63 @@ int OS_Sendsms(MailConfig *mail, struct tm *p, MailMsg *sms_msg) strftime(snd_msg, 127, "Date: %a, %d %b %Y %T %z\r\n", p); #endif - OS_SendTCP(socket, snd_msg); + if (sendmail) { + fprintf(sendmail, snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } /* Send subject */ memset(snd_msg, '\0', 128); snprintf(snd_msg, 127, SUBJECT, sms_msg->subject); - OS_SendTCP(socket, snd_msg); - OS_SendTCP(socket, ENDHEADER); - /* Send body */ - OS_SendTCP(socket, sms_msg->body); + if (sendmail) { + fprintf(sendmail, snd_msg); + fprintf(sendmail, ENDHEADER); + fprintf(sendmail, sms_msg->body); + fclose(sendmail); + } else { + OS_SendTCP(socket, snd_msg); + OS_SendTCP(socket, ENDHEADER); + + /* Send body */ + OS_SendTCP(socket, sms_msg->body); - /* Send end of data \r\n.\r\n */ - OS_SendTCP(socket, ENDDATA); - msg = OS_RecvTCP(socket, OS_SIZE_1024); - if (mail->strict_checking && ((msg == NULL) || (!OS_Match(VALIDMAIL, msg)))) { - merror(END_DATA_ERROR); + /* Send end of data \r\n.\r\n */ + OS_SendTCP(socket, ENDDATA); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if (mail->strict_checking && ((msg == NULL) || (!OS_Match(VALIDMAIL, msg)))) { + merror(END_DATA_ERROR); + if (msg) { + free(msg); + } + close(socket); + return (OS_INVALID); + } + /* Check msg, since it may be null */ if (msg) { free(msg); } - close(socket); - return (OS_INVALID); - } - /* Check msg, since it may be null */ - if (msg) { - free(msg); - } - /* Quit and close socket */ - OS_SendTCP(socket, QUITMSG); - msg = OS_RecvTCP(socket, OS_SIZE_1024); + /* Quit and close socket */ + OS_SendTCP(socket, QUITMSG); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + + if (msg) { + free(msg); + } - if (msg) { - free(msg); + close(socket); } memset_secure(snd_msg, '\0', 128); - close(socket); - return (0); } int OS_Sendmail(MailConfig *mail, struct tm *p) { - int socket; + FILE *sendmail = NULL; + int socket = -1; unsigned int i = 0; char *msg; char snd_msg[128]; @@ -259,100 +285,81 @@ int OS_Sendmail(MailConfig *mail, struct tm *p) return (OS_INVALID); } - /* Connect to the SMTP server */ - socket = OS_ConnectTCP(SMTP_DEFAULT_PORT, mail->smtpserver, 0, NULL); - if (socket < 0) { - return (socket); - } - - /* Receive the banner */ - msg = OS_RecvTCP(socket, OS_SIZE_1024); - if ((msg == NULL) || (!OS_Match(VALIDBANNER, msg))) { - merror(BANNER_ERROR); - if (msg) { - free(msg); + if (mail->smtpserver[0] == '/') { + sendmail = popen(mail->smtpserver, "w"); + if (!sendmail) { + return (OS_INVALID); } - close(socket); - return (OS_INVALID); - } - MAIL_DEBUG("DEBUG: Received banner: '%s' %s", msg, ""); - free(msg); - - /* Send HELO message */ - memset(snd_msg, '\0', 128); - if (mail->heloserver) { - snprintf(snd_msg, 127, "Helo %s\r\n", mail->heloserver); } else { - snprintf(snd_msg, 127, "Helo %s\r\n", "notify.ossec.net"); - } - OS_SendTCP(socket, snd_msg); - msg = OS_RecvTCP(socket, OS_SIZE_1024); - if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { - if (msg) { - /* In some cases (with virus scans in the middle) - * we may get two banners. Check for that in here. - */ - if (OS_Match(VALIDBANNER, msg)) { + /* Connect to the SMTP server */ + socket = OS_ConnectTCP(SMTP_DEFAULT_PORT, mail->smtpserver, 0, NULL); + if (socket < 0) { + return (socket); + } + + /* Receive the banner */ + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDBANNER, msg))) { + merror(BANNER_ERROR); + if (msg) { free(msg); + } + close(socket); + return (OS_INVALID); + } + MAIL_DEBUG("DEBUG: Received banner: '%s' %s", msg, ""); + free(msg); - /* Try again */ - msg = OS_RecvTCP(socket, OS_SIZE_1024); - if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { - merror("%s:%s", HELO_ERROR, msg != NULL ? msg : "null"); - if (msg) { - free(msg); + /* Send HELO message */ + memset(snd_msg, '\0', 128); + if (mail->heloserver) { + snprintf(snd_msg, 127, "Helo %s\r\n", mail->heloserver); + } else { + snprintf(snd_msg, 127, "Helo %s\r\n", "notify.ossec.net"); + } + OS_SendTCP(socket, snd_msg); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { + if (msg) { + /* In some cases (with virus scans in the middle) + * we may get two banners. Check for that in here. + */ + if (OS_Match(VALIDBANNER, msg)) { + free(msg); + + /* Try again */ + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { + merror("%s:%s", HELO_ERROR, msg != NULL ? msg : "null"); + if (msg) { + free(msg); + } + close(socket); + return (OS_INVALID); } + } else { + merror("%s:%s", HELO_ERROR, msg); + free(msg); close(socket); return (OS_INVALID); } } else { - merror("%s:%s", HELO_ERROR, msg); - free(msg); + merror("%s:%s", HELO_ERROR, "null"); close(socket); return (OS_INVALID); } - } else { - merror("%s:%s", HELO_ERROR, "null"); - close(socket); - return (OS_INVALID); } - } - MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); - free(msg); + MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); + free(msg); - /* Build "Mail from" msg */ - memset(snd_msg, '\0', 128); - snprintf(snd_msg, 127, MAILFROM, mail->from); - OS_SendTCP(socket, snd_msg); - msg = OS_RecvTCP(socket, OS_SIZE_1024); - if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { - merror(FROM_ERROR); - if (msg) { - free(msg); - } - close(socket); - return (OS_INVALID); - } - MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); - free(msg); - - /* Build "RCPT TO" msg */ - while (1) { - if (mail->to[i] == NULL) { - if (i == 0) { - merror(INTERNAL_ERROR); - close(socket); - return (OS_INVALID); - } - break; - } + /* Build "Mail from" msg */ memset(snd_msg, '\0', 128); - snprintf(snd_msg, 127, RCPTTO, mail->to[i++]); + snprintf(snd_msg, 127, MAILFROM, mail->from); OS_SendTCP(socket, snd_msg); msg = OS_RecvTCP(socket, OS_SIZE_1024); if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { - merror(TO_ERROR, mail->to[i - 1]); + merror(FROM_ERROR); if (msg) { free(msg); } @@ -361,61 +368,96 @@ int OS_Sendmail(MailConfig *mail, struct tm *p) } MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); free(msg); - } - /* Additional RCPT to */ - if (mail->gran_to) { - i = 0; - while (mail->gran_to[i] != NULL) { - if (mail->gran_set[i] != FULL_FORMAT) { - i++; - continue; + /* Build "RCPT TO" msg */ + while (1) { + if (mail->to[i] == NULL) { + if (i == 0) { + merror(INTERNAL_ERROR); + close(socket); + return (OS_INVALID); + } + break; } - memset(snd_msg, '\0', 128); - snprintf(snd_msg, 127, RCPTTO, mail->gran_to[i]); + snprintf(snd_msg, 127, RCPTTO, mail->to[i++]); OS_SendTCP(socket, snd_msg); msg = OS_RecvTCP(socket, OS_SIZE_1024); if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { - merror(TO_ERROR, mail->gran_to[i]); + merror(TO_ERROR, mail->to[i - 1]); if (msg) { free(msg); } + close(socket); + return (OS_INVALID); + } + MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); + free(msg); + } + + /* Additional RCPT to */ + if (mail->gran_to) { + i = 0; + while (mail->gran_to[i] != NULL) { + if (mail->gran_set[i] != FULL_FORMAT) { + i++; + continue; + } + + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, RCPTTO, mail->gran_to[i]); + OS_SendTCP(socket, snd_msg); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDMAIL, msg))) { + merror(TO_ERROR, mail->gran_to[i]); + if (msg) { + free(msg); + } + + i++; + continue; + } + MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); + free(msg); i++; continue; } - - MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); - free(msg); - i++; - continue; } - } - /* Send the "DATA" msg */ - OS_SendTCP(socket, DATAMSG); - msg = OS_RecvTCP(socket, OS_SIZE_1024); - if ((msg == NULL) || (!OS_Match(VALIDDATA, msg))) { - merror(DATA_ERROR); - if (msg) { - free(msg); + /* Send the "DATA" msg */ + OS_SendTCP(socket, DATAMSG); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if ((msg == NULL) || (!OS_Match(VALIDDATA, msg))) { + merror(DATA_ERROR); + if (msg) { + free(msg); + } + close(socket); + return (OS_INVALID); } - close(socket); - return (OS_INVALID); + MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", DATAMSG, msg); + free(msg); } - MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", DATAMSG, msg); - free(msg); - /* Building "From" and "To" in the e-mail header */ memset(snd_msg, '\0', 128); snprintf(snd_msg, 127, TO, mail->to[0]); - OS_SendTCP(socket, snd_msg); + + if (sendmail) { + fprintf(sendmail, snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } memset(snd_msg, '\0', 128); snprintf(snd_msg, 127, FROM, mail->from); - OS_SendTCP(socket, snd_msg); + + if (sendmail) { + fprintf(sendmail, snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } /* Add CCs */ if (mail->to[1]) { @@ -427,7 +469,12 @@ int OS_Sendmail(MailConfig *mail, struct tm *p) memset(snd_msg, '\0', 128); snprintf(snd_msg, 127, TO, mail->to[i]); - OS_SendTCP(socket, snd_msg); + + if (sendmail) { + fprintf(sendmail, snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } i++; } @@ -444,7 +491,13 @@ int OS_Sendmail(MailConfig *mail, struct tm *p) memset(snd_msg, '\0', 128); snprintf(snd_msg, 127, TO, mail->gran_to[i]); - OS_SendTCP(socket, snd_msg); + + if (sendmail) { + fprintf(sendmail, snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } + i++; continue; } @@ -460,13 +513,22 @@ int OS_Sendmail(MailConfig *mail, struct tm *p) strftime(snd_msg, 127, "Date: %a, %d %b %Y %T %z\r\n", p); #endif - OS_SendTCP(socket, snd_msg); + if (sendmail) { + fprintf(sendmail, snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } if (mail->idsname) { /* Send server name header */ memset(snd_msg, '\0', 128); snprintf(snd_msg, 127, XHEADER, mail->idsname); - OS_SendTCP(socket, snd_msg); + + if (sendmail) { + fprintf(sendmail, snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } } /* Send subject */ @@ -482,45 +544,58 @@ int OS_Sendmail(MailConfig *mail, struct tm *p) } else { snprintf(snd_msg, 127, SUBJECT, mailmsg->mail->subject); } - OS_SendTCP(socket, snd_msg); - OS_SendTCP(socket, ENDHEADER); + + if (sendmail) { + fprintf(sendmail, snd_msg); + fprintf(sendmail, ENDHEADER); + } else { + OS_SendTCP(socket, snd_msg); + OS_SendTCP(socket, ENDHEADER); + } /* Send body */ /* Send multiple emails together if we have to */ do { - OS_SendTCP(socket, mailmsg->mail->body); + if (sendmail) { + fprintf(sendmail, mailmsg->mail->body); + } else { + OS_SendTCP(socket, mailmsg->mail->body); + } mailmsg = OS_PopLastMail(); } while (mailmsg); - /* Send end of data \r\n.\r\n */ - OS_SendTCP(socket, ENDDATA); - msg = OS_RecvTCP(socket, OS_SIZE_1024); - if (mail->strict_checking && ((msg == NULL) || (!OS_Match(VALIDMAIL, msg)))) { - merror(END_DATA_ERROR); + if (sendmail) { + fclose(sendmail); + } else { + /* Send end of data \r\n.\r\n */ + OS_SendTCP(socket, ENDDATA); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + if (mail->strict_checking && ((msg == NULL) || (!OS_Match(VALIDMAIL, msg)))) { + merror(END_DATA_ERROR); + if (msg) { + free(msg); + } + close(socket); + return (OS_INVALID); + } + + /* Check msg, since it may be null */ if (msg) { free(msg); } - close(socket); - return (OS_INVALID); - } - /* Check msg, since it may be null */ - if (msg) { - free(msg); - } + /* Quit and close socket */ + OS_SendTCP(socket, QUITMSG); + msg = OS_RecvTCP(socket, OS_SIZE_1024); - /* Quit and close socket */ - OS_SendTCP(socket, QUITMSG); - msg = OS_RecvTCP(socket, OS_SIZE_1024); + if (msg) { + free(msg); + } - if (msg) { - free(msg); + close(socket); } memset_secure(snd_msg, '\0', 128); - close(socket); - return (0); } -