2

Host foo is an IBM MQ client (i.e. client mode connection over TCP/IP). Host bar is the system on which the queue manager is running. Bar grants permission (by IP address) for foo to instantiate a com.ibm.mq.MQQueueManager object but does not grant permission to host foobar.

Therefore, I am encapsulating all of the IBM MQ contact into a new app running on foo. Together with foobar, a client/server app is forming, using sockets, where foo is the server and foobar is the client. Foo is still the IBM MQ client, as before.

So far, all I’ve tried to do on foo in the new app (MQ-related) is to instantiate an MQQueueManager object. That’s successful, until I introduce java.lang.SecurityManager.

Local applications executed via the java command, such as this one on foo, are by default not run with a SecurityManager installed. Now it is run with a SecurityManager installed. The reason is to control access to this app running on foo. The security policy accepts connections from foobar (java.net.SocketPermission). This works. The owner of foo can now control the permission granted to foobar.

But we’re getting some interference in the interaction between foo and bar. The interference is coming from the SecurityManager. Don’t run with a SecurityManager installed and foo can instantiate MQQueueManager. Run with a SecurityManager and foo hangs in the MQQueueManager constructor.

Foo is using the Policy reference implementation described in https://docs.oracle.com/javase/7/docs/technotes/guides/security/PolicyFiles.html

The following permission on foo results in the MQQueueManager constructor hanging.

permission java.net.SocketPermission "bar", "connect, accept";

-Dcom.ibm.msg.client.commonservices.trace.status=ON

-Djava.security.debug="access,failure"

... access denied ("java.util.PropertyPermission" "mqs.disable.all.intercept" "read") [java.security.AccessControlException] ...

... access denied ("java.util.PropertyPermission" "mqs.intercept.serializeconn" "read") [java.security.AccessControlException] ...
JoshMc
  • 10,239
  • 2
  • 19
  • 38
Alan Feldstein
  • 93
  • 1
  • 10
  • Just to clear things up, I understand from your question that you are trying to lock down connections into your application from another application by IP address or hostname using the SecurityManager, secondary to this you must allow your app to connect as a MQ client to the queue manager, it is not extra security you are trying to add for your MQ client to MQ server connection. – JoshMc Jun 07 '18 at 20:00
  • The MQ version, from every com.ibm.mq*.jar file that has a MANIFEST.MF file, seems to be 8.0.0.3. – Alan Feldstein Jun 07 '18 at 23:09
  • Yes, I suspected that that "connect" action should have been sufficient. The challenge here has been that the MQQueueManager constructor is a black box. – Alan Feldstein Jun 07 '18 at 23:12
  • Your "just to clear things up" comment is exactly right. Foo alone has access rights to MQ (on bar). I don't want to violate the spirit of that, so I keep the owner of foo in control of extending (abstract) access to foobar. – Alan Feldstein Jun 07 '18 at 23:17
  • Reviewing the link I provided I don't see those specific properties mentioned, but I would suggest adding this and trying again `permission java.util.PropertyPermission "mqs.*","read";` – JoshMc Jun 11 '18 at 18:02
  • Finally had a test of this late yesterday. I hadn't noticed that PropertyPermission "mqs.*" wasn't addressed in the link you provided, so thanks for pointing that out. I'm beginning to look at the problems we haven't solved yet. Expect an edit to my question or a more informative comment soon. – Alan Feldstein Jun 14 '18 at 15:18
  • Are you using AMS? – JoshMc Jun 14 '18 at 17:00
  • "Problems we haven't solved yet" turned out to be mostly just excessive output due to tracing inadvertently left on. The MQQueueManager constructor no longer hangs when a SecurityManager is installed. `permission java.util.PropertyPermission "mqs.*","read";` was unnecessary. The remaining (minor) SecurityManager issue is unrelated to MQ, so it's inappropriate in this thread. – Alan Feldstein Jun 14 '18 at 19:34
  • I'm not sure if IBM MQ Advanced Message Security (AMS) is being used. – Alan Feldstein Jun 14 '18 at 19:37
  • The only reference I found to the "mqs.*" properties was for AMS for MQ v7.0.1 when AMS was a separate product. It may be that it inquires some properties to see if it is in use so not having permission does not harm anything if you are not using that feature. – JoshMc Jun 14 '18 at 22:32

2 Answers2

1

The IBM MQ v8 KC has a page "Running IBM MQ classes for Java applications under the Java Security Manager".

This page states related to MQ client connections:

//For the client transport type.
permission java.net.SocketPermission "*","connect,resolve";

The only thing I noticed is the lack of spaces in the example above compared to what you posted, also you would not need to provide accept permission, and I also noted in sun documentation that resolve is implied with connect so should not be specifically need.

There are a lot of other settings that related to other permissions you may need so I would suggest reviewing the above page for more specifics.


You can take a IBM MQ Classes for Java trace using the following java system property:

-Dcom.ibm.msg.client.commonservices.trace.status=ON

By default the trace will output to a file in the current directory called mqjms_%PID%.trc were %PID% is replaced by the process ID of your java process.

If you want to specify a different file name or path you can add the following java system property:

-Dcom.ibm.msg.client.commonservices.trace.outputName=/tmp/x/y/z/mqjms_%PID%.trc 

Example command with both:

java -Dcom.ibm.msg.client.commonservices.trace.status=ON -Dcom.ibm.msg.client.commonservices.trace.outputName=mqjms_%PID%.trc SomeJavaApp

A java security manager trace could be helpful, you can turn this on by adding the following java system property:

-Djava.security.debug="access,failure"
JoshMc
  • 10,239
  • 2
  • 19
  • 38
  • All attempts to accept this answer or mark it as useful result in an error message from Stack Overflow. "An error has occurred - please retry your request." – Alan Feldstein Jun 14 '18 at 19:39
0

But we’re getting some interference in the interaction between foo and bar. The interference is coming from the SecurityManager. Don’t run with a SecurityManager installed and foo can instantiate MQQueueManager. Run with a SecurityManager and foo hangs in the MQQueueManager constructor.

This is just weird. Where in the MQ documentation does it say to use the Java SecurityManager. Someone has given you bad information. Also, you don't do MQ security with SecurityManager.

The following permission on foo results in the MQQueueManager constructor hanging. permission java.net.SocketPermission "bar", "connect, accept";

Why are you restricting what the MQ client library can do? If it can't listen & resolve tcp communication then it will not work. Just remove that line.

Roger
  • 7,062
  • 13
  • 20
  • Where in the MQ documentation does it say that I can't use the Java SecurityManager to restrict access to foo? Understand that foobar is to know nothing about IBM MQ, just that there are some queues accessible at foo. I don't want to restrict in any way what the MQ client library can do. The "resolve" action is implied when any of the other actions are present. The "listen" action is only meaningful when used with "localhost" and means the ability to bind to a specified port. Removing that line entirely denies even the "connect" and "accept" actions. – Alan Feldstein Jun 07 '18 at 14:52
  • I've been creating Java/MQ client applications for more than 15 years. I've created 100's of them, the most well known one is MQ Visual Edit. Never once in all these years have I ever thought, let me apply security using SecurityManager class. The proper way to do security is at the queue manager using CONNAUTH (for authentication), CHLAUTH (for filtering) and setmqaut (for authorization). – Roger Jun 07 '18 at 15:56