Пример #1
0
VOID PhSvcHandleConnectionRequest(
    __in PPHSVC_API_MSG Message
    )
{
    NTSTATUS status;
    PPHSVC_CLIENT client;
    HANDLE portHandle;
    REMOTE_PORT_VIEW clientView;

    client = PhSvcCreateClient(&Message->h.ClientId);

    if (!client)
    {
        NtAcceptConnectPort(&portHandle, NULL, &Message->h, FALSE, NULL, NULL);
        return;
    }

    Message->ConnectInfo.ServerProcessId = NtCurrentProcessId();

    clientView.Length = sizeof(REMOTE_PORT_VIEW);
    clientView.ViewSize = 0;
    clientView.ViewBase = NULL;

    status = NtAcceptConnectPort(
        &portHandle,
        client,
        &Message->h,
        TRUE,
        NULL,
        &clientView
        );

    if (!NT_SUCCESS(status))
    {
        PhDereferenceObject(client);
        return;
    }

    client->PortHandle = portHandle;
    client->ClientViewBase = clientView.ViewBase;
    client->ClientViewLimit = (PCHAR)clientView.ViewBase + clientView.ViewSize;

    status = NtCompleteConnectPort(portHandle);

    if (!NT_SUCCESS(status))
    {
        PhDereferenceObject(client);
        return;
    }

    if (_InterlockedIncrement(&PhSvcApiNumberOfClients) == 1)
    {
        NtSetEvent(PhSvcTimeoutCancelEventHandle, NULL);
    }
}
Пример #2
0
/*++
 * @name CsrSbApiHandleConnectionRequest
 *
 * The CsrSbApiHandleConnectionRequest routine handles and accepts a new
 * connection request to the SM API LPC Port.
 *
 * @param ApiMessage
 *        Pointer to the incoming CSR API Message which contains the
 *        connection request.
 *
 * @return STATUS_SUCCESS in case of success, or status code which caused
 *         the routine to error.
 *
 * @remarks None.
 *
 *--*/
