コード例 #1
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="targetHost"></param>
        /// <param name="autoHandle"></param>
        public RdpemtClient(RdpeudpSocket socket, string targetHost, bool autoHandle = true)
            : base(autoHandle)
        {
            if (!socket.AutoHandle)
            {
                throw new NotSupportedException("To Create RDPEMT Server, RDPEUDP Socket must be auto handle.");
            }

            if (socket.TransMode == TransportMode.Reliable)
            {
                RdpeudpTLSChannel secChannel = new RdpeudpTLSChannel(socket);
                secChannel.Received += ReceiveBytes;
                secChannel.AuthenticateAsClient(targetHost);
                this.secureChannel = secChannel;
            }
            else
            {
                RdpeudpDTLSChannel secChannel = new RdpeudpDTLSChannel(socket);
                secChannel.Received += ReceiveBytes;
                secChannel.AuthenticateAsClient(targetHost);
                this.secureChannel = secChannel;
            }

            bandwidthMeasureStartTime        = DateTime.Now;
            bandwidthMeasurePayloadByteCount = 0;
            detectBandwidth = false;
        }
コード例 #2
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="eudpSocket">RDPEUDP Socket, which is transport</param>
        public RdpeudpDTLSChannel(RdpeudpSocket eudpSocket)
        {
            if (eudpSocket == null || eudpSocket.TransMode == TransportMode.Reliable)
            {
                throw new NotSupportedException("RdpeudpSocket is null or it is a socket for reliable RDPEUDP connection.");
            }

            this.rdpeudpSocket           = eudpSocket;
            this.rdpeudpSocket.Received += ReceiveBytes;
            isAuthenticated              = false;

            rdpeudpSocket.Disconnected += RdpeudpSocket_Disconnected;

            receivedBuffer = new List <byte[]>();
            toSendBuffer   = new List <byte[]>();

            if (eudpSocket.AutoHandle)
            {
                // Check whether there is packets in unprocessed packet buffer

                RdpeudpPacket packet = eudpSocket.ExpectPacket(shortWaitTime);
                if (packet != null)
                {
                    eudpSocket.ReceivePacket(packet);
                }
            }
        }
コード例 #3
0
        /// <summary>
        /// Send an invalid UDP source Packet.
        /// </summary>
        /// <param name="udpTransportMode"></param>
        /// <param name="invalidType"></param>
        private void SendInvalidUdpSourcePacket(TransportMode udpTransportMode, SourcePacket_InvalidType invalidType)
        {
            RdpeudpSocket rdpeudpSocket = rdpeudpSocketR;
            RdpemtServer  rdpemtServer  = rdpemtServerR;

            if (udpTransportMode == TransportMode.Lossy)
            {
                rdpeudpSocket = rdpeudpSocketL;
                rdpemtServer  = rdpemtServerL;
            }

            if (invalidType == SourcePacket_InvalidType.LargerSourcePayload)
            {
                // Change UpStreamMtu of RDPEUDP Socket, so that large data can be sent
                ushort upstreamMtu = rdpeudpSocket.UUpStreamMtu;
                rdpeudpSocket.UUpStreamMtu = 2000;

                byte[]          data       = new byte[1600];
                RDP_TUNNEL_DATA tunnelData = rdpemtServer.CreateTunnelDataPdu(data, null);
                rdpemtServer.SendRdpemtPacket(tunnelData);

                // Change UpStreamMtu to correct value
                rdpeudpSocket.UUpStreamMtu = upstreamMtu;
            }
        }
コード例 #4
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="targetHost"></param>
        /// <param name="autoHandle"></param>
        /// <param name="selectedSslProtocols">The selected SSL protocols.</param>
        public RdpemtClient(RdpeudpSocket socket, string targetHost, bool autoHandle = true, SslProtocols selectedSslProtocols = SslProtocols.Tls)
            : base(autoHandle)
        {
            if (!socket.AutoHandle)
            {
                throw new NotSupportedException("To Create RDPEMT Server, RDPEUDP Socket must be auto handle.");
            }

            if (socket.TransMode == TransportMode.Reliable)
            {
                RdpeudpTLSChannel secChannel = new RdpeudpTLSChannel(socket);
                secChannel.Received += ReceiveBytes;
                secChannel.AuthenticateAsClient(targetHost, selectedSslProtocols);
                this.secureChannel = secChannel;
            }
            else
            {
                RdpeudpDTLSChannel secChannel = new RdpeudpDTLSChannel(socket);
                secChannel.Received += ReceiveBytes;
                secChannel.AuthenticateAsClient(targetHost);
                this.secureChannel = secChannel;
            }

            Initialize();
        }
