Queue-based security automatically protects WebSphere MQ Everyplace message data between the initiating queue manager and the queue, on the queue itself, and between the queue and the receiving queue manager. This form of protection requires the target queue to be defined with an attribute. This protection is independent of whether the queue is owned by a local or a remote queue manager.
A simple example of this is a target queue defined with an attribute that has an authenticator, an MQe3DESCryptor and an MQeRleCompressor. When such a target queue is accessed (either locally or remotely), using putMessage, getMessage or browseMessages, the queue attribute is automatically applied. In this example the application initiating the access has to satisfy the requirements of the authenticator before the operation is permitted. If the operation is permitted, the message data is automatically encoded and decoded using the attribute's MQe3DESCryptor and MQeRleCompressor. When the example target queue is remotely accessed, for example using putMessage, queue-based security automatically ensures that the message data is protected at the level defined by the queue attribute. This protection applies during transfer between the initiating queue manager and the queue, while the message is stored on the queue, and during transfer between the queue and the receiving queue manager.
With synchronous queues, queue-based security is relatively simple. In this case a message is put to a synchronous remote queue definition that has the same security attributes as the destination queue. The message is transmitted over a connection with appropriate security attributes and is stored on the secure queue.
With asynchronous queues, especially Store-and-forward queues and Home-server queues, the transmitting and receiving queues are more likely to have different security attributes. These differences have to be managed during message transfer.
Once a message has been put to an asynchronous queue it is transmitted from one queue to another until it reaches its destination. A queue manager is responsible for requesting the transfer of the message between a pair of queues and another queue manager is responsible for responding to the request.
If queue based security is used, the requesting queue manager tries to establish a connection with security attributes that match the queue that it owns. The queue manager receiving the request checks that the existing attributes are sufficient for its queue. For example, suppose a client queue manager has a queue with a DES cryptor on it and messages are routed from this to a server's Store-and-forward queue that has a MARS cryptor. When the client is triggered to send a message it tries to establish a DES encrytped connection to the server; the server asks the Store-and-forward queue whether it will accept messages over a DES encrypted connection.
If a queue doesn't have any attribute rules, it only accepts a connection that has exactly the same cryptor as itself. This behavior can be overridden by attribute rules and by default queues use examples.rules.AttributeRules. These default rules group cryptors into four strengths:
Using these rules, a queue accepts messages from a connection if the cryptor on the connection is at least as strong as its own cryptor:
In the previous example, if the Store-and-forward queue used these rules it would not accept a DES encrypted connection because DES is not as strong as its own MARS cryptor, it would throw an "attribute mismatch" exception.
A Home-server queue trying to pull messages from a Store-and-forward queue needs a cryptor that is at least as strong as that on the Store-and-forward queue, because the Home-server queue is at the initiating end of the request. Once the Home-server queue has received the message it can store it on a local queue that has any level of protection.
This behavior can be changed by using different attribute rules on the queues. The equals() method is used to compare the cryptors, so if the attribute rule has an equals() method that always returns true, the queue accepts connections with any cryptor.
Trying to send a message from a queue with a weaker cryptor to a queue with a stronger cryptor usually results in an "attribute mismatch" exception. However if a connection with a strong cryptor already exists between the queue managers, this can be reused (depending on the attribute rules on the connection) and result in the message being delivered.
WebSphere MQ Everyplace queue-based security can be used whenever you need to protect the confidentiality of message data being transferred between queue managers.
A typical scenario could be a service that is delivered over an open network, like the internet, where an initiating application makes requests, using a queue manager on a client, to access a service provided by a server queue manager application.
This can be implemented as follows:
One way to support this simple example would be to define the following queues:
While a number of choices exist, setting the TestClient_HomeServerQ TimerInterval option, to 5000 for example, sets a 5sec poll interval and triggers the client queue manager to poll the server queue manager. This poll 'pulls' any messages on the server queue manager's store-and-forward queue that have been directed to the client queue manager. Also, before running any client queue manager application, the MQE_ADMIN_ACTION_ADD_QMGR option must be used to add a reference to the server queue manager.
Defining the TestServer_StoreAndForwardQ for use in this scenario requires two steps.
When using queue-based security all the choices for attribute are available:
Queue-based security is appropriate for solutions designed to use synchronous queues. In this case, the selection criteria is really concerned with the selection of the (synchronous) queue attribute's authenticator, cryptor and compressor.
The option to use an Authenticator is driven by the need to provide additional controls to prevent access to the local data by unauthorized users. This is equally relevant when the queue data is accessed locally or remotely.
Using a descendant of LogonAuthenticator, when the attribute is activated, for example when an application is performing a putMessage(), getMessage() or browseMessages() of data on the queue, the requirements of the authenticator have to be satisfied before the operation is permitted. In the queue-based Usage scenario, if the XXX_service_request queue is defined with an attribute including the NTAuthenticator, then access to the server XXX_service_request queue (for example when attempting to putMessage() requests to this queue from a client queue manager), is restricted to the set of users defined as valid NT users in the target server's domain.
Using MQeWTLSCertAuthenticator ensures that all remote accesses to a queue protected with an attribute using this authenticator have completed mutual authentication before the operation can be executed. The mutual authentication of the mini-certificates exchanged consists of each participant validating the mini-certificate it receives. This validation checks the mini-certificate received is a valid signed entity, signed by the same mini-certificate server as the requestor's own mini-certificate, and that it is valid with respect to date, that is the current date is not prior to its from-date or after its to-date. An administration option enables the solution creator to choose whether a target queue manager queue has its own credentials (that it is an authenticatable entity in its own right, with its own mini-certificate and associated private key) or shares the credentials of its owning queue manager. In the queue-based Usage scenario, if the XXX_service_request queue is defined with an attribute containing the MQeWTLSCertAuthenticator, then access to the server XXX_service_request queue, for example when the initiating client queue manager application performs a remote putMessage(), depends on the credentials of the initiating client queue manager and the target XXX_service_request queue being successfully mutually authenticated.
The choice of cryptor is driven by the strength of protection required, that is, the degree of difficulty that an attacker would face when cryptographically attacking the protected data to get illegal access. Data protected with symmetric ciphers which use 128 bit keys is acknowledged as being more difficult to attack than data protected using ciphers that use shorter keys. But in addition to cryptographic strength. The selection of a cipher may also be driven by many other factors. An example of this is some financial solutions require the use of triple DES in order to get audit approval.
The option to use a compressor is driven by the need to optimize the size of the protected data. However, the effectiveness of the compressor depends on the content of the data. The MQeRleCompressor performs run length encoding ; that is, the compressor routines compress and/or expand repeated bytes. Hence it is effective in compressing/decompressing data with many repeated bytes. MQeLZWCompressor uses the LZW scheme. The simplest form of the LZW algorithm uses a dictionary data structure in which various words (data patterns) are stored against different codes. This compressor is likely to be most effective where the data has a significant number of repeating words (data patterns).
To use queue base security, the queue manager that owns the queue must have a private registry. If the MQeWTLSCertAuthenticator is used, the registry must also have its own credentials, which it obtains by auto-registering with the mini-certificate server. In the following example the credentials process is enabled by adding information to the Registry Section of the queue manager's configuration (.ini) file. If the MQeWTLSCertAuthenticator is not used, a private registry is still required but it does not have to register with the mini-certificate server to obtain credentials.
The following code fragments provide an example of how to create queue manager instances and define the queues identified for the queue-based scenario described in Usage scenario.
qm_create assists users to create queue manager instances that have private registries. The class uses parameters found in the Registry Section of MQePrivateClient1.ini and MQePrivateServer1.ini.
The particular instances can be created as follows:
qm_create ServerQMgr -p 12345678 -c 12345678 -k It_is_a_secret -s 127.0.0.1:8082 qm_create ClientQMgr -p 12345678 -c 22345678 -k It_is_a_secret -s 127.0.0.1:8082
There are several ways to add queue definitions to a queue manager instance. The method described here starts the queue manager instance locally, adds the new queue definitions by creating the relevant administration messages and sending them to the queue manager's own administration queue, and then waits for confirmation of success in an AdminReply queue.
Start the ClientQMgr locally then create and use administration messages to add the queue and set the poll interval.
q_create ClientQMgr TestClient_HomeServerQ -h ServerQMgr Network:127.0.0.1:8081 TestServer_StoreAndForwardQ -p 12345678 -c 12345678 -k It_is_a_secret -s FastNetwork:127.0.0.1:8082
Start the ClientQMgr locally then create and use an administration messages to add the queue.
q_create ClientQMgr XXX_service_reply -r -p 12345678 -c 12345678 -k It_is_a_secret -s FastNetwork:127.0.0.1:8082
Start the ServerQMgr locally , create and use an administration messages to add the queue, and then add a remote queue manager reference.
q_create ServerQMgr TestServer_StoreAndForwardQ -f ClientQMgr -p 12345678 -c 12345678 -k It_is_a_secret -s FastNetwork:127.0.0.1:8082
Start the ServerQMgr locally using the MQePrivateClient class, (using a different version, MQePrivateServer2.ini, that deliberately does not hold hard coded values for PIN, KeyRingPassword and CertReqPIN) then create and use an administration messages to add the queue.
q_create ServerQMgr XXX_service_request -q -p 12345678 -c 12345678 -k It_is_a_secret -s FastNetwork:127.0.0.1:8082
An example Server TestService program, securityTestService, is provided. It can be started by the command:
securityTestService ServerQMgr ClientQMgr -p 12345678 -c 12345678 -k It_is_a_secret -s FastNetwork:127.0.0.1:8082
The example queue-based security scenario in Usage scenario describes a client queue manager application that initiates XXX_service_request messages by encapsulating the request in a MQeMsgObject and using putMessage() to reliably deliver the request to the server queue manager's XXX_sevice_request queue. It then waits for the reply to the service request by using waitForReply() on its own XXX_service_reply queue.
In the scenario, the TestService application on the server processes the service request by using getMessage() to get the service request from the XXX_service_request queue, processes the request (for example by invocation of a backend transaction), builds the reply MQeMsgObject, and uses the server queue manager putMessage() to return the reply to the (remote) initiating client queue manager.
The server queue manager internally puts the message onto its TestServer_StoreAndForwardQ. The client queue manager pulls the message from the TestServer_StoreAndForwardQ and receives it in its ClientTest_HomeServerQ before putting it on the intended target XXX_service_reply queue.
An example Client TestService program, securityTestClient, is also provided. It invokes a service request and processes the resulting reply. This example can be started by the command:
securityTestClient ClientQMgr ServerQMgr Network:127.0.0.1:8081 -p 12345678 -c 22345678 -k It_is_a_secret -s FastNetwork:127.0.0.1:8082
When a queue manager accesses a remote queue or any local queue that is defined with an attribute including the MQeWTLSCertAuthenticator, then the queue manager and queues are authenticatable entities and require their own credentials.
A queue manager's credentials are created by triggering auto-registration. The simplest way of triggering auto-registration is to include the relevant keywords in the registry section of the ini file used when the queue manager is created. The keywords needed on the command line are:
-c 22345678 -k It_is_a_secret -s FastNetwork:127.0.0.1:8082
The credentials of queues (with an attribute including MQeWTLSCertAuthenticator) are also created by triggering auto-registration. This happens automatically when an administration message adding the queue is processed providing that:
When adding a queue (with an attribute including MQeWTLSCertAuthenticator) the queue can have its own credentials or it can share its owning queue manager's credentials. This choice is determined when the 'create queue' administration message is constructed.
The following describes how to create a queue with name ServerTestQWTLS on ServerQMgr.
Assume that the mini-certificate server administrator has added ServerQMgr+ServerTestQWTLS2 with Certificate Request PIN equal to 12345678, and has started the mini-certificate server in 'server' mode. Use the -o flag on a q_create command to create queue ServerTestQWTLS2 as in the following example:
q_create ServerQMgr ServerTestQWTLS2 -o -p 12345678 -c 12345678 -k It_is_a_secret -s FastNetwork:127.0.0.1:8082
Where the 12345678 following -c is ServerTestQWTLS2's Certificate Request PIN (not ServerQMgr's). Effectively, the -o flag causes the MQE_QUEUE_TARGETREGISTRY field in the queue creation administration message to be set to MQE_QUEUE_REGISTRYQUEUE, which means that the queue to be created should have its own credentials. (If the queue to be created is sharing its queue manager's credentials, MQE_QUEUE_TARGETREGISTRY must be set to MQE_QUEUE_REGISTRYQMGR. If the queue to be created is not having credentials, MQE_QUEUE_TARGETREGISTRY must be set to MQE_QUEUE_REGISTRYNONE.) The -o also causes the obtained credentials to be published in the queue manager's public registry.
Whenever a queue manager and any of its queues are authenticatable entities, that is, have their own credentials, then, in order to access these credentials, the appropriate parameters are needed when the queue manager is started.
While hard coding these parameters in the registry section of the appropriate ini file is a convenient mechanism during solution development, it is inappropriate for a production system. Whenever possible, these parameters should be collected interactively and used to start a queue manager instance without storing them in a file.
When data is sent between a queue manager and a remote queue, the queue manager opens a connection to the remote queue manager that owns the queue. By default, if the remote queue is protected, for example with a cryptor, the connection is given exactly the same level of protection as the queue. To reduce the number of connections open concurrently, the queue manager can reuse an existing connection if its level of protection is adequate. If none of the connections has a suitable level of protection, the queue manager can also change the level of protection on an existing connection to match that required for the queue. The default behavior can be changed by using attribute rules on both the queue and the connection. These rules apply to the attribute on the queue (and connection), they are not the same as queue rules.
The C Bindings code API does not support attribute rules written in C. However, users can write their own rules in Java. An example Java rule, examples.rules.AttributeRule, is provided.
While the examples.rules.AttributeRule provides practical defaults, there may be a solution specific reason why different behavior is required. You can modify the way connections are reused by extending or replacing the default examples.rules.AttributeRule with rules that define the desired behavior.
If attribute rules are defined for the queue, the queue manager uses the rules to decide whether an existing connection has sufficient protection for the queue. If the equals() function in the rules returns true, the connection can be used. WebSphere MQ Everyplace provides an example rule, examples.rules.AttributeRule, that can be used on the queue. This rule allows a connection to be used for a queue if the following conditions are met:
The example rules define "better" for a cryptor to mean:
If none of the existing connections has sufficient protection for the queue, the queue manager checks if any of the connections can be upgraded to the required level. If attribute rules are defined for the connection, the permit() function is used to determine this. The examples.rules.AttributeRule uses the following criteria:
Before allowing connection reuse, the target queue uses its current AttributeRule equals() function to determine if the connection attribute can provide an appropriate level of protection for the target queue. This provides protection against inconsistency in the queue attribute rules on the local and target queue managers.
Attribute rules are set on a queue when it is created or modified using administration messages. Attribute rules are set on connections by defining an alias on ChannelAttrRules. For example, the following pseudo-code shows how to make a queue manager use examples.rules.AttributeRule.
mqe_alias(pErrorBlock, MQeString("ChannelAttrRules"), MQeString("examples.rules.AttributeRule"));
It is possible to run without setting ChannelAttrRules, but this mode of operation is not recommended.