conf: add check if migration_host is a localhost address

Signed-off-by: Chen Fan <chen.fan.fnst@cn.fujitsu.com>

Signed-off-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Chen Fan 2014-10-07 12:07:31 +08:00 committed by Ján Tomko
parent 69f7b67d55
commit 24c1603762
5 changed files with 82 additions and 0 deletions

View File

@ -1916,6 +1916,7 @@ virSocketAddrGetIpPrefix;
virSocketAddrGetPort;
virSocketAddrGetRange;
virSocketAddrIsNetmask;
virSocketAddrIsNumericLocalhost;
virSocketAddrIsPrivate;
virSocketAddrIsWildcard;
virSocketAddrMask;

View 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);

View 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;
}

View 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__ */

View 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;
}