public static Destination.Destination ParseDestinationFromRequest(ReadOnlySpan <byte> payload) { if (payload.Length < 8) { throw RequestTooShortException; } if (payload[0] != 5) { throw BadRequestException; } TransportProtocol protocol; switch (payload[1]) { case 1: protocol = TransportProtocol.Tcp; break; case 3: protocol = TransportProtocol.Udp; break; default: throw UnknownTypeException; } if (Adapter.Destination.Destination.TryParseSocks5StyleAddress(payload.Slice(3), out Destination.Destination destination, protocol) == 0) { throw RequestTooShortException; } // Some SOCKS5 clients (e.g. curl) can resolve IP addresses locally. // In this case, we got a fake IP address and need to // convert it back to the corresponding domain name. switch (destination.Host) { case Ipv4Host ipv4: destination = new Destination.Destination(DnsProxyServer.TryLookup(ipv4.Data), destination.Port, protocol); break; } return(destination); }
internal TunSocketAdapter(TcpSocket socket, TunInterface tun, IRemoteAdapter remoteAdapter) { Interlocked.Increment(ref OpenCount); var pipe = new Pipe(); inboundReader = pipe.Reader; inboundWriter = pipe.Writer; _socket = socket; _tun = tun; socket.DataReceived += Socket_DataReceived; socket.DataSent += Socket_DataSent; socket.SocketError += Socket_SocketError; socket.RecvFinished += Socket_RecvFinished; // Resolve destination host var host = DnsProxyServer.TryLookup(socket.RemoteAddr); Destination = new Destination.Destination(host, socket.RemotePort, TransportProtocol.Tcp); this.remoteAdapter = remoteAdapter; StartPush(); Init(); }
async public void Init() { try { await r.ConnectAsync(server, port); } catch (Exception) { Debug.WriteLine("Error connecting to remote"); return; } Debug.WriteLine("Connected"); /* * var header = new byte[7]; * header[0] = 0x01; * header[1] = (byte)(_socket.RemoteAddr & 0xFF); * header[2] = (byte)(_socket.RemoteAddr >> 8 & 0xFF); * header[3] = (byte)(_socket.RemoteAddr >> 16 & 0xFF); * header[4] = (byte)(_socket.RemoteAddr >> 24); * header[5] = (byte)(_socket.RemotePort >> 8); * header[6] = (byte)(_socket.RemotePort & 0xFF); */ string domain = DnsProxyServer.Lookup((byte)(_socket.RemoteAddr >> 24 & 0xFF)); var header = new byte[domain.Length + 4]; header[0] = 0x03; header[1] = (byte)domain.Length; Encoding.ASCII.GetBytes(domain).CopyTo(header, 2); header[header.Length - 2] = (byte)(_socket.RemotePort >> 8); header[header.Length - 1] = (byte)(_socket.RemotePort & 0xFF); // Let header be sent first remoteConnected = true; SendToRemote(header); byte[] remotebuf = new byte[2048]; while (r.Connected) { while (sendBuffers.Count > 1) { checkSendBufferHandle.WaitOne(); checkSendBufferHandle.Reset(); } try { var len = await r.ReceiveAsync(new ArraySegment <byte>(remotebuf), SocketFlags.None); if (len == 0) { Debug.WriteLine("Empty run"); break; } Debug.WriteLine($"Received {len} bytes"); RemoteReceived(remotebuf.Take(len).ToArray()); } catch (Exception) { break; } } DisconnectRemote(); }
public async void Init() { try { await r.ConnectAsync(server, port); networkStream = r.GetStream(); } catch (Exception) { Debug.WriteLine("Error connecting to remote"); DisconnectRemote(); Reset(); return; } Debug.WriteLine("Connected"); /* * var header = new byte[7]; * header[0] = 0x01; * header[1] = (byte)(_socket.RemoteAddr & 0xFF); * header[2] = (byte)(_socket.RemoteAddr >> 8 & 0xFF); * header[3] = (byte)(_socket.RemoteAddr >> 16 & 0xFF); * header[4] = (byte)(_socket.RemoteAddr >> 24); * header[5] = (byte)(_socket.RemotePort >> 8); * header[6] = (byte)(_socket.RemotePort & 0xFF); */ string domain = DnsProxyServer.Lookup(_socket.RemoteAddr); if (domain == null) { Debug.WriteLine("Cannot find DNS record"); DisconnectRemote(); Reset(); return; } byte[] firstSeg = null; int headerLen = domain.Length + 4; int bytesToConfirm = 0; if (localbuf.TryDequeue(out var firstBuf)) { bytesToConfirm = firstBuf.Length; firstSeg = new byte[headerLen + firstBuf.Length]; Array.Copy(firstBuf, 0, firstSeg, headerLen, firstBuf.Length); } else { firstSeg = new byte[headerLen]; } firstSeg[0] = 0x03; firstSeg[1] = (byte)domain.Length; Encoding.ASCII.GetBytes(domain).CopyTo(firstSeg, 2); firstSeg[headerLen - 2] = (byte)(_socket.RemotePort >> 8); firstSeg[headerLen - 1] = (byte)(_socket.RemotePort & 0xFF); var(encryptedFirstSeg, encryptedFirstSegLen) = Encrypt(firstSeg, (uint)firstSeg.Length); try { await networkStream.WriteAsync(encryptedFirstSeg, 0, (int)encryptedFirstSegLen); while (localbuf.TryDequeue(out var buf)) { bytesToConfirm += buf.Length; // await networkWriteStream.WriteAsync(await Encrypt(buf)); var(data, len) = Encrypt(buf, (uint)buf.Length); await networkStream.WriteAsync(data, 0, (int)len); } remoteConnected = true; Recved((ushort)bytesToConfirm); //await networkWriteStream.FlushAsync(); Debug.WriteLine("Sent data with header"); } catch (Exception) { Debug.WriteLine("Error sending header to remote"); DisconnectRemote(); Reset(); return; } // IBuffer remotebuf = WindowsRuntimeBuffer.Create(RECV_BUFFER_LEN); byte[] remotebuf = new byte[RECV_BUFFER_LEN]; while (r.Connected && networkStream.CanRead) { try { var len = await networkStream.ReadAsync(remotebuf, 0, RECV_BUFFER_LEN).ConfigureAwait(false); if (len == 0) { break; } #if YTLOG_VERBOSE Debug.WriteLine($"Received {len} bytes"); #endif await RemoteReceived(Decrypt(remotebuf, (uint)len)); } catch (Exception) { break; } } try { Debug.WriteLine("Remote sent no data"); // networkReadStream?.Dispose(); r?.Client?.Shutdown(SocketShutdown.Receive); Close(); } catch (Exception) { } }
public async void Init(string hashedPassword) { try { await r.ConnectAsync(server, port); // TODO: verify certificate // TODO: compile first // networkStream = new SslStream(r.GetStream(), false, new RemoteCertificateValidationCallback((a, b, c, d) => true)); // await networkStream.AuthenticateAsClientAsync(server); } catch (Exception) { Debug.WriteLine("Error connecting to remote"); DisconnectRemote(); Reset(); return; } Debug.WriteLine("Connected"); string domain = DnsProxyServer.Lookup(_socket.RemoteAddr); if (domain == null) { Debug.WriteLine("Cannot find DNS record"); DisconnectRemote(); Reset(); return; } byte[] firstSeg = null; int headerLen = domain.Length + 65; int bytesToConfirm = 0; if (localbuf.TryDequeue(out var firstBuf)) { bytesToConfirm = firstBuf.Length; firstSeg = new byte[headerLen + firstBuf.Length]; Array.Copy(firstBuf, 0, firstSeg, headerLen, firstBuf.Length); } else { firstSeg = new byte[headerLen]; } Encoding.UTF8.GetBytes(hashedPassword).CopyTo(firstSeg.AsSpan()); // hex(SHA224(password)) firstSeg[56] = 0x0D; // CR firstSeg[57] = 0x0A; // LF firstSeg[58] = 0x01; // CMD firstSeg[59] = 0x03; // ATYP firstSeg[60] = (byte)domain.Length; // DST.ADDR length Encoding.ASCII.GetBytes(domain).CopyTo(firstSeg, 61); firstSeg[headerLen - 4] = (byte)(_socket.RemotePort >> 8); firstSeg[headerLen - 3] = (byte)(_socket.RemotePort & 0xFF); firstSeg[headerLen - 2] = 0x0D; firstSeg[headerLen - 1] = 0x0A; await networkStream.WriteAsync(firstSeg, 0, firstSeg.Length); try { while (localbuf.TryDequeue(out var buf)) { bytesToConfirm += buf.Length; await networkStream.WriteAsync(buf, 0, buf.Length); } remoteConnected = true; Recved((ushort)bytesToConfirm); Debug.WriteLine("Sent data with header"); } catch (Exception) { Debug.WriteLine("Error sending header to remote"); DisconnectRemote(); Reset(); return; } byte[] remotebuf = new byte[RECV_BUFFER_LEN]; while (r.Connected && networkStream.CanRead) { try { var len = await networkStream.ReadAsync(remotebuf, 0, RECV_BUFFER_LEN).ConfigureAwait(false); if (len == 0) { break; } #if YTLOG_VERBOSE Debug.WriteLine($"Received {len} bytes"); #endif await RemoteReceived(remotebuf.AsMemory(0, len)); } catch (Exception) { break; } } try { Debug.WriteLine("Remote sent no data"); r?.Client?.Shutdown(SocketShutdown.Receive); Close(); } catch (Exception) { } }
public async void Init() { var connectTask = r.ConnectAsync(server, port); Debug.WriteLine("Connected"); string domain = DnsProxyServer.Lookup(_socket.RemoteAddr); if (domain == null) { Debug.WriteLine("Cannot find DNS record"); DisconnectRemote(); Reset(); return; } string portStr = _socket.RemotePort.ToString(); byte[] portBytes = Encoding.UTF8.GetBytes(portStr); byte[] domainBytes = Encoding.UTF8.GetBytes(domain); int headerLen = HEADER1.Length + domainBytes.Length + 1 + portBytes.Length + HEADER2.Length; byte[] firstSeg = new byte[headerLen]; HEADER1.CopyTo(firstSeg, 0); domainBytes.CopyTo(firstSeg, HEADER1.Length); firstSeg[HEADER1.Length + domainBytes.Length] = (byte)':'; portBytes.CopyTo(firstSeg, HEADER1.Length + domainBytes.Length + 1); HEADER2.CopyTo(firstSeg, headerLen - HEADER2.Length); try { await connectTask; networkStream = r.GetStream(); await networkStream.WriteAsync(firstSeg, 0, headerLen); byte[] responseBuf = new byte[RECV_BUFFER_LEN]; var responseLen = await networkStream.ReadAsync(responseBuf, 0, 100); if (responseLen < 14) { throw new InvalidOperationException("Remote response too short."); } if ((responseBuf[9] == (byte)'2') && (responseBuf[10] == (byte)'0') && (responseBuf[11] == (byte)'0')) { // 200 objk } else { throw new InvalidOperationException("Remote connection cannot be established."); } bool foundHeader = false; int headerStart; for (headerStart = 12; headerStart < responseLen - 3; headerStart++) { if (responseBuf[headerStart] == '\r') { if (responseBuf[headerStart + 1] == '\n') { if (responseBuf[headerStart + 2] == '\r') { if (responseBuf[headerStart + 3] == '\n') { foundHeader = true; break; } } } } } if (!foundHeader) { throw new InvalidOperationException("Unrecognized remote header."); } headerStart += 4; if (headerStart >= responseLen) { // No initial data } else { await RemoteReceived(responseBuf.AsMemory(headerStart, responseLen)); } int bytesToConfirm = 0; while (localbuf.TryDequeue(out var buf)) { bytesToConfirm += buf.Length; // await networkWriteStream.WriteAsync(await Encrypt(buf)); await networkStream.WriteAsync(buf, 0, buf.Length); } remoteConnected = true; if (bytesToConfirm > 0) { Recved((ushort)bytesToConfirm); } //await networkWriteStream.FlushAsync(); Debug.WriteLine("Sent data with header"); } catch (Exception ex) { Debug.WriteLine("Error sending header to remote" + ex.Message); DisconnectRemote(); Reset(); return; } // IBuffer remotebuf = WindowsRuntimeBuffer.Create(RECV_BUFFER_LEN); byte[] remotebuf = new byte[RECV_BUFFER_LEN]; while (r.Connected && networkStream.CanRead) { try { var len = await networkStream.ReadAsync(remotebuf, 0, RECV_BUFFER_LEN).ConfigureAwait(false); if (len == 0) { break; } #if YTLOG_VERBOSE Debug.WriteLine($"Received {len} bytes"); #endif await RemoteReceived(remotebuf.AsMemory(0, len)); } catch (Exception) { break; } } try { Debug.WriteLine("Remote sent no data"); // networkReadStream?.Dispose(); r?.Client?.Shutdown(SocketShutdown.Receive); Close(); } catch (Exception) { } }