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.
- messenger_proxy-0.4.1/LICENSE +28 -0
- messenger_proxy-0.4.1/PKG-INFO +109 -0
- messenger_proxy-0.4.1/README.md +79 -0
- messenger_proxy-0.4.1/builder/__init__.py +0 -0
- messenger_proxy-0.4.1/builder/clients/__init__.py +0 -0
- messenger_proxy-0.4.1/builder/clients/csharp/MessengerClient/App.config +14 -0
- messenger_proxy-0.4.1/builder/clients/csharp/MessengerClient/Crypto.cs +85 -0
- messenger_proxy-0.4.1/builder/clients/csharp/MessengerClient/HTTPMessengerClient.cs +173 -0
- messenger_proxy-0.4.1/builder/clients/csharp/MessengerClient/Message.cs +410 -0
- messenger_proxy-0.4.1/builder/clients/csharp/MessengerClient/MessengerClient.cs +188 -0
- messenger_proxy-0.4.1/builder/clients/csharp/MessengerClient/MessengerClient.csproj +62 -0
- messenger_proxy-0.4.1/builder/clients/csharp/MessengerClient/MessengerClient.sln +25 -0
- messenger_proxy-0.4.1/builder/clients/csharp/MessengerClient/Program.cs +171 -0
- messenger_proxy-0.4.1/builder/clients/csharp/MessengerClient/Properties/AssemblyInfo.cs +36 -0
- messenger_proxy-0.4.1/builder/clients/csharp/MessengerClient/RemotePortForwarder.cs +86 -0
- messenger_proxy-0.4.1/builder/clients/csharp/MessengerClient/WebsocketMessengerClient.cs +218 -0
- messenger_proxy-0.4.1/builder/clients/csharp/README.md +41 -0
- messenger_proxy-0.4.1/builder/clients/nodejs/README.md +127 -0
- messenger_proxy-0.4.1/builder/clients/nodejs/builder.py +60 -0
- messenger_proxy-0.4.1/builder/clients/nodejs/electron +39 -0
- messenger_proxy-0.4.1/builder/clients/nodejs/requirements.txt +1 -0
- messenger_proxy-0.4.1/builder/clients/nodejs/templates/messenger-client.js +751 -0
- messenger_proxy-0.4.1/builder/clients/nodejs/webpack.conf.js +50 -0
- messenger_proxy-0.4.1/builder/clients/python/README.md +143 -0
- messenger_proxy-0.4.1/builder/clients/python/builder.py +70 -0
- messenger_proxy-0.4.1/builder/clients/python/messenger-client-http.py +746 -0
- messenger_proxy-0.4.1/builder/clients/python/messenger-client-ws.py +478 -0
- messenger_proxy-0.4.1/builder/clients/python/messenger-client.py +959 -0
- messenger_proxy-0.4.1/builder/clients/python/requirements.txt +1 -0
- messenger_proxy-0.4.1/builder/clients/python/templates/messenger-client.py +896 -0
- messenger_proxy-0.4.1/messenger/__init__.py +10 -0
- messenger_proxy-0.4.1/messenger/aes.py +20 -0
- messenger_proxy-0.4.1/messenger/convert.py +21 -0
- messenger_proxy-0.4.1/messenger/engine.py +76 -0
- messenger_proxy-0.4.1/messenger/forwarder_clients.py +186 -0
- messenger_proxy-0.4.1/messenger/forwarders.py +331 -0
- messenger_proxy-0.4.1/messenger/generator.py +60 -0
- messenger_proxy-0.4.1/messenger/http_ws_server.py +134 -0
- messenger_proxy-0.4.1/messenger/manager.py +737 -0
- messenger_proxy-0.4.1/messenger/message.py +267 -0
- messenger_proxy-0.4.1/messenger/messengers.py +226 -0
- messenger_proxy-0.4.1/messenger/output.py +31 -0
- messenger_proxy-0.4.1/messenger/resources/top_ports.txt +8320 -0
- messenger_proxy-0.4.1/messenger/scanner.py +179 -0
- messenger_proxy-0.4.1/messenger/text.py +35 -0
- messenger_proxy-0.4.1/messenger-builder +111 -0
- messenger_proxy-0.4.1/messenger-cli +30 -0
- messenger_proxy-0.4.1/messenger_proxy.egg-info/PKG-INFO +109 -0
- messenger_proxy-0.4.1/messenger_proxy.egg-info/SOURCES.txt +52 -0
- messenger_proxy-0.4.1/messenger_proxy.egg-info/dependency_links.txt +1 -0
- messenger_proxy-0.4.1/messenger_proxy.egg-info/requires.txt +4 -0
- messenger_proxy-0.4.1/messenger_proxy.egg-info/top_level.txt +2 -0
- messenger_proxy-0.4.1/setup.cfg +4 -0
- 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
|
+
}
|