Skip to content

Commit

Permalink
Ability to print format of ticket
Browse files Browse the repository at this point in the history
  • Loading branch information
jvyden committed Jul 26, 2023
1 parent 375da4f commit 20ec784
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 28 deletions.
5 changes: 5 additions & 0 deletions NPTicket.Test/Program.cs
Original file line number Diff line number Diff line change
@@ -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));
Expand Down
36 changes: 34 additions & 2 deletions NPTicket/Reader/TicketReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand Down
38 changes: 12 additions & 26 deletions NPTicket/Ticket.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Text.RegularExpressions;
using NPTicket.Reader;
using NPTicket.Types;
using NPTicket.Types.Parsers;
using NPTicket.Verification;

namespace NPTicket;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand Down
37 changes: 37 additions & 0 deletions NPTicket/Types/Parsers/TicketParser21.cs
Original file line number Diff line number Diff line change
@@ -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})");
}
}
}
11 changes: 11 additions & 0 deletions NPTicket/Types/Parsers/TicketParser30.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using NPTicket.Reader;

namespace NPTicket.Types.Parsers;

internal static class TicketParser30
{
internal static void ParseTicket(Ticket ticket, TicketReader reader)
{

}
}

0 comments on commit 20ec784

Please sign in to comment.