applets: Implement Auth applet backend
This is responsible for parental controls and supports verifying, changing, and registering PIN codes.
This commit is contained in:
parent
221996a194
commit
9d2d349d7b
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
namespace Service::AM::Applets {
|
namespace Service::AM::Applets {
|
||||||
|
|
||||||
|
constexpr ResultCode ERROR_INVALID_PIN{ErrorModule::PCTL, 221};
|
||||||
|
|
||||||
static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix) {
|
static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix) {
|
||||||
std::unique_ptr<IStorage> storage = broker.PopNormalDataToApplet();
|
std::unique_ptr<IStorage> storage = broker.PopNormalDataToApplet();
|
||||||
for (; storage != nullptr; storage = broker.PopNormalDataToApplet()) {
|
for (; storage != nullptr; storage = broker.PopNormalDataToApplet()) {
|
||||||
|
@ -35,6 +37,120 @@ static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Auth::Auth(Core::Frontend::ParentalControlsApplet& frontend) : frontend(frontend) {}
|
||||||
|
|
||||||
|
Auth::~Auth() = default;
|
||||||
|
|
||||||
|
void Auth::Initialize() {
|
||||||
|
Applet::Initialize();
|
||||||
|
complete = false;
|
||||||
|
|
||||||
|
const auto storage = broker.PopNormalDataToApplet();
|
||||||
|
ASSERT(storage != nullptr);
|
||||||
|
const auto data = storage->GetData();
|
||||||
|
ASSERT(data.size() >= 0xC);
|
||||||
|
|
||||||
|
struct Arg {
|
||||||
|
INSERT_PADDING_BYTES(4);
|
||||||
|
AuthAppletType type;
|
||||||
|
u8 arg0;
|
||||||
|
u8 arg1;
|
||||||
|
u8 arg2;
|
||||||
|
INSERT_PADDING_BYTES(1);
|
||||||
|
};
|
||||||
|
static_assert(sizeof(Arg) == 0xC, "Arg (AuthApplet) has incorrect size.");
|
||||||
|
|
||||||
|
Arg arg{};
|
||||||
|
std::memcpy(&arg, data.data(), sizeof(Arg));
|
||||||
|
|
||||||
|
type = arg.type;
|
||||||
|
arg0 = arg.arg0;
|
||||||
|
arg1 = arg.arg1;
|
||||||
|
arg2 = arg.arg2;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Auth::TransactionComplete() const {
|
||||||
|
return complete;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultCode Auth::GetStatus() const {
|
||||||
|
return successful ? RESULT_SUCCESS : ERROR_INVALID_PIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Auth::ExecuteInteractive() {
|
||||||
|
UNREACHABLE_MSG("Unexpected interactive applet data.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Auth::Execute() {
|
||||||
|
if (complete) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto unimplemented_log = [this] {
|
||||||
|
UNIMPLEMENTED_MSG("Unimplemented Auth applet type for type={:08X}, arg0={:02X}, "
|
||||||
|
"arg1={:02X}, arg2={:02X}",
|
||||||
|
static_cast<u32>(type), arg0, arg1, arg2);
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case AuthAppletType::ShowParentalAuthentication: {
|
||||||
|
const auto callback = [this](bool successful) { AuthFinished(successful); };
|
||||||
|
|
||||||
|
if (arg0 == 1 && arg1 == 0 && arg2 == 1) {
|
||||||
|
// ShowAuthenticatorForConfiguration
|
||||||
|
frontend.VerifyPINForSettings(callback);
|
||||||
|
} else if (arg1 == 0 && arg2 == 0) {
|
||||||
|
// ShowParentalAuthentication(bool)
|
||||||
|
frontend.VerifyPIN(callback, static_cast<bool>(arg0));
|
||||||
|
} else {
|
||||||
|
unimplemented_log();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AuthAppletType::RegisterParentalPasscode: {
|
||||||
|
const auto callback = [this] { AuthFinished(true); };
|
||||||
|
|
||||||
|
if (arg0 == 0 && arg1 == 0 && arg2 == 0) {
|
||||||
|
// RegisterParentalPasscode
|
||||||
|
frontend.RegisterPIN(callback);
|
||||||
|
} else {
|
||||||
|
unimplemented_log();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AuthAppletType::ChangeParentalPasscode: {
|
||||||
|
const auto callback = [this] { AuthFinished(true); };
|
||||||
|
|
||||||
|
if (arg0 == 0 && arg1 == 0 && arg2 == 0) {
|
||||||
|
// ChangeParentalPasscode
|
||||||
|
frontend.ChangePIN(callback);
|
||||||
|
} else {
|
||||||
|
unimplemented_log();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
unimplemented_log();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Auth::AuthFinished(bool successful) {
|
||||||
|
this->successful = successful;
|
||||||
|
|
||||||
|
struct Return {
|
||||||
|
ResultCode result_code;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(Return) == 0x4, "Return (AuthApplet) has incorrect size.");
|
||||||
|
|
||||||
|
Return return_{GetStatus()};
|
||||||
|
|
||||||
|
std::vector<u8> out(sizeof(Return));
|
||||||
|
std::memcpy(out.data(), &return_, sizeof(Return));
|
||||||
|
|
||||||
|
broker.PushNormalDataFromApplet(IStorage{out});
|
||||||
|
broker.SignalStateChanged();
|
||||||
|
}
|
||||||
|
|
||||||
PhotoViewer::PhotoViewer(const Core::Frontend::PhotoViewerApplet& frontend) : frontend(frontend) {}
|
PhotoViewer::PhotoViewer(const Core::Frontend::PhotoViewerApplet& frontend) : frontend(frontend) {}
|
||||||
|
|
||||||
PhotoViewer::~PhotoViewer() = default;
|
PhotoViewer::~PhotoViewer() = default;
|
||||||
|
|
|
@ -8,6 +8,36 @@
|
||||||
|
|
||||||
namespace Service::AM::Applets {
|
namespace Service::AM::Applets {
|
||||||
|
|
||||||
|
enum class AuthAppletType : u32 {
|
||||||
|
ShowParentalAuthentication,
|
||||||
|
RegisterParentalPasscode,
|
||||||
|
ChangeParentalPasscode,
|
||||||
|
};
|
||||||
|
|
||||||
|
class Auth final : public Applet {
|
||||||
|
public:
|
||||||
|
explicit Auth(Core::Frontend::ParentalControlsApplet& frontend);
|
||||||
|
~Auth() override;
|
||||||
|
|
||||||
|
void Initialize() override;
|
||||||
|
bool TransactionComplete() const override;
|
||||||
|
ResultCode GetStatus() const override;
|
||||||
|
void ExecuteInteractive() override;
|
||||||
|
void Execute() override;
|
||||||
|
|
||||||
|
void AuthFinished(bool successful = true);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Core::Frontend::ParentalControlsApplet& frontend;
|
||||||
|
bool complete = false;
|
||||||
|
bool successful = false;
|
||||||
|
|
||||||
|
AuthAppletType type = AuthAppletType::ShowParentalAuthentication;
|
||||||
|
u8 arg0 = 0;
|
||||||
|
u8 arg1 = 0;
|
||||||
|
u8 arg2 = 0;
|
||||||
|
};
|
||||||
|
|
||||||
enum class PhotoViewerAppletMode : u8 {
|
enum class PhotoViewerAppletMode : u8 {
|
||||||
CurrentApp = 0,
|
CurrentApp = 0,
|
||||||
AllApps = 1,
|
AllApps = 1,
|
||||||
|
|
Reference in New Issue