]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
conf: add check if migration_host is a localhost address
authorChen Fan <chen.fan.fnst@cn.fujitsu.com>
Tue, 7 Oct 2014 04:07:31 +0000 (12:07 +0800)
committerJán Tomko <jtomko@redhat.com>
Wed, 15 Oct 2014 07:25:33 +0000 (09:25 +0200)
Signed-off-by: Chen Fan <chen.fan.fnst@cn.fujitsu.com>
Signed-off-by: Ján Tomko <jtomko@redhat.com>
src/libvirt_private.syms
src/qemu/qemu_conf.c
src/util/virsocketaddr.c
src/util/virsocketaddr.h
tests/sockettest.c

index 04bb4f0ab6601549d548ad8e588993484e5c4912..9bad47596a94d2d5e16766a1019923a006f82651 100644 (file)
@@ -1916,6 +1916,7 @@ virSocketAddrGetIpPrefix;
 virSocketAddrGetPort;
 virSocketAddrGetRange;
 virSocketAddrIsNetmask;
+virSocketAddrIsNumericLocalhost;
 virSocketAddrIsPrivate;
 virSocketAddrIsWildcard;
 virSocketAddrMask;
index adc6cafb2762d7d9b098538b12aed3552e976e65..e2a3505ed102d138b6853023facc2793727032a7 100644 (file)
@@ -707,6 +707,17 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
     GET_VALUE_LONG("seccomp_sandbox", cfg->seccompSandbox);
 
     GET_VALUE_STR("migration_host", cfg->migrateHost);
+    virStringStripIPv6Brackets(cfg->migrateHost);
+    if (cfg->migrateHost &&
+        (STRPREFIX(cfg->migrateHost, "localhost") ||
+         virSocketAddrIsNumericLocalhost(cfg->migrateHost))) {
+        virReportError(VIR_ERR_CONF_SYNTAX,
+                       _("migration_host must not be the address of"
+                         " the local machine: %s"),
+                       cfg->migrateHost);
+        goto cleanup;
+    }
+
     GET_VALUE_STR("migration_address", cfg->migrationAddress);
 
     GET_VALUE_BOOL("log_timestamp", cfg->logTimestamp);
index 7fe7a151c0317904124a18d84d4e68dad3e1c5dc..a19e3afcccc53af1430ca81278082dcb9c810038 100644 (file)
@@ -878,3 +878,36 @@ virSocketAddrNumericFamily(const char *address)
     freeaddrinfo(res);
     return family;
 }
+
+/**
+ * virSocketAddrIsNumericLocalhost:
+ * @address: address to check
+ *
+ * Check if passed address is a numeric 'localhost' address.
+ *
+ * Returns: true if @address is a numeric 'localhost' address,
+ *          false otherwise
+ */
+bool
+virSocketAddrIsNumericLocalhost(const char *addr)
+{
+    struct addrinfo *res;
+    struct in_addr tmp = { .s_addr = htonl(INADDR_LOOPBACK) };
+    struct sockaddr_in *inet4;
+    struct sockaddr_in6 *inet6;
+
+    if (virSocketAddrParseInternal(&res, addr, AF_UNSPEC, false) < 0)
+        return false;
+
+    switch (res->ai_addr->sa_family) {
+    case AF_INET:
+        inet4 = (struct sockaddr_in*) res->ai_addr;
+        return memcmp(&inet4->sin_addr.s_addr, &tmp.s_addr,
+                      sizeof(inet4->sin_addr.s_addr)) == 0;
+    case AF_INET6:
+        inet6 = (struct sockaddr_in6*) res->ai_addr;
+        return IN6_IS_ADDR_LOOPBACK(&(inet6->sin6_addr));
+    }
+    return false;
+
+}
index 35c9c1a589a6005120cb467bd1a8cbaabd97e223..053855be4ceb42d246bcc62821d0d727b5348557 100644 (file)
@@ -126,4 +126,6 @@ bool virSocketAddrIsPrivate(const virSocketAddr *addr);
 bool virSocketAddrIsWildcard(const virSocketAddr *addr);
 
 int virSocketAddrNumericFamily(const char *address);
+
+bool virSocketAddrIsNumericLocalhost(const char *addr);
 #endif /* __VIR_SOCKETADDR_H__ */
index e790b5184162bcbf2ce2128da316790e16b2bf27..fbb5db81a542b2a9952af78020002798fc64f1b4 100644 (file)
@@ -234,6 +234,21 @@ testNumericHelper(const void *opaque)
     return 0;
 }
 
+struct testIsLocalhostData {
+    const char *addr;
+    bool result;
+};
+
+static int
+testIsLocalhostHelper(const void *opaque)
+{
+    const struct testIsLocalhostData *data = opaque;
+
+    if (virSocketAddrIsNumericLocalhost(data->addr) != data->result)
+        return -1;
+    return 0;
+}
+
 static int
 mymain(void)
 {
@@ -322,6 +337,13 @@ mymain(void)
             ret = -1;                                                   \
     } while (0)
 
+#define DO_TEST_LOCALHOST(addr, pass)                                   \
+    do {                                                                \
+        struct testIsLocalhostData data = { addr, pass };               \
+        if (virtTestRun("Test localhost " addr,                         \
+                       testIsLocalhostHelper, &data) < 0)               \
+            ret = -1;                                                   \
+    } while (0)
 
     DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_UNSPEC, true);
     DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_INET, true);
@@ -391,6 +413,19 @@ mymain(void)
     DO_TEST_NUMERIC_FAMILY("::ffff", AF_INET6);
     DO_TEST_NUMERIC_FAMILY("examplehost", -1);
 
+    DO_TEST_LOCALHOST("127.0.0.1", true);
+    DO_TEST_LOCALHOST("2130706433", true);
+    DO_TEST_LOCALHOST("0177.0.0.01", true);
+    DO_TEST_LOCALHOST("::1", true);
+    DO_TEST_LOCALHOST("0::1", true);
+    DO_TEST_LOCALHOST("0:0:0::1", true);
+    DO_TEST_LOCALHOST("[00:0::1]", false);
+    DO_TEST_LOCALHOST("[::1]", false);
+    DO_TEST_LOCALHOST("128.0.0.1", false);
+    DO_TEST_LOCALHOST("0.0.0.1", false);
+    DO_TEST_LOCALHOST("hello", false);
+    DO_TEST_LOCALHOST("fe80::1:1", false);
+
     return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
 }