コード例 #1
0
 void session_PlayTokenLost(ISession sender, SessionEventArgs e)
 {
     this.ParentForm.BeginInvoke(new MethodInvoker(delegate()
         {
             CF_displayMessage("Play token lost! What do we do???" + Environment.NewLine + e.Status.ToString() + Environment.NewLine + e.Message);
         }));
 }
コード例 #2
0
        //Test On Request, intecept requests
        //Read browser URL send back to proxy by the injection script in OnResponse event
        public void OnRequest(object sender, SessionEventArgs e)
        {
            Console.WriteLine(e.ProxySession.Request.Url);

            ////read request headers
            //var requestHeaders = e.ProxySession.Request.RequestHeaders;

            //if ((e.RequestMethod.ToUpper() == "POST" || e.RequestMethod.ToUpper() == "PUT"))
            //{
            //    //Get/Set request body bytes
            //    byte[] bodyBytes = e.GetRequestBody();
            //    e.SetRequestBody(bodyBytes);

            //    //Get/Set request body as string
            //    string bodyString = e.GetRequestBodyAsString();
            //    e.SetRequestBodyString(bodyString);

            //}

            ////To cancel a request with a custom HTML content
            ////Filter URL

            //if (e.ProxySession.Request.RequestUrl.Contains("google.com"))
            //{
            //    e.Ok("<!DOCTYPE html><html><body><h1>Website Blocked</h1><p>Blocked by titanium web proxy.</p></body></html>");
            //}
        }
コード例 #3
0
 void session_MessageToUser(ISession sender, SessionEventArgs e)
 {
     this.ParentForm.BeginInvoke(new MethodInvoker(delegate()
         {
             CF_displayMessage(e.Message);
         }));
 }
コード例 #4
0
        public void Session()
        {
            Mocks mocks = new Mocks();

            SessionEventArgs s = new SessionEventArgs(mocks.Session.Object);

            Assert.Equal(s.Session, mocks.Session.Object);
        }
コード例 #5
0
 void session_Exception(ISession sender, SessionEventArgs e)
 {
     this.ParentForm.BeginInvoke(new MethodInvoker(delegate()
         {
             WriteError(e.Message);
             CF_displayMessage(e.Status.ToString() + Environment.NewLine + e.Message);
         }));
 }
コード例 #6
0
 private void OnConnectionError(object sender, SessionEventArgs e)
 {
     if (e.Status != Error.OK)
     {
         _logger.Log("Connection error " + e.Message + "[" + e.Status + "]", Category.Exception, Priority.High);
     }
     else
     {
         _logger.Log("Connected", Category.Info, Priority.Low);
     }
 }
コード例 #7
0
 void session_LoginComplete(ISession sender, SessionEventArgs e)
 {
     this.ParentForm.BeginInvoke(new MethodInvoker(() =>
         {
             if (e.Status != sp_error.OK)
             {
                 CF_displayMessage("Login Failed: " + e.Status + Environment.NewLine + e.Message);
             }
             else
             {
                 OnLoginComplete();
             }
         }));
 }
コード例 #8
0
ファイル: ResponseHandler.cs プロジェクト: amitla/Titanium
        private static void Dispose(TcpClient client, Stream clientStream, CustomBinaryReader clientStreamReader, StreamWriter clientStreamWriter, SessionEventArgs args)
        {
            if (args != null)
                args.Dispose();

            if (clientStreamReader != null)
                clientStreamReader.Dispose();

            if (clientStreamWriter != null)
                clientStreamWriter.Dispose();

            if (clientStream != null)
                clientStream.Dispose();

            if (client != null)
                client.Close();
        }
コード例 #9
0
        //Test script injection
        //Insert script to read the Browser URL and send it back to proxy
        public void OnResponse(object sender, SessionEventArgs e)
        {
            ////read response headers
               // var responseHeaders = e.ProxySession.Response.ResponseHeaders;

            //if (!e.ProxySession.Request.Hostname.Equals("medeczane.sgk.gov.tr")) return;
            //if (e.RequestMethod == "GET" || e.RequestMethod == "POST")
            //{
            //    if (e.ProxySession.Response.ResponseStatusCode == "200")
            //    {
            //        if (e.ProxySession.Response.ContentType.Trim().ToLower().Contains("text/html"))
            //        {
            //            string body = e.GetResponseBodyAsString();
            //        }
            //    }
            //}
        }
コード例 #10
0
        //Called asynchronously when a request was successfully and we received the response
        private static void HandleHttpSessionResponse(SessionEventArgs args)
        {
            args.ProxySession.ReceiveResponse();

            try
            {

                args.ProxySession.Response.ResponseHeaders = ReadResponseHeaders(args.ProxySession);
                args.ProxySession.Response.ResponseStream = args.ProxySession.ProxyClient.ServerStreamReader.BaseStream;


                if (BeforeResponse != null)
                {
                    args.ProxySession.Response.Encoding = args.ProxySession.GetResponseEncoding();
                    BeforeResponse(null, args);
                }

                args.ProxySession.Response.ResponseLocked = true;

                if (args.ProxySession.Response.ResponseBodyRead)
                {
                    var isChunked = args.ProxySession.Response.IsChunked;
                    var contentEncoding = args.ProxySession.Response.ContentEncoding;

                    if(contentEncoding!=null)
                    switch (contentEncoding)
                    {
                        case "gzip":
                            args.ProxySession.Response.ResponseBody = CompressionHelper.CompressGzip(args.ProxySession.Response.ResponseBody);
                            break;
                        case "deflate":
                            args.ProxySession.Response.ResponseBody = CompressionHelper.CompressDeflate(args.ProxySession.Response.ResponseBody);
                            break;
                        case "zlib":
                            args.ProxySession.Response.ResponseBody = CompressionHelper.CompressZlib(args.ProxySession.Response.ResponseBody);
                            break;
                    }

                    WriteResponseStatus(args.ProxySession.Response.HttpVersion, args.ProxySession.Response.ResponseStatusCode,
                        args.ProxySession.Response.ResponseStatusDescription, args.Client.ClientStreamWriter);
                    WriteResponseHeaders(args.Client.ClientStreamWriter, args.ProxySession.Response.ResponseHeaders, args.ProxySession.Response.ResponseBody.Length,
                        isChunked);
                    WriteResponseBody(args.Client.ClientStream, args.ProxySession.Response.ResponseBody, isChunked);
                }
                else
                {
                    WriteResponseStatus(args.ProxySession.Response.HttpVersion, args.ProxySession.Response.ResponseStatusCode,
                         args.ProxySession.Response.ResponseStatusDescription, args.Client.ClientStreamWriter);
                    WriteResponseHeaders(args.Client.ClientStreamWriter, args.ProxySession.Response.ResponseHeaders);

                    if (args.ProxySession.Response.IsChunked || args.ProxySession.Response.ContentLength > 0)
                        WriteResponseBody(args.ProxySession.ProxyClient.ServerStreamReader, args.Client.ClientStream, args.ProxySession.Response.IsChunked, args.ProxySession.Response.ContentLength);
                }

                args.Client.ClientStream.Flush();

            }
            catch
            {
                Dispose(args.Client.TcpClient, args.Client.ClientStream, args.Client.ClientStreamReader, args.Client.ClientStreamWriter, args);
            }
            finally
            {
                args.Dispose();
            }
        }
コード例 #11
0
ファイル: ClientSocket.cs プロジェクト: robert0609/BlueFox
 private void session_SessionStarted(object sender, SessionEventArgs e)
 {
     this.OnSesstionStarted(e.Session);
 }
コード例 #12
0
ファイル: HttpProxy.cs プロジェクト: dice7326/SteamTools
        public async Task OnRequest(object sender, SessionEventArgs e)
        {
#if DEBUG
            #region 测试用

            /*
             * if (e.HttpClient.Request.RequestUri.AbsoluteUri.Contains("steampowered.com"))
             * {
             *  var ip = Dns.GetHostAddresses("steampowered.com");
             *  e.HttpClient.UpStreamEndPoint = new IPEndPoint(IPAddress.Parse(ip[0].ToString()), 443);
             *  if (e.HttpClient.ConnectRequest?.ClientHelloInfo != null)
             *  {
             *      e.HttpClient.ConnectRequest.ClientHelloInfo.Extensions.Remove("server_name");
             *  }
             * }
             *
             * if (e.HttpClient.Request.RequestUri.AbsoluteUri.Contains("steamcommunity.com"))
             * {
             *  var ip = Dns.GetHostAddresses("steamcommunity-a.akamaihd.net");
             *  e.HttpClient.UpStreamEndPoint = new IPEndPoint(IPAddress.Parse(ip[0].ToString()), 443);
             *  if (e.HttpClient.ConnectRequest?.ClientHelloInfo != null)
             *  {
             *      e.HttpClient.ConnectRequest.ClientHelloInfo.Extensions.Remove("server_name");
             *  }
             * }
             */
            #endregion
            Debug.WriteLine("OnRequest " + e.HttpClient.Request.RequestUri.AbsoluteUri);
            Debug.WriteLine("OnRequest HTTP " + e.HttpClient.Request.HttpVersion);
            Logger.Info("OnRequest" + e.HttpClient.Request.RequestUri.AbsoluteUri);
#endif
            // Dns.GetHostAddressesAsync(e.HttpClient.Request.Host).ContinueWith(s =>
            //{
            //    //部分运营商将奇怪的域名解析到127.0.0.1 再此排除这些不支持的代理域名
            //    if (IPAddress.IsLoopback(s.Result.FirstOrDefault())
            //   && ProxyDomains.Count(w => w.IsEnable && w.Hosts.Contains(e.HttpClient.Request.Host)) == 0)
            //    {
            //        e.Ok($"URL : {e.HttpClient.Request.RequestUri.AbsoluteUri} \r\n not support proxy");
            //        return;
            //    }
            //});
            foreach (var item in ProxyDomains)
            {
                if (!item.IsEnable)
                {
                    continue;
                }
                foreach (var host in item.Domains)
                {
                    if (e.HttpClient.Request.RequestUri.AbsoluteUri.Contains(host))
                    {
                        IPAddress iP = null;
                        if (!string.IsNullOrEmpty(item.ProxyIPAddres))
                        {
                            iP = IPAddress.Parse(item.ProxyIPAddres);
                        }
                        else
                        {
                            var iPs = await Dns.GetHostAddressesAsync(item.ToDomain);

                            iP = iPs.FirstOrDefault();
                        }
                        if (iP != null)
                        {
                            e.HttpClient.UpStreamEndPoint = new IPEndPoint(IPAddress.Parse(iP.ToString()), item.Port);
                        }
                        if (e.HttpClient.ConnectRequest?.ClientHelloInfo != null)
                        {
                            if (!string.IsNullOrEmpty(item.ServerName))
                            {
                                var sni = e.HttpClient.ConnectRequest.ClientHelloInfo.Extensions["server_name"];
                                e.HttpClient.ConnectRequest.ClientHelloInfo.Extensions["server_name"] =
                                    new Titanium.Web.Proxy.StreamExtended.Models.SslExtension(sni.Value, sni.Name, item.ServerName, sni.Position);
                            }
                            else
                            {
                                e.HttpClient.ConnectRequest.ClientHelloInfo.Extensions.Remove("server_name");
                            }
                        }
                        return;
                    }
                }
            }

            //没有匹配到的结果直接返回不支持,避免出现Loopback死循环内存溢出
            e.Ok($"URL : {e.HttpClient.Request.RequestUri.AbsoluteUri} {Environment.NewLine} not support proxy");
            return;
        }
