public BeginConnect ( |
||
remoteEP | An |
|
callback | AsyncCallback | The |
state | object | An object that contains state information for this request. |
return | IAsyncResult |
public void Start() { // create a new ManualResetEvent. This will be used to make the main application // thread wait until the full server reply has been received. m_ResetEvent = new ManualResetEvent(false); // initialize the security options SecurityOptions options = new SecurityOptions( SecureProtocol.Ssl3 | SecureProtocol.Tls1, // use SSL3 or TLS1 null, // do not use client authentication ConnectionEnd.Client, // this is the client side CredentialVerification.None, // do not check the certificate -- this should not be used in a real-life application :-) null, // not used with automatic certificate verification "www.microsoft.com", // this is the common name of the Microsoft web server SecurityFlags.Default, // use the default security flags SslAlgorithms.SECURE_CIPHERS, // only use secure ciphers null); // do not process certificate requests. try { // create the securesocket with the specified security options m_Socket = new SecureSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp, options); // resolve www.microsoft.com IPEndPoint endpoint = new IPEndPoint(Dns.GetHostEntry("www.microsoft.com").AddressList[0], 443); // start connecting to www.microsoft.com m_Socket.BeginConnect(endpoint, new AsyncCallback(this.OnConnect), null); // wait until the entire web page has been received m_ResetEvent.WaitOne(); // close the SecureSocket m_Socket.Close(); } catch { OnError("Could not connect to the website"); } }
///<summary>Initializes a new instance of the FtpDataConnection class.</summary> ///<param name="RemoteAddress">The address on the local FTP client to connect to.</param> ///<returns>The PORT command string to send to the FTP server.</returns> public string ProcessPort(IPEndPoint RemoteAddress) { try { ListenSocket = new SecureSocket(IPAddress.Any.AddressFamily, SocketType.Stream, ProtocolType.Tcp); ListenSocket.Bind(new IPEndPoint(IPAddress.Any, 0)); ListenSocket.Listen(1); ListenSocket.BeginAccept(new AsyncCallback(this.OnPortAccept), ListenSocket); ClientSocket = new SecureSocket(RemoteAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); ClientSocket.BeginConnect(RemoteAddress, new AsyncCallback(this.OnPortConnected), ClientSocket); return "PORT " + Listener.GetLocalExternalIP().ToString().Replace('.', ',') + "," + Math.Floor(((IPEndPoint)ListenSocket.LocalEndPoint).Port / 256).ToString() + "," + (((IPEndPoint)ListenSocket.LocalEndPoint).Port % 256).ToString() + "\r\n"; } catch { Dispose(); return "PORT 0,0,0,0,0,0\r\n"; } }
///<summary>Processes a SOCKS request from a client.</summary> ///<param name="Request">The request to process.</param> protected override void ProcessRequest(byte [] Request) { int Ret; try { if (Request[0] == 1) { // CONNECT IPAddress RemoteIP; int RemotePort = Request[1] * 256 + Request[2]; Ret = Array.IndexOf(Request, (byte)0, 7); Username = Encoding.ASCII.GetString(Request, 7, Ret - 7); if (Request[3] == 0 && Request[4] == 0 && Request[5] == 0 && Request[6] != 0) {// Use remote DNS Ret = Array.IndexOf(Request, (byte)0, Ret + 1); RemoteIP = Dns.Resolve(Encoding.ASCII.GetString(Request, Username.Length + 8, Ret - Username.Length - 8)).AddressList[0]; } else { //Do not use remote DNS RemoteIP = IPAddress.Parse(Request[3].ToString() + "." + Request[4].ToString() + "." + Request[5].ToString() + "." + Request[6].ToString()); } RemoteConnection = new SecureSocket(RemoteIP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); RemoteConnection.BeginConnect(new IPEndPoint(RemoteIP, RemotePort), new AsyncCallback(this.OnConnected), RemoteConnection); } else if (Request[0] == 2) { // BIND byte [] Reply = new byte[8]; long LocalIP = Listener.GetLocalExternalIP().Address; AcceptSocket = new SecureSocket(IPAddress.Any.AddressFamily, SocketType.Stream, ProtocolType.Tcp); AcceptSocket.Bind(new IPEndPoint(IPAddress.Any, 0)); AcceptSocket.Listen(50); RemoteBindIP = IPAddress.Parse(Request[3].ToString() + "." + Request[4].ToString() + "." + Request[5].ToString() + "." + Request[6].ToString()); Reply[0] = 0; //Reply version 0 Reply[1] = 90; //Everything is ok :) Reply[2] = (byte)(Math.Floor(((IPEndPoint)AcceptSocket.LocalEndPoint).Port / 256)); //Port/1 Reply[3] = (byte)(((IPEndPoint)AcceptSocket.LocalEndPoint).Port % 256); //Port/2 Reply[4] = (byte)(Math.Floor((LocalIP % 256))); //IP Address/1 Reply[5] = (byte)(Math.Floor((LocalIP % 65536) / 256)); //IP Address/2 Reply[6] = (byte)(Math.Floor((LocalIP % 16777216) / 65536)); //IP Address/3 Reply[7] = (byte)(Math.Floor(LocalIP / 16777216)); //IP Address/4 Connection.BeginSend(Reply, 0, Reply.Length, SocketFlags.None, new AsyncCallback(this.OnStartAccept), Connection); } } catch { Dispose(91); } }
///<summary>Connects to the specified endpoint.</summary> ///<param name="RemoteServer">The IPEndPoint to connect to.</param> ///<exception cref="SocketException">There was an error connecting to the specified endpoint</exception> private void ConnectTo(IPEndPoint RemoteServer) { if (DestinationSocket != null) { try { DestinationSocket.Shutdown(SocketShutdown.Both); } catch { } finally { DestinationSocket.Close(); } } try { DestinationSocket = new SecureSocket(RemoteServer.AddressFamily, SocketType.Stream, ProtocolType.Tcp); DestinationSocket.BeginConnect(RemoteServer, new AsyncCallback(this.OnRemoteConnected), DestinationSocket); } catch { throw new SocketException(); } }
///<summary>Processes a received query.</summary> ///<param name="Query">The query to process.</param> private void ProcessQuery(byte [] Query) { try { switch(Query[1]) { case 1: //CONNECT IPAddress RemoteIP = null; int RemotePort = 0; if (Query[3] == 1) { RemoteIP = IPAddress.Parse(Query[4].ToString() + "." + Query[5].ToString() + "." + Query[6].ToString() + "." + Query[7].ToString()); RemotePort = Query[8] * 256 + Query[9]; } else if( Query[3] == 3) { RemoteIP = Dns.Resolve(Encoding.ASCII.GetString(Query, 5, Query[4])).AddressList[0]; RemotePort = Query[4] + 5; RemotePort = Query[RemotePort] * 256 + Query[RemotePort + 1]; } RemoteConnection = new SecureSocket(RemoteIP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); RemoteConnection.BeginConnect(new IPEndPoint(RemoteIP, RemotePort), new AsyncCallback(this.OnConnected), RemoteConnection); break; case 2: //BIND byte [] Reply = new byte[10]; long LocalIP = Listener.GetLocalExternalIP().Address; AcceptSocket = new SecureSocket(IPAddress.Any.AddressFamily, SocketType.Stream, ProtocolType.Tcp); AcceptSocket.Bind(new IPEndPoint(IPAddress.Any, 0)); AcceptSocket.Listen(50); Reply[0] = 5; //Version 5 Reply[1] = 0; //Everything is ok :) Reply[2] = 0; //Reserved Reply[3] = 1; //We're going to send a IPv4 address Reply[4] = (byte)(Math.Floor((LocalIP % 256))); //IP Address/1 Reply[5] = (byte)(Math.Floor((LocalIP % 65536) / 256)); //IP Address/2 Reply[6] = (byte)(Math.Floor((LocalIP % 16777216) / 65536)); //IP Address/3 Reply[7] = (byte)(Math.Floor(LocalIP / 16777216)); //IP Address/4 Reply[8] = (byte)(Math.Floor(((IPEndPoint)AcceptSocket.LocalEndPoint).Port / 256)); //Port/1 Reply[9] = (byte)(((IPEndPoint)AcceptSocket.LocalEndPoint).Port % 256); //Port/2 Connection.BeginSend(Reply, 0, Reply.Length, SocketFlags.None, new AsyncCallback(this.OnStartAccept), Connection); break; case 3: //ASSOCIATE //ASSOCIATE is not implemented (yet?) Dispose(7); break; default: Dispose(7); break; } } catch { Dispose(1); } }
///<summary>Processes a PASV reply from the server.</summary> ///<param name="Reply">The reply to process.</param> private void ProcessPasvReply(string Reply) { try { IPEndPoint ConnectTo = ParsePasvIP(Reply); DestinationSocket = new SecureSocket(ConnectTo.AddressFamily, SocketType.Stream, ProtocolType.Tcp); DestinationSocket.BeginConnect(ConnectTo, new AsyncCallback(this.OnPasvConnected), DestinationSocket); } catch { Dispose(); } }