]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/shared/dns-domain.c
build-sys: use #if Y instead of #ifdef Y everywhere
[thirdparty/systemd.git] / src / shared / dns-domain.c
index 12c4d65dd3f66f82311ee4d977d272b43a860ed6..9804907304b48f9bfec6ad47c21b5f0bd9c0e92d 100644 (file)
@@ -17,9 +17,9 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
  ***/
 
-#if defined(HAVE_LIBIDN2)
+#if HAVE_LIBIDN2
 #  include <idn2.h>
-#elif defined(HAVE_LIBIDN)
+#elif HAVE_LIBIDN
 #  include <idna.h>
 #  include <stringprep.h>
 #endif
@@ -301,7 +301,7 @@ int dns_label_escape_new(const char *p, size_t l, char **ret) {
         return r;
 }
 
-#ifdef HAVE_LIBIDN
+#if HAVE_LIBIDN
 int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) {
         _cleanup_free_ uint32_t *input = NULL;
         size_t input_size, l;
@@ -1272,24 +1272,47 @@ int dns_name_common_suffix(const char *a, const char *b, const char **ret) {
 int dns_name_apply_idna(const char *name, char **ret) {
         /* Return negative on error, 0 if not implemented, positive on success. */
 
-#if defined(HAVE_LIBIDN2)
+#if HAVE_LIBIDN2
         int r;
+        _cleanup_free_ char *t = NULL;
 
         assert(name);
         assert(ret);
 
-        r = idn2_lookup_u8((uint8_t*) name, (uint8_t**) ret,
+        r = idn2_lookup_u8((uint8_t*) name, (uint8_t**) &t,
                            IDN2_NFC_INPUT | IDN2_NONTRANSITIONAL);
-        if (r == IDN2_OK)
+        log_debug("idn2_lookup_u8: %s → %s", name, t);
+        if (r == IDN2_OK) {
+                if (!startswith(name, "xn--")) {
+                        _cleanup_free_ char *s = NULL;
+
+                        r = idn2_to_unicode_8z8z(t, &s, 0);
+                        if (r != IDN2_OK) {
+                                log_debug("idn2_to_unicode_8z8z(\"%s\") failed: %d/%s",
+                                          t, r, idn2_strerror(r));
+                                return 0;
+                        }
+
+                        if (!streq_ptr(name, s)) {
+                                log_debug("idn2 roundtrip failed: \"%s\" → \"%s\" → \"%s\", ignoring.",
+                                          name, t, s);
+                                return 0;
+                        }
+                }
+
+                *ret = t;
+                t = NULL;
                 return 1; /* *ret has been written */
-        log_debug("idn2_lookup_u8(\"%s\") failed: %s", name, idn2_strerror(r));
+        }
+
+        log_debug("idn2_lookup_u8(\"%s\") failed: %d/%s", name, r, idn2_strerror(r));
         if (r == IDN2_2HYPHEN)
                 /* The name has two hypens — forbidden by IDNA2008 in some cases */
                 return 0;
         if (IN_SET(r, IDN2_TOO_BIG_DOMAIN, IDN2_TOO_BIG_LABEL))
                 return -ENOSPC;
         return -EINVAL;
-#elif defined(HAVE_LIBIDN)
+#elif HAVE_LIBIDN
         _cleanup_free_ char *buf = NULL;
         size_t n = 0, allocated = 0;
         bool first = true;