コード例 #13
0
 void session_LogoutComplete(ISession sender, SessionEventArgs e)
 {
     loginComplete = false;
 }
コード例 #14
0
 private void OnSessionStopPlayback(object sender, SessionEventArgs e)
 {
     _logger.Log("Session - Stop playback recevied", Category.Info, Priority.Low);
 }
コード例 #15
0
ファイル: Program.cs プロジェクト: kms/torshify
        private void UserLoggedIn(object sender, SessionEventArgs e)
        {
            if (e.Status == Error.OK)
            {
                ConsoleEx.WriteLine("Successfully logged in", ConsoleColor.Yellow);
            }
            else
            {
                ConsoleEx.WriteLine("Unable to log in: " + e.Status.GetMessage(), ConsoleColor.Red);
                Console.ReadLine();
                Environment.Exit(-1);
            }

            _logInEvent.Set();
        }
コード例 #16
0
 protected virtual void OnStarted(ISession session)
 {
     var e = new SessionEventArgs(new ImmutableProxiedSession(session));
     OnStarted(e);
 }
コード例 #17
0
 private void HandshakeOnCreate(object sender, SessionEventArgs e)
 {
     e.Session.Handshake(e.Session.RemoteNodeId);
 }
コード例 #18
0
        /// <summary>
        ///     This is the core request handler method for a particular connection from client.
        ///     Will create new session (request/response) sequence until
        ///     client/server abruptly terminates connection or by normal HTTP termination.
        /// </summary>
        /// <param name="endPoint">The proxy endpoint.</param>
        /// <param name="clientConnection">The client connection.</param>
        /// <param name="clientStream">The client stream.</param>
        /// <param name="clientStreamWriter">The client stream writer.</param>
        /// <param name="cancellationTokenSource">The cancellation token source for this async task.</param>
        /// <param name="httpsConnectHostname">
        ///     The https hostname as appeared in CONNECT request if this is a HTTPS request from
        ///     explicit endpoint.
        /// </param>
        /// <param name="connectArgs">The Connect request if this is a HTTPS request from explicit endpoint.</param>
        /// <param name="prefetchConnectionTask">Prefetched server connection for current client using Connect/SNI headers.</param>
        private async Task handleHttpSessionRequest(ProxyEndPoint endPoint, TcpClientConnection clientConnection,
                                                    CustomBufferedStream clientStream, HttpResponseWriter clientStreamWriter,
                                                    CancellationTokenSource cancellationTokenSource, string httpsConnectHostname, TunnelConnectSessionEventArgs connectArgs,
                                                    Task <TcpServerConnection> prefetchConnectionTask = null)
        {
            var connectRequest = connectArgs?.HttpClient.ConnectRequest;

            var prefetchTask = prefetchConnectionTask;
            TcpServerConnection connection = null;
            bool closeServerConnection     = false;

            try
            {
                var cancellationToken = cancellationTokenSource.Token;

                // Loop through each subsequent request on this particular client connection
                // (assuming HTTP connection is kept alive by client)
                while (true)
                {
                    if (clientStream.IsClosed)
                    {
                        return;
                    }

                    // read the request line
                    string httpCmd = await clientStream.ReadLineAsync(cancellationToken);

                    if (string.IsNullOrEmpty(httpCmd))
                    {
                        return;
                    }

                    var args = new SessionEventArgs(this, endPoint, cancellationTokenSource)
                    {
                        ProxyClient = { Connection = clientConnection },
                        HttpClient  = { ConnectRequest = connectRequest },
                        UserData    = connectArgs?.UserData
                    };

                    try
                    {
                        try
                        {
                            Request.ParseRequestLine(httpCmd, out string httpMethod, out string httpUrl,
                                                     out var version);

                            // Read the request headers in to unique and non-unique header collections
                            await HeaderParser.ReadHeaders(clientStream, args.HttpClient.Request.Headers,
                                                           cancellationToken);

                            Uri httpRemoteUri;
                            if (ProxyConstants.UriSchemeRegex.IsMatch(httpUrl))
                            {
                                try
                                {
                                    httpRemoteUri = new Uri(httpUrl);
                                }
                                catch (Exception ex)
                                {
                                    throw new Exception($"Invalid URI: '{httpUrl}'", ex);
                                }
                            }
                            else
                            {
                                string host        = args.HttpClient.Request.Host ?? httpsConnectHostname;
                                string hostAndPath = host;
                                if (httpUrl.StartsWith("/"))
                                {
                                    hostAndPath += httpUrl;
                                }

                                string url = string.Concat(httpsConnectHostname == null ? "http://" : "https://",
                                                           hostAndPath);
                                try
                                {
                                    httpRemoteUri = new Uri(url);
                                }
                                catch (Exception ex)
                                {
                                    throw new Exception($"Invalid URI: '{url}'", ex);
                                }
                            }

                            var request = args.HttpClient.Request;
                            request.RequestUri  = httpRemoteUri;
                            request.OriginalUrl = httpUrl;

                            request.Method                      = httpMethod;
                            request.HttpVersion                 = version;
                            args.ProxyClient.ClientStream       = clientStream;
                            args.ProxyClient.ClientStreamWriter = clientStreamWriter;

                            if (!args.IsTransparent)
                            {
                                // proxy authorization check
                                if (httpsConnectHostname == null && await checkAuthorization(args) == false)
                                {
                                    await invokeBeforeResponse(args);

                                    // send the response
                                    await clientStreamWriter.WriteResponseAsync(args.HttpClient.Response,
                                                                                cancellationToken : cancellationToken);

                                    return;
                                }

                                prepareRequestHeaders(request.Headers);
                                request.Host = request.RequestUri.Authority;
                            }

                            // if win auth is enabled
                            // we need a cache of request body
                            // so that we can send it after authentication in WinAuthHandler.cs
                            if (isWindowsAuthenticationEnabledAndSupported && request.HasBody)
                            {
                                await args.GetRequestBody(cancellationToken);
                            }

                            //we need this to syphon out data from connection if API user changes them.
                            request.SetOriginalHeaders();

                            args.TimeLine["Request Received"] = DateTime.Now;

                            // If user requested interception do it
                            await invokeBeforeRequest(args);

                            var response = args.HttpClient.Response;

                            if (request.CancelRequest)
                            {
                                if (!(Enable100ContinueBehaviour && request.ExpectContinue))
                                {
                                    // syphon out the request body from client before setting the new body
                                    await args.SyphonOutBodyAsync(true, cancellationToken);
                                }

                                await handleHttpSessionResponse(args);

                                if (!response.KeepAlive)
                                {
                                    return;
                                }

                                continue;
                            }

                            //If prefetch task is available.
                            if (connection == null && prefetchTask != null)
                            {
                                try
                                {
                                    connection = await prefetchTask;
                                }
                                catch (SocketException e)
                                {
                                    if (e.SocketErrorCode != SocketError.HostNotFound)
                                    {
                                        throw;
                                    }
                                }

                                prefetchTask = null;
                            }

                            // create a new connection if cache key changes.
                            // only gets hit when connection pool is disabled.
                            // or when prefetch task has a unexpectedly different connection.
                            if (connection != null &&
                                (await tcpConnectionFactory.GetConnectionCacheKey(this, args,
                                                                                  clientConnection.NegotiatedApplicationProtocol)
                                 != connection.CacheKey))
                            {
                                await tcpConnectionFactory.Release(connection);

                                connection = null;
                            }

                            var result = await handleHttpSessionRequest(httpCmd, args, connection,
                                                                        clientConnection.NegotiatedApplicationProtocol,
                                                                        cancellationToken, cancellationTokenSource);

                            //update connection to latest used
                            connection            = result.LatestConnection;
                            closeServerConnection = !result.Continue;

                            //throw if exception happened
                            if (!result.IsSuccess)
                            {
                                throw result.Exception;
                            }

                            if (!result.Continue)
                            {
                                return;
                            }

                            //user requested
                            if (args.HttpClient.CloseServerConnection)
                            {
                                closeServerConnection = true;
                                return;
                            }

                            // if connection is closing exit
                            if (!response.KeepAlive)
                            {
                                closeServerConnection = true;
                                return;
                            }

                            if (cancellationTokenSource.IsCancellationRequested)
                            {
                                throw new Exception("Session was terminated by user.");
                            }

                            // Release server connection for each HTTP session instead of per client connection.
                            // This will be more efficient especially when client is idly holding server connection
                            // between sessions without using it.
                            // Do not release authenticated connections for performance reasons.
                            // Otherwise it will keep authenticating per session.
                            if (EnableConnectionPool && connection != null &&
                                !connection.IsWinAuthenticated)
                            {
                                await tcpConnectionFactory.Release(connection);

                                connection = null;
                            }
                        }
                        catch (Exception e) when(!(e is ProxyHttpException))
                        {
                            throw new ProxyHttpException("Error occured whilst handling session request", e, args);
                        }
                    }
                    catch (Exception e)
                    {
                        args.Exception        = e;
                        closeServerConnection = true;
                        throw;
                    }
                    finally
                    {
                        await invokeAfterResponse(args);

                        args.Dispose();
                    }
                }
            }
            finally
            {
                await tcpConnectionFactory.Release(connection,
                                                   closeServerConnection);

                await tcpConnectionFactory.Release(prefetchTask, closeServerConnection);
            }
        }
