Merge commit 'v2.5.1'
[ossec-hids.git] / src / os_maild / sendcustomemail.c
diff --git a/src/os_maild/sendcustomemail.c b/src/os_maild/sendcustomemail.c
new file mode 100755 (executable)
index 0000000..ea2b203
--- /dev/null
@@ -0,0 +1,280 @@
+/* @(#) $Id$ */
+
+/* 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"
+#include "maild.h"
+
+
+/* Return codes (from SMTP server) */
+#define VALIDBANNER            "220"
+#define VALIDMAIL              "250"
+#define VALIDDATA              "354"
+
+
+/* Default values use 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 TO                         "To: <%s>\r\n"
+#define CC                         "Cc: <%s>\r\n"
+#define SUBJECT                        "Subject: %s\r\n"
+#define ENDDATA                        "\r\n.\r\n"
+#define QUITMSG                "QUIT\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)
+
+
+
+/* OS_SendCustomEmail
+ */
+int OS_SendCustomEmail(char **to, char *subject, char *smtpserver, char *from, FILE *fp, struct tm *p)
+{
+    int socket,i = 0;
+    char *msg;
+
+    char snd_msg[128];
+    char buffer[2049];
+
+    buffer[2048] = '\0';
+
+
+    /* Connecting to the smtp server */        
+    socket = OS_ConnectTCP(SMTP_DEFAULT_PORT, smtpserver);
+    if(socket < 0)
+    {
+        return(socket);
+    }
+
+
+    /* Receiving 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);
+
+
+
+    /* Sending HELO message */
+    OS_SendTCP(socket,HELOMSG);
+    msg = OS_RecvTCP(socket, OS_SIZE_1024);
+    if((msg == NULL)||(!OS_Match(VALIDMAIL, msg)))
+    {
+        if(msg)
+        {
+            /* Ugly fix warning :) */
+            /* 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); 
+
+
+    /* Building "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); 
+
+
+    /* Building "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++;
+    }
+
+
+    /* Sending 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);
+
+
+    /* Building "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);
+
+    memset(snd_msg,'\0',128);
+    snprintf(snd_msg,127, FROM, from);
+    OS_SendTCP(socket, snd_msg);
+
+
+    /* Adding 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]);
+            OS_SendTCP(socket,snd_msg);
+
+            i++;
+        }
+    }
+
+
+    /* Sending date */
+    memset(snd_msg,'\0',128);
+
+
+    /* 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
+                            
+    OS_SendTCP(socket,snd_msg);
+
+
+    /* Sending subject */
+    memset(snd_msg, '\0', 128);
+    snprintf(snd_msg, 127, SUBJECT, subject);
+
+    OS_SendTCP(socket, snd_msg);
+
+
+
+     /* Sending body */
+     fseek(fp, 0, SEEK_SET);
+     while(fgets(buffer, 2048, fp) != NULL)
+     {
+         OS_SendTCP(socket,buffer);
+     }    
+
+
+    /* Sending end of data \r\n.\r\n */
+    OS_SendTCP(socket,ENDDATA);        
+    msg = OS_RecvTCP(socket, OS_SIZE_1024);
+
+
+    /* Checking msg in here, since it may be null */
+    if(msg)
+        free(msg);
+
+
+    /* quitting and closing socket */
+    OS_SendTCP(socket,QUITMSG);
+    msg = OS_RecvTCP(socket, OS_SIZE_1024);
+
+    if(msg)
+        free(msg);
+
+    memset(snd_msg,'\0',128);  
+
+
+    /* Returning 0 (success) */
+    close(socket);
+
+    return(0);
+}
+
+
+
+/* EOF */