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