private static void StartRemoteConnection(ConnectToRemoteState state) { if (state.RequestMethod.Equals("CONNECT", StringComparison.InvariantCultureIgnoreCase)) { // handle SSL response for CONNECT HandleSslConnect(state); return; } var remoteip = GetRemoteIp(state.RemoteHost); // TODO: handle SocketError.HostNotFound if (remoteip == null) { WriteLog(state.Session, 0, "ERR"); return; } var remoteClient = new TcpClient(); var remoteConnectionState = new RemoteConnectionState { Session = state.Session, ClientStream = state.ClientStream, Client = state.Client, MessageStream = state.MessageStream, RemoteClient = remoteClient, RemoteHost = state.RemoteHost, IsSsl = state.IsSsl }; remoteClient.BeginConnect(remoteip, state.RemotePort, ConnectToRemote.Run, remoteConnectionState); }
private static void HandleSslConnect(ConnectToRemoteState state) { var connectStreamWriter = new StreamWriter(state.ClientStream); connectStreamWriter.WriteLine("HTTP/1.0 200 Connection established"); connectStreamWriter.WriteLine("Timestamp: {0}", DateTime.Now); connectStreamWriter.WriteLine("Proxy-agent: GOS Proxy Service"); connectStreamWriter.WriteLine(); connectStreamWriter.Flush(); var sslStream = new SslStream(state.ClientStream, false); try { var certProvider = new CertificateProvider(); bool created; var certificate = certProvider.LoadOrCreateCertificate(state.RemoteHost, out created); sslStream.AuthenticateAsServer(certificate, false, SslProtocols.Tls | SslProtocols.Ssl3 | SslProtocols.Ssl2, true); } catch (Exception ex) { WriteLog(state.Session, 0, "ERR", ex.Message); sslStream.Close(); state.ClientStream.Close(); connectStreamWriter.Close(); return; } var nstate = new ClientConnectionState { Session = state.Session, Client = state.Client, ClientStream = sslStream, ClientStreamBase = (NetworkStream)state.ClientStream, Buffer = new byte[Globals.BufferSize], MessageStream = new MemoryStream(), IsSsl = true, }; try { sslStream.BeginRead(nstate.Buffer, 0, nstate.Buffer.Length, ReadFromClient.Run, nstate); } catch (Exception ex) { WriteLog(state.Session, 0, "ERR", ex.Message); sslStream.Close(); state.ClientStream.Close(); } }
public static void Run(IAsyncResult asyncResult) { var state = asyncResult.AsyncState as ClientConnectionState; if (state != null) { int read; try { read = state.ClientStream.EndRead(asyncResult); } catch (Exception ex) { WriteLog(state.Session, 0, "ERR", ex.Message); state.ClientStreamBase.Close(); state.ClientStream.Close(); return; } state.MessageStream.Write(state.Buffer, 0, read); if (state.ClientStreamBase.DataAvailable) { state.ClientStream.BeginRead(state.Buffer, 0, state.Buffer.Length, ReadFromClient.Run, state); } else { if (read == 0) { state.ClientStream.Close(); return; } var messageHeader = ParseClientMessage(state.MessageStream); if (messageHeader == null) { state.ClientStream.Close(); state.ClientStreamBase.Close(); return; } state.ClientMessageHeader = messageHeader; state.Session.TargetUrl = state.ClientMessageHeader.RemoteUri.ToString(); state.Session.Protocoll = state.ClientMessageHeader.Protocol; // TODO: filter the data from the client var connectState = new ConnectToRemoteState { Session = state.Session, RemotePort = state.ClientMessageHeader.RemoteUri.Port, RemoteHost = state.ClientMessageHeader.RemoteUri.Host, RequestMethod = state.ClientMessageHeader.Method, Client = state.Client, ClientStream = state.ClientStream, MessageStream = state.MessageStream, IsSsl = state.IsSsl }; StartRemoteConnection(connectState); } } }