Imported Upstream version 2.7
[ossec-hids.git] / src / os_maild / sendcustomemail.c
1 /* @(#) $Id: ./src/os_maild/sendcustomemail.c, 2011/09/08 dcid Exp $
2  */
3
4 /* Copyright (C) 2009 Trend Micro Inc.
5  * All rights reserved.
6  *
7  * This program is a free software; you can redistribute it
8  * and/or modify it under the terms of the GNU General Public
9  * License (version 2) as published by the FSF - Free Software
10  * Foundation
11  */
12
13
14 /* Basic e-mailing operations */
15
16
17 #include "shared.h"
18 #include "os_net/os_net.h"
19 #include "maild.h"
20
21
22 /* Return codes (from SMTP server) */
23 #define VALIDBANNER             "220"
24 #define VALIDMAIL               "250"
25 #define VALIDDATA               "354"
26
27
28 /* Default values use to connect */
29 #define SMTP_DEFAULT_PORT       25
30 #define HELOMSG                 "Helo notify.ossec.net\r\n"
31 #define MAILFROM                "Mail From: <%s>\r\n"
32 #define RCPTTO                  "Rcpt To: <%s>\r\n"
33 #define DATAMSG                 "DATA\r\n"
34 #define FROM                    "From: OSSEC HIDS <%s>\r\n"
35 #define TO                          "To: <%s>\r\n"
36 #define CC                          "Cc: <%s>\r\n"
37 #define SUBJECT                 "Subject: %s\r\n"
38 #define ENDDATA                 "\r\n.\r\n"
39 #define QUITMSG                 "QUIT\r\n"
40
41
42 /* Error messages - Can be translated */
43 #define INTERNAL_ERROR  "os_maild (1760): ERROR: Memory/configuration error"
44 #define BANNER_ERROR    "os_sendmail(1762): WARN: Banner not received from server"
45 #define HELO_ERROR          "os_sendmail(1763): WARN: Hello not accepted by server"
46 #define FROM_ERROR          "os_sendmail(1764): WARN: Mail from not accepted by server"
47 #define TO_ERROR            "os_sendmail(1765): WARN: RCPT TO not accepted by server - '%s'."
48 #define DATA_ERROR          "os_sendmail(1766): WARN: DATA not accepted by server"
49 #define END_DATA_ERROR  "os_sendmail(1767): WARN: End of DATA not accepted by server"
50
51
52 #define MAIL_DEBUG_FLAG     0
53 #define MAIL_DEBUG(x,y,z) if(MAIL_DEBUG_FLAG) merror(x,y,z)
54
55
56
57 /* OS_SendCustomEmail
58  */
59 int OS_SendCustomEmail(char **to, char *subject, char *smtpserver, char *from, FILE *fp, struct tm *p)
60 {
61     int socket,i = 0;
62     char *msg;
63
64     char snd_msg[128];
65     char buffer[2049];
66
67     buffer[2048] = '\0';
68
69
70     /* Connecting to the smtp server */ 
71     socket = OS_ConnectTCP(SMTP_DEFAULT_PORT, smtpserver, 0);
72     if(socket < 0)
73     {
74         return(socket);
75     }
76
77
78     /* Receiving the banner */
79     msg = OS_RecvTCP(socket, OS_SIZE_1024);
80     if((msg == NULL)||(!OS_Match(VALIDBANNER, msg)))
81     {
82         merror(BANNER_ERROR);
83         if(msg)
84             free(msg);
85         close(socket);
86         return(OS_INVALID);     
87     }
88     MAIL_DEBUG("DEBUG: Received banner: '%s' %s", msg, "");
89     free(msg);
90
91
92
93     /* Sending HELO message */
94     OS_SendTCP(socket,HELOMSG);
95     msg = OS_RecvTCP(socket, OS_SIZE_1024);
96     if((msg == NULL)||(!OS_Match(VALIDMAIL, msg)))
97     {
98         if(msg)
99         {
100             /* Ugly fix warning :) */
101             /* In some cases (with virus scans in the middle)
102              * we may get two banners. Check for that in here.
103              */
104             if(OS_Match(VALIDBANNER, msg))
105             {
106                 free(msg);
107
108                 /* Try again */
109                 msg = OS_RecvTCP(socket, OS_SIZE_1024);
110                 if((msg == NULL)||(!OS_Match(VALIDMAIL, msg)))
111                 {
112                     merror("%s:%s",HELO_ERROR,msg!= NULL?msg:"null");
113                     if(msg)
114                         free(msg);
115                     close(socket);
116                     return(OS_INVALID);
117                 }
118             }
119             else
120             {
121                 merror("%s:%s",HELO_ERROR,msg);
122                 free(msg);
123                 close(socket);
124                 return(OS_INVALID);
125             }
126         }
127         else
128         {
129             merror("%s:%s",HELO_ERROR,"null");
130             close(socket);
131             return(OS_INVALID);
132         }
133     }
134
135     MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", HELOMSG, msg);
136     free(msg);  
137
138
139     /* Building "Mail from" msg */
140     memset(snd_msg,'\0',128);
141     snprintf(snd_msg,127, MAILFROM, from);
142     OS_SendTCP(socket, snd_msg);
143     msg = OS_RecvTCP(socket, OS_SIZE_1024);
144     if((msg == NULL)||(!OS_Match(VALIDMAIL, msg)))
145     {
146         merror(FROM_ERROR);
147         if(msg)
148             free(msg);
149         close(socket);
150         return(OS_INVALID);     
151     }
152     MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg);
153     free(msg);  
154
155
156     /* Building "RCPT TO" msg */
157     while(to[i])
158     {
159         memset(snd_msg,'\0',128);
160         snprintf(snd_msg,127,RCPTTO, to[i]);
161         OS_SendTCP(socket,snd_msg);
162         msg = OS_RecvTCP(socket, OS_SIZE_1024);
163         if((msg == NULL)||(!OS_Match(VALIDMAIL, msg)))
164         {
165             merror(TO_ERROR, to[i]);
166             if(msg)
167                 free(msg);
168             close(socket);
169             return(OS_INVALID); 
170         }
171         MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg);
172         free(msg);
173
174         i++;
175     }
176
177
178     /* Sending the "DATA" msg */
179     OS_SendTCP(socket,DATAMSG);
180     msg = OS_RecvTCP(socket, OS_SIZE_1024);
181     if((msg == NULL)||(!OS_Match(VALIDDATA, msg)))
182     {
183         merror(DATA_ERROR);
184         if(msg)
185             free(msg);
186         close(socket);
187         return(OS_INVALID);     
188     }
189     MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", DATAMSG, msg);
190     free(msg);
191
192
193     /* Building "From" and "To" in the e-mail header */
194     memset(snd_msg,'\0',128);
195     snprintf(snd_msg,127, TO, to[0]);
196     OS_SendTCP(socket, snd_msg);
197
198     memset(snd_msg,'\0',128);
199     snprintf(snd_msg,127, FROM, from);
200     OS_SendTCP(socket, snd_msg);
201
202
203     /* Adding CCs */
204     if(to[1])
205     {
206         i = 1;
207         while(1)
208         {
209             if(to[i] == NULL)
210             {
211                 break;
212             }
213
214             memset(snd_msg,'\0',128);
215             snprintf(snd_msg,127, TO, to[i]);
216             OS_SendTCP(socket,snd_msg);
217
218             i++;
219         }
220     }
221
222
223     /* Sending date */
224     memset(snd_msg,'\0',128);
225
226
227     /* Solaris doesn't have the "%z", so we set the timezone to 0. */
228     #ifdef SOLARIS
229     strftime(snd_msg, 127, "Date: %a, %d %b %Y %T -0000\r\n",p);
230     #else
231     strftime(snd_msg, 127, "Date: %a, %d %b %Y %T %z\r\n",p);
232     #endif
233
234     OS_SendTCP(socket,snd_msg);
235
236
237     /* Sending subject */
238     memset(snd_msg, '\0', 128);
239     snprintf(snd_msg, 127, SUBJECT, subject);
240
241     OS_SendTCP(socket, snd_msg);
242
243
244
245      /* Sending body */
246      fseek(fp, 0, SEEK_SET);
247      while(fgets(buffer, 2048, fp) != NULL)
248      {
249          OS_SendTCP(socket,buffer);
250      }
251
252
253     /* Sending end of data \r\n.\r\n */
254     OS_SendTCP(socket,ENDDATA); 
255     msg = OS_RecvTCP(socket, OS_SIZE_1024);
256
257
258     /* Checking msg in here, since it may be null */
259     if(msg)
260         free(msg);
261
262
263     /* quitting and closing socket */
264     OS_SendTCP(socket,QUITMSG);
265     msg = OS_RecvTCP(socket, OS_SIZE_1024);
266
267     if(msg)
268         free(msg);
269
270     memset(snd_msg,'\0',128);   
271
272
273     /* Returning 0 (success) */
274     close(socket);
275
276     return(0);
277 }
278
279
280
281 /* EOF */