/// <summary> /// Invoke customize filter. /// </summary> /// <param name="stackPacket">stackPacket to be filtered.</param> /// <returns>Filter result. True if the packet should be filtered by the customized filter and discarded. Otherwise false.</returns> public bool CustomizeFilter(StackPacket stackPacket) { if (this.CustomizeFilterCallback != null) { return(this.CustomizeFilterCallback(stackPacket)); } return(false); }
/// <summary> /// Filter packets. /// </summary> /// <param name="packet">packet to be filtered.</param> /// <returns>Filter result. True if the type of packet agrees with the filter. Otherwise false.</returns> public bool FilterPacket(StackPacket packet) { //Use class name as filter lock (this) { foreach (Type type in typeFilters) { if (type == packet.GetType()) { return(true); } } } return(false); }
/// <summary> /// this function will be invoked every time a packet is sent or received. all logics about /// Client' states will be implemented here. /// </summary> /// <param name="connectionId">the connection identity.</param> /// <param name="packet">the sent or received packet in stack transport.</param> public virtual void UpdateRoleContext(int connectionId, StackPacket packet) { CifsClientPerConnection connection = this.GetConnection(connectionId) as CifsClientPerConnection; SmbPacket smbPacket = packet as SmbPacket; // Do nothing if no connection is found or the packet is not SmbPacket: if (connection == null || smbPacket == null) { return; } UpdateRoleContext(connection, smbPacket); }
/// <summary> /// Update some members of context with the specified pdu. /// </summary> /// <param name="pdu">The sending or receiving pdu.</param> public void UpdateContext(StackPacket pdu) { lock (contextLock) { if (!isSwitchOn) { // Don't update context but wait for upper layer TSD to do so. return; } if (pdu.GetType() == typeof(Client_X_224_Connection_Request_Pdu)) { x224ConnectionRequestPdu = (Client_X_224_Connection_Request_Pdu)pdu.Clone(); } else if (pdu.GetType() == typeof(Server_X_224_Connection_Confirm_Pdu)) { x224ConnectionConfirmPdu = ((Server_X_224_Connection_Confirm_Pdu)pdu.Clone()).rdpNegData; } else if (pdu.GetType() == typeof(Server_X_224_Negotiate_Failure_Pdu)) { x224NegotiateFailurePdu = ((Server_X_224_Negotiate_Failure_Pdu)pdu.Clone()).rdpNegFailure; } else if (pdu.GetType() == typeof(Client_MCS_Connect_Initial_Pdu_with_GCC_Conference_Create_Request)) { mcsConnectInitialPdu = ((Client_MCS_Connect_Initial_Pdu_with_GCC_Conference_Create_Request) pdu.Clone()).mcsCi; } else if (pdu is Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response) { mcsConnectResponsePdu = (Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response) pdu.Clone(); serverRandom = RdpbcgrUtility.CloneByteArray(mcsConnectResponsePdu.mcsCrsp.gccPdu.serverSecurityData.serverRandom); ioChannelId = mcsConnectResponsePdu.mcsCrsp.gccPdu.serverNetworkData.MCSChannelId; if(mcsConnectResponsePdu.mcsCrsp.gccPdu.serverMessageChannelData != null) mcsMsgChannelId = mcsConnectResponsePdu.mcsCrsp.gccPdu.serverMessageChannelData.MCSChannelID; encryptionAlgorithm = new EncryptionAlgorithm(RdpEncryptionMethod); } else if (pdu.GetType() == typeof(Server_MCS_Attach_User_Confirm_Pdu)) { if (((Server_MCS_Attach_User_Confirm_Pdu)pdu).attachUserConfirm.initiator != null) { userChannelId = (ushort)((Server_MCS_Attach_User_Confirm_Pdu)pdu).attachUserConfirm.initiator.Value; } } else if (pdu.GetType() == typeof(Client_Security_Exchange_Pdu)) { securityExchangePdu = (Client_Security_Exchange_Pdu)pdu.Clone(); clientRandom = RdpbcgrUtility.CloneByteArray( ((Client_Security_Exchange_Pdu)pdu).securityExchangePduData.clientRandom); GenerateSessionKey(); } else if (pdu.GetType() == typeof(Client_Info_Pdu)) { clientInfo = ((Client_Info_Pdu)pdu.Clone()).infoPacket; if (clientInfo != null && (clientInfo.flags & flags_Values.INFO_COMPRESSION) == flags_Values.INFO_COMPRESSION) { ioDecompressor = new Decompressor(SlidingWindowSize.EightKB); ioCompressor = new Compressor(SlidingWindowSize.EightKB); } isWaitingLicenseErrorPdu = true; } else if (pdu.GetType() == typeof(Server_Auto_Detect_Request_PDU)) { NETWORK_DETECTION_REQUEST requestData = ((Server_Auto_Detect_Request_PDU)pdu).autoDetectReqData.Clone(); if (requestData.requestType == AUTO_DETECT_REQUEST_TYPE.RDP_RTT_REQUEST_IN_CONNECTTIME || requestData.requestType == AUTO_DETECT_REQUEST_TYPE.RDP_RTT_REQUEST_AFTER_CONNECTTIME) { RDP_RTT_REQUEST rttRequest = (RDP_RTT_REQUEST)requestData; rttRequest.sendTime = DateTime.Now; this.serverAutoDetectRequestData.Add(rttRequest.sequenceNumber, rttRequest); } } else if (pdu.GetType() == typeof(Client_Auto_Detect_Response_PDU)) { clientAutoDetectResponsePdu = (Client_Auto_Detect_Response_PDU)pdu.Clone(); NETWORK_DETECTION_RESPONSE responseData = clientAutoDetectResponsePdu.autodetectRspPduData; if (responseData.responseType == AUTO_DETECT_RESPONSE_TYPE.RDP_RTT_RESPONSE) { RDP_RTT_REQUEST rttRequest = (RDP_RTT_REQUEST)serverAutoDetectRequestData[responseData.sequenceNumber]; if (rttRequest != null) { TimeSpan interval = DateTime.Now - rttRequest.sendTime; this.autoDetectedRTTList.Add((uint)interval.TotalMilliseconds); serverAutoDetectRequestData.Remove(responseData.sequenceNumber); } } else if (responseData.responseType == AUTO_DETECT_RESPONSE_TYPE.RDP_BW_RESULTS_AFTER_CONNECT || responseData.responseType == AUTO_DETECT_RESPONSE_TYPE.RDP_BW_RESULTS_DURING_CONNECT) { RDP_BW_RESULTS bwResult = (RDP_BW_RESULTS)responseData; if(bwResult.timeDelta != 0) this.autoDetectedBandwidth = (uint)(bwResult.byteCount / bwResult.timeDelta); } else if (responseData.responseType == AUTO_DETECT_RESPONSE_TYPE.RDP_NETCHAR_SYNC) { RDP_NETCHAR_SYNC netSync = (RDP_NETCHAR_SYNC)responseData; this.autoDetectedRTTList.Add(netSync.rtt); this.autoDetectedBandwidth = netSync.bandwidth; } } else if (pdu.GetType() == typeof(Server_License_Error_Pdu_Valid_Client)) { licenseErrorPdu = (Server_License_Error_Pdu_Valid_Client)pdu.Clone(); serverChannelId = licenseErrorPdu.commonHeader.initiator; } else if (pdu.GetType() == typeof(Server_Initiate_Multitransport_Request_PDU)) { Server_Initiate_Multitransport_Request_PDU requestPDU = (Server_Initiate_Multitransport_Request_PDU)pdu; serverInitiateMultitransportRequestPduDictionary.Add(requestPDU.requestId, requestPDU); } else if (pdu.GetType() == typeof(Client_Initiate_Multitransport_Response_PDU)) { clientInitiateMultitransportResponsePdu = (Client_Initiate_Multitransport_Response_PDU)pdu; } else if (pdu.GetType() == typeof(Server_Demand_Active_Pdu)) { serverChannelId = ((Server_Demand_Active_Pdu)pdu.Clone()).commonHeader.initiator; demandActivePdu = ((Server_Demand_Active_Pdu)pdu.Clone()).demandActivePduData; } else if (pdu.GetType() == typeof(Client_Confirm_Active_Pdu)) { comfirmActivePdu = ((Client_Confirm_Active_Pdu)pdu.Clone()).confirmActivePduData; if (channelManager == null) { channelManager = new ServerStaticVirtualChannelManager(this); } } else if (pdu.GetType() == typeof(MCS_Disconnect_Provider_Ultimatum_Server_Pdu)) { lastDisconnectReason = (int)((MCS_Disconnect_Provider_Ultimatum_Server_Pdu) pdu).disconnectProvider.reason.Value; } else if (pdu.GetType() == typeof(MCS_Disconnect_Provider_Ultimatum_Pdu)) { lastDisconnectReason = (int)((MCS_Disconnect_Provider_Ultimatum_Pdu) pdu).disconnectProvider.reason.Value; } else if (pdu.GetType() == typeof(Server_Set_Error_Info_Pdu)) { lastErrorInfo = ((Server_Set_Error_Info_Pdu)pdu).errorInfoPduData.errorInfo; } else if (pdu.GetType() == typeof(Server_Status_Info_Pdu)) { lastStatusInfo = ((Server_Status_Info_Pdu)pdu).statusCode; } else if (pdu.GetType() == typeof(Server_Save_Session_Info_Pdu)) { Server_Save_Session_Info_Pdu saveSessionInfoPdu = (Server_Save_Session_Info_Pdu)pdu.Clone(); switch (saveSessionInfoPdu.saveSessionInfoPduData.infoType) { case infoType_Values.INFOTYPE_LOGON: logonInfoV1 = (TS_LOGON_INFO)saveSessionInfoPdu.saveSessionInfoPduData.infoData; break; case infoType_Values.INFOTYPE_LOGON_LONG: logonInfoV2 = (TS_LOGON_INFO_VERSION_2)saveSessionInfoPdu.saveSessionInfoPduData.infoData; break; case infoType_Values.INFOTYPE_LOGON_EXTENDED_INF: TS_LOGON_INFO_EXTENDED infoExtended = (TS_LOGON_INFO_EXTENDED)saveSessionInfoPdu.saveSessionInfoPduData.infoData; switch (infoExtended.FieldsPresent) { case FieldsPresent_Values.LOGON_EX_AUTORECONNECTCOOKIE | FieldsPresent_Values.LOGON_EX_LOGONERRORS: autoReconnectCookie = (ARC_SC_PRIVATE_PACKET)infoExtended.LogonFields[0].FieldData; logonErrorsInfo = (TS_LOGON_ERRORS_INFO)infoExtended.LogonFields[1].FieldData; break; case FieldsPresent_Values.LOGON_EX_AUTORECONNECTCOOKIE: autoReconnectCookie = (ARC_SC_PRIVATE_PACKET)infoExtended.LogonFields[0].FieldData; break; case FieldsPresent_Values.LOGON_EX_LOGONERRORS: logonErrorsInfo = (TS_LOGON_ERRORS_INFO)infoExtended.LogonFields[0].FieldData; break; default: break; } break; default: break; } } } }
/// <summary> /// Add a unprocessed PDU into buffer of this RDP session /// </summary> /// <param name="pdu"></param> public void AddPacketToBuffer(StackPacket pdu) { lock (unprocessedPacketBuffer) { unprocessedPacketBuffer.Add(pdu); } }
/// <summary> /// Update some members of context with the specified pdu. /// </summary> /// <param name="pdu">The sending or receiving pdu.</param> public void UpdateContext(StackPacket pdu) { lock (contextLock) { if (!isSwitchOn) { // Don't update context but wait for upper layer TSD to do so. return; } if (pdu.GetType() == typeof(Client_X_224_Connection_Request_Pdu)) { x224ConnectionRequestPdu = (Client_X_224_Connection_Request_Pdu)pdu.Clone(); } else if (pdu.GetType() == typeof(Server_X_224_Connection_Confirm_Pdu)) { x224ConnectionConfirmPdu = ((Server_X_224_Connection_Confirm_Pdu)pdu.Clone()).rdpNegData; } else if (pdu.GetType() == typeof(Server_X_224_Negotiate_Failure_Pdu)) { x224NegotiateFailurePdu = ((Server_X_224_Negotiate_Failure_Pdu)pdu.Clone()).rdpNegFailure; } else if (pdu.GetType() == typeof(Client_MCS_Connect_Initial_Pdu_with_GCC_Conference_Create_Request)) { mcsConnectInitialPdu = ((Client_MCS_Connect_Initial_Pdu_with_GCC_Conference_Create_Request) pdu.Clone()).mcsCi; } else if (pdu.GetType() == typeof(Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response)) { mcsConnectResponsePdu = (Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response) pdu.Clone(); encryptionAlgorithm = new EncryptionAlgorithm(RdpEncryptionMethod); } else if (pdu.GetType() == typeof(Server_MCS_Attach_User_Confirm_Pdu)) { userChannelId = (long)((Server_MCS_Attach_User_Confirm_Pdu)pdu).attachUserConfirm.initiator.Value; } else if (pdu.GetType() == typeof(Client_Security_Exchange_Pdu)) { clientRandom = RdpbcgrUtility.CloneByteArray( ((Client_Security_Exchange_Pdu)pdu).securityExchangePduData.clientRandom); } else if (pdu.GetType() == typeof(Client_Info_Pdu)) { clientInfo = ((Client_Info_Pdu)pdu.Clone()).infoPacket; if (clientInfo != null && (clientInfo.flags & flags_Values.INFO_COMPRESSION) == flags_Values.INFO_COMPRESSION) { ioDecompressor = new Decompressor((SlidingWindowSize)CompressionTypeSupported); } } else if (pdu.GetType() == typeof(Server_License_Error_Pdu_Valid_Client)) { licenseErrorPdu = (Server_License_Error_Pdu_Valid_Client)pdu.Clone(); } else if (pdu.GetType() == typeof(Server_Initiate_Multitransport_Request_PDU)) { Server_Initiate_Multitransport_Request_PDU initRequset = pdu as Server_Initiate_Multitransport_Request_PDU; if (initRequset.requestedProtocol == Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECR) { requestIdReliable = initRequset.requestId; cookieReliable = initRequset.securityCookie; } else { requestIdLossy = initRequset.requestId; cookieLossy = initRequset.securityCookie; } } else if (pdu.GetType() == typeof(Server_Demand_Active_Pdu)) { demandActivePdu = ((Server_Demand_Active_Pdu)pdu.Clone()).demandActivePduData; } else if (pdu.GetType() == typeof(Client_Confirm_Active_Pdu)) { comfirmActivePdu = ((Client_Confirm_Active_Pdu)pdu.Clone()).confirmActivePduData; if (channelManager == null) { channelManager = new ClientStaticVirtualChannelManager(this); } } else if (pdu.GetType() == typeof(MCS_Disconnect_Provider_Ultimatum_Pdu)) { lastDisconnectReason = (int)((MCS_Disconnect_Provider_Ultimatum_Pdu) pdu).disconnectProvider.reason.Value; } else if (pdu.GetType() == typeof(Server_Set_Error_Info_Pdu)) { lastErrorInfo = ((Server_Set_Error_Info_Pdu)pdu).errorInfoPduData.errorInfo; } else if (pdu.GetType() == typeof(Server_Status_Info_Pdu)) { lastStatusInfo = ((Server_Status_Info_Pdu)pdu).statusCode; } else if (pdu.GetType() == typeof(Server_Save_Session_Info_Pdu)) { Server_Save_Session_Info_Pdu saveSessionInfoPdu = (Server_Save_Session_Info_Pdu)pdu.Clone(); switch (saveSessionInfoPdu.saveSessionInfoPduData.infoType) { case infoType_Values.INFOTYPE_LOGON: logonInfoV1 = (TS_LOGON_INFO)saveSessionInfoPdu.saveSessionInfoPduData.infoData; break; case infoType_Values.INFOTYPE_LOGON_LONG: logonInfoV2 = (TS_LOGON_INFO_VERSION_2)saveSessionInfoPdu.saveSessionInfoPduData.infoData; break; case infoType_Values.INFOTYPE_LOGON_EXTENDED_INF: TS_LOGON_INFO_EXTENDED infoExtended = (TS_LOGON_INFO_EXTENDED)saveSessionInfoPdu.saveSessionInfoPduData.infoData; switch (infoExtended.FieldsPresent) { case FieldsPresent_Values.LOGON_EX_AUTORECONNECTCOOKIE | FieldsPresent_Values.LOGON_EX_LOGONERRORS: autoReconnectCookie = (ARC_SC_PRIVATE_PACKET)infoExtended.LogonFields[0].FieldData; logonErrorsInfo = (TS_LOGON_ERRORS_INFO)infoExtended.LogonFields[1].FieldData; break; case FieldsPresent_Values.LOGON_EX_AUTORECONNECTCOOKIE: autoReconnectCookie = (ARC_SC_PRIVATE_PACKET)infoExtended.LogonFields[0].FieldData; break; case FieldsPresent_Values.LOGON_EX_LOGONERRORS: logonErrorsInfo = (TS_LOGON_ERRORS_INFO)infoExtended.LogonFields[0].FieldData; break; default: break; } break; default: break; } } } }
/// <summary> /// Send a CIFS request to server. /// </summary> /// <param name="packet">the packet to be sent. It MUST NOT be null.</param> /// <exception cref="System.ArgumentNullException">the packet to be sent is null.</exception> /// <exception cref="System.InvalidOperationException">The transport is null for not connected.</exception> public void SendPacket(StackPacket packet) { if (packet == null) { throw new ArgumentNullException("packet"); } if (this.transport == null) { throw new InvalidOperationException("The transport is null for not connected." + " Please invoke Connect(string server, string client) first."); } if (((SmbPacket)packet).IsSignRequired && this.Context.GetConnection(this.connectionId).IsSigningActive) { CifsClientPerConnection connection = this.Context.GetConnection(this.connectionId); (packet as SmbPacket).Sign(connection.ClientNextSendSequenceNumber, connection.ConnectionSigningSessionKey, connection.ConnectionSigningChallengeResponse); } if (this.IsContextUpdateEnabled) { this.Context.UpdateRoleContext(this.connectionId, packet); } this.transport.SendPacket(packet); }
/// <summary> /// Filter packets. /// </summary> /// <param name="packet">packet to be filtered.</param> /// <returns>Filter result. True if the type of packet agrees with the filter. Otherwise false.</returns> public bool FilterPacket(StackPacket packet) { //Use class name as filter lock (this) { foreach (Type type in typeFilters) { if (type == packet.GetType()) { return true; } } } return false; }
/// <summary> /// Invoke customize filter. /// </summary> /// <param name="stackPacket">stackPacket to be filtered.</param> /// <returns>Filter result. True if the packet should be filtered by the customized filter and discarded. Otherwise false.</returns> public bool CustomizeFilter(StackPacket stackPacket) { if (this.CustomizeFilterCallback != null) { return this.CustomizeFilterCallback(stackPacket); } return false; }
/// <summary> /// Send a packet to a special remote host. /// </summary> /// <param name="endPoint">The remote host to which the packet will be sent.</param> /// <param name="packet">The packet to be sent.</param> public void SendPacket(object endPoint, StackPacket packet) { ValidServerHasStarted(); IPEndPoint ipEndPoint = endPoint as IPEndPoint; if (ipEndPoint == null) { throw new ArgumentException("The endPoint is not an IPEndPoint.", "endPoint"); } // If we use raw bytes to construct the packet, we send the raw bytes out directly, // otherwise we convert the packet to bytes and send it out. byte[] writeBytes = (packet.PacketBytes == null) ? packet.ToBytes() : packet.PacketBytes; Stream stream = GetStream(ipEndPoint.Address, ipEndPoint.Port); if (stream == null) { throw new InvalidOperationException("The endPoint is not in the connect list."); } stream.Write(writeBytes, 0, writeBytes.Length); }
/// <summary> /// Add the given stack packets to the QueueManager object if packet type not in filters or Customize filter. /// </summary> /// <param name="endPoint">the endpoint of the packets</param> /// <param name="packets">decoded packets</param> private void AddPacketToQueueManager(object endPoint, StackPacket[] packets) { if (packets == null) { return; } foreach (StackPacket packet in packets) { TransportEvent packetEvent = new TransportEvent(EventType.ReceivedPacket, endPoint, packet); this.packetQueue.AddObject(packetEvent); } }
/// <summary> /// to decode the CIFS packets. /// </summary> /// <param name="endPoint">the identification of the connection.</param> /// <param name="messageBytes">the message to be decoded.</param> /// <param name="consumedLength">the bytes length which are consumed when decode.</param> /// <param name="expectedLength">the expected length of data to be received.</param> /// <returns>the packets decoded from the input buffer.</returns> public StackPacket[] DecodePacket( object endPoint, byte[] messageBytes, out int consumedLength, out int expectedLength) { StackPacket[] packets = new StackPacket[0]; StackPacket response = this.DecodeSmbResponseFromBytes((int)endPoint, messageBytes, out consumedLength); // Use the decoded packet to UpdateRoleContext if it is not null and ContextUpdate is enabled: if (response != null) { if (this.isContextUpdateEnabled) { this.clientContext.UpdateRoleContext((int)endPoint, response); } packets = new StackPacket[] { response }; } expectedLength = 0; return packets; }