mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-08-07 08:38:45 +00:00
Support DNS-MITM redirection exceptions
This commit is contained in:
parent
3afd9a737c
commit
7c50a6a3d1
2 changed files with 42 additions and 1 deletions
|
@ -10,6 +10,7 @@ DNS.mitm can be configured through the usage of a slightly-extended `hosts` file
|
||||||
In particular, hosts files parsed by DNS.mitm have the following extensions to the usual format:
|
In particular, hosts files parsed by DNS.mitm have the following extensions to the usual format:
|
||||||
+ `*` is treated as a wildcard character, matching any collection of 0 or more characters wherever it occurs in a hostname.
|
+ `*` is treated as a wildcard character, matching any collection of 0 or more characters wherever it occurs in a hostname.
|
||||||
+ `%` is treated as a stand-in for the value of `nsd!environment_identifier`. This is always `lp1`, on production devices.
|
+ `%` is treated as a stand-in for the value of `nsd!environment_identifier`. This is always `lp1`, on production devices.
|
||||||
|
+ `-` is used to begin a line and indicates that this line contains a single hostname that is to be excepted from being redirected. It can be used to override a wildcard or other entry.
|
||||||
|
|
||||||
If multiple entries in a host file match a domain, the last-defined match is used.
|
If multiple entries in a host file match a domain, the last-defined match is used.
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,7 @@ namespace ams::mitm::socket::resolver {
|
||||||
|
|
||||||
constinit os::SdkMutex g_redirection_lock;
|
constinit os::SdkMutex g_redirection_lock;
|
||||||
std::vector<std::pair<std::string, ams::socket::InAddrT>> g_redirection_list;
|
std::vector<std::pair<std::string, ams::socket::InAddrT>> g_redirection_list;
|
||||||
|
std::vector<std::string> g_exception_list;
|
||||||
|
|
||||||
void RemoveRedirection(const char *hostname) {
|
void RemoveRedirection(const char *hostname) {
|
||||||
for (auto it = g_redirection_list.begin(); it != g_redirection_list.end(); ++it) {
|
for (auto it = g_redirection_list.begin(); it != g_redirection_list.end(); ++it) {
|
||||||
|
@ -84,6 +85,12 @@ namespace ams::mitm::socket::resolver {
|
||||||
RemoveRedirection(hostname);
|
RemoveRedirection(hostname);
|
||||||
g_redirection_list.emplace(g_redirection_list.begin(), std::string(hostname), addr);
|
g_redirection_list.emplace(g_redirection_list.begin(), std::string(hostname), addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddException(const char *hostname) {
|
||||||
|
if (!(std::find(g_exception_list.begin(), g_exception_list.end(), hostname) != g_exception_list.end())){
|
||||||
|
g_exception_list.emplace(g_exception_list.begin(), std::string(hostname));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
constinit char g_specific_emummc_hosts_path[0x40] = {};
|
constinit char g_specific_emummc_hosts_path[0x40] = {};
|
||||||
|
|
||||||
|
@ -105,6 +112,7 @@ namespace ams::mitm::socket::resolver {
|
||||||
Ip4,
|
Ip4,
|
||||||
WhiteSpace,
|
WhiteSpace,
|
||||||
HostName,
|
HostName,
|
||||||
|
ExceptList,
|
||||||
};
|
};
|
||||||
|
|
||||||
ams::socket::InAddrT current_address;
|
ams::socket::InAddrT current_address;
|
||||||
|
@ -127,6 +135,9 @@ namespace ams::mitm::socket::resolver {
|
||||||
state = State::Ip1;
|
state = State::Ip1;
|
||||||
} else if (c == '\n') {
|
} else if (c == '\n') {
|
||||||
state = State::BeginLine;
|
state = State::BeginLine;
|
||||||
|
} else if (c == '-') {
|
||||||
|
work = 0;
|
||||||
|
state = State::ExceptList;
|
||||||
} else {
|
} else {
|
||||||
state = State::IgnoredLine;
|
state = State::IgnoredLine;
|
||||||
}
|
}
|
||||||
|
@ -217,6 +228,26 @@ namespace ams::mitm::socket::resolver {
|
||||||
state = State::HostName;
|
state = State::HostName;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case State::ExceptList:
|
||||||
|
if (c == '\r' || c == '\n') {
|
||||||
|
AMS_ABORT_UNLESS(work < sizeof(current_hostname));
|
||||||
|
current_hostname[work] = '\x00';
|
||||||
|
|
||||||
|
AddException(current_hostname);
|
||||||
|
work = 0;
|
||||||
|
|
||||||
|
if (c == '\n') {
|
||||||
|
state = State::BeginLine;
|
||||||
|
}
|
||||||
|
} else if (c == '%') {
|
||||||
|
AMS_ABORT_UNLESS(work < sizeof(current_hostname) - env_len);
|
||||||
|
std::memcpy(current_hostname + work, env.value, env_len);
|
||||||
|
work += env_len;
|
||||||
|
} else {
|
||||||
|
AMS_ABORT_UNLESS(work < sizeof(current_hostname) - 1);
|
||||||
|
current_hostname[work++] = c;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case State::HostName:
|
case State::HostName:
|
||||||
if (c == ' ' || c == '\r' || c == '\n' || c == '\t') {
|
if (c == ' ' || c == '\r' || c == '\n' || c == '\t') {
|
||||||
AMS_ABORT_UNLESS(work < sizeof(current_hostname));
|
AMS_ABORT_UNLESS(work < sizeof(current_hostname));
|
||||||
|
@ -311,6 +342,9 @@ namespace ams::mitm::socket::resolver {
|
||||||
/* Clear the redirections map. */
|
/* Clear the redirections map. */
|
||||||
g_redirection_list.clear();
|
g_redirection_list.clear();
|
||||||
|
|
||||||
|
/* Clear the exceptions. */
|
||||||
|
g_exception_list.clear();
|
||||||
|
|
||||||
/* Open log file. */
|
/* Open log file. */
|
||||||
::FsFile log_file;
|
::FsFile log_file;
|
||||||
mitm::fs::DeleteAtmosphereSdFile("/logs/dns_mitm_startup.log");
|
mitm::fs::DeleteAtmosphereSdFile("/logs/dns_mitm_startup.log");
|
||||||
|
@ -381,13 +415,19 @@ namespace ams::mitm::socket::resolver {
|
||||||
for (const auto &[host, address] : g_redirection_list) {
|
for (const auto &[host, address] : g_redirection_list) {
|
||||||
Log(log_file, " `%s` -> %u.%u.%u.%u\n", host.c_str(), (address >> 0) & 0xFF, (address >> 8) & 0xFF, (address >> 16) & 0xFF, (address >> 24) & 0xFF);
|
Log(log_file, " `%s` -> %u.%u.%u.%u\n", host.c_str(), (address >> 0) & 0xFF, (address >> 8) & 0xFF, (address >> 16) & 0xFF, (address >> 24) & 0xFF);
|
||||||
}
|
}
|
||||||
|
/* Print the exceptions. */
|
||||||
|
Log(log_file, "Exceptions:\n");
|
||||||
|
for (const auto &host : g_exception_list) {
|
||||||
|
Log(log_file, " `%s`\n", host.c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetRedirectedHostByName(ams::socket::InAddrT *out, const char *hostname) {
|
bool GetRedirectedHostByName(ams::socket::InAddrT *out, const char *hostname) {
|
||||||
std::scoped_lock lk(g_redirection_lock);
|
std::scoped_lock lk(g_redirection_lock);
|
||||||
|
|
||||||
for (const auto &[host, address] : g_redirection_list) {
|
for (const auto &[host, address] : g_redirection_list) {
|
||||||
if (wildcardcmp(host.c_str(), hostname)) {
|
if (wildcardcmp(host.c_str(), hostname) &&
|
||||||
|
!(std::find(g_exception_list.begin(), g_exception_list.end(), hostname) != g_exception_list.end())) {
|
||||||
*out = address;
|
*out = address;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue