1#include <re2/re2.h>
2#include <Common/RemoteHostFilter.h>
3#include <Poco/URI.h>
4#include <Formats/FormatFactory.h>
5#include <Poco/Util/AbstractConfiguration.h>
6#include <Common/StringUtils/StringUtils.h>
7#include <Common/Exception.h>
8#include <IO/WriteHelpers.h>
9
10namespace DB
11{
12namespace ErrorCodes
13{
14 extern const int UNACCEPTABLE_URL;
15}
16
17void RemoteHostFilter::checkURL(const Poco::URI & uri) const
18{
19 if (!checkForDirectEntry(uri.getHost()) &&
20 !checkForDirectEntry(uri.getHost() + ":" + toString(uri.getPort())))
21 throw Exception("URL \"" + uri.toString() + "\" is not allowed in config.xml", ErrorCodes::UNACCEPTABLE_URL);
22}
23
24void RemoteHostFilter::checkHostAndPort(const std::string & host, const std::string & port) const
25{
26 if (!checkForDirectEntry(host) &&
27 !checkForDirectEntry(host + ":" + port))
28 throw Exception("URL \"" + host + ":" + port + "\" is not allowed in config.xml", ErrorCodes::UNACCEPTABLE_URL);
29}
30
31void RemoteHostFilter::setValuesFromConfig(const Poco::Util::AbstractConfiguration & config)
32{
33 if (config.has("remote_url_allow_hosts"))
34 {
35 std::vector<std::string> keys;
36 config.keys("remote_url_allow_hosts", keys);
37 for (auto key : keys)
38 {
39 if (startsWith(key, "host_regexp"))
40 regexp_hosts.push_back(config.getString("remote_url_allow_hosts." + key));
41 else if (startsWith(key, "host"))
42 primary_hosts.insert(config.getString("remote_url_allow_hosts." + key));
43 }
44 }
45}
46
47bool RemoteHostFilter::checkForDirectEntry(const std::string & str) const
48{
49 if (!primary_hosts.empty() || !regexp_hosts.empty())
50 {
51 if (primary_hosts.find(str) == primary_hosts.end())
52 {
53 for (size_t i = 0; i < regexp_hosts.size(); ++i)
54 if (re2::RE2::FullMatch(str, regexp_hosts[i]))
55 return true;
56 return false;
57 }
58 return true;
59 }
60 return true;
61}
62}
63