Skip to content

Commit

Permalink
IOS/KD: Implement Request Register User ID
Browse files Browse the repository at this point in the history
  • Loading branch information
noahpistilli committed Jun 8, 2023
1 parent 44d9304 commit 0bdc17b
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 4 deletions.
15 changes: 15 additions & 0 deletions Source/Core/Core/IOS/Network/KD/NWC24Config.cpp
Expand Up @@ -216,4 +216,19 @@ void NWC24Config::SetEmail(const char* email)
strncpy(m_data.email, email, MAX_EMAIL_LENGTH);
m_data.email[MAX_EMAIL_LENGTH - 1] = '\0';
}

std::string NWC24Config::GetAccountURL() const
{
return {m_data.http_urls[0]};
}

void NWC24Config::SetMailCheckID(const std::string& mlchkid)
{
std::strncpy(m_data.mlchkid, mlchkid.c_str(), 36);
}

void NWC24Config::SetPassword(const std::string& password)
{
std::strncpy(m_data.paswd, password.c_str(), 32);
}
} // namespace IOS::HLE::NWC24
4 changes: 4 additions & 0 deletions Source/Core/Core/IOS/Network/KD/NWC24Config.h
Expand Up @@ -85,6 +85,10 @@ class NWC24Config final
const char* Email() const;
void SetEmail(const char* email);

std::string GetAccountURL() const;
void SetMailCheckID(const std::string& mlchkid);
void SetPassword(const std::string& password);

private:
enum
{
Expand Down
116 changes: 112 additions & 4 deletions Source/Core/Core/IOS/Network/KD/NetKDRequest.cpp
Expand Up @@ -16,6 +16,7 @@
#include "Common/Logging/Log.h"
#include "Common/NandPaths.h"
#include "Common/SettingsHandler.h"
#include "Common/StringUtil.h"

#include "Core/CommonTitles.h"
#include "Core/HW/Memmap.h"
Expand Down Expand Up @@ -182,6 +183,21 @@ void NetKDRequestDevice::Update()
}
}

std::string NetKDRequestDevice::GetValueFromCGIResponse(const std::string& response,
const std::string& key)
{
std::string val{};
const std::vector<std::string> raw_fields = SplitString(response, '\n');
for (const std::string& field : raw_fields)
{
const std::vector<std::string> key_value = SplitString(field, '=');
if (key_value[0] == key)
val = StripWhitespace(key_value[1]);
}

return val;
}

