new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / remoted / secure.c
old mode 100755 (executable)
new mode 100644 (file)
index 39f4269..861bfba
@@ -1,6 +1,3 @@
-/* @(#) $Id: ./src/remoted/secure.c, 2011/09/08 dcid Exp $
- */
-
 /* Copyright (C) 2009 Trend Micro Inc.
  * All right reserved.
  *
  * Foundation
  */
 
-
-
 #include "shared.h"
 #include "os_net/os_net.h"
-
-
 #include "remoted.h"
 
 
-/** void HandleSecure() v0.3
- * Handle the secure connections
- */
+/* Handle secure connections */
 void HandleSecure()
 {
     int agentid;
-
-    char buffer[OS_MAXSTR +1];
-    char cleartext_msg[OS_MAXSTR +1];
-    char srcip[IPSIZE +1];
+    char buffer[OS_MAXSTR + 1];
+    char cleartext_msg[OS_MAXSTR + 1];
+    char srcip[IPSIZE + 1];
     char *tmp_msg;
-    char srcmsg[OS_FLSIZE +1];
-
-
-    int recv_b;
-
-    struct sockaddr_in peer_info;
+    char srcmsg[OS_FLSIZE + 1];
+    ssize_t recv_b;
+    struct sockaddr_storage peer_info;
     socklen_t peer_size;
-
+    fd_set fdsave, fdwork;                     /* select() work areas */
+    int fdmax;                                 /* max socket number + 1 */
+    int sock;                                  /* active socket */
 
     /* Send msg init */
     send_msg_init();
 
-
-    /* Initializing key mutex. */
+    /* Initialize key mutex */
     keyupdate_init();
 
-
-    /* Initializing manager */
+    /* Initialize manager */
     manager_init(0);
 
-
-    /* Creating Ar forwarder thread */
-    if(CreateThread(AR_Forward, (void *)NULL) != 0)
-    {
+    /* Create Active Response forwarder thread */
+    if (CreateThread(AR_Forward, (void *)NULL) != 0) {
         ErrorExit(THREAD_ERROR, ARGV0);
     }
 
-    /* Creating wait_for_msgs thread */
-    if(CreateThread(wait_for_msgs, (void *)NULL) != 0)
-    {
+    /* Create wait_for_msgs thread */
+    if (CreateThread(wait_for_msgs, (void *)NULL) != 0) {
         ErrorExit(THREAD_ERROR, ARGV0);
     }
 
-
-    /* Connecting to the message queue
-     * Exit if it fails.
-     */
-    if((logr.m_queue = StartMQ(DEFAULTQUEUE,WRITE)) < 0)
-    {
+   /*
+    * Connect to the message queue
+    * Exit if it fails.
+    */
+    if ((logr.m_queue = StartMQ(DEFAULTQUEUE, WRITE)) < 0) {
         ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQUEUE);
     }
 
-
     verbose(AG_AX_AGENTS, ARGV0, MAX_AGENTS);
 
-
-    /* Reading authentication keys */
+    /* Read authentication keys */
     verbose(ENC_READ, ARGV0);
 
     OS_ReadKeys(&keys);
@@ -85,154 +66,143 @@ void HandleSecure()
     OS_StartCounter(&keys);
     debug1("%s: DEBUG: OS_StartCounter completed.", ARGV0);
 
-
-    /* setting up peer size */
+    /* Set up peer size */
     peer_size = sizeof(peer_info);
     logr.peer_size = sizeof(peer_info);
 
-
-    /* Initializing some variables */
-    memset(buffer, '\0', OS_MAXSTR +1);
-    memset(cleartext_msg, '\0', OS_MAXSTR +1);
-    memset(srcmsg, '\0', OS_FLSIZE +1);
+    /* Initialize some variables */
+    memset(buffer, '\0', OS_MAXSTR + 1);
+    memset(cleartext_msg, '\0', OS_MAXSTR + 1);
+    memset(srcmsg, '\0', OS_FLSIZE + 1);
     tmp_msg = NULL;
 
+    /* initialize select() save area */
+    fdsave = logr.netinfo->fdset;
+    fdmax  = logr.netinfo->fdmax;      /* value preset to max fd + 1 */
 
-
-    /* loop in here */
-    while(1)
-    {
-        /* Receiving message  */
-        recv_b = recvfrom(logr.sock, buffer, OS_MAXSTR, 0,
-                (struct sockaddr *)&peer_info, &peer_size);
-
-
-        /* Nothing received */
-        if(recv_b <= 0)
-        {
-            continue;
+    while (1) {
+        /* process connections through select() for multiple sockets */
+        fdwork = fdsave;
+        if (select (fdmax, &fdwork, NULL, NULL, NULL) < 0) {
+            ErrorExit("ERROR: Call to secure select() failed, errno %d - %s",
+                      errno, strerror (errno));
         }
 
+        /* read through socket list for active socket */
+        for (sock = 0; sock <= fdmax; sock++) {
+            if (FD_ISSET (sock, &fdwork)) {
 
-        /* Setting the source ip */
-        strncpy(srcip, inet_ntoa(peer_info.sin_addr), IPSIZE);
-        srcip[IPSIZE] = '\0';
+                /* Receive message  */
+                recv_b = recvfrom(sock, buffer, OS_MAXSTR, 0,
+                                  (struct sockaddr *)&peer_info, &peer_size);
 
+                /* Nothing received */
+                if (recv_b <= 0) {
+                    continue;
+                }
 
+               /*
+                * send_msg() needs a socket, but we don't know which
+                * socket is active until we receive our first packet.
+                * This sets the socket for send_msg().
+                */
+
+                logr.sock = sock;
+
+                /* Set the source IP */
+                satop((struct sockaddr *) &peer_info, srcip, IPSIZE);
+                srcip[IPSIZE] = '\0';
+
+                /* Get a valid agent id */
+                if (buffer[0] == '!') {
+                    tmp_msg = buffer;
+                    tmp_msg++;
+
+                   /*
+                    * We need to make sure that we have a valid id
+                    * and that we reduce the recv buffer size
+                    */
+                    while (isdigit((int)*tmp_msg)) {
+                        tmp_msg++;
+                        recv_b--;
+                    }
 
-        /* Getting a valid agentid */
-        if(buffer[0] == '!')
-        {
-            tmp_msg = buffer;
-            tmp_msg++;
-
-
-            /* We need to make sure that we have a valid id
-             * and that we reduce the recv buffer size.
-             */
-            while(isdigit((int)*tmp_msg))
-            {
-                tmp_msg++;
-                recv_b--;
-            }
-
-            if(*tmp_msg != '!')
-            {
-                merror(ENCFORMAT_ERROR, __local_name, srcip);
-                continue;
-            }
-
-            *tmp_msg = '\0';
-            tmp_msg++;
-            recv_b-=2;
-
-            agentid = OS_IsAllowedDynamicID(&keys, buffer +1, srcip);
-            if(agentid == -1)
-            {
-                if(check_keyupdate())
-                {
-                    agentid = OS_IsAllowedDynamicID(&keys, buffer +1, srcip);
-                    if(agentid == -1)
-                    {
-                        merror(ENC_IP_ERROR, ARGV0, srcip);
+                    if (*tmp_msg != '!') {
+                        merror(ENCFORMAT_ERROR, __local_name, srcip);
                         continue;
                     }
-                }
-                else
-                {
-                    merror(ENC_IP_ERROR, ARGV0, srcip);
-                    continue;
-                }
-            }
-        }
-        else
-        {
-            agentid = OS_IsAllowedIP(&keys, srcip);
-            if(agentid < 0)
-            {
-                if(check_keyupdate())
-                {
+
+                    *tmp_msg = '\0';
+                    tmp_msg++;
+                    recv_b -= 2;
+
+                    agentid = OS_IsAllowedDynamicID(&keys, buffer + 1, srcip);
+                    if (agentid == -1) {
+                        if (check_keyupdate()) {
+                            agentid = OS_IsAllowedDynamicID(&keys, buffer + 1, srcip);
+                            if (agentid == -1) {
+                                merror(ENC_IP_ERROR, ARGV0, buffer + 1, srcip);
+                                continue;
+                            }
+                        } else {
+                            merror(ENC_IP_ERROR, ARGV0, buffer + 1, srcip);
+                            continue;
+                        }
+                    }
+                } else {
                     agentid = OS_IsAllowedIP(&keys, srcip);
-                    if(agentid == -1)
-                    {
-                        merror(DENYIP_WARN,ARGV0,srcip);
-                        continue;
+                    if (agentid < 0) {
+                        if (check_keyupdate()) {
+                            agentid = OS_IsAllowedIP(&keys, srcip);
+                            if (agentid == -1) {
+                                merror(DENYIP_WARN, ARGV0, srcip);
+                                continue;
+                            }
+                        } else {
+                            merror(DENYIP_WARN, ARGV0, srcip);
+                            continue;
+                        }
                     }
+                    tmp_msg = buffer;
                 }
-                else
-                {
-                    merror(DENYIP_WARN,ARGV0,srcip);
+
+                /* Decrypt the message */
+                tmp_msg = ReadSecMSG(&keys, tmp_msg, cleartext_msg,
+                                     agentid, recv_b - 1);
+                if (tmp_msg == NULL) {
+                    /* If duplicated, a warning was already generated */
                     continue;
                 }
-            }
-            tmp_msg = buffer;
-        }
-
-
-        /* Decrypting the message */
-        tmp_msg = ReadSecMSG(&keys, tmp_msg, cleartext_msg,
-                             agentid, recv_b -1);
-        if(tmp_msg == NULL)
-        {
-            /* If duplicated, a warning was already generated */
-            continue;
-        }
-
-
-        /* Check if it is a control message */
-        if(IsValidHeader(tmp_msg))
-        {
-            /* We need to save the peerinfo if it is a control msg */
-            memcpy(&keys.keyentries[agentid]->peer_info, &peer_info, peer_size);
-            keys.keyentries[agentid]->rcvd = time(0);
 
-            save_controlmsg(agentid, tmp_msg);
-
-            continue;
-        }
-
-
-        /* Generating srcmsg */
-        snprintf(srcmsg, OS_FLSIZE,"(%s) %s",keys.keyentries[agentid]->name,
-                                             keys.keyentries[agentid]->ip->ip);
-
-
-        /* If we can't send the message, try to connect to the
-         * socket again. If it not exit.
-         */
-        if(SendMSG(logr.m_queue, tmp_msg, srcmsg,
-                   SECURE_MQ) < 0)
-        {
-            merror(QUEUE_ERROR, ARGV0, DEFAULTQUEUE, strerror(errno));
+                /* Check if it is a control message */
+                if (IsValidHeader(tmp_msg)) {
+                    /* We need to save the peerinfo if it is a control msg */
+                    memcpy(&keys.keyentries[agentid]->peer_info,
+                           &peer_info, peer_size);
+                    keys.keyentries[agentid]->rcvd = time(0);
+                    save_controlmsg((unsigned)agentid, tmp_msg);
+                    continue;
+                }
 
-            if((logr.m_queue = StartMQ(DEFAULTQUEUE, WRITE)) < 0)
-            {
-                ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQUEUE);
-            }
-        }
-    }
+                /* Generate srcmsg */
+                snprintf(srcmsg, OS_FLSIZE, "(%s) %s",
+                         keys.keyentries[agentid]->name,
+                         keys.keyentries[agentid]->ip->ip);
+
+               /*
+                * If we can't send the message, try to connect to the
+                * socket again. If it fails exit.
+                */
+                if (SendMSG(logr.m_queue, tmp_msg, srcmsg,
+                            SECURE_MQ) < 0) {
+                    merror(QUEUE_ERROR, ARGV0, DEFAULTQUEUE, strerror(errno));
+
+                    if ((logr.m_queue = StartMQ(DEFAULTQUEUE, WRITE)) < 0) {
+                        ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQUEUE);
+                    }
+                }
+            } /* if socket active */
+        } /* for() loop on sockets */
+    } /* while(1) loop for messages */
 }
 
-
-
-/* EOF */