Writing a security exit

We can write a security exit by using the security exit skeleton code.

Figure 1 illustrates how to write a security exit.

Figure 1. Security exit skeleton code
void MQENTRY MQStart() {;}
void MQENTRY EntryPoint (PMQVOID pChannelExitParms,
                        PMQVOID pChannelDefinition,
                        PMQLONG pDataLength,
                        PMQLONG pAgentBufferLength,
                        PMQVOID pAgentBuffer,
                        PMQLONG pExitBufferLength,
                        PMQPTR  pExitBufferAddr)
{
  PMQCXP pParms = (PMQCXP)pChannelExitParms;
  PMQCD  pChDef = (PMQCD)pChannelDefinition;
  /* TODO: Add Security Exit Code Here */

}
The standard IBM MQ Entry Point MQStart must exist, but is not required to perform any function. The name of the function (EntryPoint in this example) can be changed, but the function must be exported when the library is compiled and linked. As in the previous example, the pointers pChannelExitParms must be cast to PMQCXP and pChannelDefinition must be cast to PMQCD. For general information about calling channel exits and the use of parameters, see MQ_CHANNEL_EXIT. These parameters are used in a security exit as follows:

    PMQVOID pChannelExitParms
    input/output Pointer to MQCXP structure - cast to PMQCXP to access fields. This structure is used to communicate between the Exit and MCA. The following fields in the MQCXP are of particular interest for Security Exits:

      ExitReason
      Tells the Security Exit the current state in the security exchange and is used when deciding what action to take.

      ExitResponse
      The response to the MCA which dictates the next stage in the security exchange.

      ExitResponse2
      Extra control flags to govern how the MCA interprets the response of the Security Exit.

      ExitUserArea
      16 bytes (maximum) of storage which can be used by the Security Exit to maintain state between calls.

      ExitData
      Contains the data specified in the SCYDATA field of the channel definition (32 bytes padded to the right with blanks).

    PMQVOID pChannelDefinition
    input/output Pointer to MQCD structure - cast to PMQCD to access fields. This parameter contains the definition of the channel. The following fields in the MQCD are of particular interest for Security Exits:

      ChannelName
      The channel name (20 bytes padded to the right with blanks).

      ChannelType
      A code defining the channel type.

      MCA User Identifier
      This group of three fields is initialized to the value of the MCAUSER field specified in the channel definition. Any user identifier specified by the Security Exit in these fields is used for access control (not applicable to SDR, SVR, CLNTCONN, or CLUSSDR channels).

        MCAUserIdentifier
        First 12 bytes of identifier padded to the right with blanks.

        LongMCAUserIdPtr
        Pointer to a buffer containing the full length identifier (not guaranteed null terminated) takes priority over MCAUserIdentifier.

        LongMCAUserIdLength
        Length of string pointed to by LongMCAUserIdPtr - must be set if LongMCAUserIdPtr is set.

      Remote User Identifier
      Only applies to CLNTCONN/SVRCONN channel pairs. If no CLNTCONN Security Exit is defined then these three fields are initialized by the client MCA, so they might contain a user identifier from the environment of the client which can be used by a SVRCONN Security Exit for authentication and when specifying the MCA User Identifier. If a CLNTCONN Security Exit is defined then these fields are not initialized and can be set by the CLNTCONN Security Exit, or security messages can be used to pass a user identifier from Client to Server.

        RemoteUserIdentifier
        First 12 Bytes of identifier padded to the right with blanks.

        LongRemoteUserIdPtr
        Pointer to a buffer containing the full length identifier (not guaranteed null terminated) takes priority over RemoteUserIdentifier.

        LongRemoteUserIdLength
        Length of string pointed to by LongRemoteUserIdPtr - must be set if LongRemoteUserIdPtr is set.

    PMQLONG pDataLength
    input/output

    Pointer to MQLONG. Contains the length of any Security Exit contained in the AgentBuffer upon invocation of the Security Exit. Must be set by a Security Exit to the length of any message being sent in the AgentBuffer or ExitBuffer.

    PMQLONG pAgentBufferLength
    input

    Pointer to MQLONG. The length of the data contained in the AgentBuffer on invocation of the Security Exit.

    PMQVOID pAgentBuffer
    input/output

    On invocation of the Security Exit, this points to any message sent from the partner exit. If ExitResponse2 in the MQCXP structure has the MQXR2_USE_AGENT_BUFFER flag set (default) then a Security Exit needs to set this parameter to point to any message data being sent.

    PMQLONG pExitBufferLength
    input/output

    Pointer to MQLONG. This parameter is initialized to 0 on the first invocation of a Security Exit and the value returned is maintained between calls to the Security Exit during a security exchange.

    PMQPTR pExitBufferAddr
    input/output

    This parameter is initialized to a null pointer on the first invocation of a Security Exit and the value returned is maintained between calls to the Security Exit during a security exchange. If the MQXR2_USE_EXIT_BUFFER flag is set in the ExitResponse2 in the MQCXP structure then a Security Exit needs to set this parameter to point to any message data being sent.