Skip to content
This repository was archived by the owner on Jul 9, 2023. It is now read-only.

Commit 25f2d28

Browse files
authored
Merge pull request #713 from justcoding121/master
socks endpoint
2 parents 4c5d4cd + 5bd2c5c commit 25f2d28

File tree

15 files changed

+229
-76
lines changed

15 files changed

+229
-76
lines changed

examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,15 @@ public void StartProxy()
9797
//proxyServer.UpStreamHttpProxy = new ExternalProxy("46.63.0.17", 4145) { ProxyType = ExternalProxyType.Socks4 };
9898
//proxyServer.UpStreamHttpsProxy = new ExternalProxy("46.63.0.17", 4145) { ProxyType = ExternalProxyType.Socks4 };
9999

100+
//var socksEndPoint = new SocksProxyEndPoint(IPAddress.Any, 1080, true)
101+
//{
102+
// // Generic Certificate hostname to use
103+
// // When SNI is disabled by client
104+
// GenericCertificateName = "google.com"
105+
//};
106+
107+
//proxyServer.AddEndPoint(socksEndPoint);
108+
100109
foreach (var endPoint in proxyServer.ProxyEndPoints)
101110
{
102111
Console.WriteLine("Listening on '{0}' endpoint at Ip {1} and port: {2} ", endPoint.GetType().Name,

examples/Titanium.Web.Proxy.Examples.Wpf/MainWindow.xaml.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,15 @@ public MainWindow()
8181
// Password = "Titanium",
8282
//};
8383

84+
//var socksEndPoint = new SocksProxyEndPoint(IPAddress.Any, 1080, true)
85+
//{
86+
// // Generic Certificate hostname to use
87+
// // When SNI is disabled by client
88+
// //GenericCertificateName = "google.com"
89+
//};
90+
91+
//proxyServer.AddEndPoint(socksEndPoint);
92+
8493
proxyServer.BeforeRequest += ProxyServer_BeforeRequest;
8594
proxyServer.BeforeResponse += ProxyServer_BeforeResponse;
8695
proxyServer.AfterResponse += ProxyServer_AfterResponse;

src/Titanium.Web.Proxy/Http2/Http2Helper.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-

2-
using Titanium.Web.Proxy.Extensions;
3-
#if NETSTANDARD2_1
1+
#if NETSTANDARD2_1
42
using System;
53
using System.Collections.Concurrent;
64
using System.Diagnostics;
@@ -12,6 +10,7 @@
1210
using Titanium.Web.Proxy.Compression;
1311
using Titanium.Web.Proxy.EventArguments;
1412
using Titanium.Web.Proxy.Exceptions;
13+
using Titanium.Web.Proxy.Extensions;
1514
using Titanium.Web.Proxy.Http;
1615
using Titanium.Web.Proxy.Http2.Hpack;
1716
using Titanium.Web.Proxy.Models;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using System.Diagnostics;
2+
using System.Net;
3+
using System.Threading.Tasks;
4+
using Titanium.Web.Proxy.EventArguments;
5+
using Titanium.Web.Proxy.Extensions;
6+
7+
namespace Titanium.Web.Proxy.Models
8+
{
9+
/// <summary>
10+
/// A proxy end point client is not aware of.
11+
/// Useful when requests are redirected to this proxy end point through port forwarding via router.
12+
/// </summary>
13+
[DebuggerDisplay("SOCKS: {IpAddress}:{Port}")]
14+
public class SocksProxyEndPoint : TransparentBaseProxyEndPoint
15+
{
16+
/// <summary>
17+
/// Initialize a new instance.
18+
/// </summary>
19+
/// <param name="ipAddress">Listening Ip address.</param>
20+
/// <param name="port">Listening port.</param>
21+
/// <param name="decryptSsl">Should we decrypt ssl?</param>
22+
public SocksProxyEndPoint(IPAddress ipAddress, int port, bool decryptSsl = true) : base(ipAddress, port,
23+
decryptSsl)
24+
{
25+
GenericCertificateName = "localhost";
26+
}
27+
28+
/// <summary>
29+
/// Name of the Certificate need to be sent (same as the hostname we want to proxy).
30+
/// This is valid only when UseServerNameIndication is set to false.
31+
/// </summary>
32+
public override string GenericCertificateName { get; set; }
33+
34+
/// <summary>
35+
/// Before Ssl authentication this event is fired.
36+
/// </summary>
37+
public event AsyncEventHandler<BeforeSslAuthenticateEventArgs>? BeforeSslAuthenticate;
38+
39+
internal override async Task InvokeBeforeSslAuthenticate(ProxyServer proxyServer,
40+
BeforeSslAuthenticateEventArgs connectArgs, ExceptionHandler exceptionFunc)
41+
{
42+
if (BeforeSslAuthenticate != null)
43+
{
44+
await BeforeSslAuthenticate.InvokeAsync(proxyServer, connectArgs, exceptionFunc);
45+
}
46+
}
47+
}
48+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System;
2+
using System.Net;
3+
using System.Threading.Tasks;
4+
using Titanium.Web.Proxy.EventArguments;
5+
6+
namespace Titanium.Web.Proxy.Models
7+
{
8+
public abstract class TransparentBaseProxyEndPoint : ProxyEndPoint
9+
{
10+
public abstract string GenericCertificateName { get; set; }
11+
12+
protected TransparentBaseProxyEndPoint(IPAddress ipAddress, int port, bool decryptSsl) : base(ipAddress, port, decryptSsl)
13+
{
14+
}
15+
16+
internal abstract Task InvokeBeforeSslAuthenticate(ProxyServer proxyServer,
17+
BeforeSslAuthenticateEventArgs connectArgs, ExceptionHandler exceptionFunc);
18+
}
19+
}

src/Titanium.Web.Proxy/Models/TransparentProxyEndPoint.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace Titanium.Web.Proxy.Models
1111
/// Useful when requests are redirected to this proxy end point through port forwarding via router.
1212
/// </summary>
1313
[DebuggerDisplay("Transparent: {IpAddress}:{Port}")]
14-
public class TransparentProxyEndPoint : ProxyEndPoint
14+
public class TransparentProxyEndPoint : TransparentBaseProxyEndPoint
1515
{
1616
/// <summary>
1717
/// Initialize a new instance.
@@ -29,14 +29,14 @@ public TransparentProxyEndPoint(IPAddress ipAddress, int port, bool decryptSsl =
2929
/// Name of the Certificate need to be sent (same as the hostname we want to proxy).
3030
/// This is valid only when UseServerNameIndication is set to false.
3131
/// </summary>
32-
public string GenericCertificateName { get; set; }
32+
public override string GenericCertificateName { get; set; }
3333

3434
/// <summary>
3535
/// Before Ssl authentication this event is fired.
3636
/// </summary>
3737
public event AsyncEventHandler<BeforeSslAuthenticateEventArgs>? BeforeSslAuthenticate;
3838

39-
internal async Task InvokeBeforeSslAuthenticate(ProxyServer proxyServer,
39+
internal override async Task InvokeBeforeSslAuthenticate(ProxyServer proxyServer,
4040
BeforeSslAuthenticateEventArgs connectArgs, ExceptionHandler exceptionFunc)
4141
{
4242
if (BeforeSslAuthenticate != null)

src/Titanium.Web.Proxy/Net45Compatibility.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
#if NET45
22
using System;
3-
using System.Collections.Generic;
4-
using System.Linq;
5-
using System.Text;
63
using System.Threading.Tasks;
74

85
namespace Titanium.Web.Proxy

src/Titanium.Web.Proxy/Network/Tcp/TcpClientConnection.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System.Net.Sockets;
66
using System.Security.Authentication;
77
using System.Threading.Tasks;
8-
using Titanium.Web.Proxy.Extensions;
98
using Titanium.Web.Proxy.Helpers;
109
using Titanium.Web.Proxy.Models;
1110

src/Titanium.Web.Proxy/Network/Tcp/TcpServerConnection.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
using System.Net.Security;
44
using System.Net.Sockets;
55
using System.Threading.Tasks;
6-
using Titanium.Web.Proxy.Extensions;
76
using Titanium.Web.Proxy.Helpers;
87
using Titanium.Web.Proxy.Models;
98

src/Titanium.Web.Proxy/ProxyServer.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -798,13 +798,17 @@ private async Task handleClient(Socket tcpClientSocket, ProxyEndPoint endPoint)
798798

799799
using (var clientConnection = new TcpClientConnection(this, tcpClientSocket))
800800
{
801-
if (endPoint is TransparentProxyEndPoint tep)
801+
if (endPoint is ExplicitProxyEndPoint eep)
802+
{
803+
await handleClient(eep, clientConnection);
804+
}
805+
else if (endPoint is TransparentProxyEndPoint tep)
802806
{
803807
await handleClient(tep, clientConnection);
804808
}
805-
else
809+
else if (endPoint is SocksProxyEndPoint sep)
806810
{
807-
await handleClient((ExplicitProxyEndPoint)endPoint, clientConnection);
811+
await handleClient(sep, clientConnection);
808812
}
809813
}
810814
}

src/Titanium.Web.Proxy/ProxySocket/SocksHandler.cs

Lines changed: 8 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -144,16 +144,8 @@ protected void HandleEndSend(IAsyncResult ar, int expectedLength)
144144
/// <exception cref="ArgumentNullException">The specified value is null.</exception>
145145
protected Socket Server
146146
{
147-
get
148-
{
149-
return _server;
150-
}
151-
set
152-
{
153-
if (value == null)
154-
throw new ArgumentNullException();
155-
_server = value;
156-
}
147+
get => _server;
148+
set => _server = value ?? throw new ArgumentNullException();
157149
}
158150

159151
/// <summary>
@@ -163,16 +155,8 @@ protected Socket Server
163155
/// <exception cref="ArgumentNullException">The specified value is null.</exception>
164156
protected string Username
165157
{
166-
get
167-
{
168-
return _username;
169-
}
170-
set
171-
{
172-
if (value == null)
173-
throw new ArgumentNullException();
174-
_username = value;
175-
}
158+
get => _username;
159+
set => _username = value ?? throw new ArgumentNullException();
176160
}
177161

178162
/// <summary>
@@ -181,47 +165,21 @@ protected string Username
181165
/// <value>An IAsyncProxyResult object that is the return value of the BeginConnect call.</value>
182166
protected IAsyncProxyResult AsyncResult
183167
{
184-
get
185-
{
186-
return _asyncResult;
187-
}
188-
set
189-
{
190-
_asyncResult = value;
191-
}
168+
get => _asyncResult;
169+
set => _asyncResult = value;
192170
}
193171

194172
/// <summary>
195173
/// Gets or sets a byte buffer.
196174
/// </summary>
197175
/// <value>An array of bytes.</value>
198-
protected byte[] Buffer
199-
{
200-
get
201-
{
202-
return _buffer;
203-
}
204-
set
205-
{
206-
_buffer = value;
207-
}
208-
}
176+
protected byte[] Buffer { get; set; }
209177

210178
/// <summary>
211179
/// Gets or sets the number of bytes that have been received from the remote proxy server.
212180
/// </summary>
213181
/// <value>An integer that holds the number of bytes that have been received from the remote proxy server.</value>
214-
protected int Received
215-
{
216-
get
217-
{
218-
return _received;
219-
}
220-
set
221-
{
222-
_received = value;
223-
}
224-
}
182+
protected int Received { get; set; }
225183

226184
// private variables
227185
/// <summary>Holds the value of the Server property.</summary>
@@ -233,12 +191,6 @@ protected int Received
233191
/// <summary>Holds the value of the AsyncResult property.</summary>
234192
private IAsyncProxyResult _asyncResult;
235193

236-
/// <summary>Holds the value of the Buffer property.</summary>
237-
private byte[] _buffer;
238-
239-
/// <summary>Holds the value of the Received property.</summary>
240-
private int _received;
241-
242194
/// <summary>Holds the address of the method to call when the SOCKS protocol has been completed.</summary>
243195
protected HandShakeComplete ProtocolComplete;
244196

src/Titanium.Web.Proxy/RequestHandler.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,10 @@ public partial class ProxyServer
3232
/// <param name="cancellationTokenSource">The cancellation token source for this async task.</param>
3333
/// <param name="connectArgs">The Connect request if this is a HTTPS request from explicit endpoint.</param>
3434
/// <param name="prefetchConnectionTask">Prefetched server connection for current client using Connect/SNI headers.</param>
35+
/// <param name="isHttps">Is HTTPS</param>
3536
private async Task handleHttpSessionRequest(ProxyEndPoint endPoint, HttpClientStream clientStream,
3637
CancellationTokenSource cancellationTokenSource, TunnelConnectSessionEventArgs? connectArgs = null,
37-
Task<TcpServerConnection>? prefetchConnectionTask = null)
38+
Task<TcpServerConnection>? prefetchConnectionTask = null, bool isHttps = false)
3839
{
3940
var connectRequest = connectArgs?.HttpClient.ConnectRequest;
4041

@@ -67,6 +68,8 @@ private async Task handleHttpSessionRequest(ProxyEndPoint endPoint, HttpClientSt
6768
UserData = connectArgs?.UserData
6869
};
6970

71+
args.HttpClient.Request.IsHttps = isHttps;
72+
7073
try
7174
{
7275
try
@@ -217,7 +220,6 @@ await HeaderParser.ReadHeaders(clientStream, args.HttpClient.Request.Headers,
217220
await tcpConnectionFactory.Release(connection);
218221
connection = null;
219222
}
220-
221223
}
222224
catch (Exception e) when (!(e is ProxyHttpException))
223225
{

src/Titanium.Web.Proxy/ResponseHandler.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ await serverStream.CopyBodyAsync(response, false, clientStream, TransformationMo
122122
}
123123
}
124124

125-
126125
args.TimeLine["Response Sent"] = DateTime.Now;
127126
}
128127

0 commit comments

Comments
 (0)