From 874f5b22e0b4520d32b374ddb16f4cab7808cfd7 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 2 Feb 2021 00:38:04 -0800 Subject: [PATCH] dns.mitm: support % in hosts file as stand-in for environment identifier --- .../libstratosphere/include/stratosphere.hpp | 1 + .../include/stratosphere/nsd.hpp | 18 +++++++ .../nsd/impl/device/nsd_device.hpp | 24 +++++++++ .../include/stratosphere/nsd/nsd_types.hpp | 37 ++++++++++++++ .../source/nsd/impl/device/nsd_device.cpp | 49 +++++++++++++++++++ .../include/vapours/util/util_string_util.hpp | 4 +- .../dns_mitm/dnsmitm_host_redirection.cpp | 23 ++++++--- 7 files changed, 148 insertions(+), 8 deletions(-) create mode 100644 libraries/libstratosphere/include/stratosphere/nsd.hpp create mode 100644 libraries/libstratosphere/include/stratosphere/nsd/impl/device/nsd_device.hpp create mode 100644 libraries/libstratosphere/include/stratosphere/nsd/nsd_types.hpp create mode 100644 libraries/libstratosphere/source/nsd/impl/device/nsd_device.cpp diff --git a/libraries/libstratosphere/include/stratosphere.hpp b/libraries/libstratosphere/include/stratosphere.hpp index aa648c200..c6bbe862b 100644 --- a/libraries/libstratosphere/include/stratosphere.hpp +++ b/libraries/libstratosphere/include/stratosphere.hpp @@ -61,6 +61,7 @@ #include #include #include +#include #include #include #include diff --git a/libraries/libstratosphere/include/stratosphere/nsd.hpp b/libraries/libstratosphere/include/stratosphere/nsd.hpp new file mode 100644 index 000000000..d0cfe3845 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/nsd.hpp @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include diff --git a/libraries/libstratosphere/include/stratosphere/nsd/impl/device/nsd_device.hpp b/libraries/libstratosphere/include/stratosphere/nsd/impl/device/nsd_device.hpp new file mode 100644 index 000000000..38521e386 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/nsd/impl/device/nsd_device.hpp @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include + +namespace ams::nsd::impl::device { + + const EnvironmentIdentifier &GetEnvironmentIdentifierFromSettings(); + +} diff --git a/libraries/libstratosphere/include/stratosphere/nsd/nsd_types.hpp b/libraries/libstratosphere/include/stratosphere/nsd/nsd_types.hpp new file mode 100644 index 000000000..9f8ace67a --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/nsd/nsd_types.hpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::nsd { + + struct EnvironmentIdentifier { + static constexpr size_t Size = 8; + char value[Size]; + + constexpr friend bool operator==(const EnvironmentIdentifier &lhs, const EnvironmentIdentifier &rhs) { + return util::Strncmp(lhs.value, rhs.value, Size) == 0; + } + + constexpr friend bool operator!=(const EnvironmentIdentifier &lhs, const EnvironmentIdentifier &rhs) { + return !(lhs == rhs); + } + }; + + constexpr inline const EnvironmentIdentifier EnvironmentIdentifierOfProductDevice = {"lp1"}; + constexpr inline const EnvironmentIdentifier EnvironmentIdentifierOfNotProductDevice = {"dd1"}; + +} diff --git a/libraries/libstratosphere/source/nsd/impl/device/nsd_device.cpp b/libraries/libstratosphere/source/nsd/impl/device/nsd_device.cpp new file mode 100644 index 000000000..8d06b32b9 --- /dev/null +++ b/libraries/libstratosphere/source/nsd/impl/device/nsd_device.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include + +namespace ams::nsd::impl::device { + + namespace { + + constexpr const char SettingsName[] = "nsd"; + constexpr const char SettingsKey[] = "environment_identifier"; + + constinit os::SdkMutex g_environment_identifier_lock; + constinit EnvironmentIdentifier g_environment_identifier = {}; + constinit bool g_determined_environment_identifier = false; + + } + + const EnvironmentIdentifier &GetEnvironmentIdentifierFromSettings() { + std::scoped_lock lk(g_environment_identifier_lock); + + if (!g_determined_environment_identifier) { + /* Check size. */ + AMS_ABORT_UNLESS(settings::fwdbg::GetSettingsItemValueSize(SettingsName, SettingsKey) != 0); + + /* Get value. */ + const size_t size = settings::fwdbg::GetSettingsItemValue(g_environment_identifier.value, EnvironmentIdentifier::Size, SettingsName, SettingsKey); + AMS_ABORT_UNLESS(size < EnvironmentIdentifier::Size); + AMS_ABORT_UNLESS(g_environment_identifier == EnvironmentIdentifierOfProductDevice || g_environment_identifier == EnvironmentIdentifierOfNotProductDevice); + + g_determined_environment_identifier = true; + } + + return g_environment_identifier; + } + +} diff --git a/libraries/libvapours/include/vapours/util/util_string_util.hpp b/libraries/libvapours/include/vapours/util/util_string_util.hpp index d06d96a7d..9abe8aaab 100644 --- a/libraries/libvapours/include/vapours/util/util_string_util.hpp +++ b/libraries/libvapours/include/vapours/util/util_string_util.hpp @@ -31,7 +31,7 @@ namespace ams::util { } template - int Strncmp(const T *lhs, const T *rhs, int count) { + constexpr int Strncmp(const T *lhs, const T *rhs, int count) { AMS_ASSERT(lhs != nullptr); AMS_ASSERT(rhs != nullptr); AMS_ABORT_UNLESS(count >= 0); @@ -50,7 +50,7 @@ namespace ams::util { } template - int Strnicmp(const T *lhs, const T *rhs, int count) { + constexpr int Strnicmp(const T *lhs, const T *rhs, int count) { AMS_ASSERT(lhs != nullptr); AMS_ASSERT(rhs != nullptr); AMS_ABORT_UNLESS(count >= 0); diff --git a/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_host_redirection.cpp b/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_host_redirection.cpp index f4057dddc..44d205e75 100644 --- a/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_host_redirection.cpp +++ b/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_host_redirection.cpp @@ -66,10 +66,7 @@ namespace ams::mitm::socket::resolver { constexpr const char DefaultHostsFile[] = "# Nintendo telemetry servers\n" - "127.0.0.1 receive-*.*.srv.nintendo.net\n"; - - static_assert(wildcardcmp("receive-*.*.srv.nintendo.net", "receive-lp1.dg.srv.nintendo.net") == 1); - static_assert(wildcardcmp("receive-*.*.srv.nintendo.net", "receive-lp1.er.srv.nintendo.net") == 1); + "127.0.0.1 receive-%.dg.srv.nintendo.net receive-%.er.srv.nintendo.net\n"; constinit os::SdkMutex g_redirection_lock; std::unordered_map g_redirection_map; @@ -77,6 +74,11 @@ namespace ams::mitm::socket::resolver { constinit char g_specific_emummc_hosts_path[0x40] = {}; void ParseHostsFile(const char *file_data) { + /* Get the environment identifier from settings. */ + const auto env = ams::nsd::impl::device::GetEnvironmentIdentifierFromSettings(); + const auto env_len = std::strlen(env.value); + + /* Parse the file. */ enum class State { IgnoredLine, BeginLine, @@ -189,8 +191,13 @@ namespace ams::mitm::socket::resolver { if (c == '\n') { state = State::BeginLine; } else if (c != ' ' && c != '\r' && c != '\t') { - current_hostname[0] = c; - work = 1; + if (c == '%') { + std::memcpy(current_hostname, env.value, env_len); + work = env_len; + } else { + current_hostname[0] = c; + work = 1; + } state = State::HostName; } break; @@ -207,6 +214,10 @@ namespace ams::mitm::socket::resolver { } else { state = State::WhiteSpace; } + } 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;