X-Git-Url: http://ftp.carnet.hr/carnet-debian/scm?p=ossec-hids.git;a=blobdiff_plain;f=src%2Fmonitord%2Fsendcustomemail.c;fp=src%2Fmonitord%2Fsendcustomemail.c;h=f25d5d3f1cb7a4377ccad3151d89d8cb201aa837;hp=0000000000000000000000000000000000000000;hb=3f728675941dc69d4e544d3a880a56240a6e394a;hpb=927951d1c1ad45ba9e7325f07d996154a91c911b diff --git a/src/monitord/sendcustomemail.c b/src/monitord/sendcustomemail.c new file mode 100644 index 0000000..f25d5d3 --- /dev/null +++ b/src/monitord/sendcustomemail.c @@ -0,0 +1,324 @@ +/* Copyright (C) 2009 Trend Micro Inc. + * All rights reserved. + * + * This program is a free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public + * License (version 2) as published by the FSF - Free Software + * Foundation + */ + +/* Basic e-mailing operations */ + +#include "shared.h" +#include "os_net/os_net.h" + +/* Return codes (from SMTP server) */ +#define VALIDBANNER "220" +#define VALIDMAIL "250" +#define VALIDDATA "354" + +/* Default values used to connect */ +#define SMTP_DEFAULT_PORT "25" +#define HELOMSG "Helo notify.ossec.net\r\n" +#define MAILFROM "Mail From: <%s>\r\n" +#define RCPTTO "Rcpt To: <%s>\r\n" +#define DATAMSG "DATA\r\n" +#define FROM "From: OSSEC HIDS <%s>\r\n" +#define REPLYTO "Reply-To: OSSEC HIDS <%s>\r\n" +#define TO "To: <%s>\r\n" +#define CC "Cc: <%s>\r\n" +#define SUBJECT "Subject: %s\r\n" +#define ENDHEADER "\r\n" +#define ENDDATA "\r\n.\r\n" +#define QUITMSG "QUIT\r\n" +#define XHEADER "X-IDS-OSSEC: %s\r\n" + +/* Error messages - Can be translated */ +#define INTERNAL_ERROR "os_maild (1760): ERROR: Memory/configuration error" +#define BANNER_ERROR "os_sendmail(1762): WARN: Banner not received from server" +#define HELO_ERROR "os_sendmail(1763): WARN: Hello not accepted by server" +#define FROM_ERROR "os_sendmail(1764): WARN: Mail from not accepted by server" +#define TO_ERROR "os_sendmail(1765): WARN: RCPT TO not accepted by server - '%s'." +#define DATA_ERROR "os_sendmail(1766): WARN: DATA not accepted by server" +#define END_DATA_ERROR "os_sendmail(1767): WARN: End of DATA not accepted by server" + +#define MAIL_DEBUG_FLAG 0 +#define MAIL_DEBUG(x,y,z) if(MAIL_DEBUG_FLAG) merror(x,y,z) + + +int OS_SendCustomEmail2(char **to, char *subject, char *smtpserver, char *from, char *replyto, char *idsname, __attribute__((unused)) char *fname) +{ + FILE *sendmail = NULL; + int socket = -1, i = 0; + char *msg; + char snd_msg[128]; + char buffer[2049]; + + buffer[2048] = '\0'; + + 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); + 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); + + /* 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, "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); + + /* 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++; + } + + /* 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); + } + + /* Build "From" and "To" in the e-mail header */ + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, TO, to[0]); + + if (sendmail) { + fprintf(sendmail, "%s", snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } + + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, FROM, from); + + if (sendmail) { + fprintf(sendmail, "%s", snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } + + if (replyto) { + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, REPLYTO, replyto); + if(sendmail) { + fprintf(sendmail, "%s", snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } + + } + + /* Add CCs */ + if (to[1]) { + i = 1; + while (1) { + if (to[i] == NULL) { + break; + } + + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, TO, to[i]); + + if (sendmail) { + fprintf(sendmail, "%s", snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } + + i++; + } + } + + /* Send date */ + memset(snd_msg, '\0', 128); + time_t tm; + tm = time(NULL); + const struct tm *p; + p = localtime(&tm); + + /* Solaris doesn't have the "%z", so we set the timezone to 0 */ +#ifdef SOLARIS + strftime(snd_msg, 127, "Date: %a, %d %b %Y %T -0000\r\n", p); +#else + strftime(snd_msg, 127, "Date: %a, %d %b %Y %T %z\r\n", p); +#endif + + if (sendmail) { + fprintf(sendmail, "%s", 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); + + if (sendmail) { + fprintf(sendmail, "%s", snd_msg); + } else { + OS_SendTCP(socket, snd_msg); + } + } + + /* Send subject */ + memset(snd_msg, '\0', 128); + snprintf(snd_msg, 127, SUBJECT, subject); + + if (sendmail) { + fprintf(sendmail, "%s", snd_msg); + fprintf(sendmail, ENDHEADER); + } else { + OS_SendTCP(socket, snd_msg); + OS_SendTCP(socket, ENDHEADER); + } + + + char fname2[256]; + fname2[255] = '\0'; + snprintf(fname2, 255, "/logs/.report-%d.log", getpid()); + + /* Send body */ + FILE *fp; + fp = fopen(fname2, "r"); + if(!fp) { + merror("%s: ERROR: Cannot open %s: %s", __local_name, fname2, strerror(errno)); + if(socket >= 0) { + close(socket); + } + if(sendmail) { + pclose(sendmail); + } + return(1); + } + + + while (fgets(buffer, 2048, fp) != NULL) { + if (sendmail) { + fprintf(sendmail, "%s", buffer); + } else { + OS_SendTCP(socket, buffer); + } + } + fclose(fp); + + if (sendmail) { + if (pclose(sendmail) == -1) { + merror(WAITPID_ERROR, ARGV0, errno, strerror(errno)); + } + } 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); + } + + /* Quit and close socket */ + OS_SendTCP(socket, QUITMSG); + msg = OS_RecvTCP(socket, OS_SIZE_1024); + + if (msg) { + free(msg); + } + + close(socket); + } + + memset_secure(snd_msg, '\0', 128); + return (0); +} +