From 42e35359878e6f14870697a5deedf853938d1c5a Mon Sep 17 00:00:00 2001 From: Honfika Date: Sat, 31 Aug 2019 20:00:10 +0200 Subject: [PATCH 1/2] allow to gt the dectypted data from a tunnel --- .../MainWindow.xaml.cs | 69 +++++++++++++------ .../EventArguments/TunnelConnectEventArgs.cs | 35 ++++++++++ .../ExplicitClientHandler.cs | 9 ++- 3 files changed, 90 insertions(+), 23 deletions(-) diff --git a/examples/Titanium.Web.Proxy.Examples.Wpf/MainWindow.xaml.cs b/examples/Titanium.Web.Proxy.Examples.Wpf/MainWindow.xaml.cs index 1edd61075..533bf4a5b 100644 --- a/examples/Titanium.Web.Proxy.Examples.Wpf/MainWindow.xaml.cs +++ b/examples/Titanium.Web.Proxy.Examples.Wpf/MainWindow.xaml.cs @@ -231,35 +231,55 @@ private SessionListItem createSessionListItem(SessionEventArgsBase e) }; //if (isTunnelConnect || e.HttpClient.Request.UpgradeToWebSocket) + e.DataReceived += (sender, args) => { - e.DataReceived += (sender, args) => + var session = (SessionEventArgsBase)sender; + if (sessionDictionary.TryGetValue(session.HttpClient, out var li)) { - var session = (SessionEventArgsBase)sender; - if (sessionDictionary.TryGetValue(session.HttpClient, out var li)) + var tunnelType = session.HttpClient.ConnectRequest?.TunnelType ?? TunnelType.Unknown; + if (tunnelType != TunnelType.Unknown) { - var tunnelType = session.HttpClient.ConnectRequest?.TunnelType ?? TunnelType.Unknown; - if (tunnelType != TunnelType.Unknown) - { - li.Protocol = TunnelTypeToString(tunnelType); - } + li.Protocol = TunnelTypeToString(tunnelType); + } + + li.ReceivedDataCount += args.Count; + + AppendTransferLog(session.GetHashCode() + (isTunnelConnect ? "_tunnel" : "") + "_received", + args.Buffer, args.Offset, args.Count); + } + }; - li.ReceivedDataCount += args.Count; + e.DataSent += (sender, args) => + { + var session = (SessionEventArgsBase)sender; + if (sessionDictionary.TryGetValue(session.HttpClient, out var li)) + { + var tunnelType = session.HttpClient.ConnectRequest?.TunnelType ?? TunnelType.Unknown; + if (tunnelType != TunnelType.Unknown) + { + li.Protocol = TunnelTypeToString(tunnelType); } - }; - e.DataSent += (sender, args) => + li.SentDataCount += args.Count; + + AppendTransferLog(session.GetHashCode() + (isTunnelConnect ? "_tunnel" : "") + "_sent", + args.Buffer, args.Offset, args.Count); + } + }; + + if (e is TunnelConnectSessionEventArgs te) + { + te.DecryptedDataReceived += (sender, args) => { var session = (SessionEventArgsBase)sender; - if (sessionDictionary.TryGetValue(session.HttpClient, out var li)) - { - var tunnelType = session.HttpClient.ConnectRequest?.TunnelType ?? TunnelType.Unknown; - if (tunnelType != TunnelType.Unknown) - { - li.Protocol = TunnelTypeToString(tunnelType); - } + AppendTransferLog(session.GetHashCode() + "_decrypted_received", args.Buffer, args.Offset, + args.Count); + }; - li.SentDataCount += args.Count; - } + te.DecryptedDataSent += (sender, args) => + { + var session = (SessionEventArgsBase)sender; + AppendTransferLog(session.GetHashCode() + "_decrypted_sent", args.Buffer, args.Offset, args.Count); }; } @@ -267,6 +287,15 @@ private SessionListItem createSessionListItem(SessionEventArgsBase e) return item; } + private void AppendTransferLog(string fileName, byte[] buffer, int offset, int count) + { + //string basePath = @"c:\!titanium\"; + //using (var fs = new FileStream(basePath + fileName, FileMode.Append, FileAccess.Write, FileShare.Read)) + //{ + // fs.Write(buffer, offset, count); + //} + } + private string TunnelTypeToString(TunnelType tunnelType) { switch (tunnelType) diff --git a/src/Titanium.Web.Proxy/EventArguments/TunnelConnectEventArgs.cs b/src/Titanium.Web.Proxy/EventArguments/TunnelConnectEventArgs.cs index a4615ef39..e1c9475cc 100644 --- a/src/Titanium.Web.Proxy/EventArguments/TunnelConnectEventArgs.cs +++ b/src/Titanium.Web.Proxy/EventArguments/TunnelConnectEventArgs.cs @@ -2,6 +2,7 @@ using System.Threading; using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Models; +using Titanium.Web.Proxy.StreamExtended.Network; namespace Titanium.Web.Proxy.EventArguments { @@ -40,5 +41,39 @@ public bool IsHttpsConnect internal set => isHttpsConnect = value; } + + /// + /// Fired when decrypted data is sent within this session to server/client. + /// + public event EventHandler DecryptedDataSent; + + /// + /// Fired when decrypted data is received within this session from client/server. + /// + public event EventHandler DecryptedDataReceived; + + internal void OnDecryptedDataSent(byte[] buffer, int offset, int count) + { + try + { + DecryptedDataSent?.Invoke(this, new DataEventArgs(buffer, offset, count)); + } + catch (Exception ex) + { + ExceptionFunc(new Exception("Exception thrown in user event", ex)); + } + } + + internal void OnDecryptedDataReceived(byte[] buffer, int offset, int count) + { + try + { + DecryptedDataReceived?.Invoke(this, new DataEventArgs(buffer, offset, count)); + } + catch (Exception ex) + { + ExceptionFunc(new Exception("Exception thrown in user event", ex)); + } + } } } diff --git a/src/Titanium.Web.Proxy/ExplicitClientHandler.cs b/src/Titanium.Web.Proxy/ExplicitClientHandler.cs index 540476753..6a94d096f 100644 --- a/src/Titanium.Web.Proxy/ExplicitClientHandler.cs +++ b/src/Titanium.Web.Proxy/ExplicitClientHandler.cs @@ -216,6 +216,8 @@ await clientStreamWriter.WriteResponseAsync(connectArgs.HttpClient.Response, // HTTPS server created - we can now decrypt the client's traffic clientStream = new CustomBufferedStream(sslStream, BufferPool); + clientStream.DataRead += (o, args) => connectArgs.OnDecryptedDataSent(args.Buffer, args.Offset, args.Count); + clientStream.DataWrite += (o, args) => connectArgs.OnDecryptedDataReceived(args.Buffer, args.Offset, args.Count); clientStreamWriter = new HttpResponseWriter(clientStream, BufferPool); } catch (Exception e) @@ -286,7 +288,8 @@ await clientStreamWriter.WriteResponseAsync(connectArgs.HttpClient.Response, if (!clientStream.IsClosed && !connection.Stream.IsClosed) { await TcpHelper.SendRaw(clientStream, connection.Stream, BufferPool, - null, null, connectArgs.CancellationTokenSource, ExceptionFunc); + null, null, + connectArgs.CancellationTokenSource, ExceptionFunc); } } finally @@ -336,8 +339,8 @@ await TcpHelper.SendRaw(clientStream, connection.Stream, BufferPool, await connection.StreamWriter.WriteLineAsync(cancellationToken); #if NETCOREAPP2_1 await Http2Helper.SendHttp2(clientStream, connection.Stream, BufferPool.BufferSize, - (buffer, offset, count) => { connectArgs.OnDataSent(buffer, offset, count); }, - (buffer, offset, count) => { connectArgs.OnDataReceived(buffer, offset, count); }, + (buffer, offset, count) => { connectArgs.OnDecryptedDataSent(buffer, offset, count); }, + (buffer, offset, count) => { connectArgs.OnDecryptedDataReceived(buffer, offset, count); }, () => new SessionEventArgs(this, endPoint, cancellationTokenSource) { ProxyClient = { Connection = clientConnection }, From bac300f363a0c5bbcc19fa5f190bf33f95ff661c Mon Sep 17 00:00:00 2001 From: buildbot121 Date: Sat, 31 Aug 2019 18:01:33 +0000 Subject: [PATCH 2/2] API documentation update by build server --- ...guments.TunnelConnectSessionEventArgs.html | 70 +++++++++++++++++-- docs/index.json | 2 +- docs/xrefmap.yml | 12 ++++ 3 files changed, 79 insertions(+), 5 deletions(-) diff --git a/docs/api/Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs.html b/docs/api/Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs.html index dec7ba309..c91195e7c 100644 --- a/docs/api/Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs.html +++ b/docs/api/Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs.html @@ -185,7 +185,7 @@