コード例 #19
0
        /// <summary>
        ///     Handle windows NTLM/Kerberos authentication.
        ///     Note: NTLM/Kerberos cannot do a man in middle operation
        ///     we do for HTTPS requests.
        ///     As such we will be sending local credentials of current
        ///     User to server to authenticate requests.
        ///     To disable this set ProxyServer.EnableWinAuth to false.
        /// </summary>
        private async Task handle401UnAuthorized(SessionEventArgs args)
        {
            string?    headerName = null;
            HttpHeader?authHeader = null;

            var response = args.HttpClient.Response;

            // check in non-unique headers first
            var header = response.Headers.NonUniqueHeaders.FirstOrDefault(x => authHeaderNames.Contains(x.Key));

            if (!header.Equals(new KeyValuePair <string, List <HttpHeader> >()))
            {
                headerName = header.Key;
            }

            if (headerName != null)
            {
                authHeader = response.Headers.NonUniqueHeaders[headerName]
                             .FirstOrDefault(
                    x => authSchemes.Any(y => x.Value.StartsWith(y, StringComparison.OrdinalIgnoreCase)));
            }

            // check in unique headers
            if (authHeader == null)
            {
                headerName = null;

                // check in non-unique headers first
                var uHeader = response.Headers.Headers.FirstOrDefault(x => authHeaderNames.Contains(x.Key));

                if (!uHeader.Equals(new KeyValuePair <string, HttpHeader>()))
                {
                    headerName = uHeader.Key;
                }

                if (headerName != null)
                {
                    authHeader = authSchemes.Any(x => response.Headers.Headers[headerName].Value
                                                 .StartsWith(x, StringComparison.OrdinalIgnoreCase))
                        ? response.Headers.Headers[headerName]
                        : null;
                }
            }

            if (authHeader != null)
            {
                string?scheme = authSchemes.Contains(authHeader.Value) ? authHeader.Value : null;

                var expectedAuthState =
                    scheme == null ? State.WinAuthState.INITIAL_TOKEN : State.WinAuthState.UNAUTHORIZED;

                if (!WinAuthEndPoint.ValidateWinAuthState(args.HttpClient.Data, expectedAuthState))
                {
                    // Invalid state, create proper error message to client
                    await rewriteUnauthorizedResponse(args);

                    return;
                }

                var request = args.HttpClient.Request;

                // clear any existing headers to avoid confusing bad servers
                request.Headers.RemoveHeader(KnownHeaders.Authorization);

                // initial value will match exactly any of the schemes
                if (scheme != null)
                {
                    string clientToken = WinAuthHandler.GetInitialAuthToken(request.Host !, scheme, args.HttpClient.Data);

                    string auth = string.Concat(scheme, clientToken);

                    // replace existing authorization header if any
                    request.Headers.SetOrAddHeaderValue(KnownHeaders.Authorization, auth);

                    // don't need to send body for Authorization request
                    if (request.HasBody)
                    {
                        request.ContentLength = 0;
                    }
                }
                else
                {
                    // challenge value will start with any of the scheme selected
                    scheme = authSchemes.First(x =>
                                               authHeader.Value.StartsWith(x, StringComparison.OrdinalIgnoreCase) &&
                                               authHeader.Value.Length > x.Length + 1);

                    string serverToken = authHeader.Value.Substring(scheme.Length + 1);
                    string clientToken = WinAuthHandler.GetFinalAuthToken(request.Host, serverToken, args.HttpClient.Data);

                    string auth = string.Concat(scheme, clientToken);

                    // there will be an existing header from initial client request
                    request.Headers.SetOrAddHeaderValue(KnownHeaders.Authorization, auth);

                    // send body for final auth request
                    if (request.OriginalHasBody)
                    {
                        request.ContentLength = request.Body.Length;
                    }

                    args.HttpClient.Connection.IsWinAuthenticated = true;
                }

                // Need to revisit this.
                // Should we cache all Set-Cookie headers from server during auth process
                // and send it to client after auth?

                // Let ResponseHandler send the updated request
                args.ReRequest = true;
            }
        }
コード例 #20
0
 private async void OnSessionManagerSessionStarted(object sender, SessionEventArgs e)
 {
     await SendData(true).ConfigureAwait(false);
 }
コード例 #21
0
 private async void OnSessionManagerCapabilitiesChanged(object sender, SessionEventArgs e)
 {
     await SendData(true).ConfigureAwait(false);
 }
コード例 #22
0
 private async void OnSessionManagerSessionActivity(object sender, SessionEventArgs e)
 {
     await SendData(false).ConfigureAwait(false);
 }
コード例 #23
0
 private void SessionStoppedHandler(object sender, SessionEventArgs e)
 {
     Debug.Log("SessionStoppedHandler called");
     recognizer = null;
 }
コード例 #24
0
ファイル: SessionAdapter.cs プロジェクト: BDizzle/BeepForNet
 public virtual void sessionClosed(SessionEventArgs e)
 {
 }
コード例 #25
0
        //This is called when the request is PUT/POST to read the body
        private static void SendClientRequestBody(SessionEventArgs args)
        {
            // End the operation
            var postStream = args.ProxySession.ProxyClient.Stream;


            if (args.ProxySession.Request.ContentLength > 0)
            {
                //args.ProxyRequest.AllowWriteStreamBuffering = true;
                try
                {
                    var totalbytesRead = 0;

                    int bytesToRead;
                    if (args.ProxySession.Request.ContentLength < BUFFER_SIZE)
                    {
                        bytesToRead = (int)args.ProxySession.Request.ContentLength;
                    }
                    else
                        bytesToRead = BUFFER_SIZE;


                    while (totalbytesRead < (int)args.ProxySession.Request.ContentLength)
                    {
                        var buffer = args.Client.ClientStreamReader.ReadBytes(bytesToRead);
                        totalbytesRead += buffer.Length;

                        var remainingBytes = (int)args.ProxySession.Request.ContentLength - totalbytesRead;
                        if (remainingBytes < bytesToRead)
                        {
                            bytesToRead = remainingBytes;
                        }
                        postStream.Write(buffer, 0, buffer.Length);
                    }
                }
                catch
                {
                    throw;
                }
            }
            //Need to revist, find any potential bugs
            else if (args.ProxySession.Request.SendChunked)
            {
                try
                {
                    while (true)
                    {
                        var chuchkHead = args.Client.ClientStreamReader.ReadLine();
                        var chunkSize = int.Parse(chuchkHead, NumberStyles.HexNumber);

                        if (chunkSize != 0)
                        {
                            var buffer = args.Client.ClientStreamReader.ReadBytes(chunkSize);
                            postStream.Write(buffer, 0, buffer.Length);
                            //chunk trail
                            args.Client.ClientStreamReader.ReadLine();
                        }
                        else
                        {
                            args.Client.ClientStreamReader.ReadLine();

                            break;
                        }
                    }
                }
                catch
                {
                    throw;
                }
            }
        }
コード例 #26
0
        private async Task handleClient(TransparentBaseProxyEndPoint endPoint, TcpClientConnection clientConnection,
                                        int port, CancellationTokenSource cancellationTokenSource, CancellationToken cancellationToken)
        {
            bool isHttps      = false;
            var  clientStream = new HttpClientStream(clientConnection, clientConnection.GetStream(), BufferPool, cancellationToken);

            try
            {
                var clientHelloInfo = await SslTools.PeekClientHello(clientStream, BufferPool, cancellationToken);

                if (clientHelloInfo != null)
                {
                    var httpsHostName = clientHelloInfo.GetServerName() ?? endPoint.GenericCertificateName;

                    var args = new BeforeSslAuthenticateEventArgs(clientConnection, cancellationTokenSource, httpsHostName);

                    await endPoint.InvokeBeforeSslAuthenticate(this, args, ExceptionFunc);

                    if (cancellationTokenSource.IsCancellationRequested)
                    {
                        throw new Exception("Session was terminated by user.");
                    }

                    if (endPoint.DecryptSsl && args.DecryptSsl)
                    {
                        clientStream.Connection.SslProtocol = clientHelloInfo.SslProtocol;

                        // do client authentication using certificate
                        X509Certificate2?certificate = null;
                        SslStream?       sslStream   = null;
                        try
                        {
                            sslStream = new SslStream(clientStream, false);

                            string certName = HttpHelper.GetWildCardDomainName(httpsHostName);
                            certificate = endPoint.GenericCertificate ??
                                          await CertificateManager.CreateServerCertificate(certName);

                            // Successfully managed to authenticate the client using the certificate
                            await sslStream.AuthenticateAsServerAsync(certificate, false, SslProtocols.Tls, false);

                            // HTTPS server created - we can now decrypt the client's traffic
                            clientStream = new HttpClientStream(clientStream.Connection, sslStream, BufferPool, cancellationToken);
                            sslStream    = null; // clientStream was created, no need to keep SSL stream reference
                            isHttps      = true;
                        }
                        catch (Exception e)
                        {
                            sslStream?.Dispose();

                            var certName = certificate?.GetNameInfo(X509NameType.SimpleName, false);
                            var session  = new SessionEventArgs(this, endPoint, clientStream, null, cancellationTokenSource);
                            throw new ProxyConnectException(
                                      $"Couldn't authenticate host '{httpsHostName}' with certificate '{certName}'.", e, session);
                        }
                    }
                    else
                    {
                        var sessionArgs = new SessionEventArgs(this, endPoint, clientStream, null, cancellationTokenSource);
                        var connection  = await tcpConnectionFactory.GetServerConnection(this, httpsHostName, port,
                                                                                         HttpHeader.VersionUnknown, false, null,
                                                                                         true, sessionArgs, UpStreamEndPoint,
                                                                                         UpStreamHttpsProxy, true, cancellationToken);

                        try
                        {
                            int available = clientStream.Available;

                            if (available > 0)
                            {
                                // send the buffered data
                                var data = BufferPool.GetBuffer();
                                try
                                {
                                    // clientStream.Available should be at most BufferSize because it is using the same buffer size
                                    await clientStream.ReadAsync(data, 0, available, cancellationToken);

                                    await connection.Stream.WriteAsync(data, 0, available, true, cancellationToken);
                                }
                                finally
                                {
                                    BufferPool.ReturnBuffer(data);
                                }
                            }

                            if (!clientStream.IsClosed && !connection.Stream.IsClosed)
                            {
                                await TcpHelper.SendRaw(clientStream, connection.Stream, BufferPool,
                                                        null, null, cancellationTokenSource, ExceptionFunc);
                            }
                        }
                        finally
                        {
                            await tcpConnectionFactory.Release(connection, true);
                        }

                        return;
                    }
                }

                // HTTPS server created - we can now decrypt the client's traffic
                // Now create the request
                await handleHttpSessionRequest(endPoint, clientStream, cancellationTokenSource, isHttps : isHttps);
            }
            catch (ProxyException e)
            {
                onException(clientStream, e);
            }
            catch (IOException e)
            {
                onException(clientStream, new Exception("Connection was aborted", e));
            }
            catch (SocketException e)
            {
                onException(clientStream, new Exception("Could not connect", e));
            }
            catch (Exception e)
            {
                onException(clientStream, new Exception("Error occured in whilst handling the client", e));
            }
            finally
            {
                clientStream.Dispose();
            }
        }
コード例 #27
0
 protected void OnStopped(SessionEventArgs e)
 {
     if (Stopped == null)
     {
         return;
     }
     Stopped(this, e);
 }
