diff --git a/ProjectLighthouse/Controllers/LoginController.cs b/ProjectLighthouse/Controllers/LoginController.cs index 879f7cac..7d82bda0 100644 --- a/ProjectLighthouse/Controllers/LoginController.cs +++ b/ProjectLighthouse/Controllers/LoginController.cs @@ -1,4 +1,6 @@ #nullable enable +using System; +using System.IO; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; @@ -16,21 +18,19 @@ namespace ProjectLighthouse.Controllers { if(!this.Request.Query.TryGetValue("titleID", out StringValues _)) return this.BadRequest(""); - // FIXME: this will not do, MM_AUTH is created by the client after POST /LOGIN - if(!this.Request.Cookies.TryGetValue("MM_AUTH", out string? mmAuth) || mmAuth == null) - return this.BadRequest(""); // TODO: send 403 + string body = await new StreamReader(Request.Body).ReadToEndAsync(); + + LoginData loginData; + try { + loginData = LoginData.CreateFromString(body); + } + catch(Exception e) { + return this.BadRequest(); + } await using Database database = new(); - Token? token; - - // ReSharper disable once InvertIf - if(!await database.IsUserAuthenticated(mmAuth)) { - token = await database.AuthenticateUser(mmAuth); - } - else { - token = await database.Tokens.FirstOrDefaultAsync(t => t.UserToken == mmAuth); - } + Token? token = await database.AuthenticateUser(loginData); if(token == null) return this.BadRequest(""); // TODO: send 403 diff --git a/ProjectLighthouse/Database.cs b/ProjectLighthouse/Database.cs index 9d1882ea..77bb334c 100644 --- a/ProjectLighthouse/Database.cs +++ b/ProjectLighthouse/Database.cs @@ -35,17 +35,11 @@ namespace ProjectLighthouse { return user; } - - // MM_AUTH=psn_name:?:timestamp, potentially a user creation date?:?:user id?:user's IP:?:password? SHA1 - // just blindly trust the token for now while we get it working - public async Task AuthenticateUser(string loginString) { - if(!loginString.Contains(':')) return null; - - string[] split = loginString.Split(":"); - + + public async Task AuthenticateUser(LoginData loginData) { // TODO: don't use psn name to authenticate - User user = await this.Users.FirstOrDefaultAsync(u => u.Username == split[0]) - ?? await this.CreateUser(split[0]); + User user = await this.Users.FirstOrDefaultAsync(u => u.Username == loginData.Username + u.Username[-1]) + ?? await this.CreateUser(loginData.Username + "_"); Token token = new() { UserToken = HashHelper.GenerateAuthToken(), diff --git a/ProjectLighthouse/Types/LoginData.cs b/ProjectLighthouse/Types/LoginData.cs new file mode 100644 index 00000000..84087d5f --- /dev/null +++ b/ProjectLighthouse/Types/LoginData.cs @@ -0,0 +1,43 @@ +using System.IO; +using System.Text; + +namespace ProjectLighthouse.Types { + // This is all the information I can understand for now. More testing is required. + // Example data: + // - LBP2 digital, with the RPCN username `literally1984` + // POST /LITTLEBIGPLANETPS3_XML/login?applicationID=21414&languageID=1&lbp2=1&beta=0&titleID=NPUA80662&country=us + // !�0256333||x||��Y literally198bruUP9000-NPUA80662_008D + // - LBP2 digital, with the RPCN username `jvyden` + // POST /LITTLEBIGPLANETPS3_XML/login?applicationID=21414&languageID=1&lbp2=1&beta=0&titleID=NPUA80662&country=us + // !�0220333||/u||=0� jvydebruUP9000-NPUA80662_008D + /// + /// The data sent from POST /LOGIN. + /// + public class LoginData { + public string Username { get; set; } // Cut off by one for some strange reason + public string GameVersion { get; set; } + public int UnknownNumber { get; set; } // Seems to increment by 1000 every login attempt + + public static LoginData CreateFromString(string str) { + using MemoryStream ms = new(Encoding.ASCII.GetBytes(str)); + using BinaryReader reader = new(ms); + + LoginData loginData = new(); + + reader.ReadBytes(4); // Perhaps a header of sorts? + + string number = Encoding.ASCII.GetString(reader.ReadBytes(7)); // Number is stored as text for some reason... + loginData.UnknownNumber = int.Parse(number); + + reader.ReadBytes(10); // No clue what this is. + + string end = Encoding.ASCII.GetString(reader.ReadBytes(int.MaxValue)); // ReadToEnd 2: Electric Boogaloo + string[] split = end.Split("bru"); // No idea what it means, but it seems to split the gameversion and username apart + + loginData.Username = split[0]; + loginData.GameVersion = split[1]; + + return loginData; + } + } +} \ No newline at end of file