public byte[] ToPackets() { var bPack = new List <byte>(); switch (this.Phase) { case Socks5Phase.spGreeting: if (this.Credential == null) { //匿名代理 bPack.Add(5); bPack.Add(1); bPack.Add(0); this.Phase = Socks5Phase.spConnecting; } else { //匿名或用户名密码代理 bPack.Add(5); bPack.Add(2); bPack.Add(0); bPack.Add(2); this.Phase = Socks5Phase.spAuthenticating; } break; case Socks5Phase.spAuthenticating: if (this.Credential == null) { throw new ProxyAuthException(403, "Socks5 Server request a credential"); } bPack.Add(1); bPack.Add(Convert.ToByte(this.Credential.UserName.Length)); bPack.AddRange(Encoding.ASCII.GetBytes(this.Credential.UserName)); bPack.Add(Convert.ToByte(this.Credential.Password.Length)); bPack.AddRange(Encoding.ASCII.GetBytes(this.Credential.Password)); this.Phase = Socks5Phase.spConnecting; break; case Socks5Phase.spConnecting: bPack.Add(5); bPack.Add((byte)this.Command); bPack.Add(0); bPack.Add((byte)((this.EndPoint is DnsEndPoint) ? 3 : 1)); Socks4Request.PackIn(bPack, this.EndPoint); break; } return(bPack.ToArray()); }
public byte[] ToPackets() { var bPack = new List <byte>(); bPack.Add(0x00); bPack.Add((byte)this.Status); Socks4Request.PackIn(bPack, this.RemoteEndPoint, false); return(bPack.ToArray()); }
public void ParsePack(byte[] bPack) { switch (this.Phase) { case Socks5Request.Socks5Phase.spGreeting: if (bPack[0] != 5) { throw new ProxyAuthException(403, "Only Socks5 response are supported"); } if (bPack[1] == 0xFF) { throw new ProxyAuthException(0xFF, "Authentication method not supported"); } if (this.Anonymous = bPack[1] == 0) { this.Phase = Socks5Request.Socks5Phase.spConnecting; } else { this.Phase = Socks5Request.Socks5Phase.spAuthenticating; } break; case Socks5Request.Socks5Phase.spAuthenticating: if (bPack[0] != 1) { throw new ProxyAuthException(403, "Only Socks5 response are supported"); } this.Phase = Socks5Request.Socks5Phase.spConnecting; this.Status = (ResponseStatus)bPack[1]; if (this.Status != ResponseStatus.Success) { throw new ProxyAuthException((int)this.Status, this.Status.ToDescription()); } break; case Socks5Request.Socks5Phase.spConnecting: if (bPack[0] != 5) { throw new ProxyAuthException(403, "Only Socks5 response are supported"); } int offset = 4; IPEndPoint ipe; Socks4Request.PackOut(bPack, ref offset, out ipe); this.RemoteEndPoint = ipe; break; } }
public void UdpDirectReceive(HttpContext context, UdpClient proxyClient) { context.Server.ScriptTimeout = int.MaxValue; HttpRequest Request = context.Request; HttpResponse Response = context.Response; Response.AppendHeader(HttpResponseHeader.Connection.ToString(), "close"); var bPack = new List <byte>(); while (Response.IsClientConnected) { try { var remoteIpe = new IPEndPoint(IPAddress.Any, IPEndPoint.MinPort); byte[] data = proxyClient.Receive(ref remoteIpe); if (!Response.IsClientConnected) { break; } bPack.Clear(); Socks4Request.PackIn(bPack, remoteIpe); bPack.AddRange(data); byte[] bData = bPack.ToArray(); Response.OutputStream.Write(bData, 0, bData.Length); Response.Flush(); App.LogInfo("UdpDirectReceive from {0} {1}bytes.", remoteIpe, data.Length); } catch (ObjectDisposedException ex) { #if DEBUG App.LogInfo(string.Format("Predictable objectDisposed exception: {0}", ex.StackTrace)); #endif } catch (IOException ex) { TunnelExceptionHandler.Handle(ex, proxyClient.Client, "UdpDirectReceive"); } catch (SocketException ex) { if (ex.SocketErrorCode == SocketError.Interrupted) { #if DEBUG App.LogInfo(string.Format("Predictable interrupted exception: {0}", ex.Message)); #endif return; } TunnelExceptionHandler.Handle(ex, proxyClient.Client, "UdpDirectReceive"); } } }
public byte[] ToPackets() { var bPack = new List <byte>(); switch (this.Phase) { case Socks5Request.Socks5Phase.spGreeting: if (this.Anonymous) { bPack.Add(5); bPack.Add(0); this.Phase = Socks5Request.Socks5Phase.spConnecting; } else { bPack.Add(5); bPack.Add(2); this.Phase = Socks5Request.Socks5Phase.spAuthenticating; } break; case Socks5Request.Socks5Phase.spAuthenticating: if (this.Status != ResponseStatus.Success) { throw new ProxyAuthException(403, "Authentication failure, connection must be closed"); } bPack.Add(1); bPack.Add((byte)this.Status); this.Phase = Socks5Request.Socks5Phase.spConnecting; break; case Socks5Request.Socks5Phase.spConnecting: bPack.Add(5); bPack.Add(0); bPack.Add(0); bPack.Add(1); Socks4Request.PackIn(bPack, this.RemoteEndPoint); break; } return(bPack.ToArray()); }
public void ParsePack(byte[] bPack) { if (bPack[0] != 0x00) { throw new ProxyAuthException(403, "Only Socks4/4a response are supported"); } var response = this; response.Status = (ResponseStatus)bPack[1]; int offset = 2; IPEndPoint ipe; Socks4Request.PackOut(bPack, ref offset, out ipe, false); response.RemoteEndPoint = ipe; if (response.Status != Socks4Response.ResponseStatus.RequestGranted) { throw new ProxyAuthException((int)response.Status, response.Status.ToDescription()); } }
private void UdpDirectReceive(object state) { var controlClient = (TcpClient)state; if (!controlClient.Connected) { return; } IPEndPoint remoteIpe = null; try { var currentState = this.GetUdpClientState(controlClient); //Udp无连接先发送后接收 currentState.WaitOnce(); var tunnel = this.CreateTunnel(TunnelCommand.UdpReceive, controlClient); tunnel.SendReceiveTimeout = Timeout.Infinite; var response = tunnel.GetResponse(webResponse => { var pushStream = webResponse.GetResponseStream(); byte[] data = new byte[(int)BufferSizeof.MaxSocket]; //00 00 00 01 data[3] = 1; while (controlClient.Connected && pushStream.CanRead) { try { int offset = 4; int read = pushStream.Read(data, offset, data.Length - offset); if (read == 0 || !(controlClient.Connected && pushStream.CanRead)) { break; } //4-10 中间6字节为remoteIpe Socks4Request.PackOut(data, ref offset, out remoteIpe); if (!currentState.HasRemoteEndPoint(remoteIpe)) { this.OutWrite("Udp Receive Discard {0} {1}bytes.", remoteIpe, read); App.LogInfo("Udp Receive Discard 非法远程端点."); continue; } int length = 4 + read; int sent = currentState.Client.Send(data, length, currentState.LocalEndPoint); if (length != sent) { throw new InvalidOperationException("Udp数据包错误"); } this.OutWrite("Udp {0} Receive {1}\t{2}bytes.", currentState.LocalEndPoint, remoteIpe, read); } catch (ObjectDisposedException ex) { #if DEBUG App.LogInfo(string.Format("Predictable objectDisposed exception: {0}", ex.StackTrace)); #endif return; } catch (IOException ex) { TunnelExceptionHandler.Handle(ex, controlClient.Client, string.Format("UdpDirectReceive={0}", remoteIpe)); } catch (SocketException ex) { TunnelExceptionHandler.Handle(ex, controlClient.Client, string.Format("UdpDirectReceive={0}", remoteIpe)); } } }); response.Close(); } catch (WebException ex) { bool isRejected; TunnelExceptionHandler.Handle(ex, string.Format("UdpDirectReceive={0}", remoteIpe), _output, out isRejected); if (isRejected) { this.OnServerRejected(); } } catch (Exception ex) { TunnelExceptionHandler.Handle(ex, string.Format("UdpDirectReceive={0}", remoteIpe)); } }
private void UdpDirectSend(object state) { var controlClient = (TcpClient)state; if (!controlClient.Connected) { return; } string destIpe = null; try { var currentState = this.GetUdpClientState(controlClient); while (controlClient.Connected) { try { var localIpe = new IPEndPoint(IPAddress.Any, IPEndPoint.MinPort); byte[] data = currentState.Client.Receive(ref localIpe); if (!controlClient.Connected) { break; } if (data.IsNullOrEmpty() || !(data[0] == 0 && data[1] == 0 && data[2] == 0)) { this.OutWrite("Udp Send Discard {0} {1}bytes.", localIpe, data == null ? -1 : data.Length); App.LogInfo("Udp Send Discard 非法数据包."); continue; } else if (!currentState.LocalEndPoint.Equals(localIpe)) { this.OutWrite("Udp Send Discard {0} {1}bytes.", localIpe, data == null ? -1 : data.Length); App.LogInfo("Udp Send Discard 非法本地端点."); continue; } int offset = 4; if (data[3] == 3) { DnsEndPoint de; Socks4Request.PackOut(data, ref offset, out de); currentState.AddRemoteEndPoint(de); destIpe = string.Format("{0}:{1}", de.Host, de.Port); } else { IPEndPoint ipe; Socks4Request.PackOut(data, ref offset, out ipe); currentState.AddRemoteEndPoint(ipe); destIpe = ipe.ToString(); } var tunnel = this.CreateTunnel(TunnelCommand.UdpSend, controlClient); tunnel.Headers[xHttpHandler.AgentDirect] = destIpe; var outStream = new MemoryStream(data, offset, data.Length - offset); #if DEBUG tunnel.Form[xHttpHandler.AgentChecksum] = CryptoManaged.MD5Hash(outStream).ToString(); outStream.Position = 0L; #endif tunnel.Files.Add(new HttpFileContent(xHttpHandler.AgentDirect, xHttpHandler.AgentDirect, outStream)); var response = tunnel.GetResponse(); if (response.GetResponseText() != "1") { this.OutWrite("Udp {0} Send {1}\t{2}bytes failure.", currentState.LocalEndPoint, destIpe, outStream.Length); return; } this.OutWrite("Udp {0} Send {1}\t{2}bytes.", currentState.LocalEndPoint, destIpe, outStream.Length); //开始接收数据 currentState.SetOnce(); } catch (ObjectDisposedException ex) { #if DEBUG App.LogInfo(string.Format("Predictable objectDisposed exception: {0}", ex.StackTrace)); #endif } catch (WebException ex) { bool isRejected; if (TunnelExceptionHandler.Handle(ex, string.Format("UdpDirectSend={0}", destIpe), _output, out isRejected)) { controlClient.Client.Close(); } if (isRejected) { this.OnServerRejected(); } } catch (SocketException ex) { if (ex.SocketErrorCode == SocketError.Interrupted) { #if DEBUG App.LogInfo(string.Format("Predictable interrupted exception: {0}", ex.Message)); #endif return; } TunnelExceptionHandler.Handle(ex, controlClient.Client, string.Format("UdpDirectSend={0}", destIpe)); } } } catch (Exception ex) { TunnelExceptionHandler.Handle(ex, string.Format("UdpDirectSend={0}", destIpe)); } }
public void ParsePack(byte[] bPack) { switch (this.Phase) { case Socks5Phase.spGreeting: { if (bPack[0] != 5) { throw new ProxyAuthException(403, "Only Socks5 request are supported"); } //要求匿名代理 if (bPack[1] == 1 && bPack[2] == 0) { this.Credential = null; this.Phase = Socks5Phase.spConnecting; } //要求匿名或用户名密码代理 else { this.Credential = new NetworkCredential(); this.Phase = Socks5Phase.spAuthenticating; } } break; case Socks5Phase.spAuthenticating: { if (bPack[0] != 1) { throw new ProxyAuthException(403, "Only Socks5 request are supported"); } if (this.Credential == null) { throw new ProxyAuthException(403, "Socks5Phase.spAuthenticating"); } int length = Convert.ToInt32(bPack[1]); this.Credential.UserName = Encoding.ASCII.GetString(bPack, 2, length); int offset = 2 + length; length = Convert.ToInt32(bPack[offset]); this.Credential.Password = Encoding.ASCII.GetString(bPack, offset + 1, length); this.Phase = Socks5Phase.spConnecting; } break; case Socks5Phase.spConnecting: { if (bPack[0] != 5 || bPack[2] != 0) { throw new ProxyAuthException(403, "Only Socks5 request are supported"); } this.Command = (Socks5Command)bPack[1]; int offset = 4; if (bPack[3] == 3) { DnsEndPoint de; Socks4Request.PackOut(bPack, ref offset, out de); this.EndPoint = de; } else { IPEndPoint ipe; Socks4Request.PackOut(bPack, ref offset, out ipe); this.EndPoint = ipe; } } break; } }
private void AcceptCallback(IAsyncResult ar) { if (_listener == null) { return; } _listener.BeginAcceptTcpClient(this.AcceptCallback, null); var proxyClient = _listener.EndAcceptTcpClient(ar); if (_runType.HasValue) { var proxySock = proxyClient.Client; byte[] buffer = new byte[256]; try { switch (_runType.Value) { case SocksProxyType.Socks4: case SocksProxyType.Socks4a: { int recv = proxySock.Receive(buffer); var request = new Socks4Request(); request.ParsePack(buffer); if (request.Command == Socks4Command.Bind) { App.LogInfo("{0} {1}协议错误: Bind命令暂不支持", proxySock.LocalEndPoint, _runType); goto default; } var resIpe = new IPEndPoint(request.RemoteIP, request.RemotePort); var response = new Socks4Response(resIpe); response.Status = Socks4Response.ResponseStatus.RequestGranted; proxySock.Send(response.ToPackets()); var destIpe = request.ProxyType == SocksProxyType.Socks4a ? (EndPoint) new DnsEndPoint(request.RemoteHost, request.RemotePort) : resIpe; this.PushTcpClient(proxyClient, destIpe); } break; case SocksProxyType.Socks5: { var request = new Socks5Request(); var response = new Socks5Response(); proxySock.Receive(buffer); request.ParsePack(buffer); if (request.Credential == null) { //请求匿名 response.Anonymous = true; proxySock.Send(response.ToPackets()); } else { response.Anonymous = false; proxySock.Send(response.ToPackets()); proxySock.Receive(buffer); request.ParsePack(buffer); var cred = request.Credential; //验证凭证 //if (!true) //{ // goto default; //} response.Status = Socks5Response.ResponseStatus.Success; proxySock.Send(response.ToPackets()); } proxySock.Receive(buffer); request.ParsePack(buffer); bool isDns = request.EndPoint is DnsEndPoint; var resIpe = isDns ? new IPEndPoint(IPAddress.Any, IPEndPoint.MinPort) : (IPEndPoint)request.EndPoint; switch (request.Command) { case Socks5Command.TcpBind: App.LogInfo("{0} {1}协议错误: Bind命令暂不支持", proxySock.LocalEndPoint, _runType); goto default; case Socks5Command.UdpAssociate: //客户端预备开放的Udp端口 int clientPort = isDns ? ((DnsEndPoint)request.EndPoint).Port : ((IPEndPoint)request.EndPoint).Port; //服务端开放的Udp端点 IPEndPoint localIpe; this.PushUdpClient(proxyClient, clientPort, out localIpe); response.RemoteEndPoint = localIpe; proxySock.Send(response.ToPackets()); return; default: response.RemoteEndPoint = resIpe; proxySock.Send(response.ToPackets()); this.PushTcpClient(proxyClient, request.EndPoint); break; } } break; case SocksProxyType.Http: { //GoAgent集成不做任何协议处理 this.PushTcpClient(proxyClient, xHttpHandler.GoAgent); } break; default: proxyClient.Close(); return; } } catch (Exception ex) { this.OutWrite("{0} {1}协议错误: {2}", proxySock.LocalEndPoint, _runType, ex.Message); App.LogError(ex, "代理协议错误"); proxyClient.Close(); return; } } else { this.PushTcpClient(proxyClient, _remoteEndPoint); } TaskHelper.Factory.StartNew(this.DirectReceive, new object[] { proxyClient }); TaskHelper.Factory.StartNew(this.DirectSend, new object[] { proxyClient }); }