Imported Upstream version 2.7
[ossec-hids.git] / src / os_csyslogd / csyslogd.c
1 /* @(#) $Id: ./src/os_csyslogd/csyslogd.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
17
18 /* strnlen is a GNU extension */
19 #ifdef __linux__
20  #define _GNU_SOURCE
21  #include <string.h>
22 #endif
23 #include "csyslogd.h"
24 #include "os_net/os_net.h"
25
26
27
28 /* OS_SyslogD: Monitor the alerts and sends them via syslog.
29  * Only return in case of error.
30  */
31 void OS_CSyslogD(SyslogConfig **syslog_config)
32 {
33     int s = 0;
34     time_t tm;
35     struct tm *p;
36     int tries = 0;
37
38     file_queue *fileq;
39     alert_data *al_data;
40
41
42     /* Getting currently time before starting */
43     tm = time(NULL);
44     p = localtime(&tm);
45
46
47     /* Initating file queue - to read the alerts */
48     os_calloc(1, sizeof(file_queue), fileq);
49     while( (Init_FileQueue(fileq, p, 0) ) < 0 ) {
50         tries++;
51         if( tries > OS_CSYSLOGD_MAX_TRIES ) {
52             merror("%s: ERROR: Could not open queue after %d tries, exiting!",
53                    ARGV0, tries
54             );
55             exit(1);
56         }
57         sleep(1);
58     }
59     merror("%s: INFO: File queue connected.", ARGV0 );
60
61
62     /* Connecting to syslog. */
63     s = 0;
64     while(syslog_config[s])
65     {
66         syslog_config[s]->socket = OS_ConnectUDP(syslog_config[s]->port,
67                                                  syslog_config[s]->server, 0);
68         if(syslog_config[s]->socket < 0)
69         {
70             merror(CONNS_ERROR, ARGV0, syslog_config[s]->server);
71         }
72         else
73         {
74             merror("%s: INFO: Forwarding alerts via syslog to: '%s:%d'.",
75                    ARGV0, syslog_config[s]->server, syslog_config[s]->port);
76         }
77
78         s++;
79     }
80
81
82
83     /* Infinite loop reading the alerts and inserting them. */
84     while(1)
85     {
86         tm = time(NULL);
87         p = localtime(&tm);
88
89
90         /* Get message if available (timeout of 5 seconds) */
91         al_data = Read_FileMon(fileq, p, 5);
92         if(!al_data)
93         {
94             continue;
95         }
96
97
98
99         /* Sending via syslog */
100         s = 0;
101         while(syslog_config[s])
102         {
103             OS_Alert_SendSyslog(al_data, syslog_config[s]);
104             s++;
105         }
106
107
108         /* Clearing the memory */
109         FreeAlertData(al_data);
110     }
111 }
112
113 /* Format Field for output */
114 int field_add_string(char *dest, int size, const char *format, const char *value ) {
115     char buffer[OS_SIZE_2048];
116     int len = 0;
117     int dest_sz = size - strnlen(dest, OS_SIZE_2048);
118
119     if(dest_sz <= 0 ) {
120         // Not enough room in the buffer
121         return -1;
122     }
123
124     if(value != NULL &&
125             (
126                 ((value[0] != '(') && (value[1] != 'n') && (value[2] != 'o')) ||
127                 ((value[0] != '(') && (value[1] != 'u') && (value[2] != 'n')) ||
128                 ((value[0] != 'u') && (value[1] != 'n') && (value[4] != 'k'))
129             )
130     ) {
131         len = snprintf(buffer, sizeof(buffer) - dest_sz - 1, format, value);
132         strncat(dest, buffer, dest_sz);
133     }
134
135     return len;
136 }
137
138 /* Add a field, but truncate if too long */
139 int field_add_truncated(char *dest, int size, const char *format, const char *value, int fmt_size ) {
140     char buffer[OS_SIZE_2048];
141
142     int available_sz = size - strnlen(dest, OS_SIZE_2048);
143     int total_sz = strlen(value) + strlen(format) - fmt_size;
144     int field_sz = available_sz - strlen(format) + fmt_size;
145
146     int len = 0;
147     char trailer[] = "...";
148     char *truncated;
149
150     if(available_sz <= 0 ) {
151         // Not enough room in the buffer
152         return -1;
153     }
154
155     if(value != NULL &&
156             (
157                 ((value[0] != '(') && (value[1] != 'n') && (value[2] != 'o')) ||
158                 ((value[0] != '(') && (value[1] != 'u') && (value[2] != 'n')) ||
159                 ((value[0] != 'u') && (value[1] != 'n') && (value[4] != 'k'))
160             )
161     ) {
162
163         if( (truncated=malloc(field_sz + 1)) != NULL ) {
164             if( total_sz > available_sz ) {
165                 // Truncate and add a trailer
166                 os_substr(truncated, value, 0, field_sz - strlen(trailer));
167                 strcat(truncated, trailer);
168             }
169             else {
170                 strncpy(truncated,value,field_sz);
171             }
172
173             len = snprintf(buffer, available_sz, format, truncated);
174             strncat(dest, buffer, available_sz);
175         }
176         else {
177             // Memory Error
178             len = -3;
179         }
180     }
181     // Free the temporary pointer
182     free(truncated);
183
184     return len;
185 }
186
187 /* Handle integers in the second position */
188 int field_add_int(char *dest, int size, const char *format, const int value ) {
189     char buffer[255];
190     int len = 0;
191     int dest_sz = size - strnlen(dest, OS_SIZE_2048);
192
193     if(dest_sz <= 0 ) {
194         // Not enough room in the buffer
195         return -1;
196     }
197
198     if( value > 0 ) {
199         len = snprintf(buffer, sizeof(buffer), format, value);
200         strncat(dest, buffer, dest_sz);
201     }
202
203     return len;
204 }
205 /* EOF */