Imported Upstream version 2.7
[ossec-hids.git] / src / logcollector / read_djb_multilog.c
1 /* @(#) $Id: ./src/logcollector/read_djb_multilog.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  * License details at the LICENSE file included with OSSEC or
13  * online at: http://www.ossec.net/en/licensing.html
14  */
15
16 /* Read DJB multilog */
17
18
19 #include "shared.h"
20 #include "logcollector.h"
21
22
23 /* To translante between month (int) to month (char) */
24 char *(djb_month[])={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug",
25                      "Sep","Oct","Nov","Dec"};
26
27 char djb_host[512 +1];
28
29
30
31 /* Initializes multilog. */
32 int init_djbmultilog(int pos)
33 {
34     char *djbp_name = NULL;
35     char *tmp_str = NULL;
36
37
38     logff[pos].djb_program_name = NULL;
39
40
41     /* Initializing hostname. */
42     memset(djb_host, '\0', 512 +1);
43
44     #ifndef WIN32
45     if(gethostname(djb_host, 512 -1) != 0)
46     {
47         strncpy(djb_host, "unknown", 512 -1);
48     }
49     else
50     {
51         char *_ltmp;
52
53         /* Remove domain part if available */
54         _ltmp = strchr(djb_host, '.');
55         if(_ltmp)
56             *_ltmp = '\0';
57     }
58     #else
59     strncpy(djb_host, "win32", 512 -1);
60     #endif
61
62
63
64     /* Multilog must be in the following format: /path/program_name/current */
65     tmp_str = strrchr(logff[pos].file, '/');
66     if(!tmp_str)
67         return(0);
68
69
70     /* Must end with /current and must not be in the beginning of the string. */
71     if((strcmp(tmp_str, "/current") != 0) || (tmp_str == logff[pos].file))
72     {
73         return(0);
74     }
75
76
77     tmp_str[0] = '\0';
78
79
80     /* Getting final name. */
81     djbp_name = strrchr(logff[pos].file, '/');
82     if(djbp_name == logff[pos].file)
83     {
84         tmp_str[0] = '/';
85         return(0);
86     }
87
88
89     os_strdup(djbp_name+1, logff[pos].djb_program_name);
90     tmp_str[0] = '/';
91
92
93     verbose("%s: INFO: Using program name '%s' for DJB multilog file: '%s'.",
94             ARGV0, logff[pos].djb_program_name, logff[pos].file);
95
96
97     return(1);
98 }
99
100
101
102 /* Read DJB multilog. */
103 void *read_djbmultilog(int pos, int *rc, int drop_it)
104 {
105     int str_len = 0;
106     int need_clear = 0;
107     char *p;
108     char str[OS_MAXSTR + 1];
109     char buffer[OS_MAXSTR + 1];
110
111     str[OS_MAXSTR]= '\0';
112     *rc = 0;
113
114
115     /* Must have a valid program name. */
116     if(!logff[pos].djb_program_name)
117     {
118         return(NULL);
119     }
120
121
122
123     /* Getting new entry */
124     while(fgets(str, OS_MAXSTR - OS_LOG_HEADER, logff[pos].fp) != NULL)
125     {
126
127         /* Getting buffer size */
128         str_len = strlen(str);
129
130
131         /* Getting the last occurence of \n */
132         if ((p = strrchr(str, '\n')) != NULL)
133         {
134             *p = '\0';
135
136             /* If need clear is set, we just get the line and ignore it. */
137             if(need_clear)
138             {
139                 need_clear = 0;
140                 continue;
141             }
142         }
143         else
144         {
145             need_clear = 1;
146         }
147
148
149         /* Multilog messages have the following format:
150          * @40000000463246020c2ca16c xx...
151          */
152         if((str_len > 26) &&
153            (str[0] == '@') &&
154            isalnum((int)str[1]) &&
155            isalnum((int)str[2]) &&
156            isalnum((int)str[3]) &&
157            isalnum((int)str[24]) &&
158            (str[25] == ' '))
159         {
160             /* Removing spaces and tabs */
161             p = str + 26;
162             while(*p == ' ' || *p == '\t')
163             {
164                 p++;
165             }
166
167
168             /* If message has a valid syslog header, send as is. */
169             if((str_len > 44) &&
170                (p[3] == ' ') &&
171                (p[6] == ' ') &&
172                (p[9] == ':') &&
173                (p[12] == ':') &&
174                (p[15] == ' '))
175             {
176                 p+=16;
177                 strncpy(buffer, p, OS_MAXSTR);
178             }
179             else
180             {
181                 /* We will add a proper syslog header. */
182                 time_t djbtime;
183                 struct tm *pt;
184
185
186                 djbtime = time(NULL);
187                 pt = localtime(&djbtime);
188
189
190                 /* Syslog time: Apr 27 14:50:32  */
191                 snprintf(buffer, OS_MAXSTR, "%s %02d %02d:%02d:%02d %s %s: %s",
192                                              djb_month[pt->tm_mon],
193                                              pt->tm_mday,
194                                              pt->tm_hour,
195                                              pt->tm_min,
196                                              pt->tm_sec,
197                                              djb_host,
198                                              logff[pos].djb_program_name,
199                                              p);
200             }
201         }
202
203
204         else
205         {
206             debug2("%s: DEBUG: Invalid DJB log: '%s'", ARGV0, str);
207             continue;
208         }
209
210
211         debug2("%s: DEBUG: Reading DJB multilog message: '%s'", ARGV0, buffer);
212
213
214         /* Sending message to queue */
215         if(drop_it == 0)
216         {
217             if(SendMSG(logr_queue, buffer, logff[pos].file, MYSQL_MQ) < 0)
218             {
219                 merror(QUEUE_SEND, ARGV0);
220                 if((logr_queue = StartMQ(DEFAULTQPATH,WRITE)) < 0)
221                 {
222                     ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH);
223                 }
224             }
225         }
226
227         continue;
228     }
229
230     return(NULL);
231 }
232
233 /* EOF */