How to Register a Client with Configuration Manager

Applies To: System Center Configuration Manager 2007, System Center Configuration Manager 2007 R2, System Center Configuration Manager 2007 R3, System Center Configuration Manager 2007 SP1, System Center Configuration Manager 2007 SP2

You register a client with Microsoft System Center Configuration Manager 2007 by using the registration endpoint.

To register with Configuration Manager 2007, the ISV proxy creates a ClientRegistrationRequest message that contains the registration request data for the client.

The response is returned in a ClientRegistrationResponse message. The registration request might return indicating that the request is still pending. The client should then, after a short wait, request confirmation of the registration.

Note

Depending on the server load, the wait period can be from 30 seconds to 5 minutes.

For troubleshooting information, see About Configuration Manager Management Point Interface Messages.

Note

If you are creating registration messages in the common language runtime, signatures are reversed because of byte orders between the native Win32 API and the .NET Framework API. Before writing the signature to the registration message, reverse the signature array by calling Array.Reverse so that the byte order matches the native Win32 API. For more information about Array.Reverse, see MSDN documentation for Array.Reverse Method. For more information about signature verification, see MSDN documentation for CryptVerifySignature Function.

The following C++ example demonstrates how to make a mixed-mode registration request, in a function named SendRegistration. The second function, SendConfirmation, demonstrates how to request a registration confirmation in native mode.

Both functions demonstrate how to:

  • Create the message.

  • Set the message body for the registration or confirmation request. In both cases, you must implement the helper functions that return the required message in a string. The memory for the string must be created using CoTaskMemAlloc. For more information about the message, see Configuration Manager Registration Message XML.

  • Set appropriate security flags for the message. For more information, see Configuration Manager Registration Message XML.

  • Set the target endpoint.

  • Set the HTTP port used for communication

  • Send the message to the management point.

  • Verify that the management point is a known server by calling VerifyServerSignature. The certificate you supply is the self-signed, public certificate of the management point.

  • Extract the returned message.

Example

HRESULT SendRegistration()
{
    ISmsMessaging               *pMessaging = NULL;

    ISmsMessage                 *pRequest = NULL;
    ISmsMessage                 *pReply = NULL;
    ISmsMessage4                *pRequest4 = NULL;
    ISmsMessage4                *pReply4 = NULL;
    WCHAR                       *pszRequestMessage = NULL;
    WCHAR                       *pszReplyMessage = NULL;

    _BEGIN

        // Create root messaging object.
        _CHECKHR( ::CoCreateInstance(
                        CLSID_SmsMessaging,
                        NULL,
                        CLSCTX_INPROC,
                        IID_ISmsMessaging,
                        (LPVOID*)&pMessaging) );

        // Create message object for the request.
        _CHECKHR( pMessaging->CreateMessage(&pRequest) );

        // QI for ISmsMessage4 on the request object.
        _CHECKHR( pRequest->QueryInterface(__uuidof(ISmsMessage4), (LPVOID*)&pRequest4) );

        // Set the target of the message to be the Registration Manager endpoint.
        _CHECKHR( pRequest->SetTargetEndpoint(L"MP_ClientRegistration") );

        // Construct a registration request message.
        _CHECKHR( CreateRegistrationRequestMessage(&pszRequestMessage) );

        // Set the message body with the request.
        _CHECKHR( pRequest->SetBodyFromString(pszRequestMessage) );

        // Set the security flags for the message.
        _CHECKHR( pRequest4->SetSecurityFlags( MPAPI_SECURITY_FLAG_MIXED_MODE ) );

        // Specify the HTTP port to use for communication.
        _CHECKHR( pRequest4->SetPort( 8080 ) );

        // Invoke the targeted endpoint on the local machine with the request,
        // and retrieve the reply.
        _CHECKHR( pMessaging->Invoke(NULL, pRequest, &pReply) );

        // QI for ISmsMessage4 on the request object.
        _CHECKHR( pReply->QueryInterface(__uuidof(ISmsMessage4), (LPVOID*)&pReply4) );

        // Verify that the reply was signed by a known management point.
        _CHECKHR( pReply4->VerifyServerSignature( MPAPI_CERT_STORE_LOCATION_LOCAL_MACHINE, L"mpsigningcerts" ) );

        // Extract the body from the reply message.
        _CHECKHR( pReply->GetBodyToString(&pszReplyMessage) );

        // Add your code to use the reply message.

    _END

    // All cleanup must go after _END block to ensure it gets invoked.

    if(pszReplyMessage)
    {
        ::CoTaskMemFree(pszReplyMessage);
    }

    if(pReply)
    {
        pReply->Release();
    }

    if(pReply4)
    {
        pReply4->Release();
    }

    if(pszRequestMessage)
    {
        ::CoTaskMemFree(pszRequestMessage);
    }

    if(pRequest)
    {
        pRequest->Release();
    }

    if(pRequest4)
    {
        pRequest4->Release();
    }

    if(pMessaging)
    {
        pMessaging->Release();
    }

    return _RETVAL;
}