コード例 #5
0
        /// <summary>
        /// Expect for a Source Packet.
        /// </summary>
        /// <param name="udpTransportMode">Transport mode: reliable or lossy.</param>
        /// <param name="timeout">Wait time</param>
        /// <returns></returns>
        private RdpeudpPacket WaitForSourcePacket(TransportMode udpTransportMode, TimeSpan timeout, uint sequnceNumber = 0)
        {
            RdpeudpSocket rdpeudpSocket = rdpeudpSocketR;

            if (udpTransportMode == TransportMode.Lossy)
            {
                rdpeudpSocket = rdpeudpSocketL;
            }

            DateTime endTime = DateTime.Now + timeout;

            while (DateTime.Now < endTime)
            {
                RdpeudpPacket packet = rdpeudpSocket.ExpectPacket(endTime - DateTime.Now);
                if (packet != null && packet.fecHeader.uFlags.HasFlag(RDPUDP_FLAG.RDPUDP_FLAG_DATA))
                {
                    if (sequnceNumber == 0 || packet.sourceHeader.Value.snSourceStart == sequnceNumber)
                    {
                        return(packet);
                    }
                }
            }

            return(null);
        }
コード例 #6
0
        /// <summary>
        /// Send a udp packet.
        /// </summary>
        /// <param name="udpTransportMode">Transport mode: reliable or lossy.</param>
        /// <param name="packet">The packet to send.</param>
        private void SendPacket(TransportMode udpTransportMode, RdpeudpPacket packet)
        {
            RdpeudpSocket rdpeudpSocket = rdpeudpSocketR;
            if (udpTransportMode == TransportMode.Lossy)
            {
                rdpeudpSocket = rdpeudpSocketL;
            }

            rdpeudpSocket.SendPacket(packet);
        }
コード例 #7
0
        /// <summary>
        /// Establish a MultiTransport Connection
        /// </summary>
        private void EstablishTransportConnection()
        {
            // Send the Server Initial multitransport
            byte[] securityCookie = new byte[16];
            Random rnd            = new Random();

            rnd.NextBytes(securityCookie);

            Server_Initiate_Multitransport_Request_PDU requestPDU = rdpbcgrServer.CreateServerInitiateMultitransportRequestPDU(serverSessionContext, ++multitransportId, transportProtocol, securityCookie);

            rdpbcgrServer.SendPdu(serverSessionContext, requestPDU);

            //Create RDP-UDP Connection
            CreateRdpeudpServer(this.serverSessionContext);
            TransportMode transMode = TransportMode.Reliable;

            if (transportProtocol == Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECL)
            {
                transMode = TransportMode.Lossy;
            }

            rdpeudpSocket = rdpeudpServer.Accept(((IPEndPoint)serverSessionContext.Identity).Address, transMode, timeout);
            if (rdpeudpSocket == null)
            {
                if (rdpeudpServer != null && rdpeudpServer.Running)
                {
                    rdpeudpServer.Dispose();
                }

                throw new NotSupportedException("RDPEMT Server create rdpedupSocket failed.");
            }
            rdpemtServer           = new RdpemtServer(rdpeudpSocket, rdpbcgrServer.AuthCertificate, true);
            rdpemtServer.Received += ReceivedBytes;

            uint receivedRequestId;

            byte[] receivedCookie;
            if (!rdpemtServer.ExpectConnect(timeout, out receivedRequestId, out receivedCookie))
            {
                throw new ProtocolViolationException("RDPEMT Server Expect Connection failed");
            }
            if (receivedRequestId != multitransportId || receivedCookie == null || receivedCookie.Length != 16)
            {
                throw new ProtocolViolationException("RDPEMT Server received a connection with un-expected request id or Cookie is null (or cookie's length is not 16)!");
            }

            for (int i = 0; i < receivedCookie.Length; i++)
            {
                if (receivedCookie[i] != securityCookie[i])
                {
                    throw new ProtocolViolationException("RDPEMT Server received a connection with un-correct cookie!");
                }
            }
        }
