Friday, August 5, 2016

OpenAM 13.0.0 Radius Server Flaw

OpenAM version 13.0.0 was the first version of OpenAM that enabled it to act as a RADIUS server. It has supported being a RADIUS client for many years meaning that validation of authentication can be deferred to an external RADIUS server. With OpenAM now able to act as a RADIUS server, many of its existing authentication modules and the flexibility of its authentication chains can be leveraged by resources that can defer their authentication to a RADIUS server.  VPN concentrators are but one example. Where previously my employer's VPN could only defer to an LDAP store, it can now pass authentications to OpenAM and leverage the same multi-factor mechanisms that they support for web authentications.

But inclusion of the RADIUS server functionality in version 13.0.0 of OpenAM inadvertently included a subtle flaw. If an incoming RADIUS request did not contain a username field, the internal thread of OpenAM's RADIUS listener died. Thereafter, any further incoming requests never get handled nor responded to. The characteristics are obvious. Client's fail to get responses back from the server and if debug logging is enabled for OpenAM's RADIUS server, that log file ceases to receive any more traffic logs.

Is My Server Susceptible?

 

You can tell if your server is susceptible by using a client that does not include a username field in the RADIUS request if the username is left empty. The Console Client expected to be included in version 14.0.0 of OpenAM behaves in that way. Until that version is available in the nightly war I've made it and the relevant jars available in a temporary git repo here.  You can clone that repo and follow the steps outlined there to get that newer version of ConsoleClient running for use in the steps below.

In my previous post on Using OpenAM 13's Radius Server  I showed how to use the Console Client included in OpenAM's war file to test the RADIUS server functionality. As outlined in that post, to expose what was going on in the RADUS Server, we enabled the Radius loggers at Message level. For clarity I'm adding a bit more detail here on how to do that. If you already know how and where the debug file is located just skip the next section.

Enabling Radius Loggers


To enable Radius logging at Message level as noted in that post, I first log into OpenAM as amadmin and go to <your-openam-root-path>/Debug.jsp. For example, I deploy in tomcat running on port 8080, with a war file renamed to sso.war, and an entry in my etc/hosts file pointing ident-local.lds.org to 127.0.0.1. So Debug.jsp is found on my box as shown in the image.



In that page select the Radius category and a level of Message and press the Submit button. That leads to the next screen where you must confirm your selection.



Once confirmed, output related to the RADIUS server functionality will begin to appear in a log file having the name of Radius and located under your configuration directory in a path of <config-root>/<webapp-root>/debug. I use a configuration directory of /opt/openam which places my log file at /opt/openam/sso/debug/Radius.

Does It Kill It?

 

Once you have the RADIUS Server enabled, a RADIUS client defined, have created the radius.properties file and have the newer Console Client running, don't enter a username. Just hit the Enter key and move on to the password prompt. Enter some value for the password and submit. You'll correctly be denied access as shown in my example run. (Ignore that NPE. As noted on the git repo it is innocuous and goes away if a larger set of OpenAM's jars are available.)

java -jar lib/openam-radius-server-14.0.0-SNAPSHOT.jar
? Username:
? Password:

DebugConfiguration:08/05/2016 04:14:42:775 PM MDT: Thread[main,5,main]
'/debugconfig.properties' isn't valid, the default configuration will be used instead: Can't find the configuration file '/debugconfig.properties'.
DebugImpl:08/05/2016 04:14:42:786 PM MDT: Thread[main,5,main]
Can't read debug files map. '. Please check the configuration file '/debugfiles.properties'.
java.lang.NullPointerException
at java.util.Properties$LineReader.readLine(Properties.java:434)

--snipped-stack-trace--

NOTE: username is empty string. Leaving out of request to test error handling.
Packet To 127.0.0.1:1814
  ACCESS_REQUEST [1]
    - USER_PASSWORD : *******
    - NAS_IP_ADDRESS : localhost/127.0.0.1
    - NAS_PORT : 0
    - NAS_IDENTIFIER : console-client

Packet From 127.0.0.1:1814
  ACCESS_REJECT [1]

---> Sorry. Not Authenticated.


Now try again with a valid username or actually with any values at all in the username and password fields. The request is sent to the server, but Console Client never receives any response from the server and therefore appears to hang:

java -jar lib/openam-radius-server-14.0.0-SNAPSHOT.jar
? Username:
? Password:

DebugConfiguration:08/05/2016 04:17:28:355 PM MDT: Thread[main,5,main]
'/debugconfig.properties' isn't valid, the default configuration will be used instead: Can't find the configuration file '/debugconfig.properties'.
DebugImpl:08/05/2016 04:17:28:364 PM MDT: Thread[main,5,main]
Can't read debug files map. '. Please check the configuration file '/debugfiles.properties'.
java.lang.NullPointerException
at java.util.Properties$LineReader.readLine(Properties.java:434)

--snipped-stack-trace--


NOTE: username is empty string. Leaving out of request to test error handling.
Packet To 127.0.0.1:1814
  ACCESS_REQUEST [1]
    - USER_PASSWORD : *******
    - NAS_IP_ADDRESS : localhost/127.0.0.1
    - NAS_PORT : 0
    - NAS_IDENTIFIER : console-client


If you look in the RADIUS debug log at /opt/openam/sso/debug/Radius the last 100 lines or so will include your incoming packet like so:

amRadiusServer:08/05/2016 04:14:42:795 PM MDT: Thread[pool-8-thread-1,5,main]: TransactionId[683ced09-8e8b-48dd-b05e-aca40583cf05-27]
WARNING:
Packet from local:
  ACCESS_REQUEST [1]
    - USER_PASSWORD : *******
    - NAS_IP_ADDRESS : /127.0.0.1
    - NAS_PORT : 0
    - NAS_IDENTIFIER : console-client

And not far after that you'll see a NullPointerException that looks like this:

amRadiusServer:08/05/2016 04:14:42:801 PM MDT: Thread[pool-8-thread-1,5,main]: TransactionId[683ced09-8e8b-48dd-b05e-aca40583cf05-27]
ERROR: Exception occured while handling radius request for RADIUS client 'local'. Rejecting access.
java.lang.NullPointerException
        at org.forgerock.openam.radius.server.spi.handlers.OpenAMAuthHandler.startAuthProcess(OpenAMAuthHandler.java:726)

--snipped-stack-trace--


And you'll see the returned RADIUS response. But no log entries will appear thereafter and the RADIUS listener thread has died.

How to Fix It?

Patches to fix this issue are available from ForgeRock Support for both 13.0.0 and 13.5.0. And that fix will  also be included in 14.0.0 when it moves to GA. Once you've applied the patch you'll still see the NPE but it won't damage the RADIUS listener and all further requests will continue to received responses from the server.

Enjoy.