From 376b249425abe97610ae3ef64847b5d4b26db121 Mon Sep 17 00:00:00 2001 From: GitHubProUser67 <127040195+GitHubProUser67@users.noreply.github.com> Date: Sun, 15 Dec 2024 13:12:43 +0100 Subject: [PATCH] Ace Zlib Security fixes + Ram optimizations in Quazal / HomeTools and the NetworkLibrary HTTP system and local certificate loading behaviour change in SpaceWizards. Also includes a fix for the Quazal friend list v2Services and allows to Grab a owned certificate from local appdata folder despite using a global certificate. --- .../HomeTools/BARFramework/ZLibCompressor.cs | 46 ++--- .../Deflate.cs | 5 +- .../InfBlocks.cs | 171 +++++++++--------- .../InfCodes.cs | 50 +++-- .../ZLib.cs | 46 +++++ .../ZOutputStream.cs | 130 ++++++++++--- .../ComponentAce.Compression.Libs.zlib/Zip.cs | 31 ++++ .../CompressionLibrary/Edge/Zlib.cs | 83 +++++---- .../NetworkLibrary/HTTP/HTTPProcessor.cs | 11 +- .../System/Net/Managed/HttpConnection.cs | 77 ++++---- .../QuazalServer/QNetZ/Helper.cs | 71 ++++---- ...acyFriendsService.cs => FriendsService.cs} | 15 +- 12 files changed, 445 insertions(+), 291 deletions(-) create mode 100644 BackendServices/CompressionLibrary/ComponentAce.Compression.Libs.zlib/ZLib.cs create mode 100644 BackendServices/CompressionLibrary/ComponentAce.Compression.Libs.zlib/Zip.cs rename SpecializedServers/QuazalServer/RDVServices/v2Services/{LegacyFriendsService.cs => FriendsService.cs} (61%) diff --git a/AuxiliaryServices/HomeTools/BARFramework/ZLibCompressor.cs b/AuxiliaryServices/HomeTools/BARFramework/ZLibCompressor.cs index db2b151f7..5d0fd5950 100644 --- a/AuxiliaryServices/HomeTools/BARFramework/ZLibCompressor.cs +++ b/AuxiliaryServices/HomeTools/BARFramework/ZLibCompressor.cs @@ -10,34 +10,38 @@ internal static class ZLibCompressor internal static byte[] Compress(byte[] inData, bool NoHeader) { byte[] result = null; - MemoryStream memoryStream = new MemoryStream(); - ZOutputStream zoutputStream = new ZOutputStream(memoryStream, 9, NoHeader); - try + using (MemoryStream memoryStream = new MemoryStream()) + using (ZOutputStream zoutputStream = new ZOutputStream(memoryStream, 9, NoHeader)) { - zoutputStream.Write(inData, 0, inData.Length); - } - catch (Exception ex) - { - LoggerAccessor.LogError($"[ZlibCompressor] - Compressed errored out with this exception - {ex}"); - return Array.Empty(); - } - finally - { - zoutputStream.Close(); - memoryStream.Close(); - result = memoryStream.ToArray(); + try + { + zoutputStream.Write(inData, 0, inData.Length); + } + catch (Exception ex) + { + LoggerAccessor.LogError($"[ZlibCompressor] - Compressed errored out with this exception - {ex}"); + return Array.Empty(); + } + finally + { + zoutputStream.Close(); + memoryStream.Close(); + result = memoryStream.ToArray(); + } } return result; } internal static byte[] Decompress(byte[] inData, bool NoHeader) { - MemoryStream memoryStream = new MemoryStream(); - ZOutputStream zoutputStream = new ZOutputStream(memoryStream, NoHeader); - zoutputStream.Write(inData, 0, inData.Length); - zoutputStream.Close(); - memoryStream.Close(); - return memoryStream.ToArray(); + using (MemoryStream memoryStream = new MemoryStream()) + using (ZOutputStream zoutputStream = new ZOutputStream(memoryStream, NoHeader)) + { + zoutputStream.Write(inData, 0, inData.Length); + zoutputStream.Close(); + memoryStream.Close(); + return memoryStream.ToArray(); + } } } } \ No newline at end of file diff --git a/BackendServices/CompressionLibrary/ComponentAce.Compression.Libs.zlib/Deflate.cs b/BackendServices/CompressionLibrary/ComponentAce.Compression.Libs.zlib/Deflate.cs index 2443af16e..0461aa324 100644 --- a/BackendServices/CompressionLibrary/ComponentAce.Compression.Libs.zlib/Deflate.cs +++ b/BackendServices/CompressionLibrary/ComponentAce.Compression.Libs.zlib/Deflate.cs @@ -1222,7 +1222,8 @@ internal int deflate(ZStream strm, int flush) putShortMSB((int)SupportClass.URShift(strm.adler, 16)); putShortMSB((int)(strm.adler & 0xFFFF)); } - strm.adler = strm._adler.adler32(0L, null, 0, 0); + if (strm._adler != null) + strm.adler = strm._adler.adler32(0L, null, 0, 0); } if (pending != 0) { @@ -1273,7 +1274,7 @@ internal int deflate(ZStream strm, int flush) else { _tr_stored_block(0, 0, eof: false); - if (flush == 3) + if (flush == 3 && head != null) { for (int i = 0; i < hash_size; i++) { diff --git a/BackendServices/CompressionLibrary/ComponentAce.Compression.Libs.zlib/InfBlocks.cs b/BackendServices/CompressionLibrary/ComponentAce.Compression.Libs.zlib/InfBlocks.cs index 45c78a0ea..932236b6a 100644 --- a/BackendServices/CompressionLibrary/ComponentAce.Compression.Libs.zlib/InfBlocks.cs +++ b/BackendServices/CompressionLibrary/ComponentAce.Compression.Libs.zlib/InfBlocks.cs @@ -113,9 +113,9 @@ internal void reset(ZStream z, long[] c) mode = 0; bitk = 0; bitb = 0; - read = (write = 0); + read = write = 0; if (checkfn != null && z._adler != null) - z.adler = (check = z._adler.adler32(0L, null, 0, 0)); + z.adler = check = z._adler.adler32(0L, null, 0, 0); } internal int proc(ZStream z, int r) @@ -278,7 +278,7 @@ internal int proc(ZStream z, int r) num6 = num2; if (num6 > num5) num6 = num5; - if (z.next_in != null && window != null) + if (z.next_in != null) Array.Copy(z.next_in, num, window, num4, num6); num += num6; num2 -= num6; @@ -360,28 +360,30 @@ internal int proc(ZStream z, int r) { blens[border[index++]] = 0; } - } - bb[0] = 7; - int num6 = InfTree.inflate_trees_bits(blens, bb, tb, hufts ?? Array.Empty(), z); - if (num6 != 0) - { - r = num6; - if (r == -3) + bb[0] = 7; + int num6 = InfTree.inflate_trees_bits(blens, bb, tb, hufts ?? Array.Empty(), z); + if (num6 != 0) { - blens = null; - mode = 9; + r = num6; + if (r == -3) + { + blens = null; + mode = 9; + } + bitb = num3; + bitk = i; + z.avail_in = num2; + z.total_in += num - z.next_in_index; + z.next_in_index = num; + write = num4; + return inflate_flush(z, r); } - bitb = num3; - bitk = i; - z.avail_in = num2; - z.total_in += num - z.next_in_index; - z.next_in_index = num; - write = num4; - return inflate_flush(z, r); + index = 0; + mode = 5; + goto case 5; } - index = 0; - mode = 5; - goto case 5; + + return -1; } case 5: { @@ -410,69 +412,63 @@ internal int proc(ZStream z, int r) } _ = tb[0]; _ = -1; - if (hufts != null) + num6 = hufts[(tb[0] + (num3 & inflate_mask[num6])) * 3 + 1]; + int num7 = hufts[(tb[0] + (num3 & inflate_mask[num6])) * 3 + 2]; + if (num7 < 16) { - num6 = hufts[(tb[0] + (num3 & inflate_mask[num6])) * 3 + 1]; - int num7 = hufts[(tb[0] + (num3 & inflate_mask[num6])) * 3 + 2]; - if (num7 < 16 && blens != null) - { - num3 = SupportClass.URShift(num3, num6); - i -= num6; - blens[index++] = num7; - continue; - } - int num8 = ((num7 == 18) ? 7 : (num7 - 14)); - int num9 = ((num7 == 18) ? 11 : 3); - for (; i < num6 + num8; i += 8) - { - if (num2 != 0 && z.next_in != null) - { - r = 0; - num2--; - num3 |= (z.next_in[num++] & 0xFF) << i; - continue; - } - bitb = num3; - bitk = i; - z.avail_in = num2; - z.total_in += num - z.next_in_index; - z.next_in_index = num; - write = num4; - return inflate_flush(z, r); - } num3 = SupportClass.URShift(num3, num6); i -= num6; - num9 += num3 & inflate_mask[num8]; - num3 = SupportClass.URShift(num3, num8); - i -= num8; - num8 = index; - num6 = table; - if (num8 + num9 > 258 + (num6 & 0x1F) + ((num6 >> 5) & 0x1F) || (num7 == 16 && num8 < 1)) - { - blens = null; - mode = 9; - z.msg = "invalid bit length repeat"; - r = -3; - bitb = num3; - bitk = i; - z.avail_in = num2; - z.total_in += num - z.next_in_index; - z.next_in_index = num; - write = num4; - return inflate_flush(z, r); - } - if (blens != null) + blens[index++] = num7; + continue; + } + int num8 = (num7 == 18) ? 7 : (num7 - 14); + int num9 = (num7 == 18) ? 11 : 3; + for (; i < num6 + num8; i += 8) + { + if (num2 != 0 && z.next_in != null) { - num7 = ((num7 == 16) ? blens[num8 - 1] : 0); - do - { - blens[num8++] = num7; - } - while (--num9 != 0); + r = 0; + num2--; + num3 |= (z.next_in[num++] & 0xFF) << i; + continue; } - - index = num8; + bitb = num3; + bitk = i; + z.avail_in = num2; + z.total_in += num - z.next_in_index; + z.next_in_index = num; + write = num4; + return inflate_flush(z, r); + } + num3 = SupportClass.URShift(num3, num6); + i -= num6; + num9 += num3 & inflate_mask[num8]; + num3 = SupportClass.URShift(num3, num8); + i -= num8; + num8 = index; + num6 = table; + if (num8 + num9 > 258 + (num6 & 0x1F) + ((num6 >> 5) & 0x1F) || (num7 == 16 && num8 < 1)) + { + blens = null; + mode = 9; + z.msg = "invalid bit length repeat"; + r = -3; + bitb = num3; + bitk = i; + z.avail_in = num2; + z.total_in += num - z.next_in_index; + z.next_in_index = num; + write = num4; + return inflate_flush(z, r); } + num7 = (num7 == 16) ? blens[num8 - 1] : 0; + do + { + blens[num8++] = num7; + } + while (--num9 != 0); + + index = num8; } tb[0] = -1; int[] array = new int[1]; @@ -482,8 +478,7 @@ internal int proc(ZStream z, int r) array[0] = 9; array2[0] = 6; num6 = table; - if (blens != null && hufts != null) - num6 = InfTree.inflate_trees_dynamic(257 + (num6 & 0x1F), 1 + ((num6 >> 5) & 0x1F), blens, array, array2, array3, array4, hufts, z); + num6 = InfTree.inflate_trees_dynamic(257 + (num6 & 0x1F), 1 + ((num6 >> 5) & 0x1F), blens, array, array2, array3, array4, hufts, z); if (num6 != 0) { if (num6 == -3) @@ -500,8 +495,7 @@ internal int proc(ZStream z, int r) write = num4; return inflate_flush(z, r); } - if (hufts != null) - codes = new InfCodes(array[0], array2[0], hufts, array3[0], hufts, array4[0], z); + codes = new InfCodes(array[0], array2[0], hufts, array3[0], hufts, array4[0], z); blens = null; mode = 6; goto case 6; @@ -589,8 +583,7 @@ internal void free(ZStream z) internal void set_dictionary(byte[] d, int start, int n) { - if (window != null) - Array.Copy(d, start, window, 0, n); + Array.Copy(d, start, window, 0, n); read = write = n; } @@ -614,8 +607,8 @@ internal int inflate_flush(ZStream z, int r) z.avail_out -= num2; z.total_out += num2; if (checkfn != null && z._adler != null) - z.adler = (check = z._adler.adler32(check, window, num, num2)); - if (window != null && z.next_out != null) + z.adler = check = z._adler.adler32(check, window, num, num2); + if (z.next_out != null) Array.Copy(window, num, z.next_out, next_out_index, num2); next_out_index += num2; num += num2; @@ -632,8 +625,8 @@ internal int inflate_flush(ZStream z, int r) z.avail_out -= num2; z.total_out += num2; if (checkfn != null && z._adler != null) - z.adler = (check = z._adler.adler32(check, window, num, num2)); - if (window != null && z.next_out != null) + z.adler = check = z._adler.adler32(check, window, num, num2); + if (z.next_out != null) Array.Copy(window, num, z.next_out, next_out_index, num2); next_out_index += num2; num += num2; diff --git a/BackendServices/CompressionLibrary/ComponentAce.Compression.Libs.zlib/InfCodes.cs b/BackendServices/CompressionLibrary/ComponentAce.Compression.Libs.zlib/InfCodes.cs index cd0747bcb..8e09ce084 100644 --- a/BackendServices/CompressionLibrary/ComponentAce.Compression.Libs.zlib/InfCodes.cs +++ b/BackendServices/CompressionLibrary/ComponentAce.Compression.Libs.zlib/InfCodes.cs @@ -108,7 +108,7 @@ internal int proc(InfBlocks s, ZStream z, int r) num = s.bitb; num2 = s.bitk; int num5 = s.write; - int num6 = ((num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5)); + int num6 = (num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5); while (true) { switch (mode) @@ -128,7 +128,7 @@ internal int proc(InfBlocks s, ZStream z, int r) num = s.bitb; num2 = s.bitk; num5 = s.write; - num6 = ((num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5)); + num6 = (num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5); if (r != 0) { mode = ((r == 1) ? 7 : 9); @@ -321,18 +321,18 @@ internal int proc(InfBlocks s, ZStream z, int r) if (num5 == s.end && s.read != 0) { num5 = 0; - num6 = ((num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5)); + num6 = (num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5); } if (num6 == 0) { s.write = num5; r = s.inflate_flush(z, r); num5 = s.write; - num6 = ((num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5)); + num6 = (num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5); if (num5 == s.end && s.read != 0) { num5 = 0; - num6 = ((num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5)); + num6 = (num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5); } if (num6 == 0) { @@ -346,8 +346,7 @@ internal int proc(InfBlocks s, ZStream z, int r) } } } - if (s.window != null) - s.window[num5++] = s.window[i++]; + s.window[num5++] = s.window[i++]; num6--; if (i == s.end) { @@ -364,18 +363,18 @@ internal int proc(InfBlocks s, ZStream z, int r) if (num5 == s.end && s.read != 0) { num5 = 0; - num6 = ((num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5)); + num6 = (num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5); } if (num6 == 0) { s.write = num5; r = s.inflate_flush(z, r); num5 = s.write; - num6 = ((num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5)); + num6 = (num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5); if (num5 == s.end && s.read != 0) { num5 = 0; - num6 = ((num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5)); + num6 = (num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5); } if (num6 == 0) { @@ -390,8 +389,7 @@ internal int proc(InfBlocks s, ZStream z, int r) } } r = 0; - if (s.window != null) - s.window[num5++] = (byte)lit; + s.window[num5++] = (byte)lit; num6--; mode = 0; break; @@ -405,7 +403,7 @@ internal int proc(InfBlocks s, ZStream z, int r) s.write = num5; r = s.inflate_flush(z, r); num5 = s.write; - num6 = ((num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5)); + num6 = (num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5); if (s.read != s.write) { s.bitb = num; @@ -460,7 +458,7 @@ internal int inflate_fast(int bl, int bd, int[] tl, int tl_index, int[] td, int int num2 = s.bitb; int num3 = s.bitk; int num4 = s.write; - int num5 = ((num4 < s.read) ? (s.read - num4 - 1) : (s.end - num4)); + int num5 = (num4 < s.read) ? (s.read - num4 - 1) : (s.end - num4); int num6 = inflate_mask[bl]; int num7 = inflate_mask[bd]; int num11; @@ -481,8 +479,7 @@ internal int inflate_fast(int bl, int bd, int[] tl, int tl_index, int[] td, int { num2 >>= array[(num9 + num8) * 3 + 1]; num3 -= array[(num9 + num8) * 3 + 1]; - if (s.window != null) - s.window[num4++] = (byte)array[(num9 + num8) * 3 + 2]; + s.window[num4++] = (byte)array[(num9 + num8) * 3 + 2]; num5--; } else @@ -520,7 +517,7 @@ internal int inflate_fast(int bl, int bd, int[] tl, int tl_index, int[] td, int } z.msg = "invalid distance code"; num11 = z.avail_in - num; - num11 = ((num3 >> 3 < num11) ? (num3 >> 3) : num11); + num11 = (num3 >> 3 < num11) ? (num3 >> 3) : num11; num += num11; next_in_index -= num11; num3 -= num11 << 3; @@ -545,14 +542,14 @@ internal int inflate_fast(int bl, int bd, int[] tl, int tl_index, int[] td, int if (num4 >= num12) { num13 = num4 - num12; - if (num4 - num13 > 0 && 2 > num4 - num13 && s.window != null) + if (num4 - num13 > 0 && 2 > num4 - num13) { s.window[num4++] = s.window[num13++]; num11--; s.window[num4++] = s.window[num13++]; num11--; } - else if (s.window != null) + else { Array.Copy(s.window, num13, s.window, num4, 2); num4 += 2; @@ -572,7 +569,7 @@ internal int inflate_fast(int bl, int bd, int[] tl, int tl_index, int[] td, int if (num11 > num10) { num11 -= num10; - if (num4 - num13 > 0 && num10 > num4 - num13 && s.window != null) + if (num4 - num13 > 0 && num10 > num4 - num13) { do { @@ -580,7 +577,7 @@ internal int inflate_fast(int bl, int bd, int[] tl, int tl_index, int[] td, int } while (--num10 != 0); } - else if (s.window != null) + else { Array.Copy(s.window, num13, s.window, num4, num10); num4 += num10; @@ -590,7 +587,7 @@ internal int inflate_fast(int bl, int bd, int[] tl, int tl_index, int[] td, int num13 = 0; } } - if (num4 - num13 > 0 && num11 > num4 - num13 && s.window != null) + if (num4 - num13 > 0 && num11 > num4 - num13) { do { @@ -599,8 +596,7 @@ internal int inflate_fast(int bl, int bd, int[] tl, int tl_index, int[] td, int while (--num11 != 0); break; } - if (s.window != null) - Array.Copy(s.window, num13, s.window, num4, num11); + Array.Copy(s.window, num13, s.window, num4, num11); num4 += num11; num13 += num11; num11 = 0; @@ -610,7 +606,7 @@ internal int inflate_fast(int bl, int bd, int[] tl, int tl_index, int[] td, int { num8 += array[(num9 + num8) * 3 + 2]; num8 += num2 & inflate_mask[num10]; - if ((num10 = array[(num9 + num8) * 3]) == 0 && s.window != null) + if ((num10 = array[(num9 + num8) * 3]) == 0) { num2 >>= array[(num9 + num8) * 3 + 1]; num3 -= array[(num9 + num8) * 3 + 1]; @@ -623,7 +619,7 @@ internal int inflate_fast(int bl, int bd, int[] tl, int tl_index, int[] td, int if (((uint)num10 & 0x20u) != 0) { num11 = z.avail_in - num; - num11 = ((num3 >> 3 < num11) ? (num3 >> 3) : num11); + num11 = (num3 >> 3 < num11) ? (num3 >> 3) : num11; num += num11; next_in_index -= num11; num3 -= num11 << 3; @@ -637,7 +633,7 @@ internal int inflate_fast(int bl, int bd, int[] tl, int tl_index, int[] td, int } z.msg = "invalid literal/length code"; num11 = z.avail_in - num; - num11 = ((num3 >> 3 < num11) ? (num3 >> 3) : num11); + num11 = (num3 >> 3 < num11) ? (num3 >> 3) : num11; num += num11; next_in_index -= num11; num3 -= num11 << 3; diff --git a/BackendServices/CompressionLibrary/ComponentAce.Compression.Libs.zlib/ZLib.cs b/BackendServices/CompressionLibrary/ComponentAce.Compression.Libs.zlib/ZLib.cs new file mode 100644 index 000000000..8152b0f92 --- /dev/null +++ b/BackendServices/CompressionLibrary/ComponentAce.Compression.Libs.zlib/ZLib.cs @@ -0,0 +1,46 @@ +using System.IO; + +#if NET6_0_OR_GREATER +using System.IO.Compression; +#else +using System; +#endif + +namespace ComponentAce.Compression.Libs.zlib +{ + internal static class ZLib + { + internal static Stream CompressOutput(Stream stream, int zlibCompressionLevel, bool leaveOpen = false) + { +#if NET6_0_OR_GREATER + return new ZLibStream(stream, GetCompressionLevel(zlibCompressionLevel), leaveOpen); +#else + return leaveOpen + ? new ZOutputStreamLeaveOpen(stream, zlibCompressionLevel, false) + : new ZOutputStream(stream, zlibCompressionLevel, false); +#endif + } + + internal static Stream DecompressInput(Stream stream, bool leaveOpen = false) + { +#if NET6_0_OR_GREATER + return new ZLibStream(stream, CompressionMode.Decompress, leaveOpen); +#else + throw new NotImplementedException("[ZLib] - DecompressInput requires NET6 or higher!"); +#endif + } + +#if NET6_0_OR_GREATER + internal static CompressionLevel GetCompressionLevel(int zlibCompressionLevel) + { + return zlibCompressionLevel switch + { + 0 => CompressionLevel.NoCompression, + 1 or 2 or 3 => CompressionLevel.Fastest, + 7 or 8 or 9 => CompressionLevel.SmallestSize, + _ => CompressionLevel.Optimal, + }; + } +#endif + } +} diff --git a/BackendServices/CompressionLibrary/ComponentAce.Compression.Libs.zlib/ZOutputStream.cs b/BackendServices/CompressionLibrary/ComponentAce.Compression.Libs.zlib/ZOutputStream.cs index 41f42e000..ed44ab18a 100644 --- a/BackendServices/CompressionLibrary/ComponentAce.Compression.Libs.zlib/ZOutputStream.cs +++ b/BackendServices/CompressionLibrary/ComponentAce.Compression.Libs.zlib/ZOutputStream.cs @@ -17,6 +17,8 @@ public class ZOutputStream : Stream protected internal bool compress; + protected bool closed = false; + private Stream out_Renamed; public virtual int FlushMode @@ -60,6 +62,46 @@ private void InitBlock() buf = new byte[bufsize]; } + private void ImplDisposing(bool disposeOutput) + { + if (!closed) + { + try + { + try + { + Finish(); + } + catch (IOException) + { + // Ignore + } + } + finally + { + closed = true; + End(); + if (disposeOutput) + out_Renamed.Dispose(); + out_Renamed = null; + } + } + } + + protected void Detach(bool disposing) + { + if (disposing) + ImplDisposing(disposeOutput: false); + base.Dispose(disposing); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + ImplDisposing(disposeOutput: true); + base.Dispose(disposing); + } + public ZOutputStream(Stream out_Renamed, bool NoHeader) { InitBlock(); @@ -110,7 +152,7 @@ public override void Write(byte[] b1, int off, int len) z.next_out = buf; z.next_out_index = 0; z.avail_out = bufsize; - num = ((!compress) ? z.inflate(flush_Renamed_Field) : z.deflate(flush_Renamed_Field)); + num = (!compress) ? z.inflate(flush_Renamed_Field) : z.deflate(flush_Renamed_Field); if (num != 0 && num != 1) throw new ZStreamException((compress ? "de" : "in") + "flating: " + z.msg); if (buf != null) @@ -120,7 +162,7 @@ public override void Write(byte[] b1, int off, int len) } } - public virtual void finish() + public virtual void Finish() { int num; if (z != null) @@ -130,7 +172,7 @@ public virtual void finish() z.next_out = buf; z.next_out_index = 0; z.avail_out = bufsize; - num = ((!compress) ? z.inflate(4) : z.deflate(4)); + num = (!compress) ? z.inflate(4) : z.deflate(4); if (num != 1 && num != 0) throw new ZStreamException((compress ? "de" : "in") + "flating: " + z.msg); if (bufsize - z.avail_out > 0 && buf != null) @@ -138,40 +180,45 @@ public virtual void finish() } while ((z.avail_in > 0 || z.avail_out == 0) && num == 0); } - try - { - Flush(); - } - catch - { - } + Flush(); } - public virtual void end() + public virtual void End() { - if (compress) - z?.deflateEnd(); - else - z?.inflateEnd(); - z?.free(); + if (z != null) + { + if (compress) + z.deflateEnd(); + else + z.inflateEnd(); + z.free(); + } z = null; } public override void Close() { - try - { - finish(); - } - catch - { - } - finally + if (!closed) { - end(); - out_Renamed?.Close(); - out_Renamed = null; + try + { + try + { + Finish(); + } + catch (IOException) + { + // Ignore + } + } + finally + { + closed = true; + End(); + out_Renamed.Close(); + out_Renamed = null; + } } } @@ -194,4 +241,33 @@ public override long Seek(long offset, SeekOrigin origin) return 0L; } } + + public class ZOutputStreamLeaveOpen + : ZOutputStream + { + public ZOutputStreamLeaveOpen(Stream output) + : base(output, false) + { + } + + public ZOutputStreamLeaveOpen(Stream output, bool NoHeader) + : base(output, NoHeader) + { + } + + public ZOutputStreamLeaveOpen(Stream output, int level, bool NoHeader) + : base(output, level, NoHeader) + { + } + + public override void Close() + { + Detach(true); + } + + protected override void Dispose(bool disposing) + { + Detach(disposing); + } + } } \ No newline at end of file diff --git a/BackendServices/CompressionLibrary/ComponentAce.Compression.Libs.zlib/Zip.cs b/BackendServices/CompressionLibrary/ComponentAce.Compression.Libs.zlib/Zip.cs new file mode 100644 index 000000000..d6e0a9bce --- /dev/null +++ b/BackendServices/CompressionLibrary/ComponentAce.Compression.Libs.zlib/Zip.cs @@ -0,0 +1,31 @@ +using System.IO; + +#if NET6_0_OR_GREATER +using System.IO.Compression; +#else +using System; +#endif + +namespace ComponentAce.Compression.Libs.zlib +{ + internal static class Zip + { + internal static Stream CompressOutput(Stream stream, int zlibCompressionLevel, bool leaveOpen = false) + { +#if NET6_0_OR_GREATER + return new DeflateStream(stream, ZLib.GetCompressionLevel(zlibCompressionLevel), leaveOpen); +#else + throw new NotImplementedException("[Zip] - CompressOutput requires NET6 or higher!"); +#endif + } + + internal static Stream DecompressInput(Stream stream, bool leaveOpen = false) + { +#if NET6_0_OR_GREATER + return new DeflateStream(stream, CompressionMode.Decompress, leaveOpen); +#else + throw new NotImplementedException("[Zip] - DecompressInput requires NET6 or higher!"); +#endif + } + } +} diff --git a/BackendServices/CompressionLibrary/Edge/Zlib.cs b/BackendServices/CompressionLibrary/Edge/Zlib.cs index 1b5b1b7cc..ea3ca3bbd 100644 --- a/BackendServices/CompressionLibrary/Edge/Zlib.cs +++ b/BackendServices/CompressionLibrary/Edge/Zlib.cs @@ -96,57 +96,62 @@ private static Task ICSharpDecompressEdgeZlibChunk(byte[] inData, ChunkH { if (header.CompressedSize == header.SourceSize) return Task.FromResult(inData); - MemoryStream baseInputStream = new MemoryStream(inData); - InflaterInputStream inflaterInputStream = new InflaterInputStream(baseInputStream, new Inflater(true)); - MemoryStream memoryStream = new MemoryStream(); - byte[] array = new byte[4096]; - for (; ; ) + InflaterInputStream inflaterInputStream = new InflaterInputStream(new MemoryStream(inData), new Inflater(true)); + using (MemoryStream memoryStream = new MemoryStream()) { - int num = inflaterInputStream.Read(array, 0, array.Length); - if (num <= 0) - break; - memoryStream.Write(array, 0, num); + byte[] array = new byte[4096]; + for (; ; ) + { + int num = inflaterInputStream.Read(array, 0, array.Length); + if (num <= 0) + break; + memoryStream.Write(array, 0, num); + } + inflaterInputStream.Dispose(); + return Task.FromResult(memoryStream.ToArray()); } - inflaterInputStream.Close(); - return Task.FromResult(memoryStream.ToArray()); } private static Task ComponentAceDecompressEdgeZlibChunk(byte[] InData, ChunkHeader header) { if (header.CompressedSize == header.SourceSize) return Task.FromResult(InData); - MemoryStream memoryStream = new MemoryStream(); - ZOutputStream zoutputStream = new ZOutputStream(memoryStream, true); - byte[] array = new byte[InData.Length]; - Array.Copy(InData, 0, array, 0, InData.Length); - zoutputStream.Write(array, 0, array.Length); - zoutputStream.Close(); - memoryStream.Close(); - return Task.FromResult(memoryStream.ToArray()); + using (MemoryStream memoryStream = new MemoryStream()) + using (ZOutputStream zoutputStream = new ZOutputStream(memoryStream, true)) + { + byte[] array = new byte[InData.Length]; + Array.Copy(InData, 0, array, 0, InData.Length); + zoutputStream.Write(array, 0, array.Length); + zoutputStream.Close(); + memoryStream.Close(); + return Task.FromResult(memoryStream.ToArray()); + } } private static Task ComponentAceCompressEdgeZlibChunk(byte[] InData) { - MemoryStream memoryStream = new MemoryStream(); - ZOutputStream zoutputStream = new ZOutputStream(memoryStream, 9, true); - zoutputStream.Write(InData, 0, InData.Length); - zoutputStream.Close(); - memoryStream.Close(); - byte[] array = memoryStream.ToArray(); - byte[] array2; - if (array.Length >= InData.Length) - array2 = InData; - else - array2 = array; - byte[] array3 = new byte[array2.Length + 4]; - Array.Copy(array2, 0, array3, 4, array2.Length); - ChunkHeader chunkHeader = default; - chunkHeader.SourceSize = (ushort)InData.Length; - chunkHeader.CompressedSize = (ushort)array2.Length; - byte[] array4 = chunkHeader.GetBytes(); - array4 = EndianUtils.EndianSwap(array4); - Array.Copy(array4, 0, array3, 0, ChunkHeader.SizeOf); - return Task.FromResult(array3); + using (MemoryStream memoryStream = new MemoryStream()) + using (ZOutputStream zoutputStream = new ZOutputStream(memoryStream, 9, true)) + { + zoutputStream.Write(InData, 0, InData.Length); + zoutputStream.Close(); + memoryStream.Close(); + byte[] array = memoryStream.ToArray(); + byte[] array2; + if (array.Length >= InData.Length) + array2 = InData; + else + array2 = array; + byte[] array3 = new byte[array2.Length + 4]; + Array.Copy(array2, 0, array3, 4, array2.Length); + ChunkHeader chunkHeader = default; + chunkHeader.SourceSize = (ushort)InData.Length; + chunkHeader.CompressedSize = (ushort)array2.Length; + byte[] array4 = chunkHeader.GetBytes(); + array4 = EndianUtils.EndianSwap(array4); + Array.Copy(array4, 0, array3, 0, ChunkHeader.SizeOf); + return Task.FromResult(array3); + } } internal struct ChunkHeader diff --git a/BackendServices/NetworkLibrary/HTTP/HTTPProcessor.cs b/BackendServices/NetworkLibrary/HTTP/HTTPProcessor.cs index 1894eb578..35e21aafd 100644 --- a/BackendServices/NetworkLibrary/HTTP/HTTPProcessor.cs +++ b/BackendServices/NetworkLibrary/HTTP/HTTPProcessor.cs @@ -901,7 +901,8 @@ public static byte[] Inflate(byte[] input) using (ZOutputStream zlibStream = new ZOutputStream(output, 1, true)) { zlibStream.Write(input, 0, input.Length); - zlibStream.finish(); + zlibStream.Close(); + output.Close(); return output.ToArray(); } } @@ -964,9 +965,11 @@ public static Stream InflateStream(Stream input) outMemoryStream = new HugeMemoryStream(); else outMemoryStream = new MemoryStream(); - ZOutputStream outZStream = new ZOutputStream(outMemoryStream, 1, true); - CopyStream(input, outZStream, 4096, false); - outZStream.finish(); + using (ZOutputStreamLeaveOpen outZStream = new ZOutputStreamLeaveOpen(outMemoryStream, 1, true)) + { + CopyStream(input, outZStream, 4096, false); + outZStream.Close(); + } input.Close(); input.Dispose(); outMemoryStream.Seek(0, SeekOrigin.Begin); diff --git a/BackendServices/SpaceWizards.HttpListener/System/Net/Managed/HttpConnection.cs b/BackendServices/SpaceWizards.HttpListener/System/Net/Managed/HttpConnection.cs index 564914042..e00bb8218 100644 --- a/BackendServices/SpaceWizards.HttpListener/System/Net/Managed/HttpConnection.cs +++ b/BackendServices/SpaceWizards.HttpListener/System/Net/Managed/HttpConnection.cs @@ -129,40 +129,38 @@ public HttpConnection(Socket sock, HttpEndPointListener epl, bool secure, X509Ce _timer = new Timer(OnTimeout, null, Timeout.Infinite, Timeout.Infinite); #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - if (_sslStream != null && CertificateHelper.IsCertificateAuthority(_cert)) + _sslStream?.AuthenticateAsServer(new SslServerAuthenticationOptions { - _sslStream.AuthenticateAsServer(new SslServerAuthenticationOptions + ClientCertificateRequired = false, + EnabledSslProtocols = GetSslProtocol, + CertificateRevocationCheckMode = X509RevocationMode.NoCheck, + ServerCertificateSelectionCallback = (sender, actualHostName) => { - ClientCertificateRequired = false, - EnabledSslProtocols = GetSslProtocol, - CertificateRevocationCheckMode = X509RevocationMode.NoCheck, - ServerCertificateSelectionCallback = (sender, actualHostName) => - { - IPEndPoint localEndpoint = (IPEndPoint)sock.LocalEndPoint; + IPEndPoint localEndpoint = (IPEndPoint)sock.LocalEndPoint; - if (string.IsNullOrEmpty(actualHostName)) - { - _sniDomain = localEndpoint.Address.ToString() ?? "127.0.0.1"; - } - else - { - _sniDomain = actualHostName; - } + if (string.IsNullOrEmpty(actualHostName)) + { + _sniDomain = localEndpoint.Address.ToString() ?? "127.0.0.1"; + } + else + { + _sniDomain = actualHostName; + } #if NET5_0_OR_GREATER - // Actually load the certificate - try + // Actually load the certificate + try + { + int port = localEndpoint.Port; + string dirname = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); + string path = Path.Combine(dirname, ".mono"); + path = Path.Combine(path, "httplistener"); + string cert_file = Path.Combine(path, string.Format("{0}.pem", _sniDomain + $"-{port}")); + string pvk_file = Path.Combine(path, string.Format("{0}_privkey.pem", _sniDomain + $"-{port}")); + if (File.Exists(cert_file) && File.Exists(pvk_file)) { - int port = localEndpoint.Port; - string dirname = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); - string path = Path.Combine(dirname, ".mono"); - path = Path.Combine(path, "httplistener"); - string cert_file = Path.Combine(path, string.Format("{0}.pem", _sniDomain + $"-{port}")); - string pvk_file = Path.Combine(path, string.Format("{0}_privkey.pem", _sniDomain + $"-{port}")); - if (File.Exists(cert_file) && File.Exists(pvk_file)) - { #if NET6_0_OR_GREATER - return X509Certificate2.CreateFromPemFile(cert_file, pvk_file); + return X509Certificate2.CreateFromPemFile(cert_file, pvk_file); #else string[] privateKeyBlocks = File.ReadAllText(pvk_file).Split("-", StringSplitOptions.RemoveEmptyEntries); @@ -177,24 +175,19 @@ public HttpConnection(Socket sock, HttpEndPointListener epl, bool secure, X509Ce return new X509Certificate2(cert.CopyWithPrivateKey(rsa).Export(X509ContentType.Pfx)); } #endif - } - } - catch - { - // ignore errors } + } + catch + { + // ignore errors + } #endif - return CertificateHelper.MakeChainSignedCert(_sniDomain, _cert, epl.Listener.GetPreferedHashAlgorithm(), - ((IPEndPoint)sock.RemoteEndPoint).Address ?? IPAddress.Any, DateTimeOffset.Now.AddDays(-1), DateTimeOffset.Now.AddDays(7), - epl.Listener.wildcardCertificates); - } - }); - } - else - { - _sslStream?.AuthenticateAsServer(_cert, false, GetSslProtocol, false); - } + return CertificateHelper.IsCertificateAuthority(_cert) ? CertificateHelper.MakeChainSignedCert(_sniDomain, _cert, epl.Listener.GetPreferedHashAlgorithm(), + ((IPEndPoint)sock.RemoteEndPoint).Address ?? IPAddress.Any, DateTimeOffset.Now.AddDays(-1), DateTimeOffset.Now.AddDays(7), + epl.Listener.wildcardCertificates) : _cert; + } + }); #else _sslStream?.AuthenticateAsServer(_cert, false, GetSslProtocol, false); #endif diff --git a/SpecializedServers/QuazalServer/QNetZ/Helper.cs b/SpecializedServers/QuazalServer/QNetZ/Helper.cs index 71d86f3a3..c9bc7d00c 100644 --- a/SpecializedServers/QuazalServer/QNetZ/Helper.cs +++ b/SpecializedServers/QuazalServer/QNetZ/Helper.cs @@ -225,44 +225,43 @@ public static void WriteDateTime(Stream s, DateTime v) public static byte[] Decompress(string AccessKey, byte[] InData) { - MemoryStream memoryStream = new(); - - switch (AccessKey) + using (MemoryStream memoryStream = new()) { - case "hg7j1": - case "yh64s": - case "uG9Kv3p": - case "1WguH+y": - using (LzoStream lzo = new(new MemoryStream(InData), System.IO.Compression.CompressionMode.Decompress)) - { - lzo.CopyTo(memoryStream); - lzo.Close(); - memoryStream.Position = 0; - memoryStream.Close(); + switch (AccessKey) + { + case "hg7j1": + case "yh64s": + case "uG9Kv3p": + case "1WguH+y": + using (LzoStream lzo = new(new MemoryStream(InData), System.IO.Compression.CompressionMode.Decompress)) + { + lzo.CopyTo(memoryStream); + lzo.Dispose(); + memoryStream.Position = 0; + return memoryStream.ToArray(); + } + default: + InflaterInputStream inflaterInputStream = new(new MemoryStream(InData), new Inflater()); + byte[] array = new byte[4096]; + for (; ; ) + { + int num = inflaterInputStream.Read(array, 0, array.Length); + if (num <= 0) + break; + memoryStream.Write(array, 0, num); + } + inflaterInputStream.Dispose(); return memoryStream.ToArray(); - } - default: - InflaterInputStream inflaterInputStream = new(new MemoryStream(InData), new Inflater()); - byte[] array = new byte[4096]; - for (; ; ) - { - int num = inflaterInputStream.Read(array, 0, array.Length); - if (num <= 0) - break; - memoryStream.Write(array, 0, num); - } - inflaterInputStream.Close(); - return memoryStream.ToArray(); + } } } public static byte[] Compress(byte[] InData) { - MemoryStream memoryStream = new(); + MemoryStream memoryStream = new(); DeflaterOutputStream deflaterOutputStream = new(memoryStream, new Deflater(9)); deflaterOutputStream.Write(InData, 0, InData.Length); - deflaterOutputStream.Close(); - memoryStream.Close(); + deflaterOutputStream.Dispose(); return memoryStream.ToArray(); // Send OG data if compressed size higher? } @@ -344,8 +343,7 @@ public static byte[] DeriveKey(uint pid, string input) public static byte[] MakeHMAC(byte[] key, byte[] data) { - HMACMD5 hmac = new(key); - return hmac.ComputeHash(data); + return new HMACMD5(key).ComputeHash(data); } public static byte[] MakeFilledArray(int len) @@ -360,12 +358,13 @@ public static byte[] ParseByteArray(string s) { s = s.Trim().Replace(" ", string.Empty); - var m = new MemoryStream(); - - for (int i = 0; i < s.Length / 2; i++) - m.WriteByte(Convert.ToByte(s.Substring(i * 2, 2), 16)); + using (MemoryStream m = new MemoryStream()) + { + for (int i = 0; i < s.Length / 2; i++) + m.WriteByte(Convert.ToByte(s.Substring(i * 2, 2), 16)); - return m.ToArray(); + return m.ToArray(); + } } } } diff --git a/SpecializedServers/QuazalServer/RDVServices/v2Services/LegacyFriendsService.cs b/SpecializedServers/QuazalServer/RDVServices/v2Services/FriendsService.cs similarity index 61% rename from SpecializedServers/QuazalServer/RDVServices/v2Services/LegacyFriendsService.cs rename to SpecializedServers/QuazalServer/RDVServices/v2Services/FriendsService.cs index d6a35303d..efea6c942 100644 --- a/SpecializedServers/QuazalServer/RDVServices/v2Services/LegacyFriendsService.cs +++ b/SpecializedServers/QuazalServer/RDVServices/v2Services/FriendsService.cs @@ -1,5 +1,6 @@ using QuazalServer.QNetZ.Attributes; using QuazalServer.QNetZ.Interfaces; +using QuazalServer.RDVServices.DDL.Models; using QuazalServer.RDVServices.RMC; namespace QuazalServer.RDVServices.v2Services @@ -8,7 +9,7 @@ namespace QuazalServer.RDVServices.v2Services /// User friends service /// [RMCService(RMCProtocolId.FriendsService)] - public class LegacyFriendsService : RMCServiceBase + public class FriendsService : RMCServiceBase { [RMCMethod(3)] public RMCResult UpdateDetails(uint uiPlayer, uint uiDetails) @@ -20,8 +21,14 @@ public RMCResult UpdateDetails(uint uiPlayer, uint uiDetails) [RMCMethod(10)] public RMCResult GetDetailedList(byte byRelationship, bool bReversed) { - UNIMPLEMENTED(); - return Error(0); + // TODO, relationship means to switch to relationship list, bReversed I assume is order. + + List result = new(); + + if (bReversed) + result.Reverse(); + + return Result(result); } - } + } } \ No newline at end of file