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