1 /* Copyright (C) 2009 Trend Micro Inc.
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
11 #include "os_net/os_net.h"
15 /* Handle secure connections */
19 char buffer[OS_MAXSTR + 1];
20 char cleartext_msg[OS_MAXSTR + 1];
21 char srcip[IPSIZE + 1];
23 char srcmsg[OS_FLSIZE + 1];
25 struct sockaddr_storage peer_info;
27 fd_set fdsave, fdwork; /* select() work areas */
28 int fdmax; /* max socket number + 1 */
29 int sock; /* active socket */
34 /* Initialize key mutex */
37 /* Initialize manager */
40 /* Create Active Response forwarder thread */
41 if (CreateThread(AR_Forward, (void *)NULL) != 0) {
42 ErrorExit(THREAD_ERROR, ARGV0);
45 /* Create wait_for_msgs thread */
46 if (CreateThread(wait_for_msgs, (void *)NULL) != 0) {
47 ErrorExit(THREAD_ERROR, ARGV0);
51 * Connect to the message queue
54 if ((logr.m_queue = StartMQ(DEFAULTQUEUE, WRITE)) < 0) {
55 ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQUEUE);
58 verbose(AG_AX_AGENTS, ARGV0, MAX_AGENTS);
60 /* Read authentication keys */
61 verbose(ENC_READ, ARGV0);
65 debug1("%s: DEBUG: OS_StartCounter.", ARGV0);
66 OS_StartCounter(&keys);
67 debug1("%s: DEBUG: OS_StartCounter completed.", ARGV0);
69 /* Set up peer size */
70 peer_size = sizeof(peer_info);
71 logr.peer_size = sizeof(peer_info);
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);
79 /* initialize select() save area */
80 fdsave = logr.netinfo->fdset;
81 fdmax = logr.netinfo->fdmax; /* value preset to max fd + 1 */
84 /* process connections through select() for multiple sockets */
86 if (select (fdmax, &fdwork, NULL, NULL, NULL) < 0) {
87 ErrorExit("ERROR: Call to secure select() failed, errno %d - %s",
88 errno, strerror (errno));
91 /* read through socket list for active socket */
92 for (sock = 0; sock <= fdmax; sock++) {
93 if (FD_ISSET (sock, &fdwork)) {
96 recv_b = recvfrom(sock, buffer, OS_MAXSTR, 0,
97 (struct sockaddr *)&peer_info, &peer_size);
99 /* Nothing received */
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().
112 /* Set the source IP */
113 satop((struct sockaddr *) &peer_info, srcip, IPSIZE);
114 srcip[IPSIZE] = '\0';
116 /* Get a valid agent id */
117 if (buffer[0] == '!') {
122 * We need to make sure that we have a valid id
123 * and that we reduce the recv buffer size
125 while (isdigit((int)*tmp_msg)) {
130 if (*tmp_msg != '!') {
131 merror(ENCFORMAT_ERROR, __local_name, srcip);
139 agentid = OS_IsAllowedDynamicID(&keys, buffer + 1, srcip);
141 if (check_keyupdate()) {
142 agentid = OS_IsAllowedDynamicID(&keys, buffer + 1, srcip);
144 merror(ENC_IP_ERROR, ARGV0, buffer + 1, srcip);
148 merror(ENC_IP_ERROR, ARGV0, buffer + 1, srcip);
153 agentid = OS_IsAllowedIP(&keys, srcip);
155 if (check_keyupdate()) {
156 agentid = OS_IsAllowedIP(&keys, srcip);
158 merror(DENYIP_WARN, ARGV0, srcip);
162 merror(DENYIP_WARN, ARGV0, srcip);
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 */
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);
187 /* Generate srcmsg */
188 snprintf(srcmsg, OS_FLSIZE, "(%s) %s",
189 keys.keyentries[agentid]->name,
190 keys.keyentries[agentid]->ip->ip);
193 * If we can't send the message, try to connect to the
194 * socket again. If it fails exit.
196 if (SendMSG(logr.m_queue, tmp_msg, srcmsg,
198 merror(QUEUE_ERROR, ARGV0, DEFAULTQUEUE, strerror(errno));
200 if ((logr.m_queue = StartMQ(DEFAULTQUEUE, WRITE)) < 0) {
201 ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQUEUE);
204 } /* if socket active */
205 } /* for() loop on sockets */
206 } /* while(1) loop for messages */