new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / remoted / sendmsg.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 <pthread.h>
11
12 #include "shared.h"
13 #include "remoted.h"
14 #include "os_net/os_net.h"
15
16 /* pthread send_msg mutex */
17 static pthread_mutex_t sendmsg_mutex;
18
19 /* pthread key update mutex */
20 static pthread_mutex_t keyupdate_mutex;
21
22
23 /* Initializes mutex */
24 void keyupdate_init()
25 {
26     /* Initialize mutex */
27     pthread_mutex_init(&keyupdate_mutex, NULL);
28 }
29
30 void key_lock()
31 {
32     if (pthread_mutex_lock(&keyupdate_mutex) != 0) {
33         merror(MUTEX_ERROR, ARGV0);
34     }
35 }
36
37 void key_unlock()
38 {
39     if (pthread_mutex_unlock(&keyupdate_mutex) != 0) {
40         merror(MUTEX_ERROR, ARGV0);
41     }
42 }
43
44 /* Check for key updates */
45 int check_keyupdate()
46 {
47     /* Check key for updates */
48     if (!OS_CheckUpdateKeys(&keys)) {
49         return (0);
50     }
51
52     key_lock();
53
54     /* Lock before using */
55     if (pthread_mutex_lock(&sendmsg_mutex) != 0) {
56         key_unlock();
57         merror(MUTEX_ERROR, ARGV0);
58         return (0);
59     }
60
61     if (OS_UpdateKeys(&keys)) {
62         if (pthread_mutex_unlock(&sendmsg_mutex) != 0) {
63             merror(MUTEX_ERROR, ARGV0);
64         }
65         key_unlock();
66         return (1);
67     }
68
69     if (pthread_mutex_unlock(&sendmsg_mutex) != 0) {
70         merror(MUTEX_ERROR, ARGV0);
71     }
72     key_unlock();
73
74     return (0);
75 }
76
77 /* Initialize send_msg */
78 void send_msg_init()
79 {
80     /* Initialize mutex */
81     pthread_mutex_init(&sendmsg_mutex, NULL);
82 }
83
84
85 /*
86  * Send message to an agent
87  * Returns -1 on error
88  */
89
90 int send_msg(unsigned int agentid, const char *msg)
91 {
92     size_t msg_size, sa_size;
93     char crypt_msg[OS_MAXSTR + 1];
94     struct sockaddr * dest_sa;
95
96     /* If we don't have the agent id, ignore it */
97     if (keys.keyentries[agentid]->rcvd < (time(0) - (2 * NOTIFY_TIME))) {
98         return (-1);
99     }
100
101     msg_size = CreateSecMSG(&keys, msg, crypt_msg, agentid);
102     if (msg_size == 0) {
103         merror(SEC_ERROR, ARGV0);
104         return (-1);
105     }
106
107     /* Lock before using */
108     if (pthread_mutex_lock(&sendmsg_mutex) != 0) {
109         merror(MUTEX_ERROR, ARGV0);
110         return (-1);
111     }
112
113     /* Send initial message */
114     dest_sa = (struct sockaddr *)&keys.keyentries[agentid]->peer_info;
115     sa_size = (dest_sa->sa_family == AF_INET) ?
116               sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
117
118    /*
119     * Because we handle multiple IP addresses, we won't know what interfaces
120     * are active for network communication until we receive something on one
121     * of them.  This is a work around in the event we need to send before
122     * we have identified the working interface in secure.c. (dgs - 2/26/18)
123     */
124
125     if (logr.sock == 0) {
126         int i, ok = 0;
127
128         /* socket not established - try current sockets */
129         for (i = 0; i < logr.netinfo->fdcnt; i++) {
130             if (sendto(logr.netinfo->fds[i], crypt_msg, msg_size, 0,
131                        dest_sa, sa_size) < 0) {
132                 continue;
133             }
134
135             ok = 1;
136             break;
137         }
138
139         /* if we tried all the sockets and noe of them worked, send an error */
140         if (ok == 0) {       
141             merror(SEND_ERROR, ARGV0, keys.keyentries[agentid]->id);
142         }
143     } else {
144         /* working socket identified in secure.c */
145         if (sendto(logr.sock, crypt_msg, msg_size, 0, dest_sa, sa_size) < 0) {
146             merror(SEND_ERROR, ARGV0, keys.keyentries[agentid]->id);
147         }
148     }
149
150     /* Unlock mutex */
151     if (pthread_mutex_unlock(&sendmsg_mutex) != 0) {
152         merror(MUTEX_ERROR, ARGV0);
153         return (-1);
154     }
155
156     return (0);
157 }
158