public async Task<UserDTO> CreateUser(NPTicket ticket) { var user = new UserDTO() { PSNUserId = ticket.OnlineId, IPAddress = Request.HttpContext.Connection.RemoteIpAddress.ToString(), Nickname = ticket.OnlineId, // For the first time, the nickname will be the same as the psn name Country = ticket.Region.ToString().TrimEnd('\0').Substring(0, 2), }; int id; try { id = (int)await _users.AddAsync(user); } catch (Exception e) { _logger.LogError("Failed to create new user for PSN User: {userName}", ticket.OnlineId); return null; } user.Id = id; _logger.LogInformation("Created user: {psnUserId} (DB: {id})", ticket.OnlineId, id); return user; }
public static bool CreateSession(string sessionid, string psnticket, string ipAddr, SQLiteCommand sqlite_cmd) { //Decode PSN ticket data //sessionid = GetSessionID(sessionid); NPTicket ticket = DecodePSNTicket(psnticket); if (players.ContainsKey(sessionid)) { return(false); } SQLiteDataReader sqReader = DatabaseManager.GetReader(sqlite_cmd, "SELECT player_id FROM Users WHERE psn_id=@id", new SQLiteParameter("@id", ticket.user_id.ToString())); int id = 1; if (!sqReader.HasRows) { sqReader.Close(); sqReader = DatabaseManager.GetReader(sqlite_cmd, "SELECT player_id FROM Users ORDER BY player_id DESC LIMIT 1;"); if (sqReader.HasRows) { id = sqReader.GetInt32(0) + 1; } sqReader.Close(); DatabaseManager.NonQuery(sqlite_cmd, "INSERT INTO Users VALUES (@psn_id,@player_id,@username,@city,@country,@created_at,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,@player_creation_quota,0,@province,@quote,0,0,@skill_level,@skill_level_id,@skill_level_name,@state,0,0,0,0,0)" , new SQLiteParameter("@psn_id", ticket.user_id.ToString()) , new SQLiteParameter("@player_id", id) , new SQLiteParameter("@username", ticket.online_id) , new SQLiteParameter("@city", "") , new SQLiteParameter("@country", ticket.region) , new SQLiteParameter("@created_at", DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss")) , new SQLiteParameter("@player_creation_quota", 30) , new SQLiteParameter("@province", "") , new SQLiteParameter("@quote", "") , new SQLiteParameter("@skill_level", "Newcomer I") , new SQLiteParameter("@skill_level_id", "1") , new SQLiteParameter("@skill_level_name", "Newcomer I") , new SQLiteParameter("@state", "")); } else { id = sqReader.GetInt32(0); sqReader.Close(); } SessionPlayer player = new SessionPlayer(); player.ip_address = ipAddr; player.player_id = (ulong)id; player.username = ticket.online_id; player.presence = "ONLINE"; player.encoding = "US-ASCII"; players.Add(sessionid, player); playerTickets.Add(sessionid, ticket); return(true); }
private bool VerifyTicket(NPTicket ticket) { // TODO: Log ticket verification problems if (ticket.OnlineId.Length > 32) return false; if (ticket.Region.Length > 2) return false; if (ticket.Domain.Length > 4) return false; return true; }
private NPTicket ReadTicket(byte[] bytes) { var ticket = new NPTicket(); ticket.version = BitConverter.ToInt32(bytes, 0); if (ticket.version == 1) { ticket.clientID = BitConverter.ToUInt64(bytes, 4); ticket.serverID = BitConverter.ToUInt64(bytes, 12); ticket.time = BitConverter.ToUInt32(bytes, 20); } return(ticket); }
static NPTicket DecodePSNTicket(string strTicket) { while (strTicket.Length % 4 != 0) { strTicket += "="; } byte[] binTicket = Convert.FromBase64String(strTicket); BinaryReader br = new BinaryReader(binTicket); NPTicket ticket = new NPTicket(); ticket.version = br.popUInt32(); br.popArray(0x08); //Skip header br.popArray(0x04); ticket.serial_vec = br.popArray(0x14); br.popArray(0x04); ticket.issuer_id = br.popUInt32(); br.popArray(0x04); ticket.issued_date = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(br.popUInt64()); br.popArray(0x04); ticket.expired_date = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(br.popUInt64()); br.popArray(0x04); ticket.user_id = br.popUInt64(); br.popArray(0x04); ticket.online_id = Encoding.ASCII.GetString(br.popArray(0x20)).Trim('\0'); br.popArray(0x04); //ticket.region = Encoding.ASCII.GetString(br.popArray(0x04)).Trim('\0'); ticket.region = "br"; br.popArray(0x04); ticket.domain = Encoding.ASCII.GetString(br.popArray(0x04)).Trim('\0'); br.popArray(0x04); ticket.service_id = Encoding.ASCII.GetString(br.popArray(0x18)).Trim('\0'); br.popArray(0x04); ticket.status = br.popUInt32(); br.popArray(0x04); ticket.status_duration = br.popUInt32(); br.popArray(0x04); ticket.date_of_birth = br.popUInt32(); br.popArray(0x04); ticket.unk = br.popArray(0x44); return(ticket); }
public async Task<ActionResult> Post(ulong pfsVersion) { PFSType pfsType = (PFSType)pfsVersion; _logger.LogDebug("Login request from {host} with PFS: {pfsType} ({pfsNum})", Request.Host, pfsType, (long)pfsType); if (_gsOptions.EnforceGameVersion && !EnsureVersion(pfsType)) return Forbid(); if (Request.ContentLength >= 0x300) { _logger.LogWarning("Received a ticket too big - {size} from {host}", Request.ContentLength, Request.Host); return BadRequest(); } NPTicket ticket; try { byte[] buf = new byte[(int)Request.ContentLength]; await Request.Body.ReadAsync(buf.AsMemory(0, buf.Length)); ticket = NPTicket.FromBuffer(buf); } catch (Exception e) { _logger.LogWarning(e, "Could not read NP ticket provided by client"); return BadRequest(); } if (!VerifyTicket(ticket)) return BadRequest(); _logger.LogDebug("Auth Request: NP_Ticket -> PFS: {pfsVersion} | OnlineID: {OnlineId} | Region: {Region}", pfsVersion, ticket.OnlineId, ticket.Region); // Check if already connected if (CheckAlreadyConnected(ticket.OnlineId)) _logger.LogTrace("Auth Request from OnlineID: {OnlineId} which was already connected", ticket.OnlineId); UserDTO user = await _users.GetByPSNUserIdAsync(ticket.OnlineId) ?? await CreateUser(ticket); if (user is null) { _logger.LogError("Failed to get or create user from db: Name: {name}", ticket.OnlineId); return Problem(); } var now = DateTime.Now; // From this point, auth is OK var resp = new TicketResult() { Result = "1", // Doesn't seem to do much. Nickname = ticket.OnlineId, UserId = ticket.OnlineId, UserNumber = user.Id, ServerTime = now, }; var expiryTime = now.AddHours(1); var sToken = new SessionToken(GenerateToken(expiryTime), expiryTime); var cookieOptions = new CookieOptions() { Expires = sToken.ExpiryDate }; Response.Cookies.Append("X-gt-token", sToken.Token, cookieOptions); var player = new Player(user, sToken); player.LastUpdate = now; _players.AddUser(player); return Ok(resp); }