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