1 /*
2 ** Zabbix
3 ** Copyright (C) 2001-2021 Zabbix SIA
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 **/
19 
20 #include "common.h"
21 
22 #include "cfg.h"
23 #include "db.h"
24 #include "log.h"
25 #include "zbxjson.h"
26 
27 #include "comms.h"
28 #include "servercomms.h"
29 
30 extern unsigned int	configured_tls_connect_mode;
31 
32 #if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
33 extern char	*CONFIG_TLS_SERVER_CERT_ISSUER;
34 extern char	*CONFIG_TLS_SERVER_CERT_SUBJECT;
35 extern char	*CONFIG_TLS_PSK_IDENTITY;
36 #endif
37 
connect_to_server(zbx_socket_t * sock,int timeout,int retry_interval)38 int	connect_to_server(zbx_socket_t *sock, int timeout, int retry_interval)
39 {
40 	int	res, lastlogtime, now;
41 	char	*tls_arg1, *tls_arg2;
42 
43 	zabbix_log(LOG_LEVEL_DEBUG, "In connect_to_server() [%s]:%d [timeout:%d]",
44 			CONFIG_SERVER, CONFIG_SERVER_PORT, timeout);
45 
46 	switch (configured_tls_connect_mode)
47 	{
48 		case ZBX_TCP_SEC_UNENCRYPTED:
49 			tls_arg1 = NULL;
50 			tls_arg2 = NULL;
51 			break;
52 #if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
53 		case ZBX_TCP_SEC_TLS_CERT:
54 			tls_arg1 = CONFIG_TLS_SERVER_CERT_ISSUER;
55 			tls_arg2 = CONFIG_TLS_SERVER_CERT_SUBJECT;
56 			break;
57 		case ZBX_TCP_SEC_TLS_PSK:
58 			tls_arg1 = CONFIG_TLS_PSK_IDENTITY;
59 			tls_arg2 = NULL;	/* zbx_tls_connect() will find PSK */
60 			break;
61 #endif
62 		default:
63 			THIS_SHOULD_NEVER_HAPPEN;
64 			return FAIL;
65 	}
66 
67 	if (FAIL == (res = zbx_tcp_connect(sock, CONFIG_SOURCE_IP, CONFIG_SERVER, CONFIG_SERVER_PORT, timeout,
68 			configured_tls_connect_mode, tls_arg1, tls_arg2)))
69 	{
70 		if (0 == retry_interval)
71 		{
72 			zabbix_log(LOG_LEVEL_WARNING, "Unable to connect to the server [%s]:%d [%s]",
73 					CONFIG_SERVER, CONFIG_SERVER_PORT, zbx_socket_strerror());
74 		}
75 		else
76 		{
77 			zabbix_log(LOG_LEVEL_WARNING, "Unable to connect to the server [%s]:%d [%s]. Will retry every"
78 					" %d second(s)", CONFIG_SERVER, CONFIG_SERVER_PORT, zbx_socket_strerror(),
79 					retry_interval);
80 
81 			lastlogtime = (int)time(NULL);
82 
83 			while (FAIL == (res = zbx_tcp_connect(sock, CONFIG_SOURCE_IP, CONFIG_SERVER, CONFIG_SERVER_PORT,
84 					timeout, configured_tls_connect_mode, tls_arg1, tls_arg2)))
85 			{
86 				now = (int)time(NULL);
87 
88 				if (60 <= now - lastlogtime)
89 				{
90 					zabbix_log(LOG_LEVEL_WARNING, "Still unable to connect...");
91 					lastlogtime = now;
92 				}
93 
94 				sleep(retry_interval);
95 			}
96 
97 			zabbix_log(LOG_LEVEL_WARNING, "Connection restored.");
98 		}
99 	}
100 
101 	return res;
102 }
103 
disconnect_server(zbx_socket_t * sock)104 void	disconnect_server(zbx_socket_t *sock)
105 {
106 	zbx_tcp_close(sock);
107 }
108 
109 /******************************************************************************
110  *                                                                            *
111  * Function: get_data_from_server                                             *
112  *                                                                            *
113  * Purpose: get configuration and other data from server                      *
114  *                                                                            *
115  * Return value: SUCCEED - processed successfully                             *
116  *               FAIL - an error occurred                                     *
117  *                                                                            *
118  ******************************************************************************/
get_data_from_server(zbx_socket_t * sock,const char * request,char ** error)119 int	get_data_from_server(zbx_socket_t *sock, const char *request, char **error)
120 {
121 	const char	*__function_name = "get_data_from_server";
122 
123 	int		ret = FAIL;
124 	struct zbx_json	j;
125 
126 	zabbix_log(LOG_LEVEL_DEBUG, "In %s() request:'%s'", __function_name, request);
127 
128 	zbx_json_init(&j, 128);
129 	zbx_json_addstring(&j, "request", request, ZBX_JSON_TYPE_STRING);
130 	zbx_json_addstring(&j, "host", CONFIG_HOSTNAME, ZBX_JSON_TYPE_STRING);
131 
132 	if (SUCCEED != zbx_tcp_send(sock, j.buffer))
133 	{
134 		*error = zbx_strdup(*error, zbx_socket_strerror());
135 		goto exit;
136 	}
137 
138 	if (SUCCEED != zbx_tcp_recv(sock))
139 	{
140 		*error = zbx_strdup(*error, zbx_socket_strerror());
141 		goto exit;
142 	}
143 
144 	zabbix_log(LOG_LEVEL_DEBUG, "Received [%s] from server", sock->buffer);
145 
146 	ret = SUCCEED;
147 exit:
148 	zbx_json_free(&j);
149 
150 	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));
151 
152 	return ret;
153 }
154 
155 /******************************************************************************
156  *                                                                            *
157  * Function: put_data_to_server                                               *
158  *                                                                            *
159  * Purpose: send data to server                                               *
160  *                                                                            *
161  * Return value: SUCCEED - processed successfully                             *
162  *               FAIL - an error occurred                                     *
163  *                                                                            *
164  ******************************************************************************/
put_data_to_server(zbx_socket_t * sock,struct zbx_json * j,char ** error)165 int	put_data_to_server(zbx_socket_t *sock, struct zbx_json *j, char **error)
166 {
167 	const char	*__function_name = "put_data_to_server";
168 
169 	int		ret = FAIL;
170 
171 	zabbix_log(LOG_LEVEL_DEBUG, "In %s() datalen:" ZBX_FS_SIZE_T, __function_name, (zbx_fs_size_t)j->buffer_size);
172 
173 	if (SUCCEED != zbx_tcp_send(sock, j->buffer))
174 	{
175 		*error = zbx_strdup(*error, zbx_socket_strerror());
176 		goto out;
177 	}
178 
179 	if (SUCCEED != zbx_recv_response(sock, 0, error))
180 		goto out;
181 
182 	ret = SUCCEED;
183 out:
184 	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));
185 
186 	return ret;
187 }
188