NTSTATUS
NTAPI
CsrSbApiHandleConnectionRequest(IN PSB_API_MSG Message)
{
    NTSTATUS Status;
    REMOTE_PORT_VIEW RemotePortView;
    HANDLE hPort;

    /* Set the Port View Structure Length */
    RemotePortView.Length = sizeof(REMOTE_PORT_VIEW);

    /* Accept the connection */
    Status = NtAcceptConnectPort(&hPort,
                                 NULL,
                                 (PPORT_MESSAGE)Message,
                                 TRUE,
                                 NULL,
                                 &RemotePortView);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("CSRSS: Sb Accept Connection failed %lx\n", Status);
        return Status;
    }

    /* Complete the Connection */
    Status = NtCompleteConnectPort(hPort);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("CSRSS: Sb Complete Connection failed %lx\n",Status);
    }

    /* Return status */
    return Status;
}
Пример #3
0
VOID
SepServerWaitForNextConnect( VOID )
{

    CONNECTION_REQUEST ConnectionRequest;

    ConnectionRequest.Length = (ULONG)sizeof(CONNECTION_REQUEST);

    //
    // Wait for the client to connect to the port
    //

    Status = NtListenPort(
                 EarPort,
                 &ConnectionRequest,
                 NULL,
                 0L
                 ); SEASSERT_SUCCESS(Status);

    Status = NtAcceptConnectPort(
                 &TalkPort,
                 NULL,
                 &ConnectionRequest,
                 TRUE,
                 NULL,
                 NULL,
                 NULL,
                 0L
                 ); SEASSERT_SUCCESS(Status);

    Status = NtCompleteConnectPort( TalkPort ); SEASSERT_SUCCESS(Status);

    return;

}
Пример #4
0
static NTSTATUS
LsapHandlePortConnection(PLSA_API_MSG RequestMsg)
{
    PLSAP_LOGON_CONTEXT LogonContext = NULL;
    HANDLE ConnectionHandle = NULL;
    BOOLEAN Accept;
    REMOTE_PORT_VIEW RemotePortView;
    NTSTATUS Status = STATUS_SUCCESS;

    TRACE("LsapHandlePortConnection(%p)\n", RequestMsg);

    TRACE("Logon Process Name: %s\n", RequestMsg->ConnectInfo.LogonProcessNameBuffer);

    if (RequestMsg->ConnectInfo.CreateContext != FALSE)
    {
        Status = LsapCheckLogonProcess(RequestMsg,
                                       &LogonContext);

        RequestMsg->ConnectInfo.OperationalMode = 0x43218765;

        RequestMsg->ConnectInfo.Status = Status;
    }

    if (NT_SUCCESS(Status))
    {
        Accept = TRUE;
    }
    else
    {
        Accept = FALSE;
    }

    RemotePortView.Length = sizeof(REMOTE_PORT_VIEW);
    Status = NtAcceptConnectPort(&ConnectionHandle,
                                 (PVOID*)LogonContext,
                                 &RequestMsg->h,
                                 Accept,
                                 NULL,
                                 &RemotePortView);
    if (!NT_SUCCESS(Status))
    {
        ERR("NtAcceptConnectPort failed (Status 0x%lx)\n", Status);
        return Status;
    }

    if (Accept != FALSE)
    {
        if (LogonContext != NULL)
        {
            LogonContext->ConnectionHandle = ConnectionHandle;

            InsertHeadList(&LsapLogonContextList,
                           &LogonContext->Entry);
        }

        Status = NtCompleteConnectPort(ConnectionHandle);
        if (!NT_SUCCESS(Status))
        {
            ERR("NtCompleteConnectPort failed (Status 0x%lx)\n", Status);
            return Status;
        }
    }

    return Status;
}
Пример #5
0
VOID PhSvcHandleConnectionRequest(
    _In_ PPORT_MESSAGE PortMessage
    )
{
    NTSTATUS status;
    PPHSVC_API_MSG message;
    PPHSVC_API_MSG64 message64;
    CLIENT_ID clientId;
    PPHSVC_CLIENT client;
    HANDLE portHandle;
    REMOTE_PORT_VIEW clientView;
    REMOTE_PORT_VIEW64 clientView64;
    PREMOTE_PORT_VIEW actualClientView;

    message = (PPHSVC_API_MSG)PortMessage;
    message64 = (PPHSVC_API_MSG64)PortMessage;

    if (PhIsExecutingInWow64())
    {
        clientId.UniqueProcess = (HANDLE)message64->h.ClientId.UniqueProcess;
        clientId.UniqueThread = (HANDLE)message64->h.ClientId.UniqueThread;
    }
    else
    {
        PPH_STRING referenceFileName;
        PPH_STRING remoteFileName;

        clientId = message->h.ClientId;

        // Make sure that the remote process is Process Hacker itself and not some other program.

        referenceFileName = NULL;
        PhGetProcessImageFileNameByProcessId(NtCurrentProcessId(), &referenceFileName);
        PH_AUTO(referenceFileName);

        remoteFileName = NULL;
        PhGetProcessImageFileNameByProcessId(clientId.UniqueProcess, &remoteFileName);
        PH_AUTO(remoteFileName);

        if (!referenceFileName || !remoteFileName || !PhEqualString(referenceFileName, remoteFileName, TRUE))
        {
            NtAcceptConnectPort(&portHandle, NULL, PortMessage, FALSE, NULL, NULL);
            return;
        }
    }

    client = PhSvcCreateClient(&clientId);

    if (!client)
    {
        NtAcceptConnectPort(&portHandle, NULL, PortMessage, FALSE, NULL, NULL);
        return;
    }

    if (PhIsExecutingInWow64())
    {
        message64->p.ConnectInfo.ServerProcessId = HandleToUlong(NtCurrentProcessId());

        clientView64.Length = sizeof(REMOTE_PORT_VIEW64);
        clientView64.ViewSize = 0;
        clientView64.ViewBase = 0;
        actualClientView = (PREMOTE_PORT_VIEW)&clientView64;
    }
    else
    {
        message->p.ConnectInfo.ServerProcessId = HandleToUlong(NtCurrentProcessId());

        clientView.Length = sizeof(REMOTE_PORT_VIEW);
        clientView.ViewSize = 0;
        clientView.ViewBase = NULL;
        actualClientView = &clientView;
    }

    status = NtAcceptConnectPort(
        &portHandle,
        client,
        PortMessage,
        TRUE,
        NULL,
        actualClientView
        );

    if (!NT_SUCCESS(status))
    {
        PhDereferenceObject(client);
        return;
    }

    // IMPORTANT: Since Vista, NtCompleteConnectPort does not do anything and simply returns STATUS_SUCCESS.
    // We will call it anyway (for completeness), but we need to use an event to ensure that other threads don't try
    // to process requests before we have finished setting up the client object.

    client->PortHandle = portHandle;

    if (PhIsExecutingInWow64())
    {
        client->ClientViewBase = (PVOID)clientView64.ViewBase;
        client->ClientViewLimit = PTR_ADD_OFFSET(clientView64.ViewBase, clientView64.ViewSize);
    }
    else
    {
        client->ClientViewBase = clientView.ViewBase;
        client->ClientViewLimit = PTR_ADD_OFFSET(clientView.ViewBase, clientView.ViewSize);
    }

    NtCompleteConnectPort(portHandle);
    PhSetEvent(&client->ReadyEvent);

    if (_InterlockedIncrement(&PhSvcApiNumberOfClients) == 1)
    {
        NtSetEvent(PhSvcTimeoutCancelEventHandle, NULL);
    }
}
Пример #6
0
NTSTATUS
SmpHandleConnectionRequest(
    IN HANDLE ConnectionPort,
    IN PSBAPIMSG Message
    )

