new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / remoted / secure.c
1 /* Copyright (C) 2009 Trend Micro Inc.
2  * All right 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 "os_net/os_net.h"
12 #include "remoted.h"
13
14
15 /* Handle secure connections */
16 void HandleSecure()
17 {
18     int agentid;
19     char buffer[OS_MAXSTR + 1];
20     char cleartext_msg[OS_MAXSTR + 1];
21     char srcip[IPSIZE + 1];
22     char *tmp_msg;
23     char srcmsg[OS_FLSIZE + 1];
24     ssize_t recv_b;
25     struct sockaddr_storage peer_info;
26     socklen_t peer_size;
27     fd_set fdsave, fdwork;                      /* select() work areas */
28     int fdmax;                                  /* max socket number + 1 */
29     int sock;                                   /* active socket */
30
31     /* Send msg init */
32     send_msg_init();
33
34     /* Initialize key mutex */
35     keyupdate_init();
36
37     /* Initialize manager */
38     manager_init(0);
39
40     /* Create Active Response forwarder thread */
41     if (CreateThread(AR_Forward, (void *)NULL) != 0) {
42         ErrorExit(THREAD_ERROR, ARGV0);
43     }
44
45     /* Create wait_for_msgs thread */
46     if (CreateThread(wait_for_msgs, (void *)NULL) != 0) {
47         ErrorExit(THREAD_ERROR, ARGV0);
48     }
49
50    /*
51     * Connect to the message queue
52     * Exit if it fails.
53     */
54     if ((logr.m_queue = StartMQ(DEFAULTQUEUE, WRITE)) < 0) {
55         ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQUEUE);
56     }
57
58     verbose(AG_AX_AGENTS, ARGV0, MAX_AGENTS);
59
60     /* Read authentication keys */
61     verbose(ENC_READ, ARGV0);
62
63     OS_ReadKeys(&keys);
64
65     debug1("%s: DEBUG: OS_StartCounter.", ARGV0);
66     OS_StartCounter(&keys);
67     debug1("%s: DEBUG: OS_StartCounter completed.", ARGV0);
68
69     /* Set up peer size */
70     peer_size = sizeof(peer_info);
71     logr.peer_size = sizeof(peer_info);
72
73     /* Initialize some variables */
74     memset(buffer, '\0', OS_MAXSTR + 1);
75     memset(cleartext_msg, '\0', OS_MAXSTR + 1);
76     memset(srcmsg, '\0', OS_FLSIZE + 1);
77     tmp_msg = NULL;
78
79     /* initialize select() save area */
80     fdsave = logr.netinfo->fdset;
81     fdmax  = logr.netinfo->fdmax;       /* value preset to max fd + 1 */
82
83     while (1) {
84         /* process connections through select() for multiple sockets */
85         fdwork = fdsave;
86         if (select (fdmax, &fdwork, NULL, NULL, NULL) < 0) {
87             ErrorExit("ERROR: Call to secure select() failed, errno %d - %s",
88                       errno, strerror (errno));
89         }
90
91         /* read through socket list for active socket */
92         for (sock = 0; sock <= fdmax; sock++) {
93             if (FD_ISSET (sock, &fdwork)) {
94
95                 /* Receive message  */
96                 recv_b = recvfrom(sock, buffer, OS_MAXSTR, 0,
97                                   (struct sockaddr *)&peer_info, &peer_size);
98
99                 /* Nothing received */
100                 if (recv_b <= 0) {
101                     continue;
102                 }
103
104                /*
105                 * send_msg() needs a socket, but we don't know which
106                 * socket is active until we receive our first packet.
107                 * This sets the socket for send_msg().
108                 */
109
110                 logr.sock = sock;
111
112                 /* Set the source IP */
113                 satop((struct sockaddr *) &peer_info, srcip, IPSIZE);
114                 srcip[IPSIZE] = '\0';
115
116                 /* Get a valid agent id */
117                 if (buffer[0] == '!') {
118                     tmp_msg = buffer;
119                     tmp_msg++;
120
121                    /*
122                     * We need to make sure that we have a valid id
123                     * and that we reduce the recv buffer size
124                     */
125                     while (isdigit((int)*tmp_msg)) {
126                         tmp_msg++;
127                         recv_b--;
128                     }
129
130                     if (*tmp_msg != '!') {
131                         merror(ENCFORMAT_ERROR, __local_name, srcip);
132                         continue;
133                     }
134
135                     *tmp_msg = '\0';
136                     tmp_msg++;
137                     recv_b -= 2;
138
139                     agentid = OS_IsAllowedDynamicID(&keys, buffer + 1, srcip);
140                     if (agentid == -1) {
141                         if (check_keyupdate()) {
142                             agentid = OS_IsAllowedDynamicID(&keys, buffer + 1, srcip);
143                             if (agentid == -1) {
144                                 merror(ENC_IP_ERROR, ARGV0, buffer + 1, srcip);
145                                 continue;
146                             }
147                         } else {
148                             merror(ENC_IP_ERROR, ARGV0, buffer + 1, srcip);
149                             continue;
150                         }
151                     }
152                 } else {
153                     agentid = OS_IsAllowedIP(&keys, srcip);
154                     if (agentid < 0) {
155                         if (check_keyupdate()) {
156                             agentid = OS_IsAllowedIP(&keys, srcip);
157                             if (agentid == -1) {
158                                 merror(DENYIP_WARN, ARGV0, srcip);
159                                 continue;
160                             }
161                         } else {
162                             merror(DENYIP_WARN, ARGV0, srcip);
163                             continue;
164                         }
165                     }
166                     tmp_msg = buffer;
167                 }
168
169                 /* Decrypt the message */
170                 tmp_msg = ReadSecMSG(&keys, tmp_msg, cleartext_msg,
171                                      agentid, recv_b - 1);
172                 if (tmp_msg == NULL) {
173                     /* If duplicated, a warning was already generated */
174                     continue;
175                 }
176
177                 /* Check if it is a control message */
178                 if (IsValidHeader(tmp_msg)) {
179                     /* We need to save the peerinfo if it is a control msg */
180                     memcpy(&keys.keyentries[agentid]->peer_info,
181                            &peer_info, peer_size);
182                     keys.keyentries[agentid]->rcvd = time(0);
183                     save_controlmsg((unsigned)agentid, tmp_msg);
184                     continue;
185                 }
186
187                 /* Generate srcmsg */
188                 snprintf(srcmsg, OS_FLSIZE, "(%s) %s",
189                          keys.keyentries[agentid]->name,
190                          keys.keyentries[agentid]->ip->ip);
191
192                /*
193                 * If we can't send the message, try to connect to the
194                 * socket again. If it fails exit.
195                 */
196                 if (SendMSG(logr.m_queue, tmp_msg, srcmsg,
197                             SECURE_MQ) < 0) {
198                     merror(QUEUE_ERROR, ARGV0, DEFAULTQUEUE, strerror(errno));
199
200                     if ((logr.m_queue = StartMQ(DEFAULTQUEUE, WRITE)) < 0) {
201                         ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQUEUE);
202                     }
203                 }
204             } /* if socket active */
205         } /* for() loop on sockets */
206     } /* while(1) loop for messages */
207 }
208