mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-23 16:12:01 +00:00
dbms: fixed error with users [#CONV-8458].
This commit is contained in:
parent
0698d868c5
commit
3e0046011a
@ -107,11 +107,51 @@ public:
|
|||||||
bool contains(const Poco::Net::IPAddress & addr) const
|
bool contains(const Poco::Net::IPAddress & addr) const
|
||||||
{
|
{
|
||||||
Poco::Net::IPAddress addr_v6 = toIPv6(addr);
|
Poco::Net::IPAddress addr_v6 = toIPv6(addr);
|
||||||
Poco::Net::HostEntry entry = Poco::Net::DNS::hostByName(host);
|
|
||||||
|
|
||||||
for (size_t i = 0, size = entry.addresses().size(); i < size; ++i)
|
/// Резолвим вручную, потому что в Poco не используется флаг AI_ALL, а он важен.
|
||||||
if (toIPv6(entry.addresses()[i]) == addr_v6)
|
addrinfo * ai = NULL;
|
||||||
|
|
||||||
|
addrinfo hints;
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_family = AF_UNSPEC;
|
||||||
|
hints.ai_flags |= AI_V4MAPPED | AI_ALL;
|
||||||
|
|
||||||
|
int ret = getaddrinfo(host.c_str(), NULL, &hints, &ai);
|
||||||
|
if (0 != ret)
|
||||||
|
throw Exception("Cannot getaddrinfo: " + std::string(gai_strerror(ret)), ErrorCodes::DNS_ERROR);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
for (; ai != NULL; ai = ai->ai_next)
|
||||||
|
{
|
||||||
|
if (ai->ai_addrlen && ai->ai_addr)
|
||||||
|
{
|
||||||
|
if (ai->ai_family == AF_INET6)
|
||||||
|
{
|
||||||
|
if (addr_v6 == Poco::Net::IPAddress(
|
||||||
|
&reinterpret_cast<sockaddr_in6*>(ai->ai_addr)->sin6_addr, sizeof(in6_addr),
|
||||||
|
reinterpret_cast<sockaddr_in6*>(ai->ai_addr)->sin6_scope_id))
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ai->ai_family == AF_INET)
|
||||||
|
{
|
||||||
|
if (addr_v6 == toIPv6(Poco::Net::IPAddress(
|
||||||
|
&reinterpret_cast<sockaddr_in*>(ai->ai_addr)->sin_addr, sizeof(in_addr))))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
freeaddrinfo(ai);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
freeaddrinfo(ai);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -5,120 +5,11 @@
|
|||||||
using namespace DB;
|
using namespace DB;
|
||||||
|
|
||||||
|
|
||||||
namespace test
|
|
||||||
{
|
|
||||||
/// Проверяет соответствие адреса одному из адресов хоста.
|
|
||||||
class HostExactPattern : public IAddressPattern
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
String host;
|
|
||||||
|
|
||||||
public:
|
|
||||||
HostExactPattern(const String & host_) : host(host_) {}
|
|
||||||
|
|
||||||
bool contains(const Poco::Net::IPAddress & addr) const
|
|
||||||
{
|
|
||||||
Poco::Net::IPAddress addr_v6 = toIPv6(addr);
|
|
||||||
|
|
||||||
addrinfo * ai = NULL;
|
|
||||||
|
|
||||||
addrinfo hints;
|
|
||||||
memset(&hints, 0, sizeof(hints));
|
|
||||||
hints.ai_family = AF_INET6;
|
|
||||||
hints.ai_flags |= AI_V4MAPPED | AI_ALL;
|
|
||||||
|
|
||||||
int ret = getaddrinfo(host.c_str(), NULL, NULL, &ai);
|
|
||||||
if (0 != ret)
|
|
||||||
throw Exception("Cannot getaddrinfo: " + std::string(gai_strerror(ret)), ErrorCodes::DNS_ERROR);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
for (; ai != NULL; ai = ai->ai_next)
|
|
||||||
{
|
|
||||||
if (ai->ai_addrlen && ai->ai_addr)
|
|
||||||
{
|
|
||||||
if (ai->ai_family == AF_INET6)
|
|
||||||
{
|
|
||||||
char buf[1024];
|
|
||||||
std::cerr << inet_ntop(ai->ai_family, &reinterpret_cast<sockaddr_in6*>(ai->ai_addr)->sin6_addr, buf, sizeof(buf)) << std::endl;
|
|
||||||
|
|
||||||
std::cerr << Poco::Net::IPAddress(
|
|
||||||
&reinterpret_cast<sockaddr_in6*>(ai->ai_addr)->sin6_addr, sizeof(in6_addr),
|
|
||||||
reinterpret_cast<sockaddr_in6*>(ai->ai_addr)->sin6_scope_id).toString() << std::endl;
|
|
||||||
|
|
||||||
if (addr_v6 == Poco::Net::IPAddress(
|
|
||||||
&reinterpret_cast<sockaddr_in6*>(ai->ai_addr)->sin6_addr, sizeof(in6_addr),
|
|
||||||
reinterpret_cast<sockaddr_in6*>(ai->ai_addr)->sin6_scope_id))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (ai->ai_family == AF_INET)
|
|
||||||
{
|
|
||||||
char buf[1024];
|
|
||||||
std::cerr << inet_ntop(ai->ai_family, &reinterpret_cast<sockaddr_in*>(ai->ai_addr)->sin_addr, buf, sizeof(buf)) << std::endl;
|
|
||||||
|
|
||||||
std::cerr << Poco::Net::IPAddress(
|
|
||||||
&reinterpret_cast<sockaddr_in*>(ai->ai_addr)->sin_addr, sizeof(in_addr)).toString() << std::endl;
|
|
||||||
|
|
||||||
if (addr_v6 == toIPv6(Poco::Net::IPAddress(
|
|
||||||
&reinterpret_cast<sockaddr_in*>(ai->ai_addr)->sin_addr, sizeof(in_addr))))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
freeaddrinfo(ai);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
freeaddrinfo(ai);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Проверяет соответствие PTR-записи для адреса регекспу (и дополнительно проверяет, что PTR-запись резолвится обратно в адрес клиента).
|
|
||||||
class HostRegexpPattern : public IAddressPattern
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
Poco::RegularExpression host_regexp;
|
|
||||||
|
|
||||||
public:
|
|
||||||
HostRegexpPattern(const String & host_regexp_) : host_regexp(host_regexp_) {}
|
|
||||||
|
|
||||||
bool contains(const Poco::Net::IPAddress & addr) const
|
|
||||||
{
|
|
||||||
Poco::Net::SocketAddress sock_addr(addr, 0);
|
|
||||||
|
|
||||||
/// Резолвим вручную, потому что в Poco нет такой функциональности.
|
|
||||||
char domain[1024];
|
|
||||||
int ret = getnameinfo(sock_addr.addr(), sock_addr.length(), domain, sizeof(domain), NULL, 0, NI_NAMEREQD);
|
|
||||||
if (0 != ret)
|
|
||||||
throw Exception("Cannot getnameinfo: " + std::string(gai_strerror(ret)), ErrorCodes::DNS_ERROR);
|
|
||||||
|
|
||||||
String domain_str = domain;
|
|
||||||
Poco::RegularExpression::Match match;
|
|
||||||
|
|
||||||
std::cerr << domain_str << ", " << host_regexp.match(domain_str, match) << std::endl;
|
|
||||||
|
|
||||||
if (host_regexp.match(domain_str, match) && HostExactPattern(domain_str).contains(addr))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char ** argv)
|
int main(int argc, char ** argv)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::cerr << test::HostRegexpPattern(argv[1]).contains(Poco::Net::IPAddress(argv[2])) << std::endl;
|
std::cerr << HostRegexpPattern(argv[1]).contains(Poco::Net::IPAddress(argv[2])) << std::endl;
|
||||||
}
|
}
|
||||||
catch (const Exception & e)
|
catch (const Exception & e)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user