HRESULT SendConfirmation()
{
    ISmsMessaging               *pMessaging = NULL;

    ISmsMessage                 *pRequest = NULL;
    ISmsMessage                 *pReply = NULL;
    ISmsMessage4                *pRequest4 = NULL;
    ISmsMessage4                *pReply4 = NULL;
    WCHAR                       *pszRequestMessage = NULL;
    WCHAR                       *pszReplyMessage = NULL;

    BYTE                        *pHash = NULL;

    _BEGIN

        // Get hash of certificate to be used for the request.
        _CHECKHR( GetClientCertificateThumbprint(&pHash) );

        // Create root messaging object.
        _CHECKHR( ::CoCreateInstance(
                        CLSID_SmsMessaging,
                        NULL,
                        CLSCTX_INPROC,
                        IID_ISmsMessaging,
                        (LPVOID*)&pMessaging) );

        // Create message object for the request.
        _CHECKHR( pMessaging->CreateMessage(&pRequest) );

        // QI for ISmsMessage4 on the request object.
        _CHECKHR( pRequest->QueryInterface(__uuidof(ISmsMessage4), (LPVOID*)&pRequest4) );

        // Set the target of the message to be the Registration Manager endpoint.
        _CHECKHR( pRequest->SetTargetEndpoint(L"MP_ClientRegistration") );

        // Construct a confirmation request message.
        _CHECKHR( CreateConfirmationRequestMessage(&pszRequestMessage) );

        // Set the message body with the request.
        _CHECKHR( pRequest->SetBodyFromString(pszRequestMessage) );

        // Set the security flags for the message.
        _CHECKHR( pRequest4->SetSecurityFlags(
            (MPAPI_SECURITY_FLAGS)(MPAPI_SECURITY_FLAG_NATIVE_MODE | MPAPI_SECURITY_FLAG_ENABLE_CRL_CHECKING)) );

        // Specify the HTTPS port to use for communication.
        _CHECKHR( pRequest4->SetPort( 44443 ) );

        // Set the client certificate to use as an SSL client certificate.
        _CHECKHR( pRequest4->SetClientCertificate( MPAPI_CERT_STORE_LOCATION_LOCAL_MACHINE, L"MY", pHash) );

        // Invoke the targeted endpoint on the local machine with the request,
        // and retrieve the reply.
        _CHECKHR( pMessaging->Invoke(NULL, pRequest, &pReply) );

        // QI for ISmsMessage4 on the request object.
        _CHECKHR( pReply->QueryInterface(__uuidof(ISmsMessage4), (LPVOID*)&pReply4) );

        // Verify that the reply was signed by a known management point.
        _CHECKHR( pReply4->VerifyServerSignature( MPAPI_CERT_STORE_LOCATION_LOCAL_MACHINE, L"mpsigningcerts" ) );

        // Extract the body from the reply message.
        _CHECKHR( pReply->GetBodyToString(&pszReplyMessage) );

        // Add your code to use the reply message.

    _END

    // All cleanup must go after _END block to ensure it gets invoked.

    if(pszReplyMessage)
    {
        ::CoTaskMemFree(pszReplyMessage);
    }

    if(pReply)
    {
        pReply->Release();
    }

    if(pReply4)
    {
        pReply4->Release();
    }

    if(pszRequestMessage)
    {
        ::CoTaskMemFree(pszRequestMessage);
    }

    if(pRequest)
    {
        pRequest->Release();
    }

    if(pRequest4)
    {
        pRequest4->Release();
    }


    if(pMessaging)
    {
        pMessaging->Release();
    }

    if(pHash)
    {
        ::CoTaskMemFree(pHash);
    }

    return _RETVAL;
}

Compiling the Code

The Configuration Manager management point interfaces DLL.

Security

You can set security options for a message using ISmsMessage4 Interface. For more information, see Configuration Manager Management Point Interface Security.

See Also

Concepts

About Configuration Manager Management Point Interface Messages
Configuration Manager Management Point Interface
Configuration Manager Management Point Message Schema
ISmsMessage Interface
ISmsMessage2 Interface
ISmsMessage4 Interface
ISmsMessaging Interface