private static BindAckPDU GetRPCBindResponse(BindPDU bindPDU, RemoteService service) { BindAckPDU bindAckPDU = new BindAckPDU(); PrepareReply(bindAckPDU, bindPDU); // See DCE 1.1: Remote Procedure Call - 12.6.3.6 // The client should set the assoc_group_id field either to 0 (zero), to indicate a new association group, // or to the known value. When the server receives a value of 0, this indicates that the client // has requested a new association group, and it assigns a server unique value to the group. if (bindPDU.AssociationGroupID == 0) { bindAckPDU.AssociationGroupID = m_associationGroupID; m_associationGroupID++; if (m_associationGroupID == 0) { m_associationGroupID++; } } else { bindAckPDU.AssociationGroupID = bindPDU.AssociationGroupID; } bindAckPDU.SecondaryAddress = @"\PIPE\" + service.PipeName; bindAckPDU.MaxReceiveFragmentSize = bindPDU.MaxReceiveFragmentSize; bindAckPDU.MaxTransmitFragmentSize = bindPDU.MaxTransmitFragmentSize; foreach (ContextElement element in bindPDU.ContextList) { ResultElement resultElement = new ResultElement(); if (element.AbstractSyntax.InterfaceUUID.Equals(service.InterfaceGuid)) { int index = IndexOfSupportedTransferSyntax(element.TransferSyntaxList); if (index >= 0) { resultElement.Result = NegotiationResult.Acceptance; resultElement.TransferSyntax = element.TransferSyntaxList[index]; } else if (element.TransferSyntaxList.Contains(new SyntaxID(BindTimeFeatureIdentifier3, 1))) { // [MS-RPCE] 3.3.1.5.3 // If the server supports bind time feature negotiation, it MUST reply with the result // field in the p_result_t structure of the bind_ack PDU equal to negotiate_ack. resultElement.Result = NegotiationResult.NegotiateAck; resultElement.Reason = RejectionReason.AbstractSyntaxNotSupported; } else { resultElement.Result = NegotiationResult.ProviderRejection; resultElement.Reason = RejectionReason.ProposedTransferSyntaxesNotSupported; } } else { resultElement.Result = NegotiationResult.ProviderRejection; resultElement.Reason = RejectionReason.AbstractSyntaxNotSupported; } bindAckPDU.ResultList.Add(resultElement); } return(bindAckPDU); }
private void ProcessRPCRequest(RPCPDU rpcRequest) { if (rpcRequest is BindPDU) { BindAckPDU bindAckPDU = RemoteServiceHelper.GetRPCBindResponse((BindPDU)rpcRequest, m_service); m_maxTransmitFragmentSize = bindAckPDU.MaxTransmitFragmentSize; Append(bindAckPDU.GetBytes()); } else if (m_maxTransmitFragmentSize.HasValue && rpcRequest is RequestPDU) // if BindPDU was not received, we treat as protocol error { List <RPCPDU> responsePDUs = RemoteServiceHelper.GetRPCResponse((RequestPDU)rpcRequest, m_service, m_maxTransmitFragmentSize.Value); foreach (RPCPDU responsePDU in responsePDUs) { Append(responsePDU.GetBytes()); } } else { FaultPDU faultPDU = new FaultPDU(); faultPDU.Flags = PacketFlags.FirstFragment | PacketFlags.LastFragment; faultPDU.DataRepresentation = new DataRepresentationFormat(CharacterFormat.ASCII, ByteOrder.LittleEndian, FloatingPointRepresentation.IEEE); faultPDU.CallID = 0; faultPDU.AllocationHint = RPCPDU.CommonFieldsLength + FaultPDU.FaultFieldsLength; faultPDU.Status = FaultStatus.ProtocolError; Append(faultPDU.GetBytes()); } }
private void ProcessRPCRequest(RPCPDU rpcRequest) { if (rpcRequest is BindPDU) { BindAckPDU bindAckPDU = RemoteServiceHelper.GetRPCBindResponse((BindPDU)rpcRequest, m_service); m_maxTransmitFragmentSize = bindAckPDU.MaxTransmitFragmentSize; Append(bindAckPDU.GetBytes()); } else if (rpcRequest is RequestPDU) { // if BindPDU was not received, we ignore any subsequent RPC packets if (m_maxTransmitFragmentSize.HasValue) { List <ResponsePDU> responsePDUs = RemoteServiceHelper.GetRPCResponse((RequestPDU)rpcRequest, m_service, m_maxTransmitFragmentSize.Value); foreach (ResponsePDU responsePDU in responsePDUs) { Append(responsePDU.GetBytes()); } } } else { throw new NotImplementedException("Unsupported RPC Packet Type"); } }
public static NTStatus BindPipe(INTFileStore namedPipeShare, string pipeName, Guid interfaceGuid, uint interfaceVersion, out object pipeHandle, out int maxTransmitFragmentSize) { maxTransmitFragmentSize = 0; FileStatus fileStatus; NTStatus status = namedPipeShare.CreateFile(out pipeHandle, out fileStatus, pipeName, (AccessMask)(FileAccessMask.FILE_READ_DATA | FileAccessMask.FILE_WRITE_DATA), 0, ShareAccess.Read | ShareAccess.Write, CreateDisposition.FILE_OPEN, 0, null); if (status != NTStatus.STATUS_SUCCESS) { return(status); } BindPDU bindPDU = new BindPDU(); bindPDU.Flags = PacketFlags.FirstFragment | PacketFlags.LastFragment; bindPDU.DataRepresentation.CharacterFormat = CharacterFormat.ASCII; bindPDU.DataRepresentation.ByteOrder = ByteOrder.LittleEndian; bindPDU.DataRepresentation.FloatingPointRepresentation = FloatingPointRepresentation.IEEE; bindPDU.MaxTransmitFragmentSize = 5680; bindPDU.MaxReceiveFragmentSize = 5680; ContextElement serviceContext = new ContextElement(); serviceContext.AbstractSyntax = new SyntaxID(interfaceGuid, interfaceVersion); serviceContext.TransferSyntaxList.Add(new SyntaxID(RemoteServiceHelper.NDRTransferSyntaxIdentifier, RemoteServiceHelper.NDRTransferSyntaxVersion)); bindPDU.ContextList.Add(serviceContext); byte[] input = bindPDU.GetBytes(); byte[] output; status = namedPipeShare.DeviceIOControl(pipeHandle, (uint)IoControlCode.FSCTL_PIPE_TRANSCEIVE, input, out output, 4096); if (status != NTStatus.STATUS_SUCCESS) { return(status); } BindAckPDU bindAckPDU = RPCPDU.GetPDU(output, 0) as BindAckPDU; if (bindAckPDU == null) { return(NTStatus.STATUS_NOT_SUPPORTED); } maxTransmitFragmentSize = bindAckPDU.MaxTransmitFragmentSize; return(NTStatus.STATUS_SUCCESS); }
public static List <string> ListShares(INTFileStore namedPipeShare, ShareType?shareType, out NTStatus status) { object pipeHandle; FileStatus fileStatus; status = namedPipeShare.CreateFile(out pipeHandle, out fileStatus, ServerService.ServicePipeName, (AccessMask)(FileAccessMask.FILE_READ_DATA | FileAccessMask.FILE_WRITE_DATA), 0, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_OPEN, 0, null); if (status != NTStatus.STATUS_SUCCESS) { return(null); } BindPDU bindPDU = new BindPDU(); bindPDU.Flags = PacketFlags.FirstFragment | PacketFlags.LastFragment; bindPDU.DataRepresentation.CharacterFormat = CharacterFormat.ASCII; bindPDU.DataRepresentation.ByteOrder = ByteOrder.LittleEndian; bindPDU.DataRepresentation.FloatingPointRepresentation = FloatingPointRepresentation.IEEE; bindPDU.MaxTransmitFragmentSize = 5680; bindPDU.MaxReceiveFragmentSize = 5680; ContextElement serverServiceContext = new ContextElement(); serverServiceContext.AbstractSyntax = new SyntaxID(ServerService.ServiceInterfaceGuid, ServerService.ServiceVersion); serverServiceContext.TransferSyntaxList.Add(new SyntaxID(RemoteServiceHelper.NDRTransferSyntaxIdentifier, RemoteServiceHelper.NDRTransferSyntaxVersion)); bindPDU.ContextList.Add(serverServiceContext); byte[] input = bindPDU.GetBytes(); byte[] output; status = namedPipeShare.DeviceIOControl(pipeHandle, (uint)IoControlCode.FSCTL_PIPE_TRANSCEIVE, input, out output, 4096); if (status != NTStatus.STATUS_SUCCESS) { return(null); } BindAckPDU bindAckPDU = RPCPDU.GetPDU(output, 0) as BindAckPDU; if (bindAckPDU == null) { status = NTStatus.STATUS_NOT_SUPPORTED; return(null); } NetrShareEnumRequest shareEnumRequest = new NetrShareEnumRequest(); shareEnumRequest.InfoStruct = new ShareEnum(); shareEnumRequest.InfoStruct.Level = 1; shareEnumRequest.InfoStruct.Info = new ShareInfo1Container(); shareEnumRequest.PreferedMaximumLength = UInt32.MaxValue; shareEnumRequest.ServerName = "*"; RequestPDU requestPDU = new RequestPDU(); requestPDU.Flags = PacketFlags.FirstFragment | PacketFlags.LastFragment; requestPDU.DataRepresentation.CharacterFormat = CharacterFormat.ASCII; requestPDU.DataRepresentation.ByteOrder = ByteOrder.LittleEndian; requestPDU.DataRepresentation.FloatingPointRepresentation = FloatingPointRepresentation.IEEE; requestPDU.OpNum = (ushort)ServerServiceOpName.NetrShareEnum; requestPDU.Data = shareEnumRequest.GetBytes(); requestPDU.AllocationHint = (uint)requestPDU.Data.Length; input = requestPDU.GetBytes(); int maxOutputLength = bindAckPDU.MaxTransmitFragmentSize; status = namedPipeShare.DeviceIOControl(pipeHandle, (uint)IoControlCode.FSCTL_PIPE_TRANSCEIVE, input, out output, maxOutputLength); if (status != NTStatus.STATUS_SUCCESS) { return(null); } ResponsePDU responsePDU = RPCPDU.GetPDU(output, 0) as ResponsePDU; if (responsePDU == null) { status = NTStatus.STATUS_NOT_SUPPORTED; return(null); } byte[] responseData = responsePDU.Data; while ((responsePDU.Flags & PacketFlags.LastFragment) == 0) { status = namedPipeShare.ReadFile(out output, pipeHandle, 0, maxOutputLength); if (status != NTStatus.STATUS_SUCCESS) { return(null); } responsePDU = RPCPDU.GetPDU(output, 0) as ResponsePDU; if (responsePDU == null) { status = NTStatus.STATUS_NOT_SUPPORTED; return(null); } responseData = ByteUtils.Concatenate(responseData, responsePDU.Data); } NetrShareEnumResponse shareEnumResponse = new NetrShareEnumResponse(responseData); ShareInfo1Container shareInfo1 = shareEnumResponse.InfoStruct.Info as ShareInfo1Container; if (shareInfo1 == null || shareInfo1.Entries == null) { if (shareEnumResponse.Result == Win32Error.ERROR_ACCESS_DENIED) { status = NTStatus.STATUS_ACCESS_DENIED; } else { status = NTStatus.STATUS_NOT_SUPPORTED; } return(null); } List <string> result = new List <string>(); foreach (ShareInfo1Entry entry in shareInfo1.Entries) { if (!shareType.HasValue || shareType.Value == entry.ShareType.ShareType) { result.Add(entry.NetName.Value); } } return(result); }