master
c 96 lines 2.88 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "daemon/common.h"
4 #include "netdata-conf-ssl.h"
5 #include <curl/curl.h>
6
7 static bool is_ca_bundle_valid(const char *ca_path) {
8 if (!ca_path || !*ca_path)
9 return false;
10
11 FILE *fp = fopen(ca_path, "r");
12 if (!fp)
13 return false;
14
15 ERR_clear_error();
16
17 int valid_certs = 0;
18 X509 *cert = NULL;
19 while ((cert = PEM_read_X509(fp, NULL, NULL, NULL)) != NULL) {
20 ASN1_TIME *not_after = X509_get_notAfter(cert);
21 int day, sec;
22
23 if (ASN1_TIME_diff(&day, &sec, NULL, not_after) == 1) {
24 if (day > 0 || (day == 0 && sec > 0)) {
25 valid_certs++;
26
27 // we found 1 valid, stop reading the file
28 X509_free(cert);
29 break;
30 }
31 }
32
33 X509_free(cert);
34 }
35
36 fclose(fp);
37
38 ERR_clear_error();
39 return valid_certs > 0;
40 }
41
42 const char *detect_libcurl_default_ca() {
43 #if LIBCURL_VERSION_NUM >= 0x074600 // 7.70.0 (CURLVERSION_SEVENTH)
44 curl_version_info_data *info = curl_version_info(CURLVERSION_NOW);
45 if (info) {
46 // Check built-in CA bundle
47 if (info->cainfo &&
48 access(info->cainfo, R_OK) == 0 &&
49 is_ca_bundle_valid(info->cainfo))
50 return info->cainfo;
51 }
52 #endif
53 return NULL;
54 }
55
56 static inline const char *detect_ca_path(void) {
57 static const char *paths[] = {
58 "/opt/netdata/etc/ssl/certs/ca-certificates.crt", // Netdata static build (needs to come first for consistency with standalone cURL in static builds)
59 "/etc/ssl/certs/ca-certificates.crt", // Debian, Ubuntu, Arch
60 "/etc/ssl/certs/ca-bundle.crt", // Rocky Linux (via symlinks)
61 "/etc/pki/tls/certs/ca-bundle.crt", // RHEL, CentOS, Fedora
62 "/etc/ssl/ca-bundle.pem", // OpenSUSE
63 "/etc/ssl/cert.pem", // Alpine
64 "/opt/netdata/share/ssl/certs/ca-certificates.crt", // Netdata static build - fallback
65 NULL
66 };
67
68 for (int i = 0; paths[i] != NULL; i++) {
69 if (access(paths[i], R_OK) == 0 &&
70 is_ca_bundle_valid(paths[i]))
71 return paths[i];
72 }
73
74 return NULL;
75 }
76
77 void netdata_conf_ssl(void) {
78 FUNCTION_RUN_ONCE();
79
80 netdata_ssl_initialize_openssl();
81
82 #if 0
83 const char *p = getenv("CURL_CA_BUNDLE");
84 if(!p || !*p) p = getenv("SSL_CERT_FILE");
85 if(!p || !*p) {
86 p = X509_get_default_cert_file();
87 if(!p || !*p || !is_ca_bundle_valid(p))
88 p = NULL;
89 }
90 if(!p || !*p) p = detect_libcurl_default_ca();
91 if(!p || !*p) p = detect_ca_path();
92 setenv("CURL_CA_BUNDLE", inicfg_get(&netdata_config, CONFIG_SECTION_ENV_VARS, "CURL_CA_BUNDLE", p ? p : ""), 1);
93 setenv("SSL_CERT_FILE", inicfg_get(&netdata_config, CONFIG_SECTION_ENV_VARS, "SSL_CERT_FILE", p ? p : ""), 1);
94 #endif
95
96 }