/*++

Routine Description:

    This routine handles connection requests from either known subsystems,
    or other clients. Other clients are admin processes.

    The protocol for connection from a known subsystem is:

        capture the name of the sub systems Sb API port

        Accept the connection

        Connect to the subsystems Sb API port

        Store the communication port handle in the known subsystem database

        signal the event associated with the known subsystem

    The protocol for others is to simply validate and accept the connection
    request.

Arguments:

Return Value:

    None.

--*/

{
    NTSTATUS st;
    HANDLE CommunicationPort;
    REMOTE_PORT_VIEW ClientView;
    PSBCONNECTINFO ConnectInfo;
    ULONG ConnectInfoLength;
    PSMPKNOWNSUBSYS KnownSubSys;
    BOOLEAN Accept;
    UNICODE_STRING SubSystemPort;
    SECURITY_QUALITY_OF_SERVICE DynamicQos;
    PSMP_CLIENT_CONTEXT ClientContext;

    //
    // Set up the security quality of service parameters to use over the
    // sb API port.  Use the most efficient (least overhead) - which is dynamic
    // rather than static tracking.
    //

    DynamicQos.ImpersonationLevel = SecurityIdentification;
    DynamicQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
    DynamicQos.EffectiveOnly = TRUE;


    ConnectInfo = &Message->ConnectionRequest;
    KnownSubSys = SmpLocateKnownSubSysByCid(&Message->h.ClientId);

    if ( KnownSubSys ) {

        if ( SmpLocateKnownSubSysByType(ConnectInfo->SubsystemImageType) ==
             KnownSubSys ) {
            Accept = FALSE;
            KdPrint(("SMSS: Connection from SubSystem rejected\n"));
            KdPrint(("SMSS: Image type already being served\n"));
        } else {
            Accept = TRUE;
            KnownSubSys->ImageType = ConnectInfo->SubsystemImageType;
        }
    } else {

        //
        // Authenticate the SOB
        //

        Accept = TRUE;

    }

    if (Accept) {
        ClientContext = RtlAllocateHeap(SmpHeap, MAKE_TAG( SM_TAG ), sizeof(SMP_CLIENT_CONTEXT));
        ClientContext->KnownSubSys = KnownSubSys;
    }

    ClientView.Length = sizeof(ClientView);
    st = NtAcceptConnectPort(
            &CommunicationPort,
            ClientContext,
            (PPORT_MESSAGE)Message,
            Accept,
            NULL,
            &ClientView
            );
    ASSERT( NT_SUCCESS(st) );

    if ( Accept ) {

        if ( KnownSubSys ) {
            KnownSubSys->SmApiCommunicationPort = CommunicationPort;
        }

        st = NtCompleteConnectPort(CommunicationPort);
        ASSERT( NT_SUCCESS(st) );

        //
        // Connect Back to subsystem
        //

        if ( KnownSubSys ) {
            RtlCreateUnicodeString( &SubSystemPort,
                                    ConnectInfo->EmulationSubSystemPortName
                                  );
            ConnectInfoLength = sizeof( *ConnectInfo );

            st = NtConnectPort(
                    &KnownSubSys->SbApiCommunicationPort,
                    &SubSystemPort,
                    &DynamicQos,
                    NULL,
                    NULL,
                    NULL,
                    NULL,
                    NULL
                    );
            if ( !NT_SUCCESS(st) ) {
                KdPrint(("SMSS: Connect back to Sb %wZ failed %lx\n",&SubSystemPort,st));
            }

            RtlFreeUnicodeString( &SubSystemPort );
            NtSetEvent(KnownSubSys->Active,NULL);
        }
    }

    return st;
}
Пример #7
0
int security_reference_monitor_t::run()
{
    const int maxlen = 0x100;
    //dprintf("starting kthread %p p = %p\n", this, process);
    current = static_cast<thread_t*>( this );
    //dprintf("current->process = %p\n", current->process);
    object_attributes_t rm_oa( (PCWSTR) L"\\SeRmCommandPort" );
    HANDLE port = 0, client = 0;
    NTSTATUS r = NtCreatePort( &port, &rm_oa, 0x100, 0x100, 0 );
    if (r == STATUS_THREAD_IS_TERMINATING)
        return 0;
    if (r < STATUS_SUCCESS)
        die("NtCreatePort(SeRmCommandPort) failed r = %08lx\n", r);

    BYTE buf[maxlen];
    LPC_MESSAGE *req = (LPC_MESSAGE*) buf;
    r = NtListenPort( port, req );
    if (r == STATUS_THREAD_IS_TERMINATING)
        return 0;
    if (r < STATUS_SUCCESS)
        die("NtListenPort(SeRmCommandPort) failed r = %08lx\n", r);

    HANDLE conn_port = 0;
    r = NtAcceptConnectPort( &conn_port, 0, req, TRUE, NULL, NULL );
    if (r == STATUS_THREAD_IS_TERMINATING)
        return 0;
    if (r < STATUS_SUCCESS)
        die("NtAcceptConnectPort(SeRmCommandPort) failed r = %08lx\n", r);

    r = NtCompleteConnectPort( conn_port );
    if (r == STATUS_THREAD_IS_TERMINATING)
        return 0;
    if (r < STATUS_SUCCESS)
        die("NtCompleteConnectPort(SeRmCommandPort) failed r = %08lx\n", r);

    unicode_string_t lsa;
    lsa.copy( (PCWSTR) L"\\SeLsaCommandPort" );

    SECURITY_QUALITY_OF_SERVICE qos;
    qos.Length = sizeof(qos);
    qos.ImpersonationLevel = SecurityAnonymous;
    qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
    qos.EffectiveOnly = TRUE;

    r = NtConnectPort( &client, &lsa, &qos, NULL, NULL, NULL, NULL, NULL );
    if (r == STATUS_THREAD_IS_TERMINATING)
        return 0;
    if (r < STATUS_SUCCESS)
        die("NtConnectPort(SeLsaCommandPort) failed r = %08lx\n", r);

    while (!terminated)
    {
        ULONG client_handle;

        r = NtReplyWaitReceivePort( port, &client_handle, 0, req );
        if (r == STATUS_THREAD_IS_TERMINATING)
            return 0;

        if (r < STATUS_SUCCESS)
            die("NtReplyWaitReceivePort(SeRmCommandPort) failed r = %08lx\n", r);

        dprintf("got message %ld\n", req->MessageId );

        // send something back...
        r = NtReplyPort( port, req );
        if (r == STATUS_THREAD_IS_TERMINATING)
            return 0;

        if (r < STATUS_SUCCESS)
            die("NtReplyPort(SeRmCommandPort) failed r = %08lx\n", r);
    }

    dprintf("done\n");
    return 0;
}
Пример #8
0
NTSTATUS
NTAPI
SmpHandleConnectionRequest(IN HANDLE SmApiPort,
                           IN PSB_API_MSG SbApiMsg)
{
    BOOLEAN Accept = TRUE;
    HANDLE PortHandle, ProcessHandle;
    ULONG SessionId;
    UNICODE_STRING SubsystemPort;
    SMP_CLIENT_CONTEXT *ClientContext;
    NTSTATUS Status;
    OBJECT_ATTRIBUTES ObjectAttributes;
    REMOTE_PORT_VIEW PortView;
    SECURITY_QUALITY_OF_SERVICE SecurityQos;
    PSMP_SUBSYSTEM CidSubsystem, TypeSubsystem;

    /* Initialize QoS data */
    SecurityQos.ImpersonationLevel = SecurityIdentification;
    SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
    SecurityQos.EffectiveOnly = TRUE;

    /* Check if this is SM connecting to itself */
    if (SbApiMsg->h.ClientId.UniqueProcess == SmUniqueProcessId)
    {
        /* No need to get any handle -- assume session 0 */
        ProcessHandle = NULL;
        SessionId = 0;
    }
    else
    {
        /* Reference the foreign process */
        InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
        Status = NtOpenProcess(&ProcessHandle,
                               PROCESS_QUERY_INFORMATION,
                               &ObjectAttributes,
                               &SbApiMsg->h.ClientId);
        if (!NT_SUCCESS(Status)) Accept = FALSE;

        /* Get its session ID */
        SmpGetProcessMuSessionId(ProcessHandle, &SessionId);
    }

    /* See if we already know about the caller's subystem */
    CidSubsystem = SmpLocateKnownSubSysByCid(&SbApiMsg->h.ClientId);
    if ((CidSubsystem) && (Accept))
    {
        /* Check if we already have a subsystem for this kind of image */
        TypeSubsystem = SmpLocateKnownSubSysByType(SessionId,
                                                   SbApiMsg->ConnectionInfo.SubsystemType);
        if (TypeSubsystem == CidSubsystem)
        {
            /* Someone is trying to take control of an existing subsystem, fail */
            Accept = FALSE;
            DPRINT1("SMSS: Connection from SubSystem rejected\n");
            DPRINT1("SMSS: Image type already being served\n");
        }
        else
        {
            /* Set this image type as the type for this subsystem */
            CidSubsystem->ImageType = SbApiMsg->ConnectionInfo.SubsystemType;
        }

        /* Drop the reference we had acquired */
        if (TypeSubsystem) SmpDereferenceSubsystem(TypeSubsystem);
    }

    /* Check if we'll be accepting the connection */
    if (Accept)
    {
        /* We will, so create a client context for it */
        ClientContext = RtlAllocateHeap(SmpHeap, 0, sizeof(SMP_CLIENT_CONTEXT));
        if (ClientContext)
        {
            ClientContext->ProcessHandle = ProcessHandle;
            ClientContext->Subsystem = CidSubsystem;
            ClientContext->dword10 = 0;
            ClientContext->PortHandle = NULL;
        }
        else
        {
            /* Failed to allocate a client context, so reject the connection */
            DPRINT1("Rejecting connectiond due to lack of memory\n");
            Accept = FALSE;
        }
    }
    else
    {
        /* Use a bogus context since we're going to reject the message */
        ClientContext = (PSMP_CLIENT_CONTEXT)SbApiMsg;
    }

    /* Now send the actual accept reply (which could be a rejection) */
    PortView.Length = sizeof(PortView);
    Status = NtAcceptConnectPort(&PortHandle,
                                 ClientContext,
                                 &SbApiMsg->h,
                                 Accept,
                                 NULL,
                                 &PortView);
    if (!(Accept) || !(NT_SUCCESS(Status)))
    {
        /* Close the process handle, reference the subsystem, and exit */
        DPRINT1("Accept failed or rejected: %lx\n", Status);
        if (ClientContext != (PVOID)SbApiMsg) RtlFreeHeap(SmpHeap, 0, ClientContext);
        if (ProcessHandle) NtClose(ProcessHandle);
        if (CidSubsystem) SmpDereferenceSubsystem(CidSubsystem);
        return Status;
    }

    /* Save the port handle now that we've accepted it */
    if (ClientContext) ClientContext->PortHandle = PortHandle;
    if (CidSubsystem) CidSubsystem->PortHandle = PortHandle;

    /* Complete the port connection */
    Status = NtCompleteConnectPort(PortHandle);
    if ((NT_SUCCESS(Status)) && (CidSubsystem))
    {
        /* This was an actual subsystem, so connect back to it */
        SbApiMsg->ConnectionInfo.SbApiPortName[119] = UNICODE_NULL;
        RtlCreateUnicodeString(&SubsystemPort,
                               SbApiMsg->ConnectionInfo.SbApiPortName);
        Status = NtConnectPort(&CidSubsystem->SbApiPort,
                               &SubsystemPort,
                               &SecurityQos,
                               NULL,
                               NULL,
                               NULL,
                               NULL,
                               NULL);
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("SMSS: Connect back to Sb %wZ failed %lx\n", &SubsystemPort, Status);
        }
        RtlFreeUnicodeString(&SubsystemPort);

        /* Now that we're connected, signal the event handle */
        NtSetEvent(CidSubsystem->Event, NULL);
    }
    else if (CidSubsystem)
    {
        /* We failed to complete the connection, so clear the port handle */
        DPRINT1("Completing the connection failed: %lx\n", Status);
        CidSubsystem->PortHandle = NULL;
    }

    /* Dereference the subsystem and return the result */
    if (CidSubsystem) SmpDereferenceSubsystem(CidSubsystem);
    return Status;
}
Пример #9
0
/**********************************************************************
 *	ProcessConnectionRequest/				PRIVATE
 *
 * DESCRIPTION
 *	This is called when a PSX process attaches to PSXDLL.DLL.
 */
