new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / os_csyslogd / csyslogd.c
1 /* Copyright (C) 2009 Trend Micro Inc.
2  * All rights reserved.
3  *
4  * This program is a free software; you can redistribute it
5  * and/or modify it under the terms of the GNU General Public
6  * License (version 2) as published by the FSF - Free Software
7  * Foundation.
8  */
9
10 #include "shared.h"
11 #include "csyslogd.h"
12 #include "os_net/os_net.h"
13
14 /* Global variables */
15 char __shost[512];
16 char __shost_long[512];
17
18
19 /* Monitor the alerts and send them via syslog
20  * Only return in case of error
21  */
22 void OS_CSyslogD(SyslogConfig **syslog_config)
23 {
24     int s = 0;
25     time_t tm;
26     struct tm *p;
27     int tries = 0;
28     file_queue *fileq;
29     alert_data *al_data;
30
31     /* Get current time before starting */
32     tm = time(NULL);
33     p = localtime(&tm);
34
35     /* Initialize file queue to read the alerts */
36     os_calloc(1, sizeof(file_queue), fileq);
37     while ( (Init_FileQueue(fileq, p, 0) ) < 0 ) {
38         tries++;
39         if ( tries > OS_CSYSLOGD_MAX_TRIES ) {
40             merror("%s: ERROR: Could not open queue after %d tries, exiting!",
41                    ARGV0, tries
42                   );
43             exit(1);
44         }
45         sleep(1);
46     }
47     debug1("%s: INFO: File queue connected.", ARGV0 );
48
49     /* Connect to syslog */
50     s = 0;
51     while (syslog_config[s]) {
52         syslog_config[s]->socket = OS_ConnectUDP(syslog_config[s]->port,
53                                                  syslog_config[s]->server);
54         if (syslog_config[s]->socket < 0) {
55             merror(CONNS_ERROR, ARGV0, syslog_config[s]->server);
56         } else {
57             merror("%s: INFO: Forwarding alerts via syslog to: '%s:%s'.",
58                    ARGV0, syslog_config[s]->server, syslog_config[s]->port);
59         }
60
61         s++;
62     }
63
64     /* Infinite loop reading the alerts and inserting them */
65     while (1) {
66         tm = time(NULL);
67         p = localtime(&tm);
68
69         /* Get message if available (timeout of 5 seconds) */
70         al_data = Read_FileMon(fileq, p, 5);
71         if (!al_data) {
72             continue;
73         }
74
75         /* Send via syslog */
76         s = 0;
77         while (syslog_config[s]) {
78             OS_Alert_SendSyslog(al_data, syslog_config[s]);
79             s++;
80         }
81
82         /* Clear the memory */
83         FreeAlertData(al_data);
84     }
85 }
86
87 /* Format Field for output */
88 int field_add_string(char *dest, size_t size, const char *format, const char *value )
89 {
90     char buffer[OS_SIZE_2048];
91     int len = 0;
92     int dest_sz = size - strlen(dest);
93
94     /* Not enough room in the buffer? */
95     if (dest_sz <= 0 ) {
96         return -1;
97     }
98
99     if (value != NULL &&
100             (
101                 ((value[0] != '(') && (value[1] != 'n') && (value[2] != 'o')) ||
102                 ((value[0] != '(') && (value[1] != 'u') && (value[2] != 'n')) ||
103                 ((value[0] != 'u') && (value[1] != 'n') && (value[4] != 'k'))
104             )
105        ) {
106         len = snprintf(buffer, sizeof(buffer) - dest_sz - 1, format, value);
107         strncat(dest, buffer, dest_sz);
108     }
109
110     return len;
111 }
112
113 /* Add a field, but truncate if too long */
114 int field_add_truncated(char *dest, size_t size, const char *format, const char *value, int fmt_size )
115 {
116     char buffer[OS_SIZE_2048];
117
118     int available_sz = size - strlen(dest);
119     int total_sz = strlen(value) + strlen(format) - fmt_size;
120     int field_sz = available_sz - strlen(format) + fmt_size;
121
122     int len = 0;
123     char trailer[] = "...";
124     char *truncated = NULL;
125
126     /* Not enough room in the buffer? */
127     if (available_sz <= 0 ) {
128         return -1;
129     }
130
131     if (
132         ((value[0] != '(') && (value[1] != 'n') && (value[2] != 'o')) ||
133         ((value[0] != '(') && (value[1] != 'u') && (value[2] != 'n')) ||
134         ((value[0] != 'u') && (value[1] != 'n') && (value[4] != 'k'))
135        ) {
136
137         if ( (truncated = (char *) malloc(field_sz + 1)) != NULL ) {
138             if ( total_sz > available_sz ) {
139                 /* Truncate and add a trailer */
140                 os_substr(truncated, value, 0, field_sz - strlen(trailer));
141                 strcat(truncated, trailer);
142             } else {
143                 strncpy(truncated, value, field_sz);
144             }
145
146             len = snprintf(buffer, available_sz, format, truncated);
147             strncat(dest, buffer, available_sz);
148         } else {
149             /* Memory Error */
150             len = -3;
151         }
152     }
153     /* Free the temporary pointer */
154     free(truncated);
155
156     return len;
157 }
158
159 /* Handle integers in the second position */
160 int field_add_int(char *dest, size_t size, const char *format, const int value )
161 {
162     char buffer[255];
163     int len = 0;
164     int dest_sz = size - strlen(dest);
165
166     /* Not enough room in the buffer? */
167     if (dest_sz <= 0 ) {
168         return -1;
169     }
170
171     if ( value > 0 ) {
172         len = snprintf(buffer, sizeof(buffer), format, value);
173         strncat(dest, buffer, dest_sz);
174     }
175
176     return len;
177 }
178