diff options
| author | 2019-06-05 12:10:23 -0400 | |
|---|---|---|
| committer | 2019-06-24 20:05:11 -0400 | |
| commit | 9d2d349d7b0d30784b13260844deec500b5a50c8 (patch) | |
| tree | 3d6124ea41ef9651c1e68e0dc1d7f400dd29bb87 /src | |
| parent | Merge pull request #2603 from WamWooWam/master (diff) | |
| download | yuzu-9d2d349d7b0d30784b13260844deec500b5a50c8.tar.gz yuzu-9d2d349d7b0d30784b13260844deec500b5a50c8.tar.xz yuzu-9d2d349d7b0d30784b13260844deec500b5a50c8.zip | |
applets: Implement Auth applet backend
This is responsible for parental controls and supports verifying, changing, and registering PIN codes.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/am/applets/general_backend.cpp | 116 | ||||
| -rw-r--r-- | src/core/hle/service/am/applets/general_backend.h | 30 |
2 files changed, 146 insertions, 0 deletions
diff --git a/src/core/hle/service/am/applets/general_backend.cpp b/src/core/hle/service/am/applets/general_backend.cpp index 54c155dd8..e0def8dff 100644 --- a/src/core/hle/service/am/applets/general_backend.cpp +++ b/src/core/hle/service/am/applets/general_backend.cpp | |||
| @@ -17,6 +17,8 @@ | |||
| 17 | 17 | ||
| 18 | namespace Service::AM::Applets { | 18 | namespace Service::AM::Applets { |
| 19 | 19 | ||
| 20 | constexpr ResultCode ERROR_INVALID_PIN{ErrorModule::PCTL, 221}; | ||
| 21 | |||
| 20 | static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix) { | 22 | static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix) { |
| 21 | std::unique_ptr<IStorage> storage = broker.PopNormalDataToApplet(); | 23 | std::unique_ptr<IStorage> storage = broker.PopNormalDataToApplet(); |
| 22 | for (; storage != nullptr; storage = broker.PopNormalDataToApplet()) { | 24 | for (; storage != nullptr; storage = broker.PopNormalDataToApplet()) { |
| @@ -35,6 +37,120 @@ static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix) | |||
| 35 | } | 37 | } |
| 36 | } | 38 | } |
| 37 | 39 | ||
| 40 | Auth::Auth(Core::Frontend::ParentalControlsApplet& frontend) : frontend(frontend) {} | ||
| 41 | |||
| 42 | Auth::~Auth() = default; | ||
| 43 | |||
| 44 | void Auth::Initialize() { | ||
| 45 | Applet::Initialize(); | ||
| 46 | complete = false; | ||
| 47 | |||
| 48 | const auto storage = broker.PopNormalDataToApplet(); | ||
| 49 | ASSERT(storage != nullptr); | ||
| 50 | const auto data = storage->GetData(); | ||
| 51 | ASSERT(data.size() >= 0xC); | ||
| 52 | |||
| 53 | struct Arg { | ||
| 54 | INSERT_PADDING_BYTES(4); | ||
| 55 | AuthAppletType type; | ||
| 56 | u8 arg0; | ||
| 57 | u8 arg1; | ||
| 58 | u8 arg2; | ||
| 59 | INSERT_PADDING_BYTES(1); | ||
| 60 | }; | ||
| 61 | static_assert(sizeof(Arg) == 0xC, "Arg (AuthApplet) has incorrect size."); | ||
| 62 | |||
| 63 | Arg arg{}; | ||
| 64 | std::memcpy(&arg, data.data(), sizeof(Arg)); | ||
| 65 | |||
| 66 | type = arg.type; | ||
| 67 | arg0 = arg.arg0; | ||
| 68 | arg1 = arg.arg1; | ||
| 69 | arg2 = arg.arg2; | ||
| 70 | } | ||
| 71 | |||
| 72 | bool Auth::TransactionComplete() const { | ||
| 73 | return complete; | ||
| 74 | } | ||
| 75 | |||
| 76 | ResultCode Auth::GetStatus() const { | ||
| 77 | return successful ? RESULT_SUCCESS : ERROR_INVALID_PIN; | ||
| 78 | } | ||
| 79 | |||
| 80 | void Auth::ExecuteInteractive() { | ||
| 81 | UNREACHABLE_MSG("Unexpected interactive applet data."); | ||
| 82 | } | ||
| 83 | |||
| 84 | void Auth::Execute() { | ||
| 85 | if (complete) { | ||
| 86 | return; | ||
| 87 | } | ||
| 88 | |||
| 89 | const auto unimplemented_log = [this] { | ||
| 90 | UNIMPLEMENTED_MSG("Unimplemented Auth applet type for type={:08X}, arg0={:02X}, " | ||
| 91 | "arg1={:02X}, arg2={:02X}", | ||
| 92 | static_cast<u32>(type), arg0, arg1, arg2); | ||
| 93 | }; | ||
| 94 | |||
| 95 | switch (type) { | ||
| 96 | case AuthAppletType::ShowParentalAuthentication: { | ||
| 97 | const auto callback = [this](bool successful) { AuthFinished(successful); }; | ||
| 98 | |||
| 99 | if (arg0 == 1 && arg1 == 0 && arg2 == 1) { | ||
| 100 | // ShowAuthenticatorForConfiguration | ||
| 101 | frontend.VerifyPINForSettings(callback); | ||
| 102 | } else if (arg1 == 0 && arg2 == 0) { | ||
| 103 | // ShowParentalAuthentication(bool) | ||
| 104 | frontend.VerifyPIN(callback, static_cast<bool>(arg0)); | ||
| 105 | } else { | ||
| 106 | unimplemented_log(); | ||
| 107 | } | ||
| 108 | break; | ||
| 109 | } | ||
| 110 | case AuthAppletType::RegisterParentalPasscode: { | ||
| 111 | const auto callback = [this] { AuthFinished(true); }; | ||
| 112 | |||
| 113 | if (arg0 == 0 && arg1 == 0 && arg2 == 0) { | ||
| 114 | // RegisterParentalPasscode | ||
| 115 | frontend.RegisterPIN(callback); | ||
| 116 | } else { | ||
| 117 | unimplemented_log(); | ||
| 118 | } | ||
| 119 | break; | ||
| 120 | } | ||
| 121 | case AuthAppletType::ChangeParentalPasscode: { | ||
| 122 | const auto callback = [this] { AuthFinished(true); }; | ||
| 123 | |||
| 124 | if (arg0 == 0 && arg1 == 0 && arg2 == 0) { | ||
| 125 | // ChangeParentalPasscode | ||
| 126 | frontend.ChangePIN(callback); | ||
| 127 | } else { | ||
| 128 | unimplemented_log(); | ||
| 129 | } | ||
| 130 | break; | ||
| 131 | } | ||
| 132 | default: | ||
| 133 | unimplemented_log(); | ||
| 134 | } | ||
| 135 | } | ||
| 136 | |||
| 137 | void Auth::AuthFinished(bool successful) { | ||
| 138 | this->successful = successful; | ||
| 139 | |||
| 140 | struct Return { | ||
| 141 | ResultCode result_code; | ||
| 142 | }; | ||
| 143 | static_assert(sizeof(Return) == 0x4, "Return (AuthApplet) has incorrect size."); | ||
| 144 | |||
| 145 | Return return_{GetStatus()}; | ||
| 146 | |||
| 147 | std::vector<u8> out(sizeof(Return)); | ||
| 148 | std::memcpy(out.data(), &return_, sizeof(Return)); | ||
| 149 | |||
| 150 | broker.PushNormalDataFromApplet(IStorage{out}); | ||
| 151 | broker.SignalStateChanged(); | ||
| 152 | } | ||
| 153 | |||
| 38 | PhotoViewer::PhotoViewer(const Core::Frontend::PhotoViewerApplet& frontend) : frontend(frontend) {} | 154 | PhotoViewer::PhotoViewer(const Core::Frontend::PhotoViewerApplet& frontend) : frontend(frontend) {} |
| 39 | 155 | ||
| 40 | PhotoViewer::~PhotoViewer() = default; | 156 | PhotoViewer::~PhotoViewer() = default; |
diff --git a/src/core/hle/service/am/applets/general_backend.h b/src/core/hle/service/am/applets/general_backend.h index fb68a2543..0da252044 100644 --- a/src/core/hle/service/am/applets/general_backend.h +++ b/src/core/hle/service/am/applets/general_backend.h | |||
| @@ -8,6 +8,36 @@ | |||
| 8 | 8 | ||
| 9 | namespace Service::AM::Applets { | 9 | namespace Service::AM::Applets { |
| 10 | 10 | ||
| 11 | enum class AuthAppletType : u32 { | ||
| 12 | ShowParentalAuthentication, | ||
| 13 | RegisterParentalPasscode, | ||
| 14 | ChangeParentalPasscode, | ||
| 15 | }; | ||
| 16 | |||
| 17 | class Auth final : public Applet { | ||
| 18 | public: | ||
| 19 | explicit Auth(Core::Frontend::ParentalControlsApplet& frontend); | ||
| 20 | ~Auth() override; | ||
| 21 | |||
| 22 | void Initialize() override; | ||
| 23 | bool TransactionComplete() const override; | ||
| 24 | ResultCode GetStatus() const override; | ||
| 25 | void ExecuteInteractive() override; | ||
| 26 | void Execute() override; | ||
| 27 | |||
| 28 | void AuthFinished(bool successful = true); | ||
| 29 | |||
| 30 | private: | ||
| 31 | Core::Frontend::ParentalControlsApplet& frontend; | ||
| 32 | bool complete = false; | ||
| 33 | bool successful = false; | ||
| 34 | |||
| 35 | AuthAppletType type = AuthAppletType::ShowParentalAuthentication; | ||
| 36 | u8 arg0 = 0; | ||
| 37 | u8 arg1 = 0; | ||
| 38 | u8 arg2 = 0; | ||
| 39 | }; | ||
| 40 | |||
| 11 | enum class PhotoViewerAppletMode : u8 { | 41 | enum class PhotoViewerAppletMode : u8 { |
| 12 | CurrentApp = 0, | 42 | CurrentApp = 0, |
| 13 | AllApps = 1, | 43 | AllApps = 1, |