// Complete the forward proxy connection if a proxy is configured and also // send any buffered data from the client to the server. void FinishConnection(Byte[] extraData, UInt32 offset, UInt32 length) { if (AppLayerProxy.ForwardProxy != null) { serverSocket.Blocking = true; BufStruct buf = default(BufStruct); AppLayerProxy.ForwardProxy.ProxyConnectTcp(serverSocket, ref serverEndPointForProxy, isConnect ? 0 : ProxyConnectOptions.ContentIsRawHttp, ref buf); if (buf.contentLength > 0) { throw new NotImplementedException("The proxy connection left over some data from the server, this is not currently being handled"); } } if (isConnect) { clientSocket.Send(HttpVars.ConnectionEstablishedAsBytes); } if (length > 0) { if (AppLayerProxy.Logger != null) { AppLayerProxy.Logger.WriteLine("{0} > {1} {2} bytes{3}", clientLogString, serverLogString, length, (clientBuffer != null && extraData == clientBuffer.bytes) ? " (buffered)" : ""); } // The clientBuffer should have already been setup then serverSocket.Send(extraData, (int)clientBuffer.contentLength, SocketFlags.None); } }
void Connect() { Console.WriteLine("[Connecting to {0}...]", serverHost); BufStruct bufStruct = default(BufStruct); serverHost.Connect(socket, DnsPriority.IPv4ThenIPv6, ProxyConnectOptions.None, ref bufStruct); if (bufStruct.contentLength > 0) { throw new NotImplementedException(); } Console.WriteLine("[Connected]"); if (bufStruct.contentLength > 0) { if (messageLogger != null) { messageLogger.Log("[RecvThread] Received {0} bytes", bufStruct.contentLength); } if (connectionLogger != null) { connectionLogger.LogDataBToA(bufStruct.buf, 0, (int)bufStruct.contentLength); } } }
static void AcceptCallback(ref SelectControl control, Socket listenSock, Buf safeBuffer) { Socket newSock = listenSock.Accept(); if (log != null) { log.WriteLine("Accepted new client {0}", newSock.SafeRemoteEndPointString()); } Socket clientSideSocket = new Socket(server.GetAddressFamilyForTcp(), SocketType.Stream, ProtocolType.Tcp); BufStruct leftOver = new BufStruct(safeBuffer.array); clientSideSocket.Connect(server, DnsPriority.IPv4ThenIPv6, ProxyConnectOptions.None, ref leftOver); if (leftOver.contentLength > 0) { newSock.Send(leftOver.buf, 0, (int)leftOver.contentLength, SocketFlags.None); if (pcapLogger != null) { //pcapLogger.LogTcpData(leftOver.buf, 0, leftOver.contentLength); } } SelectSocketTunnel tunnel = new SelectSocketTunnel(newSock, clientSideSocket); control.AddReceiveSocket(newSock, tunnel.ReceiveCallback); control.AddReceiveSocket(clientSideSocket, tunnel.ReceiveCallback); }
public override void ProxyConnectTcp(Socket socket, ref StringEndPoint endPoint, ProxyConnectOptions options, ref BufStruct buf) { if ((options & ProxyConnectOptions.ContentIsRawHttp) == 0) { throw new NotImplementedException(); } }
public Socket ListenAndAccept(UInt16 port) { Byte[] bindRequest = new Byte[9]; Byte[] replyBuffer = new Byte[8]; bindRequest[0] = 4; // Version 4 of SOCKS protocol bindRequest[1] = 2; // Command 2 "BIND" bindRequest[2] = (byte)(port >> 8); bindRequest[3] = (byte)(port); bindRequest[4] = 174; bindRequest[5] = 34; bindRequest[6] = 174; bindRequest[7] = 4; bindRequest[8] = 0; // User ID // // Connect to the proxy server // Socket socket = new Socket(host.GetAddressFamilyForTcp(), SocketType.Stream, ProtocolType.Tcp); BufStruct dataLeftOverFromProxyReceive = default(BufStruct); host.Connect(socket, host.dnsPriorityQuery, ProxyConnectOptions.None, ref dataLeftOverFromProxyReceive); if (dataLeftOverFromProxyReceive.contentLength > 0) { throw new NotImplementedException("Data left over from proxy negotiation not implemented"); } socket.Send(bindRequest); socket.ReadFullSize(replyBuffer, 0, 8); if (replyBuffer[0] != 0) { Console.WriteLine("WARNING: The first byte of the proxy response was expected to be 0 but it was {0}", replyBuffer[0]); } if (replyBuffer[1] != 90) { throw new Proxy4Exception(replyBuffer[1]); } UInt16 listenPort = (UInt16)( (0xFF00 & (replyBuffer[2] << 8)) | (0xFF & (replyBuffer[3])) ); Byte[] ip = new Byte[4]; ip[0] = replyBuffer[4]; ip[1] = replyBuffer[5]; ip[2] = replyBuffer[6]; ip[3] = replyBuffer[7]; Console.WriteLine("EndPoint {0}:{1}", new IPAddress(ip).ToString(), listenPort); return(socket); }
public static Socket NewSocketConnection(ref InternetHost host) { Socket socket = new Socket(host.GetAddressFamilyForTcp(), SocketType.Stream, ProtocolType.Tcp); BufStruct dataLeftOverFromProxyConnect = default(BufStruct); host.Connect(socket, DnsPriority.IPv4ThenIPv6, ProxyConnectOptions.None, ref dataLeftOverFromProxyConnect); if (dataLeftOverFromProxyConnect.contentLength > 0) { throw new NotImplementedException(); } return(socket); }
void Open(BufStruct buf) { if (socket == null || !socket.Connected) { if (proxy == null) { serverEndPoint.ForceIPResolution(DnsPriority.IPv4ThenIPv6); socket = new Socket(serverEndPoint.ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); socket.Connect(serverEndPoint.ipEndPoint); } else { socket = new Socket(proxy.host.GetAddressFamilyForTcp(), SocketType.Stream, ProtocolType.Tcp); proxy.ProxyConnectTcp(socket, ref serverEndPoint, ProxyConnectOptions.ContentIsRawHttp, ref buf); } } }
static Int32 Main(string[] args) { TelnetOptions optionsParser = new TelnetOptions(); List <String> nonOptionArgs = optionsParser.Parse(args); if (nonOptionArgs.Count != 1) { Console.WriteLine("Expected 1 argument but got {0}", nonOptionArgs.Count); optionsParser.PrintUsage(); return(-1); } InternetHost?serverHost; if (nonOptionArgs.Count == 1) { String connectorString = nonOptionArgs[0]; Proxy proxy; String ipOrHostOptionalPort = Proxy.StripAndParseProxies(connectorString, DnsPriority.IPv4ThenIPv6, out proxy); UInt16 port = DefaultPort; String ipOrHost = EndPoints.SplitIPOrHostAndOptionalPort(ipOrHostOptionalPort, ref port); serverHost = new InternetHost(ipOrHost, port, DnsPriority.IPv4ThenIPv6, proxy); } else { serverHost = null; } TelnetClient client = new TelnetClient(optionsParser.wantServerEcho.set, !optionsParser.disableColorDecoding.set); Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); if (serverHost != null) { BufStruct leftOver = default(BufStruct); socket.Connect(serverHost.Value, DnsPriority.IPv4ThenIPv6, ProxyConnectOptions.None, ref leftOver); if (leftOver.contentLength > 0) { Console.WriteLine(Encoding.UTF8.GetString(leftOver.buf, 0, (int)leftOver.contentLength)); } } client.Run(socket); return(0); }
public override void ProxyConnectTcp(Socket socket, ref StringEndPoint endPoint, ProxyConnectOptions options, ref BufStruct buf) { BufStruct forwardBufStruct = default(BufStruct); host.Connect(socket, DnsPriority.IPv4ThenIPv6, ProxyConnectOptions.None, ref forwardBufStruct); if (forwardBufStruct.contentLength > 0) { throw new NotImplementedException(); } if (endPoint.stringIsAnIP) { ProxyConnectTcpUsingIP(socket, endPoint.ipEndPoint.Address, endPoint.port); } else { ProxyConnectTcpUsingHost(socket, endPoint.ipOrHost, endPoint.port); } }
/* * public String ConnectorString(StringEndPoint targetEndPoint) * { * return String.Format("{0}:{1}:{2}%{3}", Type, * ipOrHost, endPoint.Port, targetEndPoint); * } * public override String ToString() * { * return String.Format("{0}:{1}:{2}", Type, ipOrHost, endPoint.Port); * } */ // Design Note: The ProxyConnect method could also connect the socket, however, // in some cases the socket will already be connected, so, this api // doesn't wrap connecting the socket. Note that this means typically // this call will always follow immediately after calling socket.Connect() /// <summary> /// Setup the proxy connection. The given socket must already be connected. /// The endpoint should have been retrieved from the proxy's CreateEndpoint method. /// /// Once the method is done, any leftover data from the socket will be in the given buffer /// </summary> /// <param name="socket">A connected tcp socket</param> /// <param name="ipEndPoint">The final destination, retreived from calling proxy.CreateEndpoint(...).</param> public abstract void ProxyConnectTcp(Socket socket, ref StringEndPoint endPoint, ProxyConnectOptions options, ref BufStruct buf);
public override Boolean ProxyConnectAsyncTcp(Socket socket, ref StringEndPoint endPoint, ProxyConnectOptions options, ref BufStruct buf) { throw new NotImplementedException(); }
public override void ProxyConnectTcp(Socket socket, ref StringEndPoint endPoint, ProxyConnectOptions options, ref BufStruct buf) { host.Connect(socket, DnsPriority.IPv4ThenIPv6, options, ref buf); }
public override void ProxyConnectTcp(Socket socket, ref StringEndPoint endPoint, ProxyConnectOptions options, ref BufStruct buf) { throw new NotImplementedException(); /* * // * // Check if the proxy end point string is valid * // * socket.Send(Encoding.UTF8.GetBytes(String.Format( * "CONNECT {0} HTTP/1.1\r\nHost: {0}:{1}\r\n\r\n", * endpoint.unparsedIPOrHost, endpoint.port))); * * NetworkStream stream = new NetworkStream(socket); * * // * // Process first line * // * for (int i = 0; i < 9; i++) * { * Int32 nextByte = stream.ReadByte(); * if ((nextByte & 0xFF) != nextByte) throw new SocketException(); * } * * // * // Get response code * // * Char[] responseCodeChars = new Char[3]; * responseCodeChars[0] = (Char)stream.ReadByte(); * responseCodeChars[1] = (Char)stream.ReadByte(); * responseCodeChars[2] = (Char)stream.ReadByte(); * String responseCodeString = new String(responseCodeChars); * * Int32 responseCode; * if (!Int32.TryParse(responseCodeString, out responseCode)) * throw new InvalidOperationException(String.Format("First line of HTTP Connect response was not formatted correctly (Expected response code but got '{0}')", responseCodeString)); * * if (responseCode != 200) throw new InvalidOperationException(String.Format("Expected response code 200 but got {0}", responseCode)); * * // * // Read until end of response * // * Int32 lineLength = 12; * * while (true) * { * Int32 nextByte = stream.ReadByte(); * //Console.WriteLine("[HttpsProxyDebug] Got Char '{0}'", (Char)nextByte); * if ((nextByte & 0xFF) != nextByte) throw new SocketException(); * * if (nextByte != '\r') * { * lineLength++; * } * else * { * nextByte = stream.ReadByte(); * if ((nextByte & 0xFF) != nextByte) throw new SocketException(); * if (nextByte != '\n') throw new InvalidOperationException(String.Format( * "Received '\\r' and expected '\\n' next but got (Char)'{0}' (Int32)'{1}'", * (Char)nextByte, nextByte)); * * * if (lineLength <= 0) break; * * lineLength = 0; * } * } */ }
public override void ProxyConnectTcp(Socket socket, ref StringEndPoint endPoint, ProxyConnectOptions options, ref BufStruct buf) { endPoint.ForceIPResolution(DnsPriority.IPv4ThenIPv6); socket.Connect(endPoint.ipEndPoint); }
public abstract Boolean ProxyConnectAsyncTcp(Socket socket, ref StringEndPoint endPoint, ProxyConnectOptions options, ref BufStruct buf);
public override void ProxyConnectTcp(Socket socket, ref StringEndPoint endPoint, ProxyConnectOptions options, ref BufStruct forwardBufStruct) { host.Connect(socket, DnsPriority.IPv4ThenIPv6, ProxyConnectOptions.None, ref forwardBufStruct); if (forwardBufStruct.contentLength > 0) { throw new NotImplementedException(); } if ((options & ProxyConnectOptions.ContentIsRawHttp) != 0) { // do nothing } else { // send an HTTP CONNECT method unsafe { AsciiPartsBuilder builder = new AsciiPartsBuilder(CONNECT_REQUEST_PARTS, endPoint.ipOrHost, endPoint.ipOrHost, endPoint.port.ToString()); UInt32 contentLength = builder.PrecalculateLength(); Byte[] buffer = new Byte[(int)contentLength]; builder.BuildInto(buffer); /* * Console.Write("Request\n--------------------------\n"); * Console.Write(Encoding.ASCII.GetString(buffer)); * Console.Write("\n--------------------------\n"); */ socket.SendFullSize(buffer); ByteBuilder responseBuilder = new ByteBuilder(200); int endOfHeadersIndex = 0; while (true) { int lastReceived = socket.Receive(buffer); if (lastReceived <= 0) { /* * Console.Write("Response\n--------------------------\n"); * Console.Write(Encoding.ASCII.GetString(responseBuilder.bytes, 0, (int)responseBuilder.contentLength)); * Console.Write("\n--------------------------\n"); */ throw new InvalidOperationException(String.Format("socket Receive returned {0} (received {1} bytes total)", lastReceived, responseBuilder.contentLength)); } responseBuilder.Append(buffer, 0, (uint)lastReceived); bool foundEndOfHeaders = false; for (; endOfHeadersIndex + 3 < responseBuilder.contentLength; endOfHeadersIndex++) { if (responseBuilder.bytes[endOfHeadersIndex] == '\r' && responseBuilder.bytes[endOfHeadersIndex + 1] == '\n' && responseBuilder.bytes[endOfHeadersIndex + 2] == '\r' && responseBuilder.bytes[endOfHeadersIndex + 3] == '\n') { endOfHeadersIndex += 4; foundEndOfHeaders = true; break; } } if (foundEndOfHeaders) { break; } // rewind 3 characters in case we got a partial double newline if (endOfHeadersIndex >= 3) { endOfHeadersIndex -= 3; } } if (!responseBuilder.bytes.Equals(0, HTTP_VERSION_RESPONSE, 0, (uint)HTTP_VERSION_RESPONSE.Length)) { throw new InvalidOperationException(String.Format( "invalid HTTP response header (starts with \"{0}\")", Encoding.ASCII.GetString(responseBuilder.bytes, 0, (HTTP_VERSION_RESPONSE.Length <= responseBuilder.contentLength) ? HTTP_VERSION_RESPONSE.Length : (int)responseBuilder.contentLength))); } if (HTTP_VERSION_RESPONSE.Length + 3 > responseBuilder.contentLength) { throw new InvalidOperationException("invalid HTTP response header (it's too short)"); } ResponseCode responseCode; responseCode.a = (char)responseBuilder.bytes[HTTP_VERSION_RESPONSE.Length + 0]; responseCode.b = (char)responseBuilder.bytes[HTTP_VERSION_RESPONSE.Length + 1]; responseCode.c = (char)responseBuilder.bytes[HTTP_VERSION_RESPONSE.Length + 2]; if (responseCode.a != '2' && responseCode.b != '0' && responseCode.c != '0') { throw new InvalidOperationException(String.Format("expected response code 200 but got {0}{1}{2}", responseCode.a, responseCode.b, responseCode.c)); } // TODO: receive the entire response if there is a content length!! Console.Write("Response\n--------------------------\n"); Console.Write(Encoding.ASCII.GetString(responseBuilder.bytes, 0, (int)responseBuilder.contentLength)); Console.Write("\n--------------------------\n"); throw new NotImplementedException(); } } }
public void Connect(Socket socket, PriorityQuery <IPAddress> dnsPriorityQuery, ProxyConnectOptions proxyOptions, ref BufStruct buf) { if (proxy == null) { targetEndPoint.ForceIPResolution(dnsPriorityQuery); socket.Connect(targetEndPoint.ipEndPoint); } else { proxy.ProxyConnectTcp(socket, ref targetEndPoint, proxyOptions, ref buf); } }
static Int32 Main(string[] args) { Options options = new Options(); if (args.Length == 0) { options.PrintUsage(); return(0); } List <String> nonOptionArgs = options.Parse(args); socketToConsoleBuffer = new Byte[options.bufferSizes.ArgValue]; consoleToSocketBuffer = new Byte[options.bufferSizes.ArgValue]; if (options.listenMode.set) { IPAddress localAddress = EndPoints.ParseIPOrResolveHost(options.localHost.ArgValue, DnsPriority.IPv4ThenIPv6); Socket listenSocket = new Socket(localAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); listenSocket.Bind(new IPEndPoint(localAddress, options.localPort.ArgValue)); listenSocket.Listen(1); dataSocket = listenSocket.Accept(); } else if (nonOptionArgs.Count != 2) { if (nonOptionArgs.Count == 0) { options.PrintUsage(); return(0); } return(options.ErrorAndUsage("In client/connect mode there should be 2 non-option command line arguments but got {0}", nonOptionArgs.Count)); } else { String connectorString = nonOptionArgs[0]; String portString = nonOptionArgs[1]; UInt16 port = UInt16.Parse(portString); InternetHost host; { Proxy proxy; String ipOrHost = Proxy.StripAndParseProxies(connectorString, DnsPriority.IPv4ThenIPv6, out proxy); host = new InternetHost(ipOrHost, port, DnsPriority.IPv4ThenIPv6, proxy); } dataSocket = new Socket(host.GetAddressFamilyForTcp(), SocketType.Stream, ProtocolType.Tcp); if (options.localPort.set) { dataSocket.Bind(new IPEndPoint(IPAddress.Any, options.localPort.ArgValue)); } BufStruct leftOverData = new BufStruct(socketToConsoleBuffer); host.Connect(dataSocket, DnsPriority.IPv4ThenIPv6, ProxyConnectOptions.None, ref leftOverData); if (leftOverData.contentLength > 0) { PrepareConsole(); consoleOutputStream.Write(leftOverData.buf, 0, (int)leftOverData.contentLength); } } // Note: I'm not sure these options are actually working if (options.tcpSendWindow.ArgValue != 0) { dataSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendBuffer, options.tcpSendWindow.ArgValue); } if (options.tcpReceiveWindow.ArgValue != 0) { dataSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, options.tcpReceiveWindow.ArgValue); } PrepareConsole(); Thread consoleReadThread = new Thread(ConsoleReceiveThread); consoleReadThread.Name = "Console Read Thread"; // Don't know how to cancel a console input stream read, so I have to // put the console read thread as a background thread so it doesn't keep // the program running. consoleReadThread.IsBackground = true; consoleReadThread.Start(); try { while (true) { Int32 bytesRead = dataSocket.Receive(socketToConsoleBuffer, socketToConsoleBuffer.Length, SocketFlags.None); if (bytesRead <= 0) { lock (typeof(NetCat)) { if (!closed) { closed = true; } } break; } consoleOutputStream.Write(socketToConsoleBuffer, 0, bytesRead); } } catch (SocketException e) { } finally { lock (typeof(NetCat)) { if (!closed) { consoleInputStream.Dispose(); closed = true; } } // Do not join other thread, just exit } return(0); }