void NetKDRequestDevice::LogError(ErrorType error_type, s32 error_code)
{
s32 new_code{};
Expand Down Expand Up @@ -337,6 +353,101 @@ IPCReply NetKDRequestDevice::HandleNWC24DownloadNowEx(const IOCtlRequest& reques
return IPCReply(IPC_SUCCESS);
}

IPCReply NetKDRequestDevice::HandleRequestRegisterUserId(const IOS::HLE::IOCtlRequest& request)
{
auto& system = GetSystem();
auto& memory = system.GetMemory();

INFO_LOG_FMT(IOS_WC24, "NET_KD_REQ: IOCTL_NWC24_REQUEST_REGISTER_USER_ID");
// Always 0 for some reason, never modified anywhere else
memory.Write_U32(0, request.buffer_out + 4);

if (config.IsRegistered())
{
WriteReturnValue(NWC24::WC24_ERR_ID_REGISTERED, request.buffer_out);
LogError(ErrorType::Account, NWC24::WC24_ERR_ID_REGISTERED);
return IPCReply{IPC_SUCCESS};
}

// We require the user's product code.
std::string product_code{};
const std::string settings_file_path =
Common::GetTitleDataPath(Titles::SYSTEM_MENU) + "/" WII_SETTING;
const auto fs = m_ios.GetFS();
if (const auto file = fs->OpenFile(PID_KD, PID_KD, settings_file_path, FS::Mode::Read))
{
Common::SettingsHandler::Buffer data;
if (file->Read(data.data(), data.size()))
{
const Common::SettingsHandler gen{std::move(data)};
product_code = gen.GetValue("CODE");
}
else
{
WriteReturnValue(NWC24::WC24_ERR_FILE_READ, request.buffer_out);
LogError(ErrorType::Account, NWC24::WC24_ERR_FILE_READ);
return IPCReply{IPC_SUCCESS};
}
}
else
{
WriteReturnValue(NWC24::WC24_ERR_FILE_OPEN, request.buffer_out);
LogError(ErrorType::Account, NWC24::WC24_ERR_FILE_OPEN);
return IPCReply{IPC_SUCCESS};
}

const std::string form_data = fmt::format("mlid=w{}&hdid={}&rgncd={}", config.Id(),
m_ios.GetIOSC().GetDeviceId(), product_code);
const Common::HttpRequest::Response response = m_http.Post(config.GetAccountURL(), form_data);

if (!response)
{
ERROR_LOG_FMT(IOS_WC24,
"NET_KD_REQ: IOCTL_NWC24_REQUEST_REGISTER_USER_ID: Failed to request data at {}.",
config.GetAccountURL());
WriteReturnValue(NWC24::WC24_ERR_SERVER, request.buffer_out);
LogError(ErrorType::Account, NWC24::WC24_ERR_SERVER);
return IPCReply{IPC_SUCCESS};
}

const std::string response_str = {response->begin(), response->end()};
const std::string code = GetValueFromCGIResponse(response_str, "cd");
if (code != "100")
{
ERROR_LOG_FMT(IOS_WC24,
"NET_KD_REQ: IOCTL_NWC24_REQUEST_REGISTER_USER_ID: Mail server returned "
"non-success code: {}",
code);
WriteReturnValue(NWC24::WC24_ERR_SERVER, request.buffer_out);
LogError(ErrorType::Account, NWC24::WC24_ERR_SERVER);
return IPCReply{IPC_SUCCESS};
}

const std::string passwd = GetValueFromCGIResponse(response_str, "passwd");
const std::string mlchkid = GetValueFromCGIResponse(response_str, "mlchkid");
if (mlchkid.size() != 36)
{
ERROR_LOG_FMT(IOS_WC24,
"NET_KD_REQ: IOCTL_NWC24_REQUEST_REGISTER_USER_ID: Mail server returned invalid "
"mlchkid: {}",
mlchkid);
WriteReturnValue(NWC24::WC24_ERR_SERVER, request.buffer_out);
LogError(ErrorType::Account, NWC24::WC24_ERR_SERVER);
return IPCReply{IPC_SUCCESS};
}

// Now write to the config.
config.SetCreationStage(NWC24::NWC24CreationStage::Registered);
config.SetPassword(passwd);
config.SetMailCheckID(mlchkid);
config.WriteConfig();
config.WriteCBK();

WriteReturnValue(NWC24::WC24_OK, request.buffer_out);

return IPCReply{IPC_SUCCESS};
}

std::optional<IPCReply> NetKDRequestDevice::IOCtl(const IOCtlRequest& request)
{
enum : u32
Expand Down Expand Up @@ -406,10 +517,7 @@ std::optional<IPCReply> NetKDRequestDevice::IOCtl(const IOCtlRequest& request)
break;

case IOCTL_NWC24_REQUEST_REGISTER_USER_ID:
INFO_LOG_FMT(IOS_WC24, "NET_KD_REQ: IOCTL_NWC24_REQUEST_REGISTER_USER_ID");
WriteReturnValue(0, request.buffer_out);
memory.Write_U32(0, request.buffer_out + 4);
break;
return LaunchAsyncTask(&NetKDRequestDevice::HandleRequestRegisterUserId, request);

case IOCTL_NWC24_REQUEST_GENERATED_USER_ID: // (Input: none, Output: 32 bytes)
INFO_LOG_FMT(IOS_WC24, "NET_KD_REQ: IOCTL_NWC24_REQUEST_GENERATED_USER_ID");
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/Core/IOS/Network/KD/NetKDRequest.h
Expand Up @@ -60,6 +60,8 @@ class NetKDRequestDevice : public EmulationDevice
};

void LogError(ErrorType error_type, s32 error_code);
IPCReply HandleRequestRegisterUserId(const IOCtlRequest& request);
static std::string GetValueFromCGIResponse(const std::string& response, const std::string& key);

NWC24::NWC24Config config;
NWC24::NWC24Dl m_dl_list;
Expand Down

0 comments on commit 0bdc17b

Please sign in to comment.