Wednesday, January 20, 2016

Fixing Your Custom Auth Modules In Open AM 13


We've been kicking the tires of Open AM 13 in several different ways particularly since it includes Radius Server support and we'll be migrating our custom version to this native version. One unrelated aspect of Open AM 13 that is proving problematic was discovered by Dave Bennet of Nulli while he was doing some investigative work for us. The gist of the problem is this,

Any custom authentication modules in Open AM 12 will be broken in Open AM 13

once you've completed your migration. But don't worry. There is a straightforward way to fix the issue. In fact, the fix is so straightforward it is surprising that it didn't make it as part of the automatic upgrade. Maybe it will make it in an early patch.

"Not found error" & "Resource XXX not found"


The characteristics of the bug can be seen in the new XUI console. I'll not be covering creation and deployment of custom authentication modules in much detail below. I'm assuming you know that stuff already. If not, that is covered in the Open AM documentation. Specifically, the developer's guide. 

But suppose you've been using such custom modules or have just deployed and registered such a module. When viewing an existing module instance in a realm you'll receive an error message that isn't very helpful:



Similarly, when attempting to create new instances of your custom module you'll see this same message again but will first be presented with a different message:

This first message is much more useful for helping to identify the underlying problem. To explain why this one is more useful, you need to know that the module's service descriptor file, previously registered with Open AM via ssoadm or ssoadm.jsp, looks like the following. Every module has one of these and this module was working just fine prior to the upgrade. (To be clear, in all of these xml snippets below I've added white space to make it more comprehensible by us humans.)

<?xml version="1.0" encoding="UTF­8"?> 
 <ServicesConfiguration>
  <Service name="iPlanetAMAuthAuthLevelSetService" version="1.0"> 
   <Schema i18nFileName="amAuthAuthLevelSet"
    i18nKey="authlevelset­service­description" revisionNumber="10"
 serviceHierarchy="/DSAMEConfig/authentication/iPlanetAMAuthAuthLevelSetService">
    <Organization>

     <AttributeSchema cosQualifier="default" i18nKey="a500" 

      isSearchable="no" listOrder="natural" 
      name="iplanet­am­auth­authlevelset­auth­level" rangeEnd="2147483647"
      rangeStart="0" syntax="number_range" type="single">
      <DefaultValues><Value>1</Value></DefaultValues>
     </AttributeSchema>

     <AttributeSchema cosQualifier="default" i18nKey="a501"
      isSearchable="no" listOrder="natural" name="upgradedAuthLevel"
      syntax="string" type="single" validator="no"/>
     <SubSchema inheritance="multiple" maintainPriority="no"
      name="serverconfig" supportsApplicableOrganization="no"
      validate="yes">

      <AttributeSchema cosQualifier="default" i18nKey="a500" 
       isSearchable="no" listOrder="natural" 
       name="iplanet­am­auth­authlevelset­auth­level" rangeEnd="2147483647"
       rangeStart="0" syntax="number_range" type="single">
       <DefaultValues><Value>1</Value></DefaultValues>
      </AttributeSchema>

      <AttributeSchema cosQualifier="default" i18nKey="a501"
       isSearchable="no" listOrder="natural" name="upgradedAuthLevel"
       syntax="string" type="single" validator="no"/>

     </SubSchema> 
    </Organization>
   </Schema> 
  </Service>
 </ServicesConfiguration>

Note the highlighted value of the name attribute of the Service element. It holds the iPlanetAMAuthAuthLevelSetService value shown in the error. That points us to this service descriptor file as being a problem. Now it had been registered and was working previous to the upgrade. So why fail now?


An Undocumented "resourceName" Attribute  


With this hint, Dave looked at the service descriptor file content within Open DJ of an authentication module native to Open AM before the upgrade and afterward. Specifically, Open AM's native DataStore module was used. Its descriptor file in Open AM 12 looked like the following:


<?xml version="1.0" encoding="UTF­8"?> 
 <ServicesConfiguration>
  <Service name="sunAMAuthDataStoreService" version="1.0"> 
   <Schema i18nFileName="amAuthDataStore"
    i18nKey="sunAMAuthDataStoreServiceDescription" revisionNumber="10" 
serviceHierarchy="/DSAMEConfig/authentication/sunAMAuthDataStoreService">
    <Organization>

     <AttributeSchema cosQualifier="default" i18nKey="a500"
      isSearchable="no" listOrder="natural" 
      name="sunAMAuthDataStoreAuthLevel" rangeEnd="2147483647"
      rangeStart="0" syntax="number_range" type="single">
      <DefaultValues><Value>0</Value></DefaultValues>
     </AttributeSchema>

     <AttributeSchema cosQualifier="default" i18nKey="" 
      isSearchable="no" listOrder="natural" 
      name="iplanet­am­auth­ldap­invalid­chars" syntax="string" type="list">
      <DefaultValues><Value>*|(|)|&amp;|!</Value></DefaultValues>
      </AttributeSchema>

     <SubSchema inheritance="multiple" maintainPriority="no"
      name="serverconfig" supportsApplicableOrganization="no"
      validate="yes">

      <AttributeSchema cosQualifier="default" i18nKey="a500"
       isSearchable="no" listOrder="natural" 
       name="sunAMAuthDataStoreAuthLevel" rangeEnd="2147483647"
       rangeStart="0" syntax="number_range" type="single">
       <DefaultValues><Value>0</Value></DefaultValues>
      </AttributeSchema>

      <AttributeSchema cosQualifier="default" i18nKey="" 
       isSearchable="no" listOrder="natural" 
       name="iplanet­am­auth­ldap­invalid­chars" syntax="string" type="list">
       <DefaultValues><Value>*|(|)|&amp;|!</Value></DefaultValues>
       </AttributeSchema>

     </SubSchema> 
    </Organization>
   </Schema> 
  </Service>
 </ServicesConfiguration>

Once the upgrade was completed, instances of this module worked just fine and new instances could be created as well without any error messages. The cause became clear by comparing the same content with that found within Open DJ after the upgrade was completed. It had been modified by the upgrade by adding the highlighted pieces:


<?xml version="1.0" encoding="UTF­8"?> 
 <ServicesConfiguration>
  <Service name="sunAMAuthDataStoreService" version="1.0"> 
   <Schema i18nFileName="amAuthDataStore"
    i18nKey="sunAMAuthDataStoreServiceDescription" revisionNumber="10" 
serviceHierarchy="/DSAMEConfig/authentication/sunAMAuthDataStoreService">
    <Organization>

     <AttributeSchema cosQualifier="default" i18nKey="a500"
      isSearchable="no" listOrder="natural" 
      name="sunAMAuthDataStoreAuthLevel" rangeEnd="2147483647"
      rangeStart="0" resourceName="authenticationLevel"
      syntax="number_range" type="single">
      <DefaultValues><Value>0</Value></DefaultValues>
     </AttributeSchema>

     <AttributeSchema cosQualifier="default" i18nKey="" 
      isSearchable="no" listOrder="natural" 
      name="iplanet­am­auth­ldap­invalid­chars" syntax="string" type="list">
      <DefaultValues><Value>*|(|)|&amp;|!</Value></DefaultValues>
      </AttributeSchema>

     <SubSchema inheritance="multiple" maintainPriority="no"
      name="serverconfig" resourceName="USEPARENT"
      supportsApplicableOrganization="no"
      validate="yes">

      <AttributeSchema cosQualifier="default" i18nKey="a500"
       isSearchable="no" listOrder="natural" 
       name="sunAMAuthDataStoreAuthLevel" rangeEnd="2147483647"
       rangeStart="0" resourceName="authenticationLevel"
       syntax="number_range" type="single">
       <DefaultValues><Value>0</Value></DefaultValues>
      </AttributeSchema>

      <AttributeSchema cosQualifier="default" i18nKey="" 
       isSearchable="no" listOrder="natural" 
       name="iplanet­am­auth­ldap­invalid­chars" syntax="string" type="list">
       <DefaultValues><Value>*|(|)|&amp;|!</Value></DefaultValues>
       </AttributeSchema>

     </SubSchema> 
    </Organization>
   </Schema> 
  </Service>
 </ServicesConfiguration>

As of publishing time this new attribute is undocumented anywhere that I can see and was only added by the upgrade to the AttributeSchema that is associated with the module's authentication level and to the service's SubSchema element. Hopefully, its definition, semantics, and use will be documented by Forge Rock at some point. Until then, the way to fix your authentication modules is now apparent.


Two Fixes: Take Your Pick


There are two different ways to fix this. You can unregister the service descriptor for the authentication module, change the xml and re-register it. The problem with this is that any instances of that module will now be invalid and you'll need to go recreate them and add them back into their consuming authentication chains.

The better approach is to modify the xml found within Open DJ. You can do this by exporting via LDIF (in which case attribute values are base 64 encoded), decoding, modifying the xml, re-encoding, and re-importing that LDIF. 

Alternatively, you can connect to Open DJ with a tool like Apache Directory Studio and modify it directly. This is particularly important if, like us, you have written your own DataStore replacement module and are not using the native version or you are using any custom module as the first one in the chain used for signing into Open AM. After upgrading you may be locked out of Open AM regardless of whether you were using XUI or not. (Correction: see update below) We didn't test that scenario but it seems highly likely. We well might have been in that state were we not to discover this problem and fix it before we upgrade.

So apply the change to any custom modules before upgrading to Open AM 13. But don't change modules native to Open AM. The upgrade will do that for you and I don't know what will happen if those values are already added.

To do this with Apache Directory Studio, open it and connect to your Open DJ with the same Directory Manager bind DN and password that Open AM uses. Expand your root  DSE (dc=openam,dc=forgerock,dc=org for a default install) and expand the ou=services object. 
Within this object is typically a single object with RDN of ou= followed by the version attribute of the Service element from your service descriptor file which is typically 1.0. Selecting this object will show its attributes in the right pane of Apache Directory Studio as shown below for one of our custom modules; SMSOTP auth:




Right click (or mac double finger tap) on the sunServiceSchema attribute and select Edit Value from the pop-up menu. That presents a Text Editor in which you can make the above changes to your module and press the OK button to save them back to Open DJ. Once those changes are made the module will be editable and create-able in Open AM 13 immediately without a restart if you are performing this after migration.

Since 13 isn't out yet I can't say for certain that this will be necessary because it still could get fixed by forge rock. But once 13 is out, if you have problems with your modules this hopefully will get you over that hurdle.

Enjoy.

--

Update 2016.01.21: Dave has confirmed today that the modules still function when authenticating. So the severity at this point is much less. The flaw only affects their management in XUI.