From 4134acc49290742005c18903952af0813a07a932 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 26 Jun 2023 10:01:20 +0200 Subject: [PATCH] Use the new "secret storage" to store the retroachievements token --- .gitignore | 2 ++ Core/Config.cpp | 4 ++-- Core/Config.h | 2 +- UI/NativeApp.cpp | 8 ++++++-- UI/RetroAchievements.cpp | 13 ++++++++++--- 5 files changed, 21 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index fd1d2d372f..0723838277 100644 --- a/.gitignore +++ b/.gitignore @@ -131,3 +131,5 @@ CMakeFiles .cache/ build libretro/obj/local + +ppsspp_retroachievements.dat diff --git a/Core/Config.cpp b/Core/Config.cpp index ebe76d625e..25420980c4 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -276,9 +276,9 @@ static const ConfigSetting achievementSettings[] = { ConfigSetting("AchievementsLogBadMemReads", &g_Config.bAchievementsLogBadMemReads, false, CfgFlag::DEFAULT), // Achievements login info. Note that password is NOT stored, only a login token. - // Still, we may wanna store it more securely than in PPSSPP.ini, especially on Android. + // And that login token is stored separately from the ini, see NativeSaveSecret. ConfigSetting("AchievementsUserName", &g_Config.sAchievementsUserName, "", CfgFlag::DEFAULT), - ConfigSetting("AchievementsToken", &g_Config.sAchievementsToken, "", CfgFlag::DEFAULT), + ConfigSetting("AchievementsToken", &g_Config.sAchievementsToken, "", CfgFlag::DONT_SAVE), ConfigSetting("AchievementsLoginTimestamp", &g_Config.sAchievementsLoginTimestamp, "", CfgFlag::DEFAULT), }; diff --git a/Core/Config.h b/Core/Config.h index c05e4a88cb..09cd56e18c 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -497,7 +497,7 @@ public: // Achivements login info. Note that password is NOT stored, only a login token. // Still, we may wanna store it more securely than in PPSSPP.ini, especially on Android. std::string sAchievementsUserName; - std::string sAchievementsToken; + std::string sAchievementsToken; // Not saved, to be used if you want to manually make your RA login persistent. See Native_SaveSecret for the normal case. std::string sAchievementsLoginTimestamp; // Various directories. Autoconfigured, not read from ini. diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 91e08ac1d3..4be2d91b14 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -1430,12 +1430,16 @@ void NativeSaveSecret(const char *nameOfSecret, const std::string &data) { // On Android, that corresponds to the app private directory. On other platforms, // the location is less secure unfortunately - to be improved. Path path = GetSecretPath(nameOfSecret); - File::WriteDataToFile(false, data.data(), data.size(), path); + if (!File::WriteDataToFile(false, data.data(), data.size(), path)) { + WARN_LOG(SYSTEM, "Failed to write secret '%s' to path '%s'", nameOfSecret, path.c_str()); + } } std::string NativeLoadSecret(const char *nameOfSecret) { Path path = GetSecretPath(nameOfSecret); std::string data; - File::ReadFileToString(false, path, data); + if (!File::ReadFileToString(false, path, data)) { + WARN_LOG(SYSTEM, "Failed to read secret '%s' from path '%s'", nameOfSecret, path.c_str()); + } return data; } diff --git a/UI/RetroAchievements.cpp b/UI/RetroAchievements.cpp index cc5bd71c62..f0ad6f622d 100644 --- a/UI/RetroAchievements.cpp +++ b/UI/RetroAchievements.cpp @@ -31,6 +31,7 @@ #include "Common/File/Path.h" #include "Common/File/FileUtil.h" #include "Common/Net/HTTPClient.h" +#include "Common/System/NativeApp.h" #include "Common/TimeUtil.h" #include "Common/Data/Text/I18n.h" #include "Common/Serialize/Serializer.h" @@ -162,6 +163,9 @@ static constexpr UI::UISound INFO_SOUND_NAME = UI::UISound::SELECT; static constexpr UI::UISound UNLOCK_SOUND_NAME = UI::UISound::TOGGLE_ON; static constexpr UI::UISound LBSUBMIT_SOUND_NAME = UI::UISound::TOGGLE_OFF; +// It's the name of the secret, not a secret name - the value is not secret :) +static const char *RA_TOKEN_SECRET_NAME = "retroachievements "; + static void FormattedError(const char *format, ...); static void LogFailedResponseJSON(const Common::HTTPDownloader::Request::Data &data); static void CheevosEventHandler(const rc_runtime_event_t *runtime_event); @@ -577,7 +581,10 @@ void Achievements::Initialize() s_last_ping_time = time_now_d(); s_username = g_Config.sAchievementsUserName; - s_api_token = g_Config.sAchievementsToken; + s_api_token = NativeLoadSecret(RA_TOKEN_SECRET_NAME); + if (s_api_token.empty()) { + s_api_token = g_Config.sAchievementsToken; + } s_logged_in = (!s_username.empty() && !s_api_token.empty()); // this is just the non-SSL path. @@ -991,8 +998,8 @@ void Achievements::LoginCallback(s32 status_code, std::string content_type, Comm // save to config g_Config.sAchievementsUserName = username; - g_Config.sAchievementsToken = api_token; g_Config.sAchievementsLoginTimestamp = StringFromFormat("%llu", (unsigned long long)std::time(nullptr)); + NativeSaveSecret(RA_TOKEN_SECRET_NAME, api_token); g_Config.Save("AchievementsLogin"); @@ -1059,7 +1066,7 @@ void Achievements::Logout() // remove from config g_Config.sAchievementsUserName.clear(); - g_Config.sAchievementsToken.clear(); + NativeSaveSecret(RA_TOKEN_SECRET_NAME, ""); g_Config.sAchievementsLoginTimestamp.clear(); g_Config.Save("Achievements logout"); }