/src/systemd/src/resolve/resolved-util.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
2 | | |
3 | | #include "alloc-util.h" |
4 | | #include "dns-def.h" |
5 | | #include "dns-domain.h" |
6 | | #include "hostname-setup.h" |
7 | | #include "hostname-util.h" |
8 | | #include "idn-util.h" |
9 | | #include "log.h" |
10 | | #include "resolved-util.h" |
11 | | #include "utf8.h" |
12 | | |
13 | 0 | int resolve_system_hostname(char **full_hostname, char **first_label) { |
14 | 0 | _cleanup_free_ char *h = NULL, *n = NULL; |
15 | | #if HAVE_LIBIDN2 |
16 | | _cleanup_free_ char *utf8 = NULL; |
17 | | #elif HAVE_LIBIDN |
18 | | int k; |
19 | | #endif |
20 | 0 | char label[DNS_LABEL_MAX+1]; |
21 | 0 | const char *p, *decoded; |
22 | 0 | int r; |
23 | | |
24 | | /* Return the full hostname in *full_hostname, if nonnull. |
25 | | * |
26 | | * Extract and normalize the first label of the locally configured hostname, check it's not |
27 | | * "localhost", and return it in *first_label, if nonnull. */ |
28 | |
|
29 | 0 | r = gethostname_strict(&h); |
30 | 0 | if (r < 0) |
31 | 0 | return log_debug_errno(r, "Can't determine system hostname: %m"); |
32 | | |
33 | 0 | p = h; |
34 | 0 | r = dns_label_unescape(&p, label, sizeof label, 0); |
35 | 0 | if (r < 0) |
36 | 0 | return log_debug_errno(r, "Failed to unescape hostname: %m"); |
37 | 0 | if (r == 0) |
38 | 0 | return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), |
39 | 0 | "Couldn't find a single label in hostname."); |
40 | | |
41 | | #if HAVE_LIBIDN || HAVE_LIBIDN2 |
42 | | r = dlopen_idn(); |
43 | | if (r < 0) { |
44 | | log_debug_errno(r, "Failed to initialize IDN support, ignoring: %m"); |
45 | | decoded = label; /* no decoding */ |
46 | | } else |
47 | | #endif |
48 | 0 | { |
49 | | #if HAVE_LIBIDN2 |
50 | | r = sym_idn2_to_unicode_8z8z(label, &utf8, 0); |
51 | | if (r != IDN2_OK) |
52 | | return log_debug_errno(SYNTHETIC_ERRNO(EUCLEAN), |
53 | | "Failed to undo IDNA: %s", sym_idn2_strerror(r)); |
54 | | assert(utf8_is_valid(utf8)); |
55 | | |
56 | | r = strlen(utf8); |
57 | | decoded = utf8; |
58 | | #elif HAVE_LIBIDN |
59 | | k = dns_label_undo_idna(label, r, label, sizeof label); |
60 | | if (k < 0) |
61 | | return log_debug_errno(k, "Failed to undo IDNA: %m"); |
62 | | if (k > 0) |
63 | | r = k; |
64 | | |
65 | | if (!utf8_is_valid(label)) |
66 | | return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), |
67 | | "System hostname is not UTF-8 clean."); |
68 | | decoded = label; |
69 | | #else |
70 | 0 | decoded = label; /* no decoding */ |
71 | 0 | #endif |
72 | 0 | } |
73 | |
|
74 | 0 | r = dns_label_escape_new(decoded, r, &n); |
75 | 0 | if (r < 0) |
76 | 0 | return log_debug_errno(r, "Failed to escape hostname: %m"); |
77 | | |
78 | 0 | if (is_localhost(n)) |
79 | 0 | return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), |
80 | 0 | "System hostname is 'localhost', ignoring."); |
81 | | |
82 | 0 | if (full_hostname) |
83 | 0 | *full_hostname = TAKE_PTR(h); |
84 | 0 | if (first_label) |
85 | 0 | *first_label = TAKE_PTR(n); |
86 | 0 | return 0; |
87 | 0 | } |