/// <summary> /// Update the config of transport at runtime. /// </summary> /// <param name="type">The type of transport stream.</param> internal void UpdateConfig(SecurityStreamType type) { foreach (Socket sock in this.receivingStreams.Keys) { if (receivingStreams[sock].ReceiveStream is SslStream || receivingStreams[sock].ReceiveStream is RdpbcgrServerCredSspStream) { //Skip the connections which already were updated to SSL or CredSSP. continue; } else { NetworkStream netStream = (NetworkStream)receivingStreams[sock].ReceiveStream; if (type == SecurityStreamType.Ssl) { SslStream sslStream = new SslStream(new ETWStream(netStream)); ((SslStream)sslStream).AuthenticateAsServer(this.cert); receivingStreams[sock].ReceiveStream = sslStream; } else if (type == SecurityStreamType.CredSsp) { string targetSPN = ConstValue.CREDSSP_SERVER_NAME_PREFIX + config.LocalIpAddress; RdpbcgrServerCredSspStream credSspStream = new RdpbcgrServerCredSspStream(new ETWStream(netStream), targetSPN); receivingStreams[sock].ReceiveStream = credSspStream; credSspStream.Authenticate(cert); } } } }
/// <summary> /// Creates a new Socket for a newly created connection and a new thread to receive packet in the loop. /// </summary> private void AcceptLoop() { while (!exitLoop) { if (this.receivingStreams.Count >= config.MaxConnections) { // not listen untill the current connections are less than the max value. // the interval to query is 1 seconds: Thread.Sleep(1000); continue; } Socket socket = null; try { socket = this.listenSock.Accept(); } catch (SocketException) { exitLoop = true; continue; } TransportEvent connectEvent; Stream receiveStream = null; Stream baseStream = new NetworkStream(socket); switch (streamType) { case SecurityStreamType.None: receiveStream = baseStream; break; case SecurityStreamType.Ssl: receiveStream = new SslStream( new ETWStream( baseStream), false ); ((SslStream)receiveStream).AuthenticateAsServer(cert); break; case SecurityStreamType.CredSsp: string targetSPN = ConstValue.CREDSSP_SERVER_NAME_PREFIX + config.LocalIpAddress; RdpbcgrServerCredSspStream credSspStream = new RdpbcgrServerCredSspStream(new ETWStream(baseStream), targetSPN); credSspStream.Authenticate(cert); receiveStream = credSspStream; break; default: receiveStream = baseStream; break; } RdpbcgrReceiveThread receiveThread = new RdpbcgrReceiveThread( socket.RemoteEndPoint, this.packetQueue, this.decoder, receiveStream, this.config.BufferSize, this.rdpbcgrServer); connectEvent = new TransportEvent(EventType.Connected, socket.RemoteEndPoint, null); RdpbcgrServerSessionContext session = new RdpbcgrServerSessionContext(); session.Identity = connectEvent.EndPoint; session.Server = this.rdpbcgrServer; session.LocalIdentity = socket.LocalEndPoint; session.IsClientToServerEncrypted = this.rdpbcgrServer.IsClientToServerEncrypted; this.rdpbcgrServer.ServerContext.AddSession(session); this.packetQueue.AddObject(connectEvent); lock (this.receivingStreams) { this.receivingStreams.Add(socket, receiveThread); } receiveThread.Start(); } }