Imported Upstream version 2.7
[ossec-hids.git] / src / remoted / secure.c
1 /* @(#) $Id: ./src/remoted/secure.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
19 #include "remoted.h"
20
21
22 /** void HandleSecure() v0.3
23  * Handle the secure connections
24  */
25 void HandleSecure()
26 {
27     int agentid;
28
29     char buffer[OS_MAXSTR +1];
30     char cleartext_msg[OS_MAXSTR +1];
31     char srcip[IPSIZE +1];
32     char *tmp_msg;
33     char srcmsg[OS_FLSIZE +1];
34
35
36     int recv_b;
37
38     struct sockaddr_in peer_info;
39     socklen_t peer_size;
40
41
42     /* Send msg init */
43     send_msg_init();
44
45
46     /* Initializing key mutex. */
47     keyupdate_init();
48
49
50     /* Initializing manager */
51     manager_init(0);
52
53
54     /* Creating Ar forwarder thread */
55     if(CreateThread(AR_Forward, (void *)NULL) != 0)
56     {
57         ErrorExit(THREAD_ERROR, ARGV0);
58     }
59
60     /* Creating wait_for_msgs thread */
61     if(CreateThread(wait_for_msgs, (void *)NULL) != 0)
62     {
63         ErrorExit(THREAD_ERROR, ARGV0);
64     }
65
66
67     /* Connecting to the message queue
68      * Exit if it fails.
69      */
70     if((logr.m_queue = StartMQ(DEFAULTQUEUE,WRITE)) < 0)
71     {
72         ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQUEUE);
73     }
74
75
76     verbose(AG_AX_AGENTS, ARGV0, MAX_AGENTS);
77
78
79     /* Reading authentication keys */
80     verbose(ENC_READ, ARGV0);
81
82     OS_ReadKeys(&keys);
83
84     debug1("%s: DEBUG: OS_StartCounter.", ARGV0);
85     OS_StartCounter(&keys);
86     debug1("%s: DEBUG: OS_StartCounter completed.", ARGV0);
87
88
89     /* setting up peer size */
90     peer_size = sizeof(peer_info);
91     logr.peer_size = sizeof(peer_info);
92
93
94     /* Initializing some variables */
95     memset(buffer, '\0', OS_MAXSTR +1);
96     memset(cleartext_msg, '\0', OS_MAXSTR +1);
97     memset(srcmsg, '\0', OS_FLSIZE +1);
98     tmp_msg = NULL;
99
100
101
102     /* loop in here */
103     while(1)
104     {
105         /* Receiving message  */
106         recv_b = recvfrom(logr.sock, buffer, OS_MAXSTR, 0,
107                 (struct sockaddr *)&peer_info, &peer_size);
108
109
110         /* Nothing received */
111         if(recv_b <= 0)
112         {
113             continue;
114         }
115
116
117         /* Setting the source ip */
118         strncpy(srcip, inet_ntoa(peer_info.sin_addr), IPSIZE);
119         srcip[IPSIZE] = '\0';
120
121
122
123         /* Getting a valid agentid */
124         if(buffer[0] == '!')
125         {
126             tmp_msg = buffer;
127             tmp_msg++;
128
129
130             /* We need to make sure that we have a valid id
131              * and that we reduce the recv buffer size.
132              */
133             while(isdigit((int)*tmp_msg))
134             {
135                 tmp_msg++;
136                 recv_b--;
137             }
138
139             if(*tmp_msg != '!')
140             {
141                 merror(ENCFORMAT_ERROR, __local_name, srcip);
142                 continue;
143             }
144
145             *tmp_msg = '\0';
146             tmp_msg++;
147             recv_b-=2;
148
149             agentid = OS_IsAllowedDynamicID(&keys, buffer +1, srcip);
150             if(agentid == -1)
151             {
152                 if(check_keyupdate())
153                 {
154                     agentid = OS_IsAllowedDynamicID(&keys, buffer +1, srcip);
155                     if(agentid == -1)
156                     {
157                         merror(ENC_IP_ERROR, ARGV0, srcip);
158                         continue;
159                     }
160                 }
161                 else
162                 {
163                     merror(ENC_IP_ERROR, ARGV0, srcip);
164                     continue;
165                 }
166             }
167         }
168         else
169         {
170             agentid = OS_IsAllowedIP(&keys, srcip);
171             if(agentid < 0)
172             {
173                 if(check_keyupdate())
174                 {
175                     agentid = OS_IsAllowedIP(&keys, srcip);
176                     if(agentid == -1)
177                     {
178                         merror(DENYIP_WARN,ARGV0,srcip);
179                         continue;
180                     }
181                 }
182                 else
183                 {
184                     merror(DENYIP_WARN,ARGV0,srcip);
185                     continue;
186                 }
187             }
188             tmp_msg = buffer;
189         }
190
191
192         /* Decrypting the message */
193         tmp_msg = ReadSecMSG(&keys, tmp_msg, cleartext_msg,
194                              agentid, recv_b -1);
195         if(tmp_msg == NULL)
196         {
197             /* If duplicated, a warning was already generated */
198             continue;
199         }
200
201
202         /* Check if it is a control message */
203         if(IsValidHeader(tmp_msg))
204         {
205             /* We need to save the peerinfo if it is a control msg */
206             memcpy(&keys.keyentries[agentid]->peer_info, &peer_info, peer_size);
207             keys.keyentries[agentid]->rcvd = time(0);
208
209             save_controlmsg(agentid, tmp_msg);
210
211             continue;
212         }
213
214
215         /* Generating srcmsg */
216         snprintf(srcmsg, OS_FLSIZE,"(%s) %s",keys.keyentries[agentid]->name,
217                                              keys.keyentries[agentid]->ip->ip);
218
219
220         /* If we can't send the message, try to connect to the
221          * socket again. If it not exit.
222          */
223         if(SendMSG(logr.m_queue, tmp_msg, srcmsg,
224                    SECURE_MQ) < 0)
225         {
226             merror(QUEUE_ERROR, ARGV0, DEFAULTQUEUE, strerror(errno));
227
228             if((logr.m_queue = StartMQ(DEFAULTQUEUE, WRITE)) < 0)
229             {
230                 ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQUEUE);
231             }
232         }
233     }
234 }
235
236
237
238 /* EOF */