Imported Upstream version 2.7
[ossec-hids.git] / src / remoted / syslogtcp.c
1 /* @(#) $Id: ./src/remoted/syslogtcp.c, 2011/09/08 dcid Exp $
2  */
3
4 /* Copyright (C) 2009 Trend Micro Inc.
5  * All right 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
15 #include "shared.h"
16 #include "os_net/os_net.h"
17
18 #include "remoted.h"
19
20
21
22 /* OS_IPNotAllowed, v0.1, 2005/02/11
23  * Checks if an IP is not allowed.
24  */
25 static int OS_IPNotAllowed(char *srcip)
26 {
27     if(logr.denyips != NULL)
28     {
29         if(OS_IPFoundList(srcip, logr.denyips))
30         {
31             return(1);
32         }
33     }
34     if(logr.allowips != NULL)
35     {
36         if(OS_IPFoundList(srcip, logr.allowips))
37         {
38             return(0);
39         }
40     }
41
42     /* If the ip is not allowed, it will be denied */
43     return(1);
44 }
45
46
47 /** void HandleClient() v0,1
48  * Handle each client
49  */
50 static void HandleClient(int client_socket, char *srcip)
51 {
52     int sb_size = OS_MAXSTR;
53     int r_sz = 0;
54
55     char buffer[OS_MAXSTR +2];
56     char storage_buffer[OS_MAXSTR +2];
57     char tmp_buffer[OS_MAXSTR +2];
58
59     char *buffer_pt = NULL;
60
61
62     /* Initializing some variables */
63     memset(buffer, '\0', OS_MAXSTR +2);
64     memset(storage_buffer, '\0', OS_MAXSTR +2);
65     memset(tmp_buffer, '\0', OS_MAXSTR +2);
66
67
68     while(1)
69     {
70         /* If we fail, we need to return and close the socket */
71         if((r_sz = OS_RecvTCPBuffer(client_socket, buffer, OS_MAXSTR -2)) < 0)
72         {
73             close(client_socket);
74             return;
75         }
76
77         /* We must have a new line at the end */
78         buffer_pt = strchr(buffer, '\n');
79         if(!buffer_pt)
80         {
81             /* Buffer is full */
82             if((sb_size - r_sz) <= 2)
83             {
84                 merror("%s: Full buffer receiving from: '%s'", ARGV0, srcip);
85                 sb_size = OS_MAXSTR;
86                 storage_buffer[0] = '\0';
87                 continue;
88             }
89
90             strncat(storage_buffer, buffer, sb_size);
91             sb_size -= r_sz;
92             continue;
93         }
94
95         /* Seeing if we received more then just one message */
96         if(*(buffer_pt +1) != '\0')
97         {
98             *buffer_pt = '\0';
99             buffer_pt++;
100             strncpy(tmp_buffer, buffer_pt, OS_MAXSTR);
101         }
102
103         /* Storing everything on the storage_buffer */
104         /* Checking if buffer will be  full */
105         if((sb_size - r_sz) <= 2)
106         {
107             merror("%s: Full buffer receiving from: '%s'.", ARGV0, srcip);
108             sb_size = OS_MAXSTR;
109             storage_buffer[0] = '\0';
110             tmp_buffer[0] = '\0';
111             continue;
112         }
113
114         strncat(storage_buffer, buffer, sb_size);
115
116
117         /* Removing carriage returns too */
118         buffer_pt = strchr(storage_buffer, '\r');
119         if(buffer_pt)
120             *buffer_pt = '\0';
121
122
123         /* Removing syslog header */
124         if(storage_buffer[0] == '<')
125         {
126             buffer_pt = strchr(storage_buffer+1, '>');
127             if(buffer_pt)
128             {
129                 buffer_pt++;
130             }
131             else
132             {
133                 buffer_pt = storage_buffer;
134             }
135         }
136         else
137         {
138             buffer_pt = storage_buffer;
139         }
140
141
142         /* Sending to the queue */
143         if(SendMSG(logr.m_queue, buffer_pt, srcip,SYSLOG_MQ) < 0)
144         {
145             merror(QUEUE_ERROR,ARGV0,DEFAULTQUEUE, strerror(errno));
146             if((logr.m_queue = StartMQ(DEFAULTQUEUE,READ)) < 0)
147             {
148                 ErrorExit(QUEUE_FATAL,ARGV0,DEFAULTQUEUE);
149             }
150         }
151
152         /* Cleaning up the buffers */
153         if(tmp_buffer[0] != '\0')
154         {
155             strncpy(storage_buffer, tmp_buffer, OS_MAXSTR);
156             sb_size = OS_MAXSTR - (strlen(storage_buffer) +1);
157             tmp_buffer[0] = '\0';
158         }
159         else
160         {
161             storage_buffer[0] = '\0';
162             sb_size = OS_MAXSTR;
163         }
164     }
165 }
166
167
168 /** void HandleSyslogTCP() v0.2
169  * Handle syslog tcp connections
170  */
171 void HandleSyslogTCP()
172 {
173     int client_socket = 0;
174     int st_errors = 0;
175     int childcount = 0;
176
177     char srcip[IPSIZE +1];
178
179     /* Initializing some variables */
180     memset(srcip, '\0', IPSIZE + 1);
181
182
183     /* Connecting to the message queue
184      * Exit if it fails.
185      */
186     if((logr.m_queue = StartMQ(DEFAULTQUEUE,WRITE)) < 0)
187     {
188         ErrorExit(QUEUE_FATAL,ARGV0, DEFAULTQUEUE);
189     }
190
191
192     /* Infinit loop in here */
193     while(1)
194     {
195         /* Waiting for the childs .. */
196         while (childcount)
197         {
198             int wp;
199             wp = waitpid((pid_t) -1, NULL, WNOHANG);
200             if (wp < 0)
201                 merror(WAITPID_ERROR, ARGV0);
202
203             /* if = 0, we still need to wait for the child process */
204             else if (wp == 0)
205                 break;
206             else
207                 childcount--;
208         }
209
210
211         /* Accepting new connections */
212         client_socket = OS_AcceptTCP(logr.sock, srcip, IPSIZE);
213         if(client_socket < 0)
214         {
215             st_errors++;
216         }
217
218         /* Checking if IP is allowed here */
219         if(OS_IPNotAllowed(srcip))
220         {
221             merror(DENYIP_WARN,ARGV0,srcip);
222             close(client_socket);
223         }
224
225
226         /* Forking to deal with new client */
227         if(fork() == 0)
228         {
229             HandleClient(client_socket, srcip);
230             exit(0);
231         }
232         else
233         {
234             childcount++;
235
236             /* Closing client socket, since the child is handling it */
237             close(client_socket);
238             continue;
239         }
240
241         /* The parent process should not reach here */
242         return;
243     }
244 }
245
246
247
248 /* EOF */