0
0
Fork 0
mirror of https://github.com/netdata/netdata.git synced 2025-04-06 06:25:32 +00:00

hostnames: convert to utf8 and santitize ()

* hostnames: convert to utf8 and santitize

* add windows version of the hostname

* fix warnings on windows

* fix freebsd

* disable iconv on posix systems
This commit is contained in:
Costa Tsaousis 2025-01-16 19:59:26 +00:00 committed by GitHub
parent a1f3b747b5
commit 06c16139f8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 199 additions and 21 deletions

View file

@ -987,6 +987,8 @@ set(LIBNETDATA_FILES
src/libnetdata/memory/alignment.h
src/libnetdata/os/get_system_pagesize.c
src/libnetdata/os/get_system_pagesize.h
src/libnetdata/os/hostname.c
src/libnetdata/os/hostname.h
)
set(LIBH2O_FILES

View file

@ -68,6 +68,7 @@
#cmakedefine HAVE_SETENV
#cmakedefine HAVE_DLSYM
#cmakedefine HAVE_LIBCURL
#cmakedefine HAVE_LIBICONV
#cmakedefine HAVE_ARC4RANDOM_BUF
#cmakedefine HAVE_ARC4RANDOM_UNIFORM

View file

@ -40,22 +40,6 @@ skip:
return processors;
}
static int get_hostname(char *buf, size_t buf_size) {
if (netdata_configured_host_prefix && *netdata_configured_host_prefix) {
char filename[FILENAME_MAX + 1];
snprintfz(filename, FILENAME_MAX, "%s/etc/hostname", netdata_configured_host_prefix);
if (!read_txt_file(filename, buf, buf_size)) {
trim(buf);
return 0;
}
}
int rc = gethostname(buf, buf_size);
buf[buf_size - 1] = '\0';
return rc;
}
void netdata_conf_glibc_malloc_initialize(size_t wanted_arenas, size_t trim_threshold __maybe_unused) {
wanted_arenas = config_get_number(CONFIG_SECTION_GLOBAL, "glibc malloc arena max for plugins", wanted_arenas);
if(wanted_arenas < 1 || wanted_arenas > os_get_system_cpus_cached(true)) {
@ -119,8 +103,8 @@ void netdata_conf_section_global(void) {
netdata_configured_host_prefix = config_get(CONFIG_SECTION_GLOBAL, "host access prefix", "");
(void) verify_netdata_host_prefix(true);
char buf[HOSTNAME_MAX + 1];
if (get_hostname(buf, sizeof(buf)))
char buf[HOST_NAME_MAX * 4 + 1];
if (!os_hostname(buf, sizeof(buf), netdata_configured_host_prefix))
netdata_log_error("Cannot get machine hostname.");
netdata_configured_hostname = config_get(CONFIG_SECTION_GLOBAL, "hostname", buf);

View file

@ -107,7 +107,7 @@ cleanup:
}
#endif // HAVE_C_MALLOC_INFO
void pulse_daemon_memory_system_do(bool extended) {
void pulse_daemon_memory_system_do(bool extended __maybe_unused) {
#ifdef HAVE_C_MALLOC_INFO
size_t glibc_arenas, glibc_allocated_arenas, glibc_unused_fast, glibc_unused_rest, glibc_allocated_mmap;

View file

@ -1577,6 +1577,10 @@ int rrdlabels_unittest_sanitization() {
const unsigned char invalid5[] = "app.clewd修改\xe7\x89_fd_open_limits";
errors += rrdlabels_unittest_sanitize_value((const char *)invalid5, "app.clewd修改e789_fd_open_limits");
// invalid UTF8 No 6
const unsigned char invalid6[] = "\260\327\312\300\322\242";
errors += rrdlabels_unittest_sanitize_value((const char *)invalid6, "d7cac0Ң");
return errors;
}

View file

@ -400,6 +400,12 @@ typedef uint32_t uid_t;
// --------------------------------------------------------------------------------------------------------------------
#ifndef HOST_NAME_MAX
#define HOST_NAME_MAX 256
#endif
// --------------------------------------------------------------------------------------------------------------------
#if defined(OS_WINDOWS)
#include <windows.h>
#include <wctype.h>

View file

@ -0,0 +1,161 @@
// SPDX-License-Identifier: GPL-3.0-or-later
#include "libnetdata/libnetdata.h"
#if defined(OS_WINDOWS)
bool os_hostname(char *dst, size_t dst_size, const char *filesystem_root __maybe_unused) {
WCHAR wbuf[HOST_NAME_MAX * 4 + 1];
char buf[HOST_NAME_MAX * 4 + 1];
DWORD size = _countof(wbuf);
bool success = false;
// First try DNS hostname
if (GetComputerNameExW(ComputerNameDnsHostname, wbuf, &size)) {
success = true;
}
// Then try NetBIOS name
else {
size = _countof(wbuf);
if (GetComputerNameW(wbuf, &size)) {
success = true;
}
}
if (success) {
// Convert UTF-16 to UTF-8
int utf8_size = WideCharToMultiByte(CP_UTF8, 0, wbuf, -1, NULL, 0, NULL, NULL);
if (utf8_size > 0 && utf8_size <= (int)sizeof(buf)) {
WideCharToMultiByte(CP_UTF8, 0, wbuf, -1, buf, utf8_size, NULL, NULL);
}
else {
success = false;
}
}
if (!success) {
// Try getting the machine GUID first
HKEY hKey;
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Cryptography", 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
WCHAR guidW[64];
DWORD guidSize = sizeof(guidW);
DWORD type = REG_SZ;
if (RegQueryValueExW(hKey, L"MachineGuid", NULL, &type, (LPBYTE)guidW, &guidSize) == ERROR_SUCCESS) {
// Convert GUID to UTF-8
if (WideCharToMultiByte(CP_UTF8, 0, guidW, -1, buf, sizeof(buf), NULL, NULL) > 0) {
success = true;
}
}
RegCloseKey(hKey);
}
if (!success) {
// If machine GUID fails, try getting volume serial number of C: drive
WCHAR rootPath[] = L"C:\\";
DWORD serialNumber;
if (GetVolumeInformationW(rootPath, NULL, 0, &serialNumber, NULL, NULL, NULL, 0)) {
snprintf(buf, sizeof(buf), "host%08lx", (long unsigned)serialNumber);
success = true;
}
else {
// Last resort: use process ID
snprintf(buf, sizeof(buf), "host%lu", (long unsigned)GetCurrentProcessId());
}
}
}
char *hostname = trim(buf);
rrdlabels_sanitize_value(dst, hostname, dst_size);
return *dst != '\0';
}
#else // !OS_WINDOWS
#ifdef HAVE_LIBICONV
#include <iconv.h>
static const char *get_current_locale(void) {
const char *locale = getenv("LC_ALL"); // LC_ALL overrides all other locale settings
if (!locale || !*locale) {
locale = getenv("LC_CTYPE"); // Check LC_CTYPE for character encoding
if (!locale || !*locale)
locale = getenv("LANG"); // Fallback to LANG
}
return locale;
}
static const char *get_encoding_from_locale(const char *locale) {
if(!locale || !*locale)
return NULL;
const char *dot = strchr(locale, '.');
if (dot)
return dot + 1;
return locale;
}
// Function to convert from a source encoding to UTF-8
static bool iconv_convert_to_utf8(const char *input, const char *src_encoding, char *output, size_t output_size) {
iconv_t cd = iconv_open("UTF-8", src_encoding);
if (cd == (iconv_t)-1) {
int i = errno;
return false;
}
char *input_ptr = (char *)input; // iconv() may modify this pointer
char *output_ptr = output; // iconv() modifies this pointer
size_t input_len = strlen(input);
size_t output_len = output_size;
// Perform the conversion
if (iconv(cd, &input_ptr, &input_len, &output_ptr, &output_len) == (size_t)-1) {
iconv_close(cd);
return false;
}
// Null-terminate the output string
*output_ptr = '\0';
iconv_close(cd);
return true;
}
#endif
bool os_hostname(char *dst, size_t dst_size, const char *filesystem_root) {
*dst = '\0';
char buf[HOST_NAME_MAX * 4 + 1];
*buf = '\0';
if (filesystem_root && *filesystem_root) {
char filename[FILENAME_MAX + 1];
snprintfz(filename, FILENAME_MAX, "%s/etc/hostname", netdata_configured_host_prefix);
if (read_txt_file(filename, buf, sizeof(buf)))
*buf = '\0';
}
if(!*buf && gethostname(buf, sizeof(buf)) != 0)
snprintf(buf, sizeof(buf), "host%ld", gethostid());
char *original_hostname = trim(buf);
#ifdef HAVE_LIBICONV
const char *locale = get_current_locale();
if (locale && *locale) {
char utf8_output[HOST_NAME_MAX * 4 + 1] = "";
if(iconv_convert_to_utf8(original_hostname, get_encoding_from_locale(locale), utf8_output, sizeof(utf8_output))) {
rrdlabels_sanitize_value(dst, trim(utf8_output), dst_size);
return *dst != '\0';
}
}
#endif
rrdlabels_sanitize_value(dst, original_hostname, dst_size);
return *dst != '\0';
}
#endif // !OS_WINDOWS

View file

@ -0,0 +1,21 @@
// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef NETDATA_HOSTNAME_H
#define NETDATA_HOSTNAME_H
#include "libnetdata/libnetdata.h"
/**
* Get system hostname in UTF-8 encoding
*
* @param dst Buffer to store the hostname
* @param dst_size Size of the destination buffer
* @param filesystem_root Optional root directory (for Unix-like systems, when running in a container)
* @return true on success, false on failure
*
* The function guarantees to return a UTF-8 encoded hostname.
* On Windows, filesystem_root is ignored.
*/
bool os_hostname(char *dst, size_t dst_size, const char *filesystem_root);
#endif //NETDATA_HOSTNAME_H

View file

@ -23,6 +23,7 @@
#include "sleep.h"
#include "uuid_generate.h"
#include "setenv.h"
#include "hostname.h"
#include "os-freebsd-wrappers.h"
#include "os-macos-wrappers.h"
#include "os-windows-wrappers.h"

View file

@ -18,8 +18,6 @@
#include "web/server/web_client.h"
#define HOSTNAME_MAX 1024
void rrd_stats_api_v1_chart(RRDSET *st, BUFFER *wb);
int data_query_execute(ONEWAYALLOC *owa, BUFFER *wb, struct query_target *qt, time_t *latest_timestamp);