protected override void OnError(System.Net.Sockets.SocketError error) { lock (stateLocker) { currState = ServerSessionState.Error; } }
protected override void OnConnected() { lock (stateLocker) { currState = ServerSessionState.Connected; } }
protected override void OnDisconnected() { lock (stateLocker) { currState = ServerSessionState.Disconnected; } lock (bufferLocker) { dataBuffer.ResetStream(); } }
public void DoUdpate(float deltaTime) { lock (stateLocker) { if (prevState != currState) { if (currState == ServerSessionState.Connected) { OnSessionConnected?.Invoke(this); } else if (currState == ServerSessionState.Disconnected) { OnSessionDisconnected?.Invoke(this); } else if (currState == ServerSessionState.Error) { OnSessionError?.Invoke(this); } prevState = currState; } } }
protected override void OnRecvData(byte[] bData, int nLen) { if (nLen == 0) { OnDisconnect("Normal closing"); return; } //Console.WriteLine(string.Format("<-- {0}", ByteSize.ByteUtils.HexStringFromByte(bData, true))); if (ServerSessionState == ServerSessionState.Forwarding) { try { ConnectClient.Send(bData, nLen); DoAsyncRead(); } catch (Exception) { } return; } ReceiveBuffer.AppendData(bData, 0, nLen); if (ServerSessionState == ServerSessionState.JustExisting) { DoAsyncRead(); // go read some more return; } byte[] bCurData = ReceiveBuffer.PeekAllSamples(); if (bCurData.Length <= 0) { DoAsyncRead(); return; } if (ServerSessionState == ServerSessionState.WaitingForMethodSelections) { int nVersion = bCurData[0]; if (nVersion == 5) { MethodSelectionsMessage msg = new MethodSelectionsMessage(); int nRead = msg.ReadFromBytes(bData, 0); if (nRead > 0) { ReceiveBuffer.GetNSamples(nRead); /// Determine which method we support /// bool bCanDoNoAuth = false; foreach (SockMethod method in msg.Methods) { if (method == SockMethod.NoAuthenticationRequired) { bCanDoNoAuth = true; break; } } if (bCanDoNoAuth == false) { MethodSelectedMessage retmsg = new MethodSelectedMessage(); retmsg.Version = 5; retmsg.SockMethod = SockMethod.NoAcceptableMethods; this.Send(retmsg.GetBytes()); this.Disconnect(); return; } else { ServerSessionState = ServerSessionState.WaitingForSocksRequestMessage; MethodSelectedMessage retmsg = new MethodSelectedMessage(); retmsg.Version = msg.Version; retmsg.SockMethod = SockMethod.NoAuthenticationRequired; this.Send(retmsg.GetBytes()); } } } else { Console.WriteLine("Version {0} not supported", nVersion); MethodSelectedMessage retmsg = new MethodSelectedMessage(); retmsg.Version = 5; retmsg.SockMethod = SockMethod.NoAcceptableMethods; this.Send(retmsg.GetBytes()); this.Disconnect(); return; } } else if (ServerSessionState == ServerSessionState.WaitingForSocksRequestMessage) { /// Read in our SocksRequestMessage /// SocksRequestMessage reqmsg = new SocksRequestMessage(); int nRead = reqmsg.ReadFromBytes(bData, 0); if (nRead > 0) { ReceiveBuffer.GetNSamples(nRead); if (reqmsg.Version != 0x05) { Console.WriteLine("No version 5, client wants version: {0}", reqmsg.Version); } //Parent.HandleRequest(reqmsg, this); if (reqmsg.SOCKSCommand == SOCKSCommand.Connect) { /// See what the man wants. It appears that mozilla immediately starts sending data if we return success here, so let's do it /// this.ServerSessionState = ServerSessionState.Forwarding; /// Let's try to connect /// /// Don't connect to a remote host in this version, just check the hash here, if it matches, send back success bool bHashMatched = false; //if (reqmsg.AddressType == AddressType.DomainName) // bConnected = ConnectClient.Connect(reqmsg.DestinationDomain, reqmsg.DestinationPort, true); //else // bConnected = ConnectClient.Connect(reqmsg.DestinationAddress.ToString(), reqmsg.DestinationPort, true); SocksReplyMessage reply = new SocksReplyMessage(); if (bHashMatched == false) { reply.SOCKSReply = SOCKSReply.ConnectionRefused; } else { reply.SOCKSReply = SOCKSReply.Succeeded; } Send(reply.GetBytes()); } else { SocksReplyMessage reply = new SocksReplyMessage(); reply.SOCKSReply = SOCKSReply.CommandNotSupported; reply.AddressType = AddressType.IPV4; Send(reply.GetBytes()); } } } DoAsyncRead(); // go read some more }
protected override void OnRecvData(byte[] bData, int nLen) { if (nLen == 0) { OnDisconnect("Normal closing"); return; } if (ServerSessionState == ServerSessionState.Forwarding) { try { if (ConnectClient != null) /// connected client may be null if we are acting as a socks5 bytestream proxy, where we don't actually forward anything { ConnectClient.Send(bData, nLen); } DoAsyncRead(); } catch (Exception) { } return; } ReceiveBuffer.AppendData(bData, 0, nLen); if (ServerSessionState == ServerSessionState.JustExisting) { DoAsyncRead(); // go read some more return; } byte[] bCurData = ReceiveBuffer.PeekAllSamples(); if (bCurData.Length <= 0) { DoAsyncRead(); return; } if (ServerSessionState == ServerSessionState.WaitingForMethodSelections) { int nVersion = bCurData[0]; if (nVersion == 5) { MethodSelectionsMessage msg = new MethodSelectionsMessage(); int nRead = msg.ReadFromBytes(bData, 0); if (nRead > 0) { ReceiveBuffer.GetNSamples(nRead); /// Determine which method we support /// bool bCanDoNoAuth = false; foreach (SockMethod method in msg.Methods) { if (method == SockMethod.NoAuthenticationRequired) { bCanDoNoAuth = true; break; } } if (bCanDoNoAuth == false) { MethodSelectedMessage retmsg = new MethodSelectedMessage(); retmsg.Version = 5; retmsg.SockMethod = SockMethod.NoAcceptableMethods; this.Send(retmsg.GetBytes()); this.Disconnect(); return; } else { ServerSessionState = ServerSessionState.WaitingForSocksRequestMessage; MethodSelectedMessage retmsg = new MethodSelectedMessage(); retmsg.Version = msg.Version; retmsg.SockMethod = SockMethod.NoAuthenticationRequired; this.Send(retmsg.GetBytes()); } } } else if (nVersion == 4) { MethodSelectionsVersionFourMessage msg = new MethodSelectionsVersionFourMessage(); int nRead = msg.ReadFromBytes(bData, 0); if (nRead > 0) { ReceiveBuffer.GetNSamples(nRead); MethodSelectedVersionFourMessage reply = new MethodSelectedVersionFourMessage(); /// See what the man wants. It appears that mozilla immediately starts sending data if we return success here, so let's do it /// this.ServerSessionState = ServerSessionState.Forwarding; /// Let's try to connect /// bool bConnected = false; if (msg.DomainName != null) { bConnected = ConnectClient.Connect(msg.DomainName, msg.DestinationPort, true); } else { bConnected = ConnectClient.Connect(msg.DestIPAddress.ToString(), msg.DestinationPort, true); } if (bConnected == false) { reply.SOCKS4Status = SOCKS4Status.RequestRejected; Send(reply.GetBytes()); Disconnect(); } else { reply.SOCKS4Status = SOCKS4Status.RequestGranted; Send(reply.GetBytes()); } } } else { Console.WriteLine("Version {0} not supported", nVersion); MethodSelectedMessage retmsg = new MethodSelectedMessage(); retmsg.Version = 5; retmsg.SockMethod = SockMethod.NoAcceptableMethods; this.Send(retmsg.GetBytes()); this.Disconnect(); return; } } else if (ServerSessionState == ServerSessionState.WaitingForSocksRequestMessage) { /// Read in our SocksRequestMessage /// SocksRequestMessage reqmsg = new SocksRequestMessage(); int nRead = reqmsg.ReadFromBytes(bData, 0); if (nRead > 0) { ReceiveBuffer.GetNSamples(nRead); if (reqmsg.Version != 0x05) { Console.WriteLine("No version 5, client wants version: {0}", reqmsg.Version); } //Parent.HandleRequest(reqmsg, this); if (reqmsg.SOCKSCommand == SOCKSCommand.Connect) { /// See what the man wants. It appears that mozilla immediately starts sending data if we return success here, so let's do it /// bool bConnected = false; if (SOCKSServerMode == SOCKSServerMode.NormalSOCKS5Server) { this.ServerSessionState = ServerSessionState.Forwarding; /// Let's try to connect /// if (reqmsg.AddressType == AddressType.DomainName) { bConnected = ConnectClient.Connect(reqmsg.DestinationDomain, reqmsg.DestinationPort, true); } else { bConnected = ConnectClient.Connect(reqmsg.DestinationAddress.ToString(), reqmsg.DestinationPort, true); } } else { Console.WriteLine("Incoming SOCKS5 Bytestream Connect command to domain: {0}, remote endppoint is: {1}", reqmsg.DestinationDomain, this.socket.RemoteEndPoint); RemoteHost = reqmsg.DestinationDomain; bConnected = true; this.ServerSessionState = ServerSessionState.JustExisting; } SocksReplyMessage reply = new SocksReplyMessage(); if (bConnected == false) { reply.SOCKSReply = SOCKSReply.ConnectionRefused; } else { reply.SOCKSReply = SOCKSReply.Succeeded; } Send(reply.GetBytes()); } else { SocksReplyMessage reply = new SocksReplyMessage(); reply.SOCKSReply = SOCKSReply.CommandNotSupported; reply.AddressType = AddressType.IPV4; Send(reply.GetBytes()); } } } DoAsyncRead(); // go read some more }
protected override void OnRecvData(byte[] bData, int nLen) { if (nLen == 0) { OnDisconnect("Normal closing"); return; } //Console.WriteLine(string.Format("<-- {0}", ByteSize.ByteUtils.HexStringFromByte(bData, true))); if (ServerSessionState == ServerSessionState.Forwarding) { try { ConnectClient.Send(bData, nLen); DoAsyncRead(); } catch (Exception) { } return; } ReceiveBuffer.AppendData(bData, 0, nLen); if (ServerSessionState == ServerSessionState.JustExisting) { DoAsyncRead(); // go read some more return; } byte[] bCurData = ReceiveBuffer.PeekAllSamples(); if (bCurData.Length <= 0) { DoAsyncRead(); return; } if (ServerSessionState == ServerSessionState.WaitingForMethodSelections) { int nVersion = bCurData[0]; if (nVersion == 5) { MethodSelectionsMessage msg = new MethodSelectionsMessage(); int nRead = msg.ReadFromBytes(bData, 0); if (nRead > 0) { ReceiveBuffer.GetNSamples(nRead); /// Determine which method we support /// bool bCanDoNoAuth = false; foreach (SockMethod method in msg.Methods) { if (method == SockMethod.NoAuthenticationRequired) { bCanDoNoAuth = true; break; } } if (bCanDoNoAuth == false) { MethodSelectedMessage retmsg = new MethodSelectedMessage(); retmsg.Version = 5; retmsg.SockMethod = SockMethod.NoAcceptableMethods; this.Send(retmsg.GetBytes()); this.Disconnect(); return; } else { ServerSessionState = ServerSessionState.WaitingForSocksRequestMessage; MethodSelectedMessage retmsg = new MethodSelectedMessage(); retmsg.Version = msg.Version; retmsg.SockMethod = SockMethod.NoAuthenticationRequired; this.Send(retmsg.GetBytes()); } } } else { Console.WriteLine("Version {0} not supported", nVersion); MethodSelectedMessage retmsg = new MethodSelectedMessage(); retmsg.Version = 5; retmsg.SockMethod = SockMethod.NoAcceptableMethods; this.Send(retmsg.GetBytes()); this.Disconnect(); return; } } else if (ServerSessionState == ServerSessionState.WaitingForSocksRequestMessage) { /// Read in our SocksRequestMessage /// SocksRequestMessage reqmsg = new SocksRequestMessage(); int nRead = reqmsg.ReadFromBytes(bData, 0); if (nRead > 0) { ReceiveBuffer.GetNSamples(nRead); if (reqmsg.Version != 0x05) Console.WriteLine("No version 5, client wants version: {0}", reqmsg.Version); //Parent.HandleRequest(reqmsg, this); if (reqmsg.SOCKSCommand == SOCKSCommand.Connect) { /// See what the man wants. It appears that mozilla immediately starts sending data if we return success here, so let's do it /// this.ServerSessionState = ServerSessionState.Forwarding; /// Let's try to connect /// /// Don't connect to a remote host in this version, just check the hash here, if it matches, send back success bool bHashMatched = false; //if (reqmsg.AddressType == AddressType.DomainName) // bConnected = ConnectClient.Connect(reqmsg.DestinationDomain, reqmsg.DestinationPort, true); //else // bConnected = ConnectClient.Connect(reqmsg.DestinationAddress.ToString(), reqmsg.DestinationPort, true); SocksReplyMessage reply = new SocksReplyMessage(); if (bHashMatched == false) { reply.SOCKSReply = SOCKSReply.ConnectionRefused; } else { reply.SOCKSReply = SOCKSReply.Succeeded; } Send(reply.GetBytes()); } else { SocksReplyMessage reply = new SocksReplyMessage(); reply.SOCKSReply = SOCKSReply.CommandNotSupported; reply.AddressType = AddressType.IPV4; Send(reply.GetBytes()); } } } DoAsyncRead(); // go read some more }
public void Start() { ServerSessionState = ServerSessionState.WaitingForMethodSelections; DoAsyncRead(); }