mirror of
https://github.com/netdata/netdata.git
synced 2025-04-06 06:25:32 +00:00
hostnames: convert to utf8 and santitize (#19418)
* 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:
parent
a1f3b747b5
commit
06c16139f8
10 changed files with 199 additions and 21 deletions
|
@ -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
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
#cmakedefine HAVE_SETENV
|
||||
#cmakedefine HAVE_DLSYM
|
||||
#cmakedefine HAVE_LIBCURL
|
||||
#cmakedefine HAVE_LIBICONV
|
||||
|
||||
#cmakedefine HAVE_ARC4RANDOM_BUF
|
||||
#cmakedefine HAVE_ARC4RANDOM_UNIFORM
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
161
src/libnetdata/os/hostname.c
Normal file
161
src/libnetdata/os/hostname.c
Normal 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
|
21
src/libnetdata/os/hostname.h
Normal file
21
src/libnetdata/os/hostname.h
Normal 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
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue