From 20ec7841dcece3bb7628e63f2dbc795b3617d5f9 Mon Sep 17 00:00:00 2001 From: jvyden Date: Wed, 26 Jul 2023 18:18:53 -0400 Subject: [PATCH] Ability to print format of ticket --- NPTicket.Test/Program.cs | 5 ++++ NPTicket/Reader/TicketReader.cs | 36 ++++++++++++++++++++-- NPTicket/Ticket.cs | 38 ++++++++---------------- NPTicket/Types/Parsers/TicketParser21.cs | 37 +++++++++++++++++++++++ NPTicket/Types/Parsers/TicketParser30.cs | 11 +++++++ 5 files changed, 99 insertions(+), 28 deletions(-) create mode 100644 NPTicket/Types/Parsers/TicketParser21.cs create mode 100644 NPTicket/Types/Parsers/TicketParser30.cs diff --git a/NPTicket.Test/Program.cs b/NPTicket.Test/Program.cs index 69d2eda..bdc1fd6 100644 --- a/NPTicket.Test/Program.cs +++ b/NPTicket.Test/Program.cs @@ -1,9 +1,14 @@ using System.Text.Json; using NPTicket; +using NPTicket.Reader; using NPTicket.Test; using NPTicket.Verification; byte[] ticketData = await File.ReadAllBytesAsync(string.Join(' ', args)); +using MemoryStream ms = new(ticketData); +using TicketReader reader = new(ms); +reader.DetermineTicketFormat(); +return; Ticket ticket = Ticket.ReadFromBytes(ticketData); Console.WriteLine(JsonSerializer.Serialize(ticket)); diff --git a/NPTicket/Reader/TicketReader.cs b/NPTicket/Reader/TicketReader.cs index b7acb97..79007c3 100644 --- a/NPTicket/Reader/TicketReader.cs +++ b/NPTicket/Reader/TicketReader.cs @@ -4,9 +4,9 @@ namespace NPTicket.Reader; -internal class TicketReader : BinaryReader +public class TicketReader : BinaryReader { - internal TicketReader(Stream input) : base(input) + public TicketReader(Stream input) : base(input) {} #region Big Endian Shenanigans @@ -32,6 +32,38 @@ internal ushort ReadTicketHeader() return ReadUInt16(); // Ticket length } + public void DetermineTicketFormat() + { + TicketVersion version = ReadTicketVersion(); + Console.Write($"Ticket version {version.Major}.{version.Minor}"); + ushort length = ReadTicketHeader(); + Console.WriteLine($", length is {length} bytes"); + + while (this.BaseStream.Position <= length) + { + DetermineSectionFormat(); + } + } + + private void DetermineSectionFormat() + { + TicketDataSection section = ReadTicketSectionHeader(); + Console.WriteLine($" {section.Type} Section, length is {section.Length} @ offset {section.Position}"); + + int endSpot = section.Length + section.Position; + while (this.BaseStream.Position <= endSpot) + { + DetermineData(); + } + } + + private void DetermineData() + { + TicketData data = ReadTicketData(TicketDataType.Empty); + Console.WriteLine($" {data.Type}, length is {data.Length}"); + this.ReadBytes(data.Length); + } + internal TicketDataSection ReadTicketSectionHeader() { long position = this.BaseStream.Position; diff --git a/NPTicket/Ticket.cs b/NPTicket/Ticket.cs index fd7ca25..ae0b488 100644 --- a/NPTicket/Ticket.cs +++ b/NPTicket/Ticket.cs @@ -6,6 +6,7 @@ using System.Text.RegularExpressions; using NPTicket.Reader; using NPTicket.Types; +using NPTicket.Types.Parsers; using NPTicket.Verification; namespace NPTicket; @@ -44,7 +45,7 @@ private Ticket() {} public byte[] SignatureData { get; set; } // TODO: Use GeneratedRegex, this is not in netstandard yet - private static readonly Regex ServiceIdRegex = new("(?<=-)[A-Z0-9]{9}(?=_)", RegexOptions.Compiled); + internal static readonly Regex ServiceIdRegex = new("(?<=-)[A-Z0-9]{9}(?=_)", RegexOptions.Compiled); [Pure] public static Ticket ReadFromBytes(byte[] data) @@ -77,32 +78,17 @@ public static Ticket ReadFromStream(Stream stream) $"was really {ticket.BodySection.Type} ({(int)ticket.BodySection.Type})"); } - ticket.SerialId = reader.ReadTicketStringData(TicketDataType.Binary); - - ticket.IssuerId = reader.ReadTicketUInt32Data(); - - ticket.IssuedDate = reader.ReadTicketTimestampData(); - ticket.ExpiryDate = reader.ReadTicketTimestampData(); - - ticket.UserId = reader.ReadTicketUInt64Data(); - ticket.Username = reader.ReadTicketStringData(); - - ticket.Country = reader.ReadTicketStringData(TicketDataType.Binary); // No I am not going to brazil - ticket.Domain = reader.ReadTicketStringData(); - - ticket.ServiceId = reader.ReadTicketStringData(TicketDataType.Binary); - ticket.TitleId = ServiceIdRegex.Matches(ticket.ServiceId)[0].ToString(); - - ticket.Status = reader.ReadUInt32(); - - // Skip padding section in ticket - reader.SkipTicketEmptyData(3); - - TicketDataSection footer = reader.ReadTicketSectionHeader(); - if (footer.Type != TicketDataSectionType.Footer) + if (ticket.Version is { Major: 2, Minor: 1 }) + { + TicketParser21.ParseTicket(ticket, reader); + } + else if (ticket.Version is { Major: 3, Minor: 0 }) + { + TicketParser30.ParseTicket(ticket, reader); + } + else { - throw new FormatException($"Expected last section to be {nameof(TicketDataSectionType.Footer)}, " + - $"was really {footer.Type} ({(int)footer.Type})"); + throw new FormatException($"Unknown/unhandled ticket version {ticket.Version.Major}.{ticket.Version.Minor}"); } ticket.SignatureIdentifier = reader.ReadTicketStringData(TicketDataType.Binary); diff --git a/NPTicket/Types/Parsers/TicketParser21.cs b/NPTicket/Types/Parsers/TicketParser21.cs new file mode 100644 index 0000000..05611df --- /dev/null +++ b/NPTicket/Types/Parsers/TicketParser21.cs @@ -0,0 +1,37 @@ +using NPTicket.Reader; + +namespace NPTicket.Types.Parsers; + +internal static class TicketParser21 +{ + internal static void ParseTicket(Ticket ticket, TicketReader reader) + { + ticket.SerialId = reader.ReadTicketStringData(TicketDataType.Binary); + + ticket.IssuerId = reader.ReadTicketUInt32Data(); + + ticket.IssuedDate = reader.ReadTicketTimestampData(); + ticket.ExpiryDate = reader.ReadTicketTimestampData(); + + ticket.UserId = reader.ReadTicketUInt64Data(); + ticket.Username = reader.ReadTicketStringData(); + + ticket.Country = reader.ReadTicketStringData(TicketDataType.Binary); // No I am not going to brazil + ticket.Domain = reader.ReadTicketStringData(); + + ticket.ServiceId = reader.ReadTicketStringData(TicketDataType.Binary); + ticket.TitleId = Ticket.ServiceIdRegex.Matches(ticket.ServiceId)[0].ToString(); + + ticket.Status = reader.ReadUInt32(); + + // Skip padding section in ticket + reader.SkipTicketEmptyData(3); + + TicketDataSection footer = reader.ReadTicketSectionHeader(); + if (footer.Type != TicketDataSectionType.Footer) + { + throw new FormatException($"Expected last section to be {nameof(TicketDataSectionType.Footer)}, " + + $"was really {footer.Type} ({(int)footer.Type})"); + } + } +} \ No newline at end of file diff --git a/NPTicket/Types/Parsers/TicketParser30.cs b/NPTicket/Types/Parsers/TicketParser30.cs new file mode 100644 index 0000000..16287d3 --- /dev/null +++ b/NPTicket/Types/Parsers/TicketParser30.cs @@ -0,0 +1,11 @@ +using NPTicket.Reader; + +namespace NPTicket.Types.Parsers; + +internal static class TicketParser30 +{ + internal static void ParseTicket(Ticket ticket, TicketReader reader) + { + + } +} \ No newline at end of file