public Boolean TryConnectAndInitialize(TlsSettings tlsSettings, Buf sendBuffer, ServerInfo serverInfo /*, SelectTunnelsThread tunnelsThread*/) { if (Connected) { throw new InvalidOperationException(String.Format( "You called Connect() on accessor '{0}' but its already connected", accessorHostString)); } try { accessorSocket = NewSocketConnection(ref accessorHost); // // Send initial connection information // Boolean setupTls = tlsSettings.requireTlsForTmpConnections; Byte[] connectionInfoPacket = new Byte[] { Tmp.CreateConnectionInfoFromTmpServerToAccessor( tlsSettings.requireTlsForTmpConnections, false) }; accessorSocket.Send(connectionInfoPacket); // // Only receive packet if tls was not required // if (!tlsSettings.requireTlsForTmpConnections) { int bytesRead = accessorSocket.Receive(connectionInfoPacket, 0, 1, SocketFlags.None); if (bytesRead <= 0) { throw new SocketException(); } setupTls = Tmp.ReadTlsRequirementFromAccessorToTmpServer(connectionInfoPacket[0]); } DataHandler accessorSendHandler = new SocketSendDataHandler(accessorSocket).HandleData; this.accessorReceiveHandler = new DataFilterHandler(new FrameProtocolFilter(), new TmpServerHandler(this, tlsSettings /*, tunnelsThread*/)); // // Initiate a tls connection if required // if (setupTls) { throw new NotImplementedException("Tls not yet implemented"); } // // Send server info // UInt32 commandLength = Tmp.SerializeCommand(ServerInfo.Serializer, Tmp.ToAccessorServerInfoID, serverInfo, sendBuffer, 0); accessorSendHandler(sendBuffer.array, 0, commandLength); return(true); } catch (Exception) { this.accessorSocket = null; this.accessorReceiveHandler = null; return(false); } }
public void AcceptClientHandler(ref SelectControl control, Socket listenSocket, Buf safeBuffer) //(Socket listenSocket, Socket socket, Buf safeBuffer) { //return tmpConnectionManager.AcceptAndInitiateTunnel(this, socket, safeBuffer); Socket clientSocket = listenSocket.Accept(); Console.WriteLine("{0} [{1}] Received tunnel connection for server '{2}' to connect to target '{3}:{4}'", DateTime.Now, clientSocket.SafeRemoteEndPointString(), serverName, targetHost, targetPort); // // Check if server is connected // TmpControlConnection tmpControlConnection = TryGetTmpControlConnection(serverName); if (tmpControlConnection == null) { Console.WriteLine("{0} [{1}] Server '{2}' is not currently connected", DateTime.Now, clientSocket.SafeRemoteEndPointString(), serverName); clientSocket.ShutdownAndDispose(); return; } // // Generate a tunnel key // Int32 randomKey = random.Next(); // // TODO: This would generate an infinite loop if every single key was taken up in the dictionary, // however, I'm not sure if I should worry about this or not? Maybe there's a better way to do // this? // while (true) { if (!incompleteTunnels.ContainsKey(randomKey)) { break; } randomKey++; } DisconnectedTunnel disconnectedTunnel = new DisconnectedTunnel(clientSocket); incompleteTunnels.Add(randomKey, disconnectedTunnel); Byte[] tunnelKey = new Byte[4]; tunnelKey[0] = (Byte)(randomKey >> 24); tunnelKey[1] = (Byte)(randomKey >> 16); tunnelKey[2] = (Byte)(randomKey >> 8); tunnelKey[3] = (Byte)(randomKey); // // Send Open Tunnel command to TmpServer // OpenAccessorTunnelRequest request = new OpenAccessorTunnelRequest(0, targetHostBytes, targetPort, tunnelKey); UInt32 commandLength = Tmp.SerializeCommand <OpenAccessorTunnelRequest>(OpenAccessorTunnelRequest.Serializer, Tmp.ToServerOpenAccessorTunnelRequestID, request, safeBuffer, 0); tmpControlConnection.dataSender.HandleData(safeBuffer.array, 0, commandLength); // // Create a diconnected tunnel handler // control.AddReceiveSocket(clientSocket, disconnectedTunnel.ConnectedSocketReceiveHandler); }
public void HandleData(Byte[] data, UInt32 offset, UInt32 length) { byte id = data[offset]; switch (id) { case Tmp.ToServerOpenTunnelRequestID: Console.WriteLine("{0} Got OpenTunnelRequest", DateTime.Now); break; case Tmp.ToServerOpenAccessorTunnelRequestID: Console.WriteLine("{0} Got OpenAccessorTunnelRequest", DateTime.Now); try { OpenAccessorTunnelRequest request; OpenAccessorTunnelRequest.Serializer.Deserialize(data, offset + 1, offset + length, out request); throw new NotImplementedException(); #if COMMENT // // Connect to accessor // Socket socketToAccessor = accessorConnection.MakeNewSocketAndConnect(); // // Handle encryption options // IDataHandler sendHandler = new SocketSendDataHandler(socketToAccessor); if ((request.Options & TunnelOptions.RequireTls) == TunnelOptions.RequireTls) { // // Send Connection Info // Byte[] connectionInfo = new Byte[] { Tmp.CreateConnectionInfoFromTmpServerToAccessor(true, true) }; socketToAccessor.Send(connectionInfo); throw new NotImplementedException("Ssl not implemented for tunnels yet"); } else { // // Send connection info and tunnel key in the same packet // Byte[] connectionInfoAndTunnelKey = new Byte[2 + request.TunnelKey.Length]; connectionInfoAndTunnelKey[0] = Tmp.CreateConnectionInfoFromTmpServerToAccessor(false, true); connectionInfoAndTunnelKey[1] = (Byte)request.TunnelKey.Length; Array.Copy(request.TunnelKey, 0, connectionInfoAndTunnelKey, 2, request.TunnelKey.Length); socketToAccessor.Send(connectionInfoAndTunnelKey); } // // Connect to target // String targetIPOrHost = Encoding.ASCII.GetString(request.TargetHost); IPEndPoint targetEndPoint = new IPEndPoint(EndPoints.ParseIPOrResolveHost(targetIPOrHost, DnsPriority.IPv4ThenIPv6), request.TargetPort); Socket socketToTarget = new Socket(targetEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); socketToTarget.Connect(targetEndPoint); tunnelsThread.Add(socketToAccessor, socketToTarget); #endif } catch (Exception e) { Console.WriteLine(e); } break; default: Console.WriteLine("{0} Got Frame with unknown id {1}", DateTime.Now, id); break; } }
/* * public SimpleSelectHandler HandleConnectionFromTmpServer(Socket listenSocket, Socket socket, Buf safeBuffer) * { * Console.WriteLine("{0} [{1}] Accepted TmpServer Socket", DateTime.Now, socket.SafeRemoteEndPointString()); * return HandleInitialConnectionInfo; * } */ static void HandleInitialConnectionInfo(ref SelectControl selectControl, Socket socket, Buf safeBuffer) { Int32 bytesRead = socket.Receive(safeBuffer.array, 1, SocketFlags.None); if (bytesRead <= 0) { Console.WriteLine("{0} WARNING: Socket closed", DateTime.Now); selectControl.DisposeAndRemoveReceiveSocket(socket); return; } Byte connectionInfo = safeBuffer.array[0]; Boolean accessorRequiresTls, isTunnel; Tmp.ReadConnectionInfoFromTmpServer(connectionInfo, out accessorRequiresTls, out isTunnel); // // Determine if TLS should be set up // Boolean setupTls; if (accessorRequiresTls) { setupTls = true; } else if (!isTunnel) { // The TmpServer is waiting for a response to indicate whether it should setup TLS setupTls = GlobalTlsSettings.requireTlsForTmpConnections; socket.Send(new Byte[] { setupTls ? (Byte)1 : (Byte)0 }); } else { setupTls = false; } IDataHandler sendDataHandler = new SocketSendDataHandler(socket); IDataFilter receiveDataFilter = null; // // Setup TLS if necessary // if (setupTls) { // // Negotiate TLS, setup sendDataHandler and receiveDataFilter // Console.WriteLine("{0} [{1}] This connection requires tls but it is not currently supported", DateTime.Now, socket.SafeRemoteEndPointString()); selectControl.ShutdownDisposeAndRemoveReceiveSocket(socket); return; } IPEndPoint remoteEndPoint = (IPEndPoint)(socket.RemoteEndPoint); if (isTunnel) { Console.WriteLine("{0} [{1}] Is a Tunnel Connection", DateTime.Now, remoteEndPoint.ToString()); TmpServerSideTunnelKeyReceiver keyReceiver = new TmpServerSideTunnelKeyReceiver(); selectControl.UpdateHandler(socket, keyReceiver.SocketReceiverHandler); } else { Console.WriteLine("{0} [{1}] Is a Control Connection", DateTime.Now, remoteEndPoint.ToString()); TmpControlConnection tmpControlConnection = new TmpControlConnection(GlobalTlsSettings, remoteEndPoint, socket, sendDataHandler, receiveDataFilter); tmpControlConnections.Add(tmpControlConnection); selectControl.UpdateHandler(socket, tmpControlConnection.SocketReceiverHandler); } }