messenger-proxy 0.4.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. messenger_proxy-0.4.1/LICENSE +28 -0
  2. messenger_proxy-0.4.1/PKG-INFO +109 -0
  3. messenger_proxy-0.4.1/README.md +79 -0
  4. messenger_proxy-0.4.1/builder/__init__.py +0 -0
  5. messenger_proxy-0.4.1/builder/clients/__init__.py +0 -0
  6. messenger_proxy-0.4.1/builder/clients/csharp/MessengerClient/App.config +14 -0
  7. messenger_proxy-0.4.1/builder/clients/csharp/MessengerClient/Crypto.cs +85 -0
  8. messenger_proxy-0.4.1/builder/clients/csharp/MessengerClient/HTTPMessengerClient.cs +173 -0
  9. messenger_proxy-0.4.1/builder/clients/csharp/MessengerClient/Message.cs +410 -0
  10. messenger_proxy-0.4.1/builder/clients/csharp/MessengerClient/MessengerClient.cs +188 -0
  11. messenger_proxy-0.4.1/builder/clients/csharp/MessengerClient/MessengerClient.csproj +62 -0
  12. messenger_proxy-0.4.1/builder/clients/csharp/MessengerClient/MessengerClient.sln +25 -0
  13. messenger_proxy-0.4.1/builder/clients/csharp/MessengerClient/Program.cs +171 -0
  14. messenger_proxy-0.4.1/builder/clients/csharp/MessengerClient/Properties/AssemblyInfo.cs +36 -0
  15. messenger_proxy-0.4.1/builder/clients/csharp/MessengerClient/RemotePortForwarder.cs +86 -0
  16. messenger_proxy-0.4.1/builder/clients/csharp/MessengerClient/WebsocketMessengerClient.cs +218 -0
  17. messenger_proxy-0.4.1/builder/clients/csharp/README.md +41 -0
  18. messenger_proxy-0.4.1/builder/clients/nodejs/README.md +127 -0
  19. messenger_proxy-0.4.1/builder/clients/nodejs/builder.py +60 -0
  20. messenger_proxy-0.4.1/builder/clients/nodejs/electron +39 -0
  21. messenger_proxy-0.4.1/builder/clients/nodejs/requirements.txt +1 -0
  22. messenger_proxy-0.4.1/builder/clients/nodejs/templates/messenger-client.js +751 -0
  23. messenger_proxy-0.4.1/builder/clients/nodejs/webpack.conf.js +50 -0
  24. messenger_proxy-0.4.1/builder/clients/python/README.md +143 -0
  25. messenger_proxy-0.4.1/builder/clients/python/builder.py +70 -0
  26. messenger_proxy-0.4.1/builder/clients/python/messenger-client-http.py +746 -0
  27. messenger_proxy-0.4.1/builder/clients/python/messenger-client-ws.py +478 -0
  28. messenger_proxy-0.4.1/builder/clients/python/messenger-client.py +959 -0
  29. messenger_proxy-0.4.1/builder/clients/python/requirements.txt +1 -0
  30. messenger_proxy-0.4.1/builder/clients/python/templates/messenger-client.py +896 -0
  31. messenger_proxy-0.4.1/messenger/__init__.py +10 -0
  32. messenger_proxy-0.4.1/messenger/aes.py +20 -0
  33. messenger_proxy-0.4.1/messenger/convert.py +21 -0
  34. messenger_proxy-0.4.1/messenger/engine.py +76 -0
  35. messenger_proxy-0.4.1/messenger/forwarder_clients.py +186 -0
  36. messenger_proxy-0.4.1/messenger/forwarders.py +331 -0
  37. messenger_proxy-0.4.1/messenger/generator.py +60 -0
  38. messenger_proxy-0.4.1/messenger/http_ws_server.py +134 -0
  39. messenger_proxy-0.4.1/messenger/manager.py +737 -0
  40. messenger_proxy-0.4.1/messenger/message.py +267 -0
  41. messenger_proxy-0.4.1/messenger/messengers.py +226 -0
  42. messenger_proxy-0.4.1/messenger/output.py +31 -0
  43. messenger_proxy-0.4.1/messenger/resources/top_ports.txt +8320 -0
  44. messenger_proxy-0.4.1/messenger/scanner.py +179 -0
  45. messenger_proxy-0.4.1/messenger/text.py +35 -0
  46. messenger_proxy-0.4.1/messenger-builder +111 -0
  47. messenger_proxy-0.4.1/messenger-cli +30 -0
  48. messenger_proxy-0.4.1/messenger_proxy.egg-info/PKG-INFO +109 -0
  49. messenger_proxy-0.4.1/messenger_proxy.egg-info/SOURCES.txt +52 -0
  50. messenger_proxy-0.4.1/messenger_proxy.egg-info/dependency_links.txt +1 -0
  51. messenger_proxy-0.4.1/messenger_proxy.egg-info/requires.txt +4 -0
  52. messenger_proxy-0.4.1/messenger_proxy.egg-info/top_level.txt +2 -0
  53. messenger_proxy-0.4.1/setup.cfg +4 -0
  54. messenger_proxy-0.4.1/setup.py +61 -0
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2024, Skyler Knecht
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,109 @@
1
+ Metadata-Version: 2.4
2
+ Name: messenger-proxy
3
+ Version: 0.4.1
4
+ Summary: Messenger uses a client-server architecture to establish a SOCKS5 tunnel. Once the client connects, the server will create a local SOCKS5 tunnel that can be used to interact with the local network the client is connected to.
5
+ Home-page: https://github.com/skylerknecht/messenger
6
+ Author: Skyler Knecht
7
+ Author-email: skyler.knecht@outlook.com
8
+ License: BSD-3-Clause
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: BSD License
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.6
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Requires-Dist: aiohttp
16
+ Requires-Dist: prompt-toolkit
17
+ Requires-Dist: pycryptodome
18
+ Requires-Dist: jinja2
19
+ Dynamic: author
20
+ Dynamic: author-email
21
+ Dynamic: classifier
22
+ Dynamic: description
23
+ Dynamic: description-content-type
24
+ Dynamic: home-page
25
+ Dynamic: license
26
+ Dynamic: license-file
27
+ Dynamic: requires-dist
28
+ Dynamic: requires-python
29
+ Dynamic: summary
30
+
31
+ # Messenger
32
+
33
+ Messenger is a tunneling toolkit that leverages a client-server infrastructure
34
+ to establish SOCKS5 proxies, local port forwards, and remote port forwards. While
35
+ the server is primarily written in Python, there are several clients written in
36
+ varying languages. Their details and major feature support can be
37
+ [found below](https://github.com/skylerknecht/messenger?tab=readme-ov-file#client-support-matrix).
38
+
39
+ ## Quick Start
40
+
41
+ To set up Messenger and establish a client connection, execute the following commands.
42
+
43
+ ### Installation
44
+ Messenger has a setup.py file that can be run directly or installed with pipx.
45
+ ```
46
+ operator~# git clone https://github.com/skylerknecht/messenger.git --recurse-submodules
47
+ operator~# cd messenger
48
+ operator~/messenger# pipx install .
49
+ ```
50
+
51
+ ### Launch
52
+ Launching Messenger will output several details that will be leveraged in later commands, including
53
+ an AES encryption key and server URL.
54
+ ```
55
+ operator~# messenger-cli
56
+ (messenger)~#
57
+ __ __
58
+ | \/ | ___ ___ ___ ___ _ __ __ _ ___ _ __
59
+ | |\/| |/ _ \/ __/ __|/ _ \ '_ \ / _` |/ _ \ '__|
60
+ | | | | __/\__ \__ \ __/ | | | (_| | __/ |
61
+ |_| |_|\___||___/___/\___|_| |_|\__, |\___|_|
62
+ by Skyler Knecht and Kevin Clark |___/ v0.4.1
63
+ [*] The AES encryption key is XhoInhAKWX
64
+ [*] Waiting for messengers on http+ws://0.0.0.0:8080/
65
+ (messenger)~#
66
+ ```
67
+
68
+ ### Build
69
+ Messenger comes with a builder utility to create clients. Leverage the help menu or the
70
+ [client support matrix](https://github.com/skylerknecht/messenger?tab=readme-ov-file#client-support-matrix)
71
+ to see builder-supported clients.
72
+ ```
73
+ operator~# messenger-builder python --encryption-key ZDXgoqyVXqDpJyBMJt
74
+ Wrote Python client to 'client.py'
75
+ ```
76
+
77
+ ### Connect
78
+ Once a client is built, execute it to connect to the server. Options can typically be hardcoded or overridden
79
+ with command line arguments.
80
+ ```
81
+ operator~# ./client.py
82
+ [+] Connected to http://localhost:8080/socketio/?EIO=4&transport=websocket
83
+ ```
84
+
85
+ ## Detailed Guides
86
+
87
+ ### Operators
88
+ - [Setup a SOCKS Proxy or Local Port Forward](docs/local-port-forwards-and-socks.md)
89
+ - [Setup a Remote Port Forward](docs/remote-port-forwards.md)
90
+ - [Chain Messenger Clients](docs/chaining-messengers.md)
91
+ - [Perform NTLMRelay2Self with Messenger](docs/ntlmrelay2self-with-messenger.md)
92
+
93
+
94
+ ### Developers
95
+ - [Communication Overview](docs/communication.md)
96
+
97
+
98
+ ## Client Support Matrix
99
+
100
+ | Clients | Messenger Builder | Protocols | Local/Remote Port Forwarding | SOCKS5 TCP | SOCKS5 UDP |
101
+ |--------------------------------------------------------------------|-------------------|-------------------|------------------------------|------------|---------------|
102
+ | [Python](https://github.com/skylerknecht/messenger-client-python) | Supported | HTTP & WebSockets | Supported | Supported | Not Supported |
103
+ | [C#](https://github.com/skylerknecht/messenger-client-python) | Not Supported | HTTP & WebSockets | Supported | Supported | Not Supported |
104
+ | [Node JS](https://github.com/skylerknecht/messenger-client-nodejs) | Not Supported | WebSockets | Supported | Supported | Not Supported |
105
+
106
+ ## Credits
107
+
108
+ - Skyler Knecht (@SkylerKnecht)
109
+ - Kevin Clark (@GuhnooPlusLinux)
@@ -0,0 +1,79 @@
1
+ # Messenger
2
+
3
+ Messenger is a tunneling toolkit that leverages a client-server infrastructure
4
+ to establish SOCKS5 proxies, local port forwards, and remote port forwards. While
5
+ the server is primarily written in Python, there are several clients written in
6
+ varying languages. Their details and major feature support can be
7
+ [found below](https://github.com/skylerknecht/messenger?tab=readme-ov-file#client-support-matrix).
8
+
9
+ ## Quick Start
10
+
11
+ To set up Messenger and establish a client connection, execute the following commands.
12
+
13
+ ### Installation
14
+ Messenger has a setup.py file that can be run directly or installed with pipx.
15
+ ```
16
+ operator~# git clone https://github.com/skylerknecht/messenger.git --recurse-submodules
17
+ operator~# cd messenger
18
+ operator~/messenger# pipx install .
19
+ ```
20
+
21
+ ### Launch
22
+ Launching Messenger will output several details that will be leveraged in later commands, including
23
+ an AES encryption key and server URL.
24
+ ```
25
+ operator~# messenger-cli
26
+ (messenger)~#
27
+ __ __
28
+ | \/ | ___ ___ ___ ___ _ __ __ _ ___ _ __
29
+ | |\/| |/ _ \/ __/ __|/ _ \ '_ \ / _` |/ _ \ '__|
30
+ | | | | __/\__ \__ \ __/ | | | (_| | __/ |
31
+ |_| |_|\___||___/___/\___|_| |_|\__, |\___|_|
32
+ by Skyler Knecht and Kevin Clark |___/ v0.4.1
33
+ [*] The AES encryption key is XhoInhAKWX
34
+ [*] Waiting for messengers on http+ws://0.0.0.0:8080/
35
+ (messenger)~#
36
+ ```
37
+
38
+ ### Build
39
+ Messenger comes with a builder utility to create clients. Leverage the help menu or the
40
+ [client support matrix](https://github.com/skylerknecht/messenger?tab=readme-ov-file#client-support-matrix)
41
+ to see builder-supported clients.
42
+ ```
43
+ operator~# messenger-builder python --encryption-key ZDXgoqyVXqDpJyBMJt
44
+ Wrote Python client to 'client.py'
45
+ ```
46
+
47
+ ### Connect
48
+ Once a client is built, execute it to connect to the server. Options can typically be hardcoded or overridden
49
+ with command line arguments.
50
+ ```
51
+ operator~# ./client.py
52
+ [+] Connected to http://localhost:8080/socketio/?EIO=4&transport=websocket
53
+ ```
54
+
55
+ ## Detailed Guides
56
+
57
+ ### Operators
58
+ - [Setup a SOCKS Proxy or Local Port Forward](docs/local-port-forwards-and-socks.md)
59
+ - [Setup a Remote Port Forward](docs/remote-port-forwards.md)
60
+ - [Chain Messenger Clients](docs/chaining-messengers.md)
61
+ - [Perform NTLMRelay2Self with Messenger](docs/ntlmrelay2self-with-messenger.md)
62
+
63
+
64
+ ### Developers
65
+ - [Communication Overview](docs/communication.md)
66
+
67
+
68
+ ## Client Support Matrix
69
+
70
+ | Clients | Messenger Builder | Protocols | Local/Remote Port Forwarding | SOCKS5 TCP | SOCKS5 UDP |
71
+ |--------------------------------------------------------------------|-------------------|-------------------|------------------------------|------------|---------------|
72
+ | [Python](https://github.com/skylerknecht/messenger-client-python) | Supported | HTTP & WebSockets | Supported | Supported | Not Supported |
73
+ | [C#](https://github.com/skylerknecht/messenger-client-python) | Not Supported | HTTP & WebSockets | Supported | Supported | Not Supported |
74
+ | [Node JS](https://github.com/skylerknecht/messenger-client-nodejs) | Not Supported | WebSockets | Supported | Supported | Not Supported |
75
+
76
+ ## Credits
77
+
78
+ - Skyler Knecht (@SkylerKnecht)
79
+ - Kevin Clark (@GuhnooPlusLinux)
File without changes
File without changes
@@ -0,0 +1,14 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <configuration>
3
+ <startup>
4
+ <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
5
+ </startup>
6
+ <runtime>
7
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
8
+ <dependentAssembly>
9
+ <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
10
+ <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
11
+ </dependentAssembly>
12
+ </assemblyBinding>
13
+ </runtime>
14
+ </configuration>
@@ -0,0 +1,85 @@
1
+ using System;
2
+ using System.Linq;
3
+ using System.Text;
4
+ using System.Security.Cryptography;
5
+
6
+
7
+ namespace MessengerClient
8
+ {
9
+ internal class Crypto
10
+ {
11
+ private const int AesBlockByteSize = 128 / 8;
12
+ private static readonly RandomNumberGenerator Random = RandomNumberGenerator.Create();
13
+
14
+ public static byte[] Hash(string encryption_key)
15
+ {
16
+ using (SHA256 sha256 = SHA256.Create())
17
+ {
18
+ return sha256.ComputeHash(Encoding.ASCII.GetBytes(encryption_key));
19
+ }
20
+ }
21
+
22
+ public static byte[] Encrypt(byte[] key, ArraySegment<byte> plainText)
23
+ {
24
+ byte[] plainTextBytes = plainText.Array;
25
+ return Encrypt(key, plainTextBytes);
26
+ }
27
+
28
+ public static byte[] Encrypt(byte[] key, string plainText)
29
+ {
30
+ byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
31
+ return Encrypt(key, plainTextBytes);
32
+ }
33
+
34
+ public static byte[] Encrypt(byte[] key, byte[] plainText)
35
+ {
36
+ using (var aes = Aes.Create())
37
+ {
38
+
39
+ byte[] iv = GenerateRandomBytes(AesBlockByteSize);
40
+
41
+ using (var encryptor = aes.CreateEncryptor(key, iv))
42
+ {
43
+ var cipherText = encryptor
44
+ .TransformFinalBlock(plainText, 0, plainText.Length);
45
+
46
+ var result = MergeArrays(iv, cipherText);
47
+ return result;
48
+ }
49
+ }
50
+ }
51
+
52
+ public static byte[] Decrypt(byte[] key, byte[] encryptedData)
53
+ {
54
+ using (var aes = Aes.Create())
55
+ {
56
+ var iv = encryptedData.Take(AesBlockByteSize).ToArray();
57
+ var cipherText = encryptedData.Skip(AesBlockByteSize).ToArray();
58
+
59
+ using (var encryptor = aes.CreateDecryptor(key, iv))
60
+ {
61
+ return encryptor.TransformFinalBlock(cipherText, 0, cipherText.Length);
62
+ }
63
+ }
64
+ }
65
+
66
+ private static byte[] GenerateRandomBytes(int numberOfBytes)
67
+ {
68
+ var randomBytes = new byte[numberOfBytes];
69
+ Random.GetBytes(randomBytes);
70
+ return randomBytes;
71
+ }
72
+
73
+ private static byte[] MergeArrays(params byte[][] arrays)
74
+ {
75
+ var merged = new byte[arrays.Sum(a => a.Length)];
76
+ var mergeIndex = 0;
77
+ for (int i = 0; i < arrays.GetLength(0); i++)
78
+ {
79
+ arrays[i].CopyTo(merged, mergeIndex);
80
+ mergeIndex += arrays[i].Length;
81
+ }
82
+ return merged;
83
+ }
84
+ }
85
+ }
@@ -0,0 +1,173 @@
1
+ using System;
2
+ using System.Collections.Concurrent;
3
+ using System.Collections.Generic;
4
+ using System.Net;
5
+ using System.Net.Http;
6
+ using System.Threading.Tasks;
7
+
8
+ namespace MessengerClient
9
+ {
10
+ public class HTTPMessengerClient : MessengerClient
11
+ {
12
+ private readonly string _uri;
13
+ private readonly HttpClient _httpClient;
14
+ private readonly byte[] _encryptionKey;
15
+ private readonly ConcurrentQueue<object> _downstreamMessages;
16
+ private string _messengerId;
17
+
18
+ public HTTPMessengerClient(string uri, byte[] encryptionKey, IWebProxy proxy = null)
19
+ {
20
+ _uri = uri;
21
+ _encryptionKey = encryptionKey;
22
+
23
+ var handler = new HttpClientHandler();
24
+ if (proxy != null)
25
+ {
26
+ handler.Proxy = proxy;
27
+ handler.UseProxy = true;
28
+ }
29
+
30
+ _httpClient = new HttpClient(handler);
31
+ _downstreamMessages = new ConcurrentQueue<object>();
32
+ }
33
+
34
+ public override async Task ConnectAsync()
35
+ {
36
+ int retryDelaySeconds = 15;
37
+ int maxTotalWaitSeconds = 1800;
38
+ int elapsedSeconds = 0;
39
+
40
+ while (elapsedSeconds < maxTotalWaitSeconds)
41
+ {
42
+ try
43
+ {
44
+ Console.WriteLine($"Connecting to HTTP server at {_uri}");
45
+
46
+ var downstreamMessage = MessageBuilder.SerializeMessage(_encryptionKey, new CheckInMessage(""));
47
+ HttpContent content = new ByteArrayContent(downstreamMessage);
48
+ content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
49
+
50
+ var response = await _httpClient.PostAsync(_uri, content);
51
+ response.EnsureSuccessStatusCode();
52
+
53
+ byte[] responseBytes = await response.Content.ReadAsByteArrayAsync();
54
+
55
+ var (_, parsedMessage) = MessageParser.DeserializeMessage(_encryptionKey, responseBytes);
56
+
57
+ if (parsedMessage is CheckInMessage checkInMsg)
58
+ {
59
+ _messengerId = checkInMsg.MessengerId;
60
+ Console.WriteLine($"[+] Connected to server with Messenger ID: {_messengerId}");
61
+
62
+ await PollServerAsync(); // Enter main loop
63
+ return; // Exit reconnect loop on success
64
+ }
65
+ else
66
+ {
67
+ throw new InvalidOperationException(
68
+ $"Expected a CheckInMessage, but got {parsedMessage.GetType().Name}"
69
+ );
70
+ }
71
+ }
72
+ catch (Exception ex)
73
+ {
74
+ Console.WriteLine($"[!] Connection attempt failed: {ex.Message}");
75
+ elapsedSeconds += retryDelaySeconds;
76
+ if (elapsedSeconds >= maxTotalWaitSeconds)
77
+ {
78
+ Console.WriteLine("[-] Reconnect timeout after 30 minutes. Giving up.");
79
+ break;
80
+ }
81
+
82
+ Console.WriteLine("[*] Retrying connection in 15 seconds...");
83
+ await Task.Delay(retryDelaySeconds * 1000);
84
+ }
85
+ }
86
+ }
87
+
88
+
89
+ private async Task PollServerAsync()
90
+ {
91
+ while (true)
92
+ {
93
+ try
94
+ {
95
+ var downstreamMessages = new List<object>();
96
+
97
+ CheckInMessage checkInMessage = new CheckInMessage(_messengerId);
98
+ downstreamMessages.Add(checkInMessage);
99
+
100
+ while (_downstreamMessages.TryDequeue(out var message))
101
+ {
102
+ downstreamMessages.Add(message);
103
+ }
104
+
105
+ HttpContent content = new ByteArrayContent(SerializeMessages(_encryptionKey, downstreamMessages));
106
+ content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
107
+ var response = await _httpClient.PostAsync(_uri, content);
108
+
109
+ if (!response.IsSuccessStatusCode)
110
+ {
111
+ Console.WriteLine($"Failed to poll server. HTTP {response.StatusCode}");
112
+ break;
113
+ }
114
+
115
+ var responseData = await response.Content.ReadAsByteArrayAsync();
116
+ var messages = DeserializeMessages(_encryptionKey, responseData);
117
+
118
+ foreach (var message in messages)
119
+ {
120
+ _ = Task.Run(() => HandleMessageAsync(message));
121
+ }
122
+
123
+ await Task.Delay(1000);
124
+ }
125
+ catch (Exception ex)
126
+ {
127
+ Console.WriteLine($"Error polling server: {ex.Message}");
128
+ break;
129
+ }
130
+ }
131
+ }
132
+
133
+ public override async Task SendDownstreamMessageAsync(object message)
134
+ {
135
+ try
136
+ {
137
+ _downstreamMessages.Enqueue(message);
138
+ }
139
+ catch (Exception ex)
140
+ {
141
+ Console.WriteLine($"Error enqueuing downstream message: {ex.Message}");
142
+ }
143
+ }
144
+
145
+ public override async Task HandleMessageAsync(object message)
146
+ {
147
+ switch (message)
148
+ {
149
+ case InitiateForwarderClientReq reqMessage:
150
+ await HandleInitiateForwarderClientReqAsync(reqMessage);
151
+ break;
152
+
153
+ case InitiateForwarderClientRep repMessage:
154
+ await StreamAsync(repMessage.ForwarderClientId);
155
+ break;
156
+
157
+ case SendDataMessage sendDataMessage:
158
+ if (ForwarderClients.TryGetValue(sendDataMessage.ForwarderClientId, out var client))
159
+ {
160
+ await client.GetStream().WriteAsync(sendDataMessage.Data, 0, sendDataMessage.Data.Length);
161
+ }
162
+ break;
163
+
164
+ case CheckInMessage checkInMessage:
165
+ break;
166
+
167
+ default:
168
+ Console.WriteLine("Unknown message type received");
169
+ break;
170
+ }
171
+ }
172
+ }
173
+ }