PRIVATE NTSTATUS STDCALL
ProcessConnectionRequest (PLPC_MAX_MESSAGE pRequest)
{
    PPSX_CONNECT_PORT_DATA pConnectData = (PPSX_CONNECT_PORT_DATA) & pRequest->Data;
    NTSTATUS               Status;
    HANDLE                 hConnectedPort;
    ULONG                  ulPortIdentifier;

    debug_print (L"PSXSS: ->%s", __FUNCTION__);
    /* Check if the caller is a process */
    Status = PsxCheckConnectionRequest (
                pConnectData,
                PSX_CONNECTION_TYPE_PROCESS
		);
    if (!NT_SUCCESS(Status))
    {
        Status = NtAcceptConnectPort (
                    & hConnectedPort,
		    NULL,
		    & pRequest->Header,
		    FALSE, /* reject connection request */
		    NULL,
		    NULL
		    );
        if (!NT_SUCCESS(Status))
	{
            debug_print(
	        L"PSXSS: %s: NtAcceptConnectPort failed with status=%08x",
		__FUNCTION__,
		Status
		);
	}
        return STATUS_UNSUCCESSFUL;
    }
    /* OK, accept the connection */
    Status = NtAcceptConnectPort (
                & hConnectedPort,
		& ulPortIdentifier,
	        & pRequest->Header,
		TRUE, /* accept connection request */
		NULL,
		NULL
		);
    if (!NT_SUCCESS(Status))
    {
        debug_print(L"PSXSS: %s: NtAcceptConnectPort failed with status=%08x", __FUNCTION__, Status);
        return Status;
    }
    Status = PsxCreateProcess (pRequest,hConnectedPort,ulPortIdentifier);
    if (!NT_SUCCESS(Status))
    {
        debug_print(L"PSXSS: %s: PsxCreateProcess failed with status=%08x", __FUNCTION__, Status);
        return Status;
    }
    Status = NtCompleteConnectPort (hConnectedPort);
    if (!NT_SUCCESS(Status))
    {
        debug_print(L"PSXSS: %s: NtCompleteConnectPort failed with status=%08x", __FUNCTION__, Status);
        return Status;
    }
    debug_print (L"PSXSS: <-%s", __FUNCTION__);
    return STATUS_SUCCESS;
}
Пример #10
0
static
DWORD
WINAPI
LsapRmServerThread(
    PVOID StartContext)
{
    LSAP_RM_API_MESSAGE Message;
    PPORT_MESSAGE ReplyMessage;
    REMOTE_PORT_VIEW RemotePortView;
    HANDLE MessagePort, DummyPortHandle;
    NTSTATUS Status;

    /* Initialize the port message */
    Message.Header.u1.s1.TotalLength = sizeof(Message);
    Message.Header.u1.s1.DataLength = 0;

    /* Listen on the LSA command port */
    Status = NtListenPort(SeLsaCommandPort, &Message.Header);
    if (!NT_SUCCESS(Status))
    {
        ERR("LsapRmServerThread - Port Listen failed 0x%lx\n", Status);
        return Status;
    }

    /* Setup the Port View Structure */
    RemotePortView.Length = sizeof(REMOTE_PORT_VIEW);
    RemotePortView.ViewSize = 0;
    RemotePortView.ViewBase = NULL;

    /* Accept the connection */
    Status = NtAcceptConnectPort(&MessagePort,
                                 0,
                                 &Message.Header,
                                 TRUE,
                                 NULL,
                                 &RemotePortView);
    if (!NT_SUCCESS(Status))
    {
        ERR("LsapRmServerThread - Port Accept Connect failed 0x%lx\n", Status);
        return Status;
    }

    /* Complete the connection */
    Status = NtCompleteConnectPort(MessagePort);
    if (!NT_SUCCESS(Status))
    {
        ERR("LsapRmServerThread - Port Complete Connect failed 0x%lx\n", Status);
        return Status;
    }

    /* No reply yet */
    ReplyMessage = NULL;

    /* Start looping */
    while (TRUE)
    {
        /* Wait for a message */
        Status = NtReplyWaitReceivePort(MessagePort,
                                        NULL,
                                        ReplyMessage,
                                        &Message.Header);
        if (!NT_SUCCESS(Status))
        {
            ERR("LsapRmServerThread - Failed to get message: 0x%lx", Status);
            ReplyMessage = NULL;
            continue;
        }

        /* Check if this is a connection request */
        if (Message.Header.u2.s2.Type == LPC_CONNECTION_REQUEST)
        {
            /* Reject connection request */
            NtAcceptConnectPort(&DummyPortHandle,
                                NULL,
                                &Message.Header,
                                FALSE,
                                NULL,
                                NULL);

            /* Start over */
            ReplyMessage = NULL;
            continue;
        }

        /* Check if this is an actual request */
        if (Message.Header.u2.s2.Type == LPC_REQUEST)
        {
            ReplyMessage = &Message.Header;

            switch (Message.ApiNumber)
            {
                case LsapAdtWriteLogApi:
                    LsapAdtWriteLog(&Message);
                    break;

                case LsapAsyncApi:
                    LsapAsync(&Message);
                    break;

                case LsapComponentTestApi:
                    LsapComponentTest(&Message);
                    break;

                default:
                    ERR("LsapRmServerThread - invalid API number: 0x%lx\n",
                        Message.ApiNumber);
                    ReplyMessage = NULL;
            }

            continue;
        }

        ERR("LsapRmServerThread - unexpected message type: 0x%lx\n",
            Message.Header.u2.s2.Type);

        /* Start over */
        ReplyMessage = NULL;
    }
}
Пример #11
0
/*++
 * @name CsrApiHandleConnectionRequest
 *
 * The CsrApiHandleConnectionRequest routine handles and accepts a new
 * connection request to the CSR API LPC Port.
 *
 * @param ApiMessage
 *        Pointer to the incoming CSR API Message which contains the
 *        connection request.
 *
 * @return STATUS_SUCCESS in case of success, or status code which caused
 *         the routine to error.
 *
 * @remarks This routine is responsible for attaching the Shared Section to
 *          new clients connecting to CSR.
 *
 *--*/