Properties Improve this Doc - View Source + View Source

DecryptSsl

@@ -217,7 +217,7 @@
Property Value
Improve this Doc - View Source + View Source

DenyConnect

@@ -248,7 +248,7 @@
Property Value
Improve this Doc - View Source + View Source

IsHttpsConnect

@@ -274,6 +274,68 @@
Property Value
+

Events +

+ + | + Improve this Doc + + + View Source + +

DecryptedDataReceived

+

Fired when decrypted data is received within this session from client/server.

+
+
+
Declaration
+
+
public event EventHandler<DataEventArgs> DecryptedDataReceived
+
+
Event Type
+ + + + + + + + + + + + + +
TypeDescription
EventHandler<DataEventArgs>
+ + | + Improve this Doc + + + View Source + +

DecryptedDataSent

+

Fired when decrypted data is sent within this session to server/client.

+
+
+
Declaration
+
+
public event EventHandler<DataEventArgs> DecryptedDataSent
+
+
Event Type
+ + + + + + + + + + + + + +
TypeDescription
EventHandler<DataEventArgs>

Implements

System.IDisposable @@ -289,7 +351,7 @@

Implements

Improve this Doc
  • - View Source + View Source
  • diff --git a/docs/index.json b/docs/index.json index 1b71f553e..4e864a176 100644 --- a/docs/index.json +++ b/docs/index.json @@ -42,7 +42,7 @@ "api/Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs.html": { "href": "api/Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs.html", "title": "Class TunnelConnectSessionEventArgs | Titanium Web Proxy", - "keywords": "Class TunnelConnectSessionEventArgs A class that wraps the state when a tunnel connect event happen for Explicit endpoints. Inheritance Object EventArgs SessionEventArgsBase TunnelConnectSessionEventArgs Implements IDisposable Inherited Members SessionEventArgsBase.BufferPool SessionEventArgsBase.ExceptionFunc SessionEventArgsBase.TimeLine SessionEventArgsBase.UserData SessionEventArgsBase.IsHttps SessionEventArgsBase.ClientEndPoint SessionEventArgsBase.HttpClient SessionEventArgsBase.WebSession SessionEventArgsBase.CustomUpStreamProxyUsed SessionEventArgsBase.LocalEndPoint SessionEventArgsBase.IsTransparent SessionEventArgsBase.Exception SessionEventArgsBase.Dispose() SessionEventArgsBase.DataSent SessionEventArgsBase.DataReceived SessionEventArgsBase.TerminateSession() EventArgs.Empty Object.Equals(Object) Object.Equals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Object.ReferenceEquals(Object, Object) Object.ToString() Namespace : Titanium.Web.Proxy.EventArguments Assembly : Titanium.Web.Proxy.dll Syntax public class TunnelConnectSessionEventArgs : SessionEventArgsBase, IDisposable Properties | Improve this Doc View Source DecryptSsl Should we decrypt the Ssl or relay it to server? Default is true. Declaration public bool DecryptSsl { get; set; } Property Value Type Description Boolean | Improve this Doc View Source DenyConnect When set to true it denies the connect request with a Forbidden status. Declaration public bool DenyConnect { get; set; } Property Value Type Description Boolean | Improve this Doc View Source IsHttpsConnect Is this a connect request to secure HTTP server? Or is it to some other protocol. Declaration public bool IsHttpsConnect { get; } Property Value Type Description Boolean Implements System.IDisposable" + "keywords": "Class TunnelConnectSessionEventArgs A class that wraps the state when a tunnel connect event happen for Explicit endpoints. Inheritance Object EventArgs SessionEventArgsBase TunnelConnectSessionEventArgs Implements IDisposable Inherited Members SessionEventArgsBase.BufferPool SessionEventArgsBase.ExceptionFunc SessionEventArgsBase.TimeLine SessionEventArgsBase.UserData SessionEventArgsBase.IsHttps SessionEventArgsBase.ClientEndPoint SessionEventArgsBase.HttpClient SessionEventArgsBase.WebSession SessionEventArgsBase.CustomUpStreamProxyUsed SessionEventArgsBase.LocalEndPoint SessionEventArgsBase.IsTransparent SessionEventArgsBase.Exception SessionEventArgsBase.Dispose() SessionEventArgsBase.DataSent SessionEventArgsBase.DataReceived SessionEventArgsBase.TerminateSession() EventArgs.Empty Object.Equals(Object) Object.Equals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Object.ReferenceEquals(Object, Object) Object.ToString() Namespace : Titanium.Web.Proxy.EventArguments Assembly : Titanium.Web.Proxy.dll Syntax public class TunnelConnectSessionEventArgs : SessionEventArgsBase, IDisposable Properties | Improve this Doc View Source DecryptSsl Should we decrypt the Ssl or relay it to server? Default is true. Declaration public bool DecryptSsl { get; set; } Property Value Type Description Boolean | Improve this Doc View Source DenyConnect When set to true it denies the connect request with a Forbidden status. Declaration public bool DenyConnect { get; set; } Property Value Type Description Boolean | Improve this Doc View Source IsHttpsConnect Is this a connect request to secure HTTP server? Or is it to some other protocol. Declaration public bool IsHttpsConnect { get; } Property Value Type Description Boolean Events | Improve this Doc View Source DecryptedDataReceived Fired when decrypted data is received within this session from client/server. Declaration public event EventHandler DecryptedDataReceived Event Type Type Description EventHandler < DataEventArgs > | Improve this Doc View Source DecryptedDataSent Fired when decrypted data is sent within this session to server/client. Declaration public event EventHandler DecryptedDataSent Event Type Type Description EventHandler < DataEventArgs > Implements System.IDisposable" }, "api/Titanium.Web.Proxy.ExceptionHandler.html": { "href": "api/Titanium.Web.Proxy.ExceptionHandler.html", diff --git a/docs/xrefmap.yml b/docs/xrefmap.yml index 0f686c94a..0bdf27db4 100644 --- a/docs/xrefmap.yml +++ b/docs/xrefmap.yml @@ -709,6 +709,18 @@ references: commentId: T:Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs fullName: Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs nameWithType: TunnelConnectSessionEventArgs +- uid: Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs.DecryptedDataReceived + name: DecryptedDataReceived + href: api/Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs.html#Titanium_Web_Proxy_EventArguments_TunnelConnectSessionEventArgs_DecryptedDataReceived + commentId: E:Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs.DecryptedDataReceived + fullName: Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs.DecryptedDataReceived + nameWithType: TunnelConnectSessionEventArgs.DecryptedDataReceived +- uid: Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs.DecryptedDataSent + name: DecryptedDataSent + href: api/Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs.html#Titanium_Web_Proxy_EventArguments_TunnelConnectSessionEventArgs_DecryptedDataSent + commentId: E:Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs.DecryptedDataSent + fullName: Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs.DecryptedDataSent + nameWithType: TunnelConnectSessionEventArgs.DecryptedDataSent - uid: Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs.DecryptSsl name: DecryptSsl href: api/Titanium.Web.Proxy.EventArguments.TunnelConnectSessionEventArgs.html#Titanium_Web_Proxy_EventArguments_TunnelConnectSessionEventArgs_DecryptSsl