コード例 #28
0
        /// <summary>
        /// This is the core request handler method for a particular connection from client
        /// Will create new session (request/response) sequence until
        /// client/server abruptly terminates connection or by normal HTTP termination
        /// </summary>
        /// <param name="client"></param>
        /// <param name="httpCmd"></param>
        /// <param name="clientStream"></param>
        /// <param name="clientStreamReader"></param>
        /// <param name="clientStreamWriter"></param>
        /// <param name="httpsConnectHostname"></param>
        /// <param name="endPoint"></param>
        /// <param name="connectRequest"></param>
        /// <param name="isTransparentEndPoint"></param>
        /// <returns></returns>
        private async Task <bool> HandleHttpSessionRequest(TcpClient client, string httpCmd, CustomBufferedStream clientStream,
                                                           CustomBinaryReader clientStreamReader, HttpResponseWriter clientStreamWriter, string httpsConnectHostname,
                                                           ProxyEndPoint endPoint, ConnectRequest connectRequest, bool isTransparentEndPoint = false)
        {
            bool disposed = false;

            TcpConnection connection = null;

            //Loop through each subsequest request on this particular client connection
            //(assuming HTTP connection is kept alive by client)
            while (true)
            {
                if (string.IsNullOrEmpty(httpCmd))
                {
                    break;
                }

                var args = new SessionEventArgs(BufferSize, endPoint, HandleHttpSessionResponse)
                {
                    ProxyClient = { TcpClient = client },
                    WebSession  = { ConnectRequest = connectRequest }
                };

                try
                {
                    string  httpMethod;
                    string  httpUrl;
                    Version version;
                    Request.ParseRequestLine(httpCmd, out httpMethod, out httpUrl, out version);

                    //Read the request headers in to unique and non-unique header collections
                    await HeaderParser.ReadHeaders(clientStreamReader, args.WebSession.Request.Headers);

                    var httpRemoteUri = new Uri(httpsConnectHostname == null
                        ? isTransparentEndPoint ? string.Concat("http://", args.WebSession.Request.Host, httpUrl) : httpUrl
                        : string.Concat("https://", args.WebSession.Request.Host ?? httpsConnectHostname, httpUrl));

                    args.WebSession.Request.RequestUri  = httpRemoteUri;
                    args.WebSession.Request.OriginalUrl = httpUrl;

                    args.WebSession.Request.Method      = httpMethod;
                    args.WebSession.Request.HttpVersion = version;
                    args.ProxyClient.ClientStream       = clientStream;
                    args.ProxyClient.ClientStreamReader = clientStreamReader;
                    args.ProxyClient.ClientStreamWriter = clientStreamWriter;

                    //proxy authorization check
                    if (httpsConnectHostname == null && await CheckAuthorization(clientStreamWriter, args) == false)
                    {
                        args.Dispose();
                        break;
                    }

                    PrepareRequestHeaders(args.WebSession.Request.Headers);
                    args.WebSession.Request.Host = args.WebSession.Request.RequestUri.Authority;

                    //if win auth is enabled
                    //we need a cache of request body
                    //so that we can send it after authentication in WinAuthHandler.cs
                    if (isWindowsAuthenticationEnabledAndSupported && args.WebSession.Request.HasBody)
                    {
                        await args.GetRequestBody();
                    }

                    //If user requested interception do it
                    if (BeforeRequest != null)
                    {
                        await BeforeRequest.InvokeParallelAsync(this, args, ExceptionFunc);
                    }

                    if (args.WebSession.Request.CancelRequest)
                    {
                        args.Dispose();
                        break;
                    }

                    //create a new connection if hostname/upstream end point changes
                    if (connection != null &&
                        (!connection.HostName.Equals(args.WebSession.Request.RequestUri.Host, StringComparison.OrdinalIgnoreCase) ||
                         (args.WebSession.UpStreamEndPoint != null &&
                          !args.WebSession.UpStreamEndPoint.Equals(connection.UpStreamEndPoint))))
                    {
                        connection.Dispose();
                        connection = null;
                        UpdateServerConnectionCount(false);
                    }

                    if (connection == null)
                    {
                        connection = await GetServerConnection(args, false);
                    }

                    //if upgrading to websocket then relay the requet without reading the contents
                    if (args.WebSession.Request.UpgradeToWebSocket)
                    {
                        //prepare the prefix content
                        var    requestHeaders = args.WebSession.Request.Headers;
                        byte[] requestBytes;
                        using (var ms = new MemoryStream())
                            using (var writer = new HttpRequestWriter(ms, BufferSize))
                            {
                                writer.WriteLine(httpCmd);
                                writer.WriteHeaders(requestHeaders);
                                requestBytes = ms.ToArray();
                            }

                        await connection.Stream.WriteAsync(requestBytes, 0, requestBytes.Length);

                        string httpStatus = await connection.StreamReader.ReadLineAsync();

                        Version responseVersion;
                        int     responseStatusCode;
                        string  responseStatusDescription;
                        Response.ParseResponseLine(httpStatus, out responseVersion, out responseStatusCode, out responseStatusDescription);
                        args.WebSession.Response.HttpVersion       = responseVersion;
                        args.WebSession.Response.StatusCode        = responseStatusCode;
                        args.WebSession.Response.StatusDescription = responseStatusDescription;

                        await HeaderParser.ReadHeaders(connection.StreamReader, args.WebSession.Response.Headers);

                        await clientStreamWriter.WriteResponseAsync(args.WebSession.Response);

                        //If user requested call back then do it
                        if (BeforeResponse != null && !args.WebSession.Response.ResponseLocked)
                        {
                            await BeforeResponse.InvokeParallelAsync(this, args, ExceptionFunc);
                        }

                        await TcpHelper.SendRaw(clientStream, connection.Stream, BufferSize,
                                                (buffer, offset, count) => { args.OnDataSent(buffer, offset, count); }, (buffer, offset, count) => { args.OnDataReceived(buffer, offset, count); });

                        args.Dispose();
                        break;
                    }

                    //construct the web request that we are going to issue on behalf of the client.
                    disposed = await HandleHttpSessionRequestInternal(connection, args, false);

                    if (disposed)
                    {
                        //already disposed inside above method
                        args.Dispose();
                        break;
                    }

                    //if connection is closing exit
                    if (args.WebSession.Response.KeepAlive == false)
                    {
                        args.Dispose();
                        break;
                    }

                    args.Dispose();

                    // read the next request
                    httpCmd = await clientStreamReader.ReadLineAsync();
                }
                catch (Exception e)
                {
                    ExceptionFunc(new ProxyHttpException("Error occured whilst handling session request", e, args));
                    break;
                }
            }

            if (!disposed)
            {
                Dispose(clientStream, clientStreamReader, clientStreamWriter, connection);
            }

            return(true);
        }
コード例 #29
0
 private void OnSessionEndOfTrack(object sender, SessionEventArgs e)
 {
     if (Playlist.CanGoNext)
     {
         Playlist.Next();
     }
 }
コード例 #30
0
        /// <summary>
        /// Handle a specific session (request/response sequence)
        /// </summary>
        /// <param name="connection"></param>
        /// <param name="args"></param>
        /// <param name="closeConnection"></param>
        /// <returns></returns>
        private async Task <bool> HandleHttpSessionRequestInternal(TcpConnection connection, SessionEventArgs args, bool closeConnection)
        {
            bool disposed  = false;
            bool keepAlive = false;

            try
            {
                args.WebSession.Request.RequestLocked = true;

                //if expect continue is enabled then send the headers first
                //and see if server would return 100 conitinue
                if (args.WebSession.Request.ExpectContinue)
                {
                    args.WebSession.SetConnection(connection);
                    await args.WebSession.SendRequest(Enable100ContinueBehaviour);
                }

                //If 100 continue was the response inform that to the client
                if (Enable100ContinueBehaviour)
                {
                    if (args.WebSession.Request.Is100Continue)
                    {
                        await args.ProxyClient.ClientStreamWriter.WriteResponseStatusAsync(args.WebSession.Response.HttpVersion, (int)HttpStatusCode.Continue, "Continue");

                        await args.ProxyClient.ClientStreamWriter.WriteLineAsync();
                    }
                    else if (args.WebSession.Request.ExpectationFailed)
                    {
                        await args.ProxyClient.ClientStreamWriter.WriteResponseStatusAsync(args.WebSession.Response.HttpVersion, (int)HttpStatusCode.ExpectationFailed, "Expectation Failed");

                        await args.ProxyClient.ClientStreamWriter.WriteLineAsync();
                    }
                }

                //If expect continue is not enabled then set the connectio and send request headers
                if (!args.WebSession.Request.ExpectContinue)
                {
                    args.WebSession.SetConnection(connection);
                    await args.WebSession.SendRequest(Enable100ContinueBehaviour);
                }

                //check if content-length is > 0
                if (args.WebSession.Request.ContentLength > 0)
                {
                    //If request was modified by user
                    if (args.WebSession.Request.IsBodyRead)
                    {
                        if (args.WebSession.Request.ContentEncoding != null)
                        {
                            args.WebSession.Request.Body =
                                await GetCompressedResponseBody(args.WebSession.Request.ContentEncoding, args.WebSession.Request.Body);
                        }

                        var body = args.WebSession.Request.Body;

                        //chunked send is not supported as of now
                        args.WebSession.Request.ContentLength = body.Length;

                        var newStream = args.WebSession.ServerConnection.Stream;
                        await newStream.WriteAsync(body, 0, body.Length);
                    }
                    else
                    {
                        if (!args.WebSession.Request.ExpectationFailed)
                        {
                            //If its a post/put/patch request, then read the client html body and send it to server
                            if (args.WebSession.Request.HasBody)
                            {
                                await SendClientRequestBody(args);
                            }
                        }
                    }
                }

                //If not expectation failed response was returned by server then parse response
                if (!args.WebSession.Request.ExpectationFailed)
                {
                    disposed = await HandleHttpSessionResponse(args);

                    //already disposed inside above method
                    if (disposed)
                    {
                        return(true);
                    }
                }

                //if connection is closing exit
                if (args.WebSession.Response.KeepAlive == false)
                {
                    return(true);
                }

                if (!closeConnection)
                {
                    keepAlive = true;
                    return(false);
                }
            }
            catch (Exception e)
            {
                ExceptionFunc(new ProxyHttpException("Error occured whilst handling session request (internal)", e, args));
                return(true);
            }
            finally
            {
                if (!disposed && !keepAlive)
                {
                    //dispose
                    Dispose(args.ProxyClient.ClientStream, args.ProxyClient.ClientStreamReader, args.ProxyClient.ClientStreamWriter,
                            args.WebSession.ServerConnection);
                }
            }

            return(true);
        }