NTSTATUS
NTAPI
CsrApiHandleConnectionRequest(IN PCSR_API_MESSAGE ApiMessage)
{
    PCSR_THREAD CsrThread = NULL;
    PCSR_PROCESS CsrProcess = NULL;
    NTSTATUS Status = STATUS_SUCCESS;
    PCSR_API_CONNECTINFO ConnectInfo = &ApiMessage->ConnectionInfo;
    BOOLEAN AllowConnection = FALSE;
    REMOTE_PORT_VIEW RemotePortView;
    HANDLE ServerPort;

    /* Acquire the Process Lock */
    CsrAcquireProcessLock();

    /* Lookup the CSR Thread */
    CsrThread = CsrLocateThreadByClientId(NULL, &ApiMessage->Header.ClientId);

    /* Check if we have a thread */
    if (CsrThread)
    {
        /* Get the Process */
        CsrProcess = CsrThread->Process;

        /* Make sure we have a Process as well */
        if (CsrProcess)
        {
            /* Reference the Process */
            CsrLockedReferenceProcess(CsrProcess);

            /* Release the lock */
            CsrReleaseProcessLock();

            /* Duplicate the Object Directory */
            Status = NtDuplicateObject(NtCurrentProcess(),
                                       CsrObjectDirectory,
                                       CsrProcess->ProcessHandle,
                                       &ConnectInfo->ObjectDirectory,
                                       0,
                                       0,
                                       DUPLICATE_SAME_ACCESS |
                                       DUPLICATE_SAME_ATTRIBUTES);

            /* Acquire the lock */
            CsrAcquireProcessLock();

            /* Check for success */
            if (NT_SUCCESS(Status))
            {
                /* Attach the Shared Section */
                Status = CsrSrvAttachSharedSection(CsrProcess, ConnectInfo);

                /* Check how this went */
                if (NT_SUCCESS(Status))
                {
                    /* Allow the connection, and return debugging flag */
                    ConnectInfo->DebugFlags = CsrDebug;
                    AllowConnection = TRUE;
                }
            }

            /* Dereference the project */
            CsrLockedDereferenceProcess(CsrProcess);
        }
    }

    /* Release the lock */
    CsrReleaseProcessLock();

    /* Setup the Port View Structure */
    RemotePortView.Length = sizeof(REMOTE_PORT_VIEW);
    RemotePortView.ViewSize = 0;
    RemotePortView.ViewBase = NULL;

    /* Save the Process ID */
    ConnectInfo->ServerProcessId = NtCurrentTeb()->ClientId.UniqueProcess;

    /* Accept the Connection */
    Status = NtAcceptConnectPort(&ServerPort,
                                 AllowConnection ? UlongToPtr(CsrProcess->SequenceNumber) : 0,
                                 &ApiMessage->Header,
                                 AllowConnection,
                                 NULL,
                                 &RemotePortView);
    if (!NT_SUCCESS(Status))
    {
         DPRINT1("CSRSS: NtAcceptConnectPort - failed.  Status == %X\n", Status);
    }
    else if (AllowConnection)
    {
        if (CsrDebug & 2)
        {
            DPRINT1("CSRSS: ClientId: %lx.%lx has ClientView: Base=%p, Size=%lx\n",
                    ApiMessage->Header.ClientId.UniqueProcess,
                    ApiMessage->Header.ClientId.UniqueThread,
                    RemotePortView.ViewBase,
                    RemotePortView.ViewSize);
        }

        /* Set some Port Data in the Process */
        CsrProcess->ClientPort = ServerPort;
        CsrProcess->ClientViewBase = (ULONG_PTR)RemotePortView.ViewBase;
        CsrProcess->ClientViewBounds = (ULONG_PTR)((ULONG_PTR)RemotePortView.ViewBase +
                                                   (ULONG_PTR)RemotePortView.ViewSize);

        /* Complete the connection */
        Status = NtCompleteConnectPort(ServerPort);
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("CSRSS: NtCompleteConnectPort - failed.  Status == %X\n", Status);
        }
    }
    else
    {
        DPRINT1("CSRSS: Rejecting Connection Request from ClientId: %lx.%lx\n",
                ApiMessage->Header.ClientId.UniqueProcess,
                ApiMessage->Header.ClientId.UniqueThread);
    }

    /* Return status to caller */
    return Status;
}
Пример #12
0
NTSTATUS AcceptLpcConnect(PLPC_PORT LpcPort, BOOL AcceptConnection, BYTE *reply, WORD replyLength)
{
    NTSTATUS    status;
    LPC_MESSAGE reqMsg, repMsg;
    PSERVER_LPC_PORT   serverPort;
    HANDLE      hPort = INVALID_HANDLE_VALUE;
    PHANDLE     phPort = &hPort;
    BOOL        stopFlag = FALSE;
 
    log("Wait for connection...");
    serverPort = (PSERVER_LPC_PORT) LpcPort;
    
    while (!stopFlag) {
        status = NtReplyWaitReceivePort(
            LpcPort->hPort,
            (PVOID *) &phPort,
            NULL,
            (PLPC_MESSAGE_HEADER) &reqMsg
            );

        log("status: %x\n", status);
        log("Message type: %x\n", reqMsg.header.MessageType);
        switch (reqMsg.header.MessageType) {
        case LPC_CONNECTION_REQUEST:
            status = NtAcceptConnectPort(
                &hPort,
                NULL,
                (PLPC_MESSAGE_HEADER) &reqMsg,
                AcceptConnection,
                NULL,
                NULL
                );

            log("NtAcceptConnectPort: %x\n", status);
            status = NtCompleteConnectPort(hPort);
            log("NtCompleteConnectPort: %x\n", status);
            break;
        case LPC_REQUEST:
        case LPC_DATAGRAM:
            memset(&repMsg, 0, sizeof(repMsg));
            memcpy(&(repMsg.header), &(reqMsg.header), sizeof(repMsg.header));
            memcpy(repMsg.data, reply, replyLength);
            repMsg.header.DataLength = replyLength;
            repMsg.header.TotalLength = replyLength + sizeof(repMsg.header);

            log("SERVER: request: %s\n", reqMsg.data);
            log("SERVER: reply: %s\n", repMsg.data);
            
            status = NtReplyPort(hPort, (PLPC_MESSAGE_HEADER) &repMsg);
            log("NtReplyPort: %x\n", status);
            status = NtCompleteConnectPort(hPort);
            //log("NtCompleteConnectPort: %x\n", status);
            stopFlag = TRUE;
            break;
        case LPC_PORT_CLOSED:
            log("LPC_PORT_CLOSED\n");
            break;
        default:
            break;
        };

    }
    return status;
}