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 #include "log.h"
22 #include "zbxhttp.h"
23
24 #ifdef HAVE_LIBCURL
25
26 extern char *CONFIG_SOURCE_IP;
27
28 extern char *CONFIG_SSL_CA_LOCATION;
29 extern char *CONFIG_SSL_CERT_LOCATION;
30 extern char *CONFIG_SSL_KEY_LOCATION;
31
zbx_http_prepare_ssl(CURL * easyhandle,const char * ssl_cert_file,const char * ssl_key_file,const char * ssl_key_password,unsigned char verify_peer,unsigned char verify_host,char ** error)32 int zbx_http_prepare_ssl(CURL *easyhandle, const char *ssl_cert_file, const char *ssl_key_file,
33 const char *ssl_key_password, unsigned char verify_peer, unsigned char verify_host,
34 char **error)
35 {
36 CURLcode err;
37
38 if (CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_SSL_VERIFYPEER, 0 == verify_peer ? 0L : 1L)))
39 {
40 *error = zbx_dsprintf(*error, "Cannot set verify the peer's SSL certificate: %s",
41 curl_easy_strerror(err));
42 return FAIL;
43 }
44
45 if (CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_SSL_VERIFYHOST, 0 == verify_host ? 0L : 2L)))
46 {
47 *error = zbx_dsprintf(*error, "Cannot set verify the certificate's name against host: %s",
48 curl_easy_strerror(err));
49 return FAIL;
50 }
51
52 if (NULL != CONFIG_SOURCE_IP)
53 {
54 if (CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_INTERFACE, CONFIG_SOURCE_IP)))
55 {
56 *error = zbx_dsprintf(*error, "Cannot specify source interface for outgoing traffic: %s",
57 curl_easy_strerror(err));
58 return FAIL;
59 }
60 }
61
62 if (0 != verify_peer && NULL != CONFIG_SSL_CA_LOCATION)
63 {
64 if (CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_CAPATH, CONFIG_SSL_CA_LOCATION)))
65 {
66 *error = zbx_dsprintf(*error, "Cannot specify directory holding CA certificates: %s",
67 curl_easy_strerror(err));
68 return FAIL;
69 }
70 }
71
72 if ('\0' != *ssl_cert_file)
73 {
74 char *file_name;
75
76 file_name = zbx_dsprintf(NULL, "%s/%s", CONFIG_SSL_CERT_LOCATION, ssl_cert_file);
77 zabbix_log(LOG_LEVEL_DEBUG, "using SSL certificate file: '%s'", file_name);
78
79 err = curl_easy_setopt(easyhandle, CURLOPT_SSLCERT, file_name);
80 zbx_free(file_name);
81
82 if (CURLE_OK != err)
83 {
84 *error = zbx_dsprintf(*error, "Cannot set SSL client certificate: %s", curl_easy_strerror(err));
85 return FAIL;
86 }
87
88 if (CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_SSLCERTTYPE, "PEM")))
89 {
90 *error = zbx_dsprintf(NULL, "Cannot specify type of the client SSL certificate: %s",
91 curl_easy_strerror(err));
92 return FAIL;
93 }
94 }
95
96 if ('\0' != *ssl_key_file)
97 {
98 char *file_name;
99
100 file_name = zbx_dsprintf(NULL, "%s/%s", CONFIG_SSL_KEY_LOCATION, ssl_key_file);
101 zabbix_log(LOG_LEVEL_DEBUG, "using SSL private key file: '%s'", file_name);
102
103 err = curl_easy_setopt(easyhandle, CURLOPT_SSLKEY, file_name);
104 zbx_free(file_name);
105
106 if (CURLE_OK != err)
107 {
108 *error = zbx_dsprintf(NULL, "Cannot specify private keyfile for TLS and SSL client cert: %s",
109 curl_easy_strerror(err));
110 return FAIL;
111 }
112
113 if (CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_SSLKEYTYPE, "PEM")))
114 {
115 *error = zbx_dsprintf(NULL, "Cannot set type of the private key file: %s",
116 curl_easy_strerror(err));
117 return FAIL;
118 }
119 }
120
121 if ('\0' != *ssl_key_password)
122 {
123 if (CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_KEYPASSWD, ssl_key_password)))
124 {
125 *error = zbx_dsprintf(NULL, "Cannot set passphrase to private key: %s",
126 curl_easy_strerror(err));
127 return FAIL;
128 }
129 }
130
131 return SUCCEED;
132 }
133
zbx_http_prepare_auth(CURL * easyhandle,unsigned char authtype,const char * username,const char * password,char ** error)134 int zbx_http_prepare_auth(CURL *easyhandle, unsigned char authtype, const char *username, const char *password,
135 char **error)
136 {
137 if (HTTPTEST_AUTH_NONE != authtype)
138 {
139 long curlauth = 0;
140 char auth[MAX_STRING_LEN];
141 CURLcode err;
142
143 zabbix_log(LOG_LEVEL_DEBUG, "setting HTTPAUTH [%d]", authtype);
144
145 switch (authtype)
146 {
147 case HTTPTEST_AUTH_BASIC:
148 curlauth = CURLAUTH_BASIC;
149 break;
150 case HTTPTEST_AUTH_NTLM:
151 curlauth = CURLAUTH_NTLM;
152 break;
153 case HTTPTEST_AUTH_NEGOTIATE:
154 #if LIBCURL_VERSION_NUM >= 0x072600
155 curlauth = CURLAUTH_NEGOTIATE;
156 #else
157 curlauth = CURLAUTH_GSSNEGOTIATE;
158 #endif
159 break;
160 default:
161 THIS_SHOULD_NEVER_HAPPEN;
162 break;
163 }
164
165 if (CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_HTTPAUTH, curlauth)))
166 {
167 *error = zbx_dsprintf(*error, "Cannot set HTTP server authentication method: %s",
168 curl_easy_strerror(err));
169 return FAIL;
170 }
171
172 zbx_snprintf(auth, sizeof(auth), "%s:%s", username, password);
173 if (CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_USERPWD, auth)))
174 {
175 *error = zbx_dsprintf(*error, "Cannot set user name and password: %s",
176 curl_easy_strerror(err));
177 return FAIL;
178 }
179 }
180
181 return SUCCEED;
182 }
183
zbx_http_get_header(char ** headers)184 char *zbx_http_get_header(char **headers)
185 {
186 while ('\0' != **headers)
187 {
188 char c, *p_end, *line;
189
190 while ('\r' == **headers || '\n' == **headers)
191 (*headers)++;
192
193 p_end = *headers;
194
195 while ('\0' != *p_end && '\r' != *p_end && '\n' != *p_end)
196 p_end++;
197
198 if (*headers == p_end)
199 return NULL;
200
201 if ('\0' != (c = *p_end))
202 *p_end = '\0';
203 line = zbx_strdup(NULL, *headers);
204 if ('\0' != c)
205 *p_end = c;
206
207 *headers = p_end;
208
209 zbx_lrtrim(line, " \t");
210 if ('\0' == *line)
211 zbx_free(line);
212 else
213 return line;
214 }
215
216 return NULL;
217 }
218
219 #endif
220