コード例 #1
0
        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);
        }
コード例 #2
0
 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());
     }
 }
コード例 #3
0
 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");
     }
 }
コード例 #4
0
        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);
        }
コード例 #5
0
        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);
        }