コード例 #31
0
ファイル: HttpProxy.cs プロジェクト: dice7326/SteamTools
        public async Task OnResponse(object sender, SessionEventArgs e)
        {
#if DEBUG
            Debug.WriteLine("OnResponse" + e.HttpClient.Request.RequestUri.AbsoluteUri);
            Logger.Info("OnResponse" + e.HttpClient.Request.RequestUri.AbsoluteUri);
#endif
            if (IsEnableScript)
            {
                if (IsOnlyWorkSteamBrowser)
                {
                    var ua = e.HttpClient.Request.Headers.GetHeaders("User-Agent");
                    if (ua.Any())
                    {
                        if (!ua.First().Value.Contains("Valve Steam"))
                        {
                            return;
                        }
                    }
                    else
                    {
                        return;
                    }
                }
                foreach (var script in Scripts)
                {
                    if (script.Enable)
                    {
                        if (e.HttpClient.Request.Method == "GET")
                        {
                            if (e.HttpClient.Response.StatusCode == 200)
                            {
                                if (e.HttpClient.Response.ContentType != null && e.HttpClient.Response.ContentType.Trim().ToLower().Contains("text/html"))
                                {
                                    foreach (var host in script.Exclude)
                                    {
                                        if (e.HttpClient.Request.RequestUri.AbsoluteUri.IsWildcard(host))
                                        {
                                            goto close;
                                        }
                                    }
                                    foreach (var host in script.Match)
                                    {
                                        if (e.HttpClient.Request.RequestUri.AbsoluteUri.IsWildcard(host))
                                        {
                                            var doc = await e.GetResponseBodyAsString();

                                            if (script.Require.Length > 0)
                                            {
                                                //var headIndex = doc.LastIndexOf("</head>", StringComparison.OrdinalIgnoreCase);
                                                //doc = doc.Insert(headIndex, "<meta http-equiv=\"Content-Security-Policy\" content=\"default - src 'self' data: gap: https://ssl.gstatic.com 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *\">");
                                                var t = e.HttpClient.Response.Headers.GetFirstHeader("Content-Security-Policy");
                                                if (!string.IsNullOrEmpty(t.Value))
                                                {
                                                    //var tt = t.Value.Split(';');
                                                    //for (var i = 0; i < tt.Length; i++)
                                                    //{
                                                    //    if (tt[i].Contains("script-src"))
                                                    //    {
                                                    //        var cc = tt[i].Split(' ').ToList();
                                                    //        foreach (var req in script.Require)
                                                    //        {
                                                    //            var u = new Uri(req);
                                                    //            cc.Add($"{u.Scheme}://{u.Host}/");
                                                    //        }
                                                    //        tt[i] = string.Join(" ", cc);
                                                    //    }
                                                    //}
                                                    //var result = string.Join(";", tt);
                                                    e.HttpClient.Response.Headers.RemoveHeader(t);
                                                    //e.HttpClient.Response.Headers.AddHeader("Content-Security-Policy", result);
                                                }
#if DEBUG
                                                Debug.WriteLine(e.HttpClient.Request.RequestUri.AbsoluteUri);
#endif
                                                foreach (var req in script.Require)
                                                {
                                                    var headIndex = doc.LastIndexOf("</head>", StringComparison.OrdinalIgnoreCase);
                                                    //<script type="text/javascript" src=""></script>
                                                    //var result = await httpServices.Get(req);
                                                    var temp1 = $"<script type=\"text/javascript\" src=\"{req}\"></script>\n";
                                                    doc = doc.Insert(headIndex, temp1);
                                                }
                                            }
                                            var index = doc.LastIndexOf("</body>", StringComparison.OrdinalIgnoreCase);
                                            var temp  = $"<script type=\"text/javascript\">{script.@Content}</script>";
                                            doc = doc.Insert(index, temp);
                                            e.SetResponseBodyString(doc);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    close :;
                }
            }
        }
コード例 #32
0
        /// <summary>
        /// Session started event handler.
        /// </summary>
        private void SessionStartedEventHandler(SessionEventArgs e, RecoType rt)
        {
            var log = (rt == RecoType.Base) ? this.baseModelLogText : this.customModelLogText;

            this.WriteLine(log, String.Format(CultureInfo.InvariantCulture, "Speech recognition: Session started event: {0}.", e.ToString()));
        }
コード例 #33
0
 private void SessionStartedHandler(object sender, SessionEventArgs e)
 {
     Debug.Log("SessionStartedHandler called");
 }
コード例 #34
0
        /// <summary>
        /// This is the core request handler method for a particular connection from client
        /// Will create new session (request/response) sequence until
        /// client/server abruptly terminates connection or by normal HTTP termination
        /// </summary>
        /// <param name="client"></param>
        /// <param name="clientStream"></param>
        /// <param name="clientStreamReader"></param>
        /// <param name="clientStreamWriter"></param>
        /// <param name="httpsConnectHostname"></param>
        /// <param name="endPoint"></param>
        /// <param name="connectRequest"></param>
        /// <param name="isTransparentEndPoint"></param>
        /// <returns></returns>
        private async Task HandleHttpSessionRequest(TcpClient client, CustomBufferedStream clientStream,
                                                    CustomBinaryReader clientStreamReader, HttpResponseWriter clientStreamWriter, string httpsConnectHostname,
                                                    ProxyEndPoint endPoint, ConnectRequest connectRequest, bool isTransparentEndPoint = false)
        {
            TcpConnection connection = null;

            try
            {
                //Loop through each subsequest request on this particular client connection
                //(assuming HTTP connection is kept alive by client)
                while (true)
                {
                    // read the request line
                    string httpCmd = await clientStreamReader.ReadLineAsync();

                    if (string.IsNullOrEmpty(httpCmd))
                    {
                        break;
                    }

                    var args = new SessionEventArgs(BufferSize, endPoint, ExceptionFunc)
                    {
                        ProxyClient = { TcpClient = client },
                        WebSession  = { ConnectRequest = connectRequest }
                    };

                    try
                    {
                        Request.ParseRequestLine(httpCmd, out string httpMethod, out string httpUrl, out var version);

                        //Read the request headers in to unique and non-unique header collections
                        await HeaderParser.ReadHeaders(clientStreamReader, args.WebSession.Request.Headers);

                        Uri httpRemoteUri;
                        if (uriSchemeRegex.IsMatch(httpUrl))
                        {
                            try
                            {
                                httpRemoteUri = new Uri(httpUrl);
                            }
                            catch (Exception ex)
                            {
                                throw new Exception($"Invalid URI: '{httpUrl}'", ex);
                            }
                        }
                        else
                        {
                            string host        = args.WebSession.Request.Host ?? httpsConnectHostname;
                            string hostAndPath = host;
                            if (httpUrl.StartsWith("/"))
                            {
                                hostAndPath += httpUrl;
                            }

                            string url = string.Concat(httpsConnectHostname == null ? "http://" : "https://", hostAndPath);
                            try
                            {
                                httpRemoteUri = new Uri(url);
                            }
                            catch (Exception ex)
                            {
                                throw new Exception($"Invalid URI: '{url}'", ex);
                            }
                        }

                        args.WebSession.Request.RequestUri  = httpRemoteUri;
                        args.WebSession.Request.OriginalUrl = httpUrl;

                        args.WebSession.Request.Method      = httpMethod;
                        args.WebSession.Request.HttpVersion = version;
                        args.ProxyClient.ClientStream       = clientStream;
                        args.ProxyClient.ClientStreamReader = clientStreamReader;
                        args.ProxyClient.ClientStreamWriter = clientStreamWriter;

                        //proxy authorization check
                        if (!args.IsTransparent && httpsConnectHostname == null && await CheckAuthorization(clientStreamWriter, args) == false)
                        {
                            break;
                        }

                        if (!isTransparentEndPoint)
                        {
                            PrepareRequestHeaders(args.WebSession.Request.Headers);
                            args.WebSession.Request.Host = args.WebSession.Request.RequestUri.Authority;
                        }

                        //if win auth is enabled
                        //we need a cache of request body
                        //so that we can send it after authentication in WinAuthHandler.cs
                        if (isWindowsAuthenticationEnabledAndSupported && args.WebSession.Request.HasBody)
                        {
                            await args.GetRequestBody();
                        }

                        //If user requested interception do it
                        if (BeforeRequest != null)
                        {
                            await BeforeRequest.InvokeAsync(this, args, ExceptionFunc);
                        }

                        var response = args.WebSession.Response;

                        if (args.WebSession.Request.CancelRequest)
                        {
                            await HandleHttpSessionResponse(args);

                            if (!response.KeepAlive)
                            {
                                break;
                            }

                            continue;
                        }

                        //create a new connection if hostname/upstream end point changes
                        if (connection != null &&
                            (!connection.HostName.Equals(args.WebSession.Request.RequestUri.Host, StringComparison.OrdinalIgnoreCase) ||
                             (args.WebSession.UpStreamEndPoint != null &&
                              !args.WebSession.UpStreamEndPoint.Equals(connection.UpStreamEndPoint))))
                        {
                            connection.Dispose();
                            connection = null;
                        }

                        if (connection == null)
                        {
                            connection = await GetServerConnection(args, false);
                        }

                        //if upgrading to websocket then relay the requet without reading the contents
                        if (args.WebSession.Request.UpgradeToWebSocket)
                        {
                            //prepare the prefix content
                            var requestHeaders = args.WebSession.Request.Headers;
                            await connection.StreamWriter.WriteLineAsync(httpCmd);

                            await connection.StreamWriter.WriteHeadersAsync(requestHeaders);

                            string httpStatus = await connection.StreamReader.ReadLineAsync();

                            Response.ParseResponseLine(httpStatus, out var responseVersion, out int responseStatusCode, out string responseStatusDescription);
                            response.HttpVersion       = responseVersion;
                            response.StatusCode        = responseStatusCode;
                            response.StatusDescription = responseStatusDescription;

                            await HeaderParser.ReadHeaders(connection.StreamReader, response.Headers);

                            if (!args.IsTransparent)
                            {
                                await clientStreamWriter.WriteResponseAsync(response);
                            }

                            //If user requested call back then do it
                            if (BeforeResponse != null && !args.WebSession.Response.ResponseLocked)
                            {
                                await BeforeResponse.InvokeAsync(this, args, ExceptionFunc);
                            }

                            await TcpHelper.SendRaw(clientStream, connection.Stream, BufferSize,
                                                    (buffer, offset, count) => { args.OnDataSent(buffer, offset, count); },
                                                    (buffer, offset, count) => { args.OnDataReceived(buffer, offset, count); },
                                                    ExceptionFunc);

                            break;
                        }

                        //construct the web request that we are going to issue on behalf of the client.
                        await HandleHttpSessionRequestInternal(connection, args);

                        //if connection is closing exit
                        if (!response.KeepAlive)
                        {
                            break;
                        }
                    }
                    catch (Exception e) when(!(e is ProxyHttpException))
                    {
                        throw new ProxyHttpException("Error occured whilst handling session request", e, args);
                    }
                    finally
                    {
                        args.Dispose();
                    }
                }
            }
            finally
            {
                connection?.Dispose();
            }
        }
コード例 #35
0
ファイル: ClientSocket.cs プロジェクト: robert0609/BlueFox
 private void session_SessionException(object sender, SessionEventArgs e)
 {
     this.OnSessionException(e.Session, e.SessionException);
 }
コード例 #36
0
        /// <summary>
        /// Handle a specific session (request/response sequence)
        /// </summary>
        /// <param name="connection"></param>
        /// <param name="args"></param>
        /// <returns>True if close the connection</returns>
        private async Task HandleHttpSessionRequestInternal(TcpConnection connection, SessionEventArgs args)
        {
            try
            {
                var request = args.WebSession.Request;
                request.RequestLocked = true;

                //if expect continue is enabled then send the headers first
                //and see if server would return 100 conitinue
                if (request.ExpectContinue)
                {
                    args.WebSession.SetConnection(connection);
                    await args.WebSession.SendRequest(Enable100ContinueBehaviour, args.IsTransparent);
                }

                //If 100 continue was the response inform that to the client
                if (Enable100ContinueBehaviour)
                {
                    var clientStreamWriter = args.ProxyClient.ClientStreamWriter;

                    if (request.Is100Continue)
                    {
                        await clientStreamWriter.WriteResponseStatusAsync(args.WebSession.Response.HttpVersion, (int)HttpStatusCode.Continue, "Continue");

                        await clientStreamWriter.WriteLineAsync();
                    }
                    else if (request.ExpectationFailed)
                    {
                        await clientStreamWriter.WriteResponseStatusAsync(args.WebSession.Response.HttpVersion, (int)HttpStatusCode.ExpectationFailed, "Expectation Failed");

                        await clientStreamWriter.WriteLineAsync();
                    }
                }

                //If expect continue is not enabled then set the connectio and send request headers
                if (!request.ExpectContinue)
                {
                    args.WebSession.SetConnection(connection);
                    await args.WebSession.SendRequest(Enable100ContinueBehaviour, args.IsTransparent);
                }

                //check if content-length is > 0
                if (request.ContentLength > 0)
                {
                    //If request was modified by user
                    if (request.IsBodyRead)
                    {
                        if (request.ContentEncoding != null)
                        {
                            request.Body = await GetCompressedResponseBody(request.ContentEncoding, request.Body);
                        }

                        var body = request.Body;

                        //chunked send is not supported as of now
                        request.ContentLength = body.Length;

                        await args.WebSession.ServerConnection.StreamWriter.WriteAsync(body);
                    }
                    else
                    {
                        if (!request.ExpectationFailed)
                        {
                            //If its a post/put/patch request, then read the client html body and send it to server
                            if (request.HasBody)
                            {
                                HttpWriter writer = args.WebSession.ServerConnection.StreamWriter;
                                await args.CopyRequestBodyAsync(writer, false);
                            }
                        }
                    }
                }

                //If not expectation failed response was returned by server then parse response
                if (!request.ExpectationFailed)
                {
                    await HandleHttpSessionResponse(args);
                }
            }
            catch (Exception e) when(!(e is ProxyHttpException))
            {
                throw new ProxyHttpException("Error occured whilst handling session request (internal)", e, args);
            }
        }
コード例 #37
0
 void session_StreamingError(ISession sender, SessionEventArgs e)
 {
     this.ParentForm.BeginInvoke(new MethodInvoker(delegate()
         {
             WriteError(e.Message);
             CF_displayMessage("Streaming Error:" + Environment.NewLine + e.Message);
         }));
 }
コード例 #38
0
ファイル: ResponseHandler.cs プロジェクト: benyamns/kaan277
        /// <summary>
        ///     Called asynchronously when a request was successful and we received the response.
        /// </summary>
        /// <param name="args">The session event arguments.</param>
        /// <returns> The task.</returns>
        private async Task handleHttpSessionResponse(SessionEventArgs args)
        {
            var cancellationToken = args.CancellationTokenSource.Token;

            // read response & headers from server
            await args.HttpClient.ReceiveResponse(cancellationToken);

            // Server may send expect-continue even if not asked for it in request.
            // According to spec "the client can simply discard this interim response."
            if (args.HttpClient.Response.StatusCode == (int)HttpStatusCode.Continue)
            {
                await args.ClearResponse(cancellationToken);

                await args.HttpClient.ReceiveResponse(cancellationToken);
            }

            args.TimeLine["Response Received"] = DateTime.UtcNow;

            var response = args.HttpClient.Response;

            args.ReRequest = false;

            // check for windows authentication
            if (args.EnableWinAuth)
            {
                if (response.StatusCode == (int)HttpStatusCode.Unauthorized)
                {
                    await handle401UnAuthorized(args);
                }
                else
                {
                    WinAuthEndPoint.AuthenticatedResponse(args.HttpClient.Data);
                }
            }

            // save original values so that if user changes them
            // we can still use original values when syphoning out data from attached tcp connection.
            response.SetOriginalHeaders();

            // if user requested call back then do it
            if (!response.Locked)
            {
                await onBeforeResponse(args);
            }

            // it may changed in the user event
            response = args.HttpClient.Response;

            var clientStream = args.ClientStream;

            // user set custom response by ignoring original response from server.
            if (response.Locked)
            {
                // write custom user response with body and return.
                await clientStream.WriteResponseAsync(response, cancellationToken);

                if (args.HttpClient.HasConnection && !args.HttpClient.CloseServerConnection)
                {
                    // syphon out the original response body from server connection
                    // so that connection will be good to be reused.
                    await args.SyphonOutBodyAsync(false, cancellationToken);
                }

                return;
            }

            // if user requested to send request again
            // likely after making modifications from User Response Handler
            if (args.ReRequest)
            {
                if (args.HttpClient.HasConnection)
                {
                    await tcpConnectionFactory.Release(args.HttpClient.Connection);
                }

                // clear current response
                await args.ClearResponse(cancellationToken);
                await handleHttpSessionRequest(args, null, args.ClientConnection.NegotiatedApplicationProtocol,
                                               cancellationToken, args.CancellationTokenSource);

                return;
            }

            response.Locked = true;

            if (!args.IsTransparent && !args.IsSocks)
            {
                response.Headers.FixProxyHeaders();
            }

            await clientStream.WriteResponseAsync(response, cancellationToken);

            if (response.OriginalHasBody)
            {
                if (response.IsBodySent)
                {
                    // syphon out body
                    await args.SyphonOutBodyAsync(false, cancellationToken);
                }
                else
                {
                    // Copy body if exists
                    var serverStream = args.HttpClient.Connection.Stream;
                    await serverStream.CopyBodyAsync(response, false, clientStream, TransformationMode.None,
                                                     args.OnDataReceived, cancellationToken);
                }
            }

            args.TimeLine["Response Sent"] = DateTime.UtcNow;
        }
コード例 #39
0
ファイル: SessionAdapter.cs プロジェクト: BDizzle/BeepForNet
 public virtual void greetingReceived(SessionEventArgs e)
 {
 }
コード例 #40
0
        /// <summary>
        /// Handle windows NTLM authentication
        /// Can expand this for Kerberos in future
        /// Note: NTLM/Kerberos cannot do a man in middle operation
        /// we do for HTTPS requests.
        /// As such we will be sending local credentials of current
        /// User to server to authenticate requests.
        /// To disable this set ProxyServer.EnableWinAuth to false
        /// </summary>
        internal async Task <bool> Handle401UnAuthorized(SessionEventArgs args)
        {
            string     headerName = null;
            HttpHeader authHeader = null;

            //check in non-unique headers first
            var header =
                args.WebSession.Response.Headers.NonUniqueHeaders.FirstOrDefault(
                    x => authHeaderNames.Any(y => x.Key.Equals(y, StringComparison.OrdinalIgnoreCase)));

            if (!header.Equals(new KeyValuePair <string, List <HttpHeader> >()))
            {
                headerName = header.Key;
            }

            if (headerName != null)
            {
                authHeader = args.WebSession.Response.Headers.NonUniqueHeaders[headerName]
                             .FirstOrDefault(x => authSchemes.Any(y => x.Value.StartsWith(y, StringComparison.OrdinalIgnoreCase)));
            }

            //check in unique headers
            if (authHeader == null)
            {
                //check in non-unique headers first
                var uHeader =
                    args.WebSession.Response.Headers.Headers.FirstOrDefault(x => authHeaderNames.Any(y => x.Key.Equals(y, StringComparison.OrdinalIgnoreCase)));

                if (!uHeader.Equals(new KeyValuePair <string, HttpHeader>()))
                {
                    headerName = uHeader.Key;
                }

                if (headerName != null)
                {
                    authHeader = authSchemes.Any(x => args.WebSession.Response.Headers.Headers[headerName].Value
                                                 .StartsWith(x, StringComparison.OrdinalIgnoreCase))
                        ? args.WebSession.Response.Headers.Headers[headerName]
                        : null;
                }
            }

            if (authHeader != null)
            {
                string scheme = authSchemes.FirstOrDefault(x => authHeader.Value.Equals(x, StringComparison.OrdinalIgnoreCase));

                //clear any existing headers to avoid confusing bad servers
                if (args.WebSession.Request.Headers.NonUniqueHeaders.ContainsKey("Authorization"))
                {
                    args.WebSession.Request.Headers.NonUniqueHeaders.Remove("Authorization");
                }

                //initial value will match exactly any of the schemes
                if (scheme != null)
                {
                    string clientToken = WinAuthHandler.GetInitialAuthToken(args.WebSession.Request.Host, scheme, args.Id);

                    var auth = new HttpHeader("Authorization", string.Concat(scheme, clientToken));

                    //replace existing authorization header if any
                    if (args.WebSession.Request.Headers.Headers.ContainsKey("Authorization"))
                    {
                        args.WebSession.Request.Headers.Headers["Authorization"] = auth;
                    }
                    else
                    {
                        args.WebSession.Request.Headers.Headers.Add("Authorization", auth);
                    }

                    //don't need to send body for Authorization request
                    if (args.WebSession.Request.HasBody)
                    {
                        args.WebSession.Request.ContentLength = 0;
                    }
                }
                //challenge value will start with any of the scheme selected
                else
                {
                    scheme = authSchemes.FirstOrDefault(x => authHeader.Value.StartsWith(x, StringComparison.OrdinalIgnoreCase) &&
                                                        authHeader.Value.Length > x.Length + 1);

                    string serverToken = authHeader.Value.Substring(scheme.Length + 1);
                    string clientToken = WinAuthHandler.GetFinalAuthToken(args.WebSession.Request.Host, serverToken, args.Id);

                    //there will be an existing header from initial client request
                    args.WebSession.Request.Headers.Headers["Authorization"] = new HttpHeader("Authorization", string.Concat(scheme, clientToken));

                    //send body for final auth request
                    if (args.WebSession.Request.HasBody)
                    {
                        args.WebSession.Request.ContentLength = args.WebSession.Request.Body.Length;
                    }
                }

                //Need to revisit this.
                //Should we cache all Set-Cokiee headers from server during auth process
                //and send it to client after auth?

                //clear current server response
                await args.ClearResponse();

                //request again with updated authorization header
                //and server cookies
                bool disposed = await HandleHttpSessionRequestInternal(args.WebSession.ServerConnection, args, false);

                return(disposed);
            }

            return(false);
        }
コード例 #41
0
        private static void HandleHttpSessionRequest(TcpClient client, string httpCmd, Stream clientStream,
            CustomBinaryReader clientStreamReader, StreamWriter clientStreamWriter, string secureTunnelHostName)
        {
            TcpConnection connection = null;
            string lastRequestHostName = null;

            while (true)
            {
                if (string.IsNullOrEmpty(httpCmd))
                {
                    Dispose(client, clientStream, clientStreamReader, clientStreamWriter, null);
                    break;
                }

                var args = new SessionEventArgs(BUFFER_SIZE);
                args.Client.TcpClient = client;

                try
                {
                    //break up the line into three components (method, remote URL & Http Version)
                    var httpCmdSplit = httpCmd.Split(SpaceSplit, 3);

                    var httpMethod = httpCmdSplit[0];
                    var httpRemoteUri =
                        new Uri(secureTunnelHostName == null ? httpCmdSplit[1] : (secureTunnelHostName + httpCmdSplit[1]));
                    var httpVersion = httpCmdSplit[2];

                    Version version;
                    if (httpVersion == "HTTP/1.1")
                    {
                        version = new Version(1, 1);
                    }
                    else
                    {
                        version = new Version(1, 0);
                    }

                    if (httpRemoteUri.Scheme == Uri.UriSchemeHttps)
                    {
                        args.IsHttps = true;
                    }


                    args.ProxySession.Request.RequestHeaders = new List<HttpHeader>();

                    string tmpLine;
                    while (!string.IsNullOrEmpty(tmpLine = clientStreamReader.ReadLine()))
                    {
                        var header = tmpLine.Split(new char[] { ':' }, 2);
                        args.ProxySession.Request.RequestHeaders.Add(new HttpHeader(header[0], header[1]));
                    }

                    SetRequestHeaders(args.ProxySession.Request.RequestHeaders, args.ProxySession);

                    if (args.ProxySession.Request.UpgradeToWebSocket)
                    {
                        TcpHelper.SendRaw(clientStreamReader.BaseStream, httpCmd, args.ProxySession.Request.RequestHeaders,
                                httpRemoteUri.Host, httpRemoteUri.Port, httpRemoteUri.Scheme == Uri.UriSchemeHttps);
                        Dispose(client, clientStream, clientStreamReader, clientStreamWriter, args);
                        return;
                    }

                    args.ProxySession.Request.RequestUri = httpRemoteUri;

                    args.ProxySession.Request.Method = httpMethod;
                    args.ProxySession.Request.HttpVersion = httpVersion;
                    args.Client.ClientStream = clientStream;
                    args.Client.ClientStreamReader = clientStreamReader;
                    args.Client.ClientStreamWriter = clientStreamWriter;
                    args.ProxySession.Request.Hostname = args.ProxySession.Request.RequestUri.Host;
                    args.ProxySession.Request.Url = args.ProxySession.Request.RequestUri.OriginalString;
                    args.Client.ClientPort = ((IPEndPoint)client.Client.RemoteEndPoint).Port;
                    args.Client.ClientIpAddress = ((IPEndPoint)client.Client.RemoteEndPoint).Address;


                    //If requested interception
                    if (BeforeRequest != null)
                    {
                        args.ProxySession.Request.Encoding = args.ProxySession.GetEncoding();
                        BeforeRequest(null, args);
                    }

                    args.ProxySession.Request.RequestLocked = true;

                    if (args.ProxySession.Request.CancelRequest)
                    {
                        Dispose(client, clientStream, clientStreamReader, clientStreamWriter, args);
                        break;
                    }


                    //construct the web request that we are going to issue on behalf of the client.
                    connection = connection == null ?
                        TcpConnectionManager.GetClient(args.ProxySession.Request.RequestUri.Host, args.ProxySession.Request.RequestUri.Port, args.IsHttps)
                        : lastRequestHostName != args.ProxySession.Request.Hostname ? TcpConnectionManager.GetClient(args.ProxySession.Request.RequestUri.Host, args.ProxySession.Request.RequestUri.Port, args.IsHttps)
                            : connection;

                    lastRequestHostName = args.ProxySession.Request.Hostname;

                    args.ProxySession.SetConnection(connection);
                    args.ProxySession.SendRequest();

                    //If request was modified by user
                    if (args.ProxySession.Request.RequestBodyRead)
                    {
                        args.ProxySession.Request.ContentLength = args.ProxySession.Request.RequestBody.Length;
                        var newStream = args.ProxySession.ProxyClient.ServerStreamReader.BaseStream;
                        newStream.Write(args.ProxySession.Request.RequestBody, 0, args.ProxySession.Request.RequestBody.Length);
                    }
                    else
                    {
                        //If its a post/put request, then read the client html body and send it to server
                        if (httpMethod.ToUpper() == "POST" || httpMethod.ToUpper() == "PUT")
                        {
                            SendClientRequestBody(args);
                        }
                    }

                    HandleHttpSessionResponse(args);

                    //if connection is closing exit
                    if (args.ProxySession.Response.ResponseKeepAlive == false)
                    {
                        connection.TcpClient.Close();
                        Dispose(client, clientStream, clientStreamReader, clientStreamWriter, args);
                        return;
                    }

                    // read the next request 
                    httpCmd = clientStreamReader.ReadLine();

                }
                catch
                {
                    Dispose(client, clientStream, clientStreamReader, clientStreamWriter, args);
                    break;
                }
   
            }

            if (connection != null)
                TcpConnectionManager.ReleaseClient(connection);
        }
コード例 #42
0
        //Test script injection
        //Insert script to read the Browser URL and send it back to proxy
        public void OnResponse(object sender, SessionEventArgs e)
        {
            try
            {
                if (e.ProxyRequest.Method == "GET" || e.ProxyRequest.Method == "POST")
                {
                    if (e.ServerResponse.StatusCode == HttpStatusCode.OK)
                    {
                        if (e.ServerResponse.ContentType.Trim().ToLower().Contains("text/html"))
                        {
                            string c = e.ServerResponse.GetResponseHeader("X-Requested-With");
                            if (e.ServerResponse.GetResponseHeader("X-Requested-With") == "")
                            {
                                e.GetResponseBody();

                                string functioname = "fr" + RandomString(10);
                                string VisitedURL  = RandomString(5);

                                string RequestVariable   = "c" + RandomString(5);
                                string RandomURLEnding   = RandomString(25);
                                string RandomLastRequest = RandomString(10);
                                string LocalRequest;

                                if (e.IsSecure)
                                {
                                    LocalRequest = "https://" + e.Hostname + "/" + RandomURLEnding;
                                }
                                else
                                {
                                    LocalRequest = "http://" + e.Hostname + "/" + RandomURLEnding;
                                }

                                string script = "var " + RandomLastRequest + " = null;" +
                                                "if(window.top==self) { " + "\n" +
                                                " " + functioname + "();" +
                                                "setInterval(" + functioname + ",500); " + "\n" + "}" +
                                                "function " + functioname + "(){ " + "\n" +
                                                "var " + RequestVariable + " = new XMLHttpRequest(); " + "\n" +
                                                "var " + VisitedURL + " = null;" + "\n" +
                                                "if(window.top.location.href!=null) " + "\n" +
                                                "" + VisitedURL + " = window.top.location.href; else " + "\n" +
                                                "" + VisitedURL + " = document.referrer; " +
                                                "if(" + RandomLastRequest + "!= " + VisitedURL + ") {" +
                                                RequestVariable + ".open(\"POST\",\"" + LocalRequest + "\", true); " + "\n" +
                                                RequestVariable + ".send(" + VisitedURL + ");} " + RandomLastRequest + " = " + VisitedURL + "}";

                                string response = e.ResponseString;
                                Regex  RE       = new Regex("</body>", RegexOptions.RightToLeft | RegexOptions.IgnoreCase | RegexOptions.Multiline);

                                string replaced = RE.Replace(response, "<script type =\"text/javascript\">" + script + "</script></body>", 1);
                                if (replaced.Length != response.Length)
                                {
                                    e.ResponseString = replaced;
                                    _URLList.Add(RandomURLEnding);
                                }
                            }
                        }
                    }
                }
            }
            catch { }
        }
コード例 #43
0
 protected void OnExpired(SessionEventArgs e)
 {
     if (Expired == null)
     {
         return;
     }
     Expired(this, e);
 }
コード例 #44
0
 private static async Task OnResponseCaptureTrafficEventHandler(object sender, SessionEventArgs e) => await Task.Run(
     () =>
 {
     if (!_responsesHistory.ContainsKey(e.HttpClient.Response.GetHashCode()) && e.HttpClient.Response != null)
     {
         _responsesHistory.Add(e.HttpClient.Response.GetHashCode(), e.HttpClient.Response);
     }
 });
コード例 #45
0
        protected virtual void OnStopped(ISession session)
        {
            AfterChanged(session);

            var e = new SessionEventArgs(new ImmutableProxiedSession(session));
            OnStopped(e);
        }
コード例 #46
0
 void _sessionManager_SessionActivity(object sender, SessionEventArgs e)
 {
     SendData(false);
 }
コード例 #47
0
ファイル: Program.cs プロジェクト: kms/torshify
 private void ConnectionError(object sender, SessionEventArgs e)
 {
     if (e.Status != Error.OK)
     {
         ConsoleEx.WriteLine("Connection error: " + e.Message, ConsoleColor.Red);
     }
 }
コード例 #48
0
 void _sessionManager_CapabilitiesChanged(object sender, SessionEventArgs e)
 {
     SendData(true);
 }
コード例 #49
0
ファイル: Program.cs プロジェクト: kms/torshify
 private void UserLoggedOut(object sender, SessionEventArgs e)
 {
     ConsoleEx.WriteLine("Logged out..", ConsoleColor.Yellow);
 }
コード例 #50
0
 /// <summary>
 /// Invocator for BeforeRequest event.
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 protected virtual void OnBeforeRequest(object sender, SessionEventArgs e)
 {
     BeforeRequest?.Invoke(sender, e);
 }
コード例 #51
0
        private void OnSessionPlayerTokenLost(object sender, SessionEventArgs e)
        {
            Pause();

            _eventAggregator
                .GetEvent<NotificationEvent>()
                .Publish(new NotificationMessage("torshify has been paused because your account is used somewhere else"));
        }
コード例 #52
0
ファイル: Program.cs プロジェクト: zerox981/SmtpServer
        static void OnSessionCompleted(object sender, SessionEventArgs e)
        {
            Console.WriteLine("SessionCompleted: {0}", e.Context.Properties[EndpointListener.RemoteEndPointKey]);

            e.Context.CommandExecuting -= OnCommandExecuting;
        }
コード例 #53
0
 void session_ConnectionError(ISession sender, SessionEventArgs e)
 {
 }
コード例 #54
0
        /// <summary>
        ///     This is the core request handler method for a particular connection from client.
        ///     Will create new session (request/response) sequence until
        ///     client/server abruptly terminates connection or by normal HTTP termination.
        /// </summary>
        /// <param name="endPoint">The proxy endpoint.</param>
        /// <param name="clientStream">The client stream.</param>
        /// <param name="cancellationTokenSource">The cancellation token source for this async task.</param>
        /// <param name="connectArgs">The Connect request if this is a HTTPS request from explicit endpoint.</param>
        /// <param name="prefetchConnectionTask">Prefetched server connection for current client using Connect/SNI headers.</param>
        /// <param name="isHttps">Is HTTPS</param>
        private async Task handleHttpSessionRequest(ProxyEndPoint endPoint, HttpClientStream clientStream,
                                                    CancellationTokenSource cancellationTokenSource, TunnelConnectSessionEventArgs?connectArgs = null,
                                                    Task <TcpServerConnection?>?prefetchConnectionTask = null, bool isHttps = false)
        {
            var connectRequest = connectArgs?.HttpClient.ConnectRequest;

            var prefetchTask = prefetchConnectionTask;
            TcpServerConnection?connection = null;
            bool closeServerConnection     = false;

            try
            {
                var cancellationToken = cancellationTokenSource.Token;

                // Loop through each subsequent request on this particular client connection
                // (assuming HTTP connection is kept alive by client)
                while (true)
                {
                    if (clientStream.IsClosed)
                    {
                        return;
                    }

                    // read the request line
                    var requestLine = await clientStream.ReadRequestLine(cancellationToken);

                    if (requestLine.IsEmpty())
                    {
                        return;
                    }

                    var args = new SessionEventArgs(this, endPoint, clientStream, connectRequest, cancellationTokenSource)
                    {
                        UserData = connectArgs?.UserData
                    };

                    var request = args.HttpClient.Request;
                    if (isHttps)
                    {
                        request.IsHttps = true;
                    }

                    try
                    {
                        try
                        {
                            // Read the request headers in to unique and non-unique header collections
                            await HeaderParser.ReadHeaders(clientStream, args.HttpClient.Request.Headers,
                                                           cancellationToken);

                            if (connectRequest != null)
                            {
                                request.IsHttps   = connectRequest.IsHttps;
                                request.Authority = connectRequest.Authority;
                            }

                            request.RequestUriString8 = requestLine.RequestUri;

                            request.Method      = requestLine.Method;
                            request.HttpVersion = requestLine.Version;

                            // we need this to syphon out data from connection if API user changes them.
                            request.SetOriginalHeaders();

                            // If user requested interception do it
                            await onBeforeRequest(args);

                            if (!args.IsTransparent && !args.IsSocks)
                            {
                                // proxy authorization check
                                if (connectRequest == null && await checkAuthorization(args) == false)
                                {
                                    await onBeforeResponse(args);

                                    // send the response
                                    await clientStream.WriteResponseAsync(args.HttpClient.Response, cancellationToken);

                                    return;
                                }

                                prepareRequestHeaders(request.Headers);
                                request.Host = request.RequestUri.Authority;
                            }

                            // if win auth is enabled
                            // we need a cache of request body
                            // so that we can send it after authentication in WinAuthHandler.cs
                            if (args.EnableWinAuth && request.HasBody)
                            {
                                await args.GetRequestBody(cancellationToken);
                            }

                            var response = args.HttpClient.Response;

                            if (request.CancelRequest)
                            {
                                if (!(Enable100ContinueBehaviour && request.ExpectContinue))
                                {
                                    // syphon out the request body from client before setting the new body
                                    await args.SyphonOutBodyAsync(true, cancellationToken);
                                }

                                await handleHttpSessionResponse(args);

                                if (!response.KeepAlive)
                                {
                                    return;
                                }

                                continue;
                            }

                            // If prefetch task is available.
                            if (connection == null && prefetchTask != null)
                            {
                                try
                                {
                                    connection = await prefetchTask;
                                }
                                catch (SocketException e)
                                {
                                    if (e.SocketErrorCode != SocketError.HostNotFound)
                                    {
                                        throw;
                                    }
                                }

                                prefetchTask = null;
                            }

                            if (connection != null)
                            {
                                var  socket = connection.TcpSocket;
                                bool part1  = socket.Poll(1000, SelectMode.SelectRead);
                                bool part2  = socket.Available == 0;
                                if (part1 & part2)
                                {
                                    //connection is closed
                                    await tcpConnectionFactory.Release(connection, true);

                                    connection = null;
                                }
                            }

                            // create a new connection if cache key changes.
                            // only gets hit when connection pool is disabled.
                            // or when prefetch task has a unexpectedly different connection.
                            if (connection != null &&
                                (await tcpConnectionFactory.GetConnectionCacheKey(this, args,
                                                                                  clientStream.Connection.NegotiatedApplicationProtocol)
                                 != connection.CacheKey))
                            {
                                await tcpConnectionFactory.Release(connection);

                                connection = null;
                            }

                            var result = await handleHttpSessionRequest(args, connection,
                                                                        clientStream.Connection.NegotiatedApplicationProtocol,
                                                                        cancellationToken, cancellationTokenSource);

                            // update connection to latest used
                            connection            = result.LatestConnection;
                            closeServerConnection = !result.Continue;

                            // throw if exception happened
                            if (result.Exception != null)
                            {
                                throw result.Exception;
                            }

                            if (!result.Continue)
                            {
                                return;
                            }

                            // user requested
                            if (args.HttpClient.CloseServerConnection)
                            {
                                closeServerConnection = true;
                                return;
                            }

                            // if connection is closing exit
                            if (!response.KeepAlive)
                            {
                                closeServerConnection = true;
                                return;
                            }

                            if (cancellationTokenSource.IsCancellationRequested)
                            {
                                throw new Exception("Session was terminated by user.");
                            }

                            // Release server connection for each HTTP session instead of per client connection.
                            // This will be more efficient especially when client is idly holding server connection
                            // between sessions without using it.
                            // Do not release authenticated connections for performance reasons.
                            // Otherwise it will keep authenticating per session.
                            if (EnableConnectionPool && connection != null &&
                                !connection.IsWinAuthenticated)
                            {
                                await tcpConnectionFactory.Release(connection);

                                connection = null;
                            }
                        }
                        catch (Exception e) when(!(e is ProxyHttpException))
                        {
                            throw new ProxyHttpException("Error occured whilst handling session request", e, args);
                        }
                    }
                    catch (Exception e)
                    {
                        args.Exception        = e;
                        closeServerConnection = true;
                        throw;
                    }
                    finally
                    {
                        await onAfterResponse(args);

                        args.Dispose();
                    }
                }
            }
            finally
            {
                if (connection != null)
                {
                    await tcpConnectionFactory.Release(connection, closeServerConnection);
                }

                await tcpConnectionFactory.Release(prefetchTask, closeServerConnection);
            }
        }
 private static async Task OnRequestRedirectTrafficEventHandler(object sender, SessionEventArgs e) => await Task.Run(
     () =>
 {
     if (_redirectUrls.Keys.Count > 0)
     {
         foreach (var redirectUrlPair in _redirectUrls)
         {
             if (e.HttpClient.Request.RequestUri.AbsoluteUri.Contains(redirectUrlPair.Key))
             {
                 e.Redirect(redirectUrlPair.Value);
             }
         }
     }
 }).ConfigureAwait(false);
コード例 #56
0
        /// <summary>
        ///     Called asynchronously when a request was successfully and we received the response.
        /// </summary>
        /// <param name="args">The session event arguments.</param>
        /// <returns> The task.</returns>
        private async Task HandleHttpSessionResponse(SessionEventArgs args)
        {
            try
            {
                var cancellationToken = args.CancellationTokenSource.Token;

                // read response & headers from server
                await args.WebSession.ReceiveResponse(cancellationToken);

                var response = args.WebSession.Response;
                args.ReRequest = false;

                // check for windows authentication
                if (isWindowsAuthenticationEnabledAndSupported)
                {
                    if (response.StatusCode == (int)HttpStatusCode.Unauthorized)
                    {
                        await Handle401UnAuthorized(args);
                    }
                    else
                    {
                        WinAuthEndPoint.AuthenticatedResponse(args.WebSession.Data);
                    }
                }

                response.OriginalHasBody = response.HasBody;

                // if user requested call back then do it
                if (!response.Locked)
                {
                    await InvokeBeforeResponse(args);
                }

                // it may changed in the user event
                response = args.WebSession.Response;

                var clientStreamWriter = args.ProxyClient.ClientStreamWriter;

                if (response.TerminateResponse || response.Locked)
                {
                    await clientStreamWriter.WriteResponseAsync(response, cancellationToken : cancellationToken);

                    if (!response.TerminateResponse)
                    {
                        // syphon out the response body from server before setting the new body
                        await args.SyphonOutBodyAsync(false, cancellationToken);
                    }
                    else
                    {
                        args.WebSession.ServerConnection.Dispose();
                        args.WebSession.ServerConnection = null;
                    }

                    return;
                }

                // if user requested to send request again
                // likely after making modifications from User Response Handler
                if (args.ReRequest)
                {
                    // clear current response
                    await args.ClearResponse(cancellationToken);
                    await HandleHttpSessionRequestInternal(args.WebSession.ServerConnection, args);

                    return;
                }

                response.Locked = true;

                // Write back to client 100-conitinue response if that's what server returned
                if (response.Is100Continue)
                {
                    await clientStreamWriter.WriteResponseStatusAsync(response.HttpVersion,
                                                                      (int)HttpStatusCode.Continue, "Continue", cancellationToken);

                    await clientStreamWriter.WriteLineAsync(cancellationToken);
                }
                else if (response.ExpectationFailed)
                {
                    await clientStreamWriter.WriteResponseStatusAsync(response.HttpVersion,
                                                                      (int)HttpStatusCode.ExpectationFailed, "Expectation Failed", cancellationToken);

                    await clientStreamWriter.WriteLineAsync(cancellationToken);
                }

                if (!args.IsTransparent)
                {
                    response.Headers.FixProxyHeaders();
                }

                if (response.IsBodyRead)
                {
                    await clientStreamWriter.WriteResponseAsync(response, cancellationToken : cancellationToken);
                }
                else
                {
                    // Write back response status to client
                    await clientStreamWriter.WriteResponseStatusAsync(response.HttpVersion, response.StatusCode,
                                                                      response.StatusDescription, cancellationToken);

                    await clientStreamWriter.WriteHeadersAsync(response.Headers, cancellationToken : cancellationToken);

                    // Write body if exists
                    if (response.HasBody)
                    {
                        await args.CopyResponseBodyAsync(clientStreamWriter, TransformationMode.None,
                                                         cancellationToken);
                    }
                }
            }
            catch (Exception e) when(!(e is ProxyHttpException))
            {
                throw new ProxyHttpException("Error occured whilst handling session response", e, args);
            }
        }
コード例 #57
0
 void _sessionManager_SessionStarted(object sender, SessionEventArgs e)
 {
     SendData(true);
 }
コード例 #58
0
 /// <summary>
 /// Invocator for BeforeResponse event.
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 /// <returns></returns>
 protected virtual void OnBeforeResponse(object sender, SessionEventArgs e)
 {
     BeforeResponse?.Invoke(sender, e);
 }
コード例 #59
0
 /// <summary>
 /// 实现对缓存数据的更新
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 void _sc_OnUpdateCacheCompleted(object sender, SessionEventArgs e)
 {
     //SessionService.Instance.Update(e.SyncCache);
 }
 private void Connector_SessionStarted(object sender, SessionEventArgs e)
 {
     this.UpdateStatus("Listening ...");
     this.RunOnUiThread(() => this.ListeningState = ListenState.Listening);
 }