コード例 #8
0
        /// <summary>
        /// Get the next valid rdpeudp packet.
        /// </summary>
        /// <param name="udpTransportMode">Transport mode: reliable or Lossy.</param>
        /// <returns>The next valid rdpeudp packet.</returns>
        private RdpeudpPacket GetNextValidUdpPacket(TransportMode udpTransportMode, byte[] data = null)
        {
            /*This function is used to get a valid rdpeudp packet.
             * Using rdpeudpSocket.LossPacket flag to control whether the socket send the packet.
             * First set rdpeudpSocket.LossPacket to true and send a tunnal Data, the socket will store the next packet(RDPEUDP socket which contains the encrypted tunnel data) and doesn't send it.
             * Then get the stored packet and return it.
             */
            RdpemtServer  rdpemtServer  = rdpemtServerR;
            RdpeudpSocket rdpeudpSocket = rdpeudpSocketR;

            if (udpTransportMode == TransportMode.Lossy)
            {
                rdpemtServer  = rdpemtServerL;
                rdpeudpSocket = rdpeudpSocketL;
            }

            if (data == null)
            {
                data = new byte[1000];
            }
            RDP_TUNNEL_DATA tunnelData = rdpemtServer.CreateTunnelDataPdu(data, null);

            byte[] unEncryptData = PduMarshaler.Marshal(tunnelData);
            byte[] encryptData   = null;

            if (udpTransportMode == TransportMode.Reliable)
            {
                RdpeudpTLSChannel secChannel = rdpemtServer.SecureChannel as RdpeudpTLSChannel;
                encryptData = secChannel.Encrypt(unEncryptData);
            }
            else
            {
                RdpeudpDTLSChannel secChannel      = rdpemtServer.SecureChannel as RdpeudpDTLSChannel;
                List <byte[]>      encryptDataList = secChannel.Encrypt(unEncryptData);
                if (encryptDataList != null && encryptDataList.Count > 0)
                {
                    encryptData = encryptDataList[0];
                }
            }

            RdpeudpPacket packet = rdpeudpSocket.CreateSourcePacket(encryptData);

            return(packet);
        }
コード例 #9
0
        /// <summary>
        /// Establish a UDP connection
        /// </summary>
        /// <param name="udpTransportMode">Transport mode: Reliable or Lossy</param>
        /// <param name="timeout">wait time</param>
        /// <returns>The accepted socket</returns>
        private void EstablishUDPConnection(TransportMode udpTransportMode, TimeSpan timeout)
        {
            //Start UDP listening
            if (rdpeudpServer == null)
            {
                rdpeudpServer = new RdpeudpServer((IPEndPoint)this.rdpbcgrAdapter.SessionContext.LocalIdentity, true);

                rdpeudpServer.UnhandledExceptionReceived += (ex) =>
                {
                    Site.Log.Add(LogEntryKind.Debug, $"Unhandled exception from RdpeudpServer: {ex}");
                };
            }
            if (!rdpeudpServer.Running)
            {
                rdpeudpServer.Start();
            }

            //Send a Server Initiate Multitransport Request PDU
            byte[] securityCookie = new byte[16];
            Random rnd            = new Random();

            rnd.NextBytes(securityCookie);
            Multitransport_Protocol_value requestedProtocol = Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECR;

            if (udpTransportMode == TransportMode.Lossy)
            {
                requestedProtocol = Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECL;
            }
            this.rdpbcgrAdapter.SendServerInitiateMultitransportRequestPDU(++this.multitransportRequestId, requestedProtocol, securityCookie);
            this.requestIdList.Add(this.multitransportRequestId);
            this.securityCookieList.Add(securityCookie);

            //create a UDP socket
            RdpeudpSocket rdpudpSocket = rdpeudpServer.Accept(((IPEndPoint)this.rdpbcgrAdapter.SessionContext.Identity).Address, udpTransportMode, timeout);

            if (udpTransportMode == TransportMode.Reliable)
            {
                this.rdpeudpSocketR = rdpudpSocket;
            }
            else
            {
                this.rdpeudpSocketL = rdpudpSocket;
            }
        }
コード例 #10
0
        /// <summary>
        /// Wait for an ACK packet which meets certain conditions.
        /// </summary>
        /// <param name="udpTransportMode">Transport mode: reliable or lossy.</param>
        /// <param name="timeout">Wait time.</param>
        /// <param name="expectAckVectors">Expected ack vectors.</param>
        /// <param name="hasFlag">Flags, which the ACK packet must contain.</param>
        /// <param name="notHasFlag">Flags, which the ACK packet must no contain.</param>
        /// <returns></returns>
        private RdpeudpPacket WaitForACKPacket(TransportMode udpTransportMode, TimeSpan timeout, AckVector[] expectAckVectors = null, RDPUDP_FLAG hasFlag = 0, RDPUDP_FLAG notHasFlag = 0)
        {
            RdpeudpSocket rdpeudpSocket = rdpeudpSocketR;

            if (udpTransportMode == TransportMode.Lossy)
            {
                rdpeudpSocket = rdpeudpSocketL;
            }

            DateTime endTime = DateTime.Now + timeout;

            while (DateTime.Now < endTime)
            {
                RdpeudpPacket ackPacket = rdpeudpSocket.ExpectACKPacket(endTime - DateTime.Now);
                if (ackPacket != null)
                {
                    if (expectAckVectors != null)
                    {
                        if (!(ackPacket.ackVectorHeader.HasValue && CompareAckVectors(ackPacket.ackVectorHeader.Value.AckVectorElement, expectAckVectors)))
                        {
                            continue;
                        }
                    }
                    if (hasFlag != 0)
                    {
                        if ((ackPacket.fecHeader.uFlags & hasFlag) != hasFlag)
                        {
                            continue;
                        }
                    }
                    if (notHasFlag != 0)
                    {
                        if ((ackPacket.fecHeader.uFlags & notHasFlag) != 0)
                        {
                            continue;
                        }
                    }
                    return(ackPacket);
                }
            }

            return(null);
        }
コード例 #11
0
        /// <summary>
        /// Used to establish a RDPEMT connection
        /// </summary>
        /// <param name="udpTransportMode">Transport Mode: Reliable or Lossy</param>
        /// <param name="timeout">wait time</param>
        private void EstablishRdpemtConnection(TransportMode udpTransportMode, TimeSpan timeout, bool verifyPacket = false)
        {
            RdpeudpSocket rdpeudpSocket = rdpeudpSocketR;

            if (udpTransportMode == TransportMode.Lossy)
            {
                rdpeudpSocket = rdpeudpSocketL;
            }

            String certFile;

            PtfPropUtility.GetPtfPropertyValue(Site, "CertificatePath", out certFile);

            String certPwd;

            PtfPropUtility.GetPtfPropertyValue(Site, "CertificatePassword", out certPwd);

            X509Certificate2 cert         = new X509Certificate2(certFile, certPwd);
            RdpemtServer     rdpemtServer = new RdpemtServer(rdpeudpSocket, cert, false);

            uint receivedRequestId;

            byte[] receivedSecurityCookie;
            if (!rdpemtServer.ExpectConnect(waitTime, out receivedRequestId, out receivedSecurityCookie))
            {
                Site.Assert.Fail("RDPEMT tunnel creation failed");
            }

            if (verifyPacket)
            {
                VerifyTunnelCreateRequestPacket(receivedRequestId, receivedSecurityCookie);
            }

            if (udpTransportMode == TransportMode.Reliable)
            {
                rdpemtServerR = rdpemtServer;
            }
            else
            {
                rdpemtServerL = rdpemtServer;
            }
        }
コード例 #12
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="eudpSocket">A RdpeudpSocket used for transport</param>
        public RdpeudpTLSChannel(RdpeudpSocket eudpSocket)
        {
            if (eudpSocket == null || eudpSocket.TransMode == TransportMode.Lossy)
            {
                throw new NotSupportedException("RdpeudpSocket is null or it is a socket for Lossy RDPEUDP connection.");
            }
            this.rdpeudpSocket           = eudpSocket;
            this.rdpeudpSocket.Received += ReceiveBytes;
            innerStream     = new SSLInnerStream();
            isAuthenticated = false;

            if (eudpSocket.AutoHandle)
            {
                // Check whether there is packets in unprocessed packet buffer

                RdpeudpPacket packet = eudpSocket.ExpectPacket(shortWaitTime);
                if (packet != null)
                {
                    eudpSocket.ReceivePacket(packet);
                }
            }
        }
コード例 #13
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="cert"></param>
        /// <param name="autoHandle"></param>
        public RdpemtServer(RdpeudpSocket socket, X509Certificate2 cert, bool autoHandle = true)
            : base(autoHandle)
        {
            if (!socket.AutoHandle)
            {
                throw new NotSupportedException("To Create RDPEMT Server, RDPEUDP Socket must be auto handle.");
            }

            if (socket.TransMode == TransportMode.Reliable)
            {
                RdpeudpTLSChannel secChannel = new RdpeudpTLSChannel(socket);
                secChannel.Received += ReceiveBytes;
                secChannel.AuthenticateAsServer(cert);
                this.secureChannel = secChannel;
            }
            else
            {
                RdpeudpDTLSChannel secChannel = new RdpeudpDTLSChannel(socket);
                secChannel.Received += ReceiveBytes;
                secChannel.AuthenticateAsServer(cert);
                this.secureChannel = secChannel;
            }
        }