izmjene licence
[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 ENDHEADER               "\r\n"
39 #define ENDDATA                 "\r\n.\r\n"
40 #define QUITMSG                 "QUIT\r\n"
41 #define XHEADER                 "X-IDS-OSSEC: %s\r\n"
42
43
44 /* Error messages - Can be translated */
45 #define INTERNAL_ERROR  "os_maild (1760): ERROR: Memory/configuration error"
46 #define BANNER_ERROR    "os_sendmail(1762): WARN: Banner not received from server"
47 #define HELO_ERROR          "os_sendmail(1763): WARN: Hello not accepted by server"
48 #define FROM_ERROR          "os_sendmail(1764): WARN: Mail from not accepted by server"
49 #define TO_ERROR            "os_sendmail(1765): WARN: RCPT TO not accepted by server - '%s'."
50 #define DATA_ERROR          "os_sendmail(1766): WARN: DATA not accepted by server"
51 #define END_DATA_ERROR  "os_sendmail(1767): WARN: End of DATA not accepted by server"
52
53
54 #define MAIL_DEBUG_FLAG     0
55 #define MAIL_DEBUG(x,y,z) if(MAIL_DEBUG_FLAG) merror(x,y,z)
56
57
58
59 /* OS_SendCustomEmail
60  */
61 int OS_SendCustomEmail(char **to, char *subject, char *smtpserver, char *from, char *idsname, FILE *fp, struct tm *p)
62 {
63     int socket,i = 0;
64     char *msg;
65
66     char snd_msg[128];
67     char buffer[2049];
68
69     buffer[2048] = '\0';
70
71
72     /* Connecting to the smtp server */ 
73     socket = OS_ConnectTCP(SMTP_DEFAULT_PORT, smtpserver, 0);
74     if(socket < 0)
75     {
76         return(socket);
77     }
78
79
80     /* Receiving the banner */
81     msg = OS_RecvTCP(socket, OS_SIZE_1024);
82     if((msg == NULL)||(!OS_Match(VALIDBANNER, msg)))
83     {
84         merror(BANNER_ERROR);
85         if(msg)
86             free(msg);
87         close(socket);
88         return(OS_INVALID);     
89     }
90     MAIL_DEBUG("DEBUG: Received banner: '%s' %s", msg, "");
91     free(msg);
92
93
94
95     /* Sending HELO message */
96     OS_SendTCP(socket,HELOMSG);
97     msg = OS_RecvTCP(socket, OS_SIZE_1024);
98     if((msg == NULL)||(!OS_Match(VALIDMAIL, msg)))
99     {
100         if(msg)
101         {
102             /* Ugly fix warning :) */
103             /* In some cases (with virus scans in the middle)
104              * we may get two banners. Check for that in here.
105              */
106             if(OS_Match(VALIDBANNER, msg))
107             {
108                 free(msg);
109
110                 /* Try again */
111                 msg = OS_RecvTCP(socket, OS_SIZE_1024);
112                 if((msg == NULL)||(!OS_Match(VALIDMAIL, msg)))
113                 {
114                     merror("%s:%s",HELO_ERROR,msg!= NULL?msg:"null");
115                     if(msg)
116                         free(msg);
117                     close(socket);
118                     return(OS_INVALID);
119                 }
120             }
121             else
122             {
123                 merror("%s:%s",HELO_ERROR,msg);
124                 free(msg);
125                 close(socket);
126                 return(OS_INVALID);
127             }
128         }
129         else
130         {
131             merror("%s:%s",HELO_ERROR,"null");
132             close(socket);
133             return(OS_INVALID);
134         }
135     }
136
137     MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", HELOMSG, msg);
138     free(msg);  
139
140
141     /* Building "Mail from" msg */
142     memset(snd_msg,'\0',128);
143     snprintf(snd_msg,127, MAILFROM, from);
144     OS_SendTCP(socket, snd_msg);
145     msg = OS_RecvTCP(socket, OS_SIZE_1024);
146     if((msg == NULL)||(!OS_Match(VALIDMAIL, msg)))
147     {
148         merror(FROM_ERROR);
149         if(msg)
150             free(msg);
151         close(socket);
152         return(OS_INVALID);     
153     }
154     MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg);
155     free(msg);  
156
157
158     /* Building "RCPT TO" msg */
159     while(to[i])
160     {
161         memset(snd_msg,'\0',128);
162         snprintf(snd_msg,127,RCPTTO, to[i]);
163         OS_SendTCP(socket,snd_msg);
164         msg = OS_RecvTCP(socket, OS_SIZE_1024);
165         if((msg == NULL)||(!OS_Match(VALIDMAIL, msg)))
166         {
167             merror(TO_ERROR, to[i]);
168             if(msg)
169                 free(msg);
170             close(socket);
171             return(OS_INVALID); 
172         }
173         MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg);
174         free(msg);
175
176         i++;
177     }
178
179
180     /* Sending the "DATA" msg */
181     OS_SendTCP(socket,DATAMSG);
182     msg = OS_RecvTCP(socket, OS_SIZE_1024);
183     if((msg == NULL)||(!OS_Match(VALIDDATA, msg)))
184     {
185         merror(DATA_ERROR);
186         if(msg)
187             free(msg);
188         close(socket);
189         return(OS_INVALID);     
190     }
191     MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", DATAMSG, msg);
192     free(msg);
193
194
195     /* Building "From" and "To" in the e-mail header */
196     memset(snd_msg,'\0',128);
197     snprintf(snd_msg,127, TO, to[0]);
198     OS_SendTCP(socket, snd_msg);
199
200     memset(snd_msg,'\0',128);
201     snprintf(snd_msg,127, FROM, from);
202     OS_SendTCP(socket, snd_msg);
203
204
205     /* Adding CCs */
206     if(to[1])
207     {
208         i = 1;
209         while(1)
210         {
211             if(to[i] == NULL)
212             {
213                 break;
214             }
215
216             memset(snd_msg,'\0',128);
217             snprintf(snd_msg,127, TO, to[i]);
218             OS_SendTCP(socket,snd_msg);
219
220             i++;
221         }
222     }
223
224
225     /* Sending date */
226     memset(snd_msg,'\0',128);
227
228
229     /* Solaris doesn't have the "%z", so we set the timezone to 0. */
230     #ifdef SOLARIS
231     strftime(snd_msg, 127, "Date: %a, %d %b %Y %T -0000\r\n",p);
232     #else
233     strftime(snd_msg, 127, "Date: %a, %d %b %Y %T %z\r\n",p);
234     #endif
235
236     OS_SendTCP(socket,snd_msg);
237
238     if (idsname)
239     {       
240         /* Sending server name header */
241         memset(snd_msg,'\0',128);
242         snprintf(snd_msg,127, XHEADER, idsname);
243         OS_SendTCP(socket, snd_msg);
244     }
245
246     /* Sending subject */
247     memset(snd_msg, '\0', 128);
248     snprintf(snd_msg, 127, SUBJECT, subject);
249
250     OS_SendTCP(socket, snd_msg);
251
252     OS_SendTCP(socket,ENDHEADER);
253
254
255      /* Sending body */
256      fseek(fp, 0, SEEK_SET);
257      while(fgets(buffer, 2048, fp) != NULL)
258      {
259          OS_SendTCP(socket,buffer);
260      }
261
262
263     /* Sending end of data \r\n.\r\n */
264     OS_SendTCP(socket,ENDDATA); 
265     msg = OS_RecvTCP(socket, OS_SIZE_1024);
266
267
268     /* Checking msg in here, since it may be null */
269     if(msg)
270         free(msg);
271
272
273     /* quitting and closing socket */
274     OS_SendTCP(socket,QUITMSG);
275     msg = OS_RecvTCP(socket, OS_SIZE_1024);
276
277     if(msg)
278         free(msg);
279
280     memset(snd_msg,'\0',128);   
281
282
283     /* Returning 0 (success) */
284     close(socket);
285
286     return(0);
287 }
288
289
290
291 /* EOF */