[Np] Complete offline authentication requests as signed out
This commit is contained in:
parent
1b66707daf
commit
124dfa8afd
|
|
@ -13,15 +13,22 @@ public static class NpAuthExports
|
|||
private const int NpAuthErrorAborted = unchecked((int)0x80550304);
|
||||
private const int NpAuthErrorRequestMaximum = unchecked((int)0x80550305);
|
||||
private const int NpAuthErrorRequestNotFound = unchecked((int)0x80550306);
|
||||
private const int NpAuthErrorServiceDown = unchecked((int)0x80550401);
|
||||
private const int NpAuthErrorInvalidArgument = unchecked((int)0x80550301);
|
||||
private const int NpErrorSignedOut = unchecked((int)0x80550006);
|
||||
private const int AuthorizationCodeSize = 136;
|
||||
private const int IdTokenSize = 4104;
|
||||
private const ulong AsyncParameterSize = 24;
|
||||
|
||||
private static readonly ConcurrentDictionary<int, AuthRequest> Requests = new();
|
||||
private static readonly object RequestGate = new();
|
||||
private static int _nextRequestId;
|
||||
|
||||
private sealed class AuthRequest
|
||||
private sealed class AuthRequest(bool async)
|
||||
{
|
||||
public bool Async { get; } = async;
|
||||
|
||||
public bool Completed { get; set; }
|
||||
|
||||
public bool Aborted { get; set; }
|
||||
|
||||
public int Result { get; set; }
|
||||
|
|
@ -47,7 +54,7 @@ public static class NpAuthExports
|
|||
ExportName = "sceNpAuthCreateRequest",
|
||||
Target = Generation.Gen5,
|
||||
LibraryName = "libSceNpAuth")]
|
||||
public static int NpAuthCreateRequest(CpuContext ctx) => CreateRequest(ctx);
|
||||
public static int NpAuthCreateRequest(CpuContext ctx) => CreateRequest(ctx, async: false);
|
||||
|
||||
[SysAbiExport(
|
||||
ExportName = "sceNpAuthCreateAsyncRequest",
|
||||
|
|
@ -63,7 +70,7 @@ public static class NpAuthExports
|
|||
return ctx.SetReturn(NpAuthErrorInvalidSize);
|
||||
}
|
||||
|
||||
return CreateRequest(ctx);
|
||||
return CreateRequest(ctx, async: true);
|
||||
}
|
||||
|
||||
[SysAbiExport(
|
||||
|
|
@ -134,21 +141,23 @@ public static class NpAuthExports
|
|||
ExportName = "sceNpAuthGetAuthorizationCodeV3",
|
||||
Target = Generation.Gen5,
|
||||
LibraryName = "libSceNpAuth")]
|
||||
public static int NpAuthGetAuthorizationCodeV3(CpuContext ctx) => RejectOnlineOperation(ctx);
|
||||
public static int NpAuthGetAuthorizationCodeV3(CpuContext ctx) =>
|
||||
CompleteSignedOut(ctx, ctx[CpuRegister.Rdx], AuthorizationCodeSize, ctx[CpuRegister.Rcx]);
|
||||
|
||||
[SysAbiExport(
|
||||
ExportName = "sceNpAuthGetIdTokenV3",
|
||||
Target = Generation.Gen5,
|
||||
LibraryName = "libSceNpAuth")]
|
||||
public static int NpAuthGetIdTokenV3(CpuContext ctx) => RejectOnlineOperation(ctx);
|
||||
public static int NpAuthGetIdTokenV3(CpuContext ctx) =>
|
||||
CompleteSignedOut(ctx, ctx[CpuRegister.Rdx], IdTokenSize, 0);
|
||||
|
||||
[SysAbiExport(
|
||||
ExportName = "sceNpAuthGetAuthorizedAppCode",
|
||||
Target = Generation.Gen5,
|
||||
LibraryName = "libSceNpAuth")]
|
||||
public static int NpAuthGetAuthorizedAppCode(CpuContext ctx) => RejectOnlineOperation(ctx);
|
||||
public static int NpAuthGetAuthorizedAppCode(CpuContext ctx) => CompleteSignedOut(ctx, 0, 0, 0);
|
||||
|
||||
private static int CreateRequest(CpuContext ctx)
|
||||
private static int CreateRequest(CpuContext ctx, bool async)
|
||||
{
|
||||
lock (RequestGate)
|
||||
{
|
||||
|
|
@ -160,7 +169,7 @@ public static class NpAuthExports
|
|||
while (true)
|
||||
{
|
||||
var id = Interlocked.Increment(ref _nextRequestId);
|
||||
if (Requests.TryAdd(id, new AuthRequest()))
|
||||
if (Requests.TryAdd(id, new AuthRequest(async)))
|
||||
{
|
||||
return ctx.SetReturn(id);
|
||||
}
|
||||
|
|
@ -168,8 +177,20 @@ public static class NpAuthExports
|
|||
}
|
||||
}
|
||||
|
||||
private static int RejectOnlineOperation(CpuContext ctx)
|
||||
private static int CompleteSignedOut(CpuContext ctx, ulong outputAddress, int outputSize, ulong issuerAddress)
|
||||
{
|
||||
if (outputAddress != 0 && outputSize != 0)
|
||||
{
|
||||
Span<byte> cleared = stackalloc byte[outputSize];
|
||||
cleared.Clear();
|
||||
ctx.Memory.TryWrite(outputAddress, cleared);
|
||||
}
|
||||
|
||||
if (issuerAddress != 0)
|
||||
{
|
||||
ctx.TryWriteUInt32(issuerAddress, 0);
|
||||
}
|
||||
|
||||
if (!Requests.TryGetValue(unchecked((int)ctx[CpuRegister.Rdi]), out var request))
|
||||
{
|
||||
return ctx.SetReturn(NpAuthErrorRequestNotFound);
|
||||
|
|
@ -177,8 +198,21 @@ public static class NpAuthExports
|
|||
|
||||
lock (request)
|
||||
{
|
||||
request.Result = request.Aborted ? NpAuthErrorAborted : NpAuthErrorServiceDown;
|
||||
return ctx.SetReturn(request.Result);
|
||||
if (request.Aborted)
|
||||
{
|
||||
request.Result = NpAuthErrorAborted;
|
||||
return ctx.SetReturn(NpAuthErrorAborted);
|
||||
}
|
||||
|
||||
if (request.Completed)
|
||||
{
|
||||
request.Result = NpAuthErrorInvalidArgument;
|
||||
return ctx.SetReturn(NpAuthErrorInvalidArgument);
|
||||
}
|
||||
|
||||
request.Completed = true;
|
||||
request.Result = NpErrorSignedOut;
|
||||
return ctx.SetReturn(request.Async ? 0 : NpErrorSignedOut);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue