ISAM Forms SSO into BMC Remedy

Updated 09/2015:
HTTP 505 error solved. See end of article.

On a customer site, I encountered BMC Remedy, and had to perform SSO into the Application from ISAM. My initial attempt included trying to use the standard integration we have with Tomcat versions, as detailed here:
http://www-01.ibm.com/support/docview.wss?uid=swg24021393

tomcatUnfortunately, this didn’t work in the time I’d allowed, the integration with Tomcat appeared to work fine, however we were still prompted for a login page on BMC Remedy. I’m not sure if this was related to not supplying the correct roles, or if Remedy doesn’t use the native Java Security Tomcat makes available. (I suspect it is the latter.)

Being a PoC, my fallback approach was to make use of Forms SSO, where I know we have another customer in the region making use of Forms SSO integration with BMC in production. I started my standard analysis of the Forms SSO integration, using Firebug, and immediately got a little concerned.

Entering the text ‘username’ and ‘password’ into the appropriate fields left me scratching my head:

Entering known incorrect, but easily discernible 'username' and 'password' into the login prompt.
Entering known incorrect, but easily discernible ‘username’ and ‘password’ into the login prompt.

The password didn’t appear to be a entered in plain text in the POST prompt:

Note the password parameter shows 'jkpsjhjhjjpmjzpx'
Note the password parameter shows ‘jkpsjhjhjjpmjzpx’

This often spells DANGER when making use of the Forms SSO capabilities of ISAM, but in this case, I noticed an interested flag ‘encpwd’ that was set to ‘1’, and it got me wondering. What if I was to set that to ‘0’ and send the original password? Would that work?

I ran some tests using the Tamper Data plugin and what do you know – it worked. If the encpwd parameter was ‘0’ encoding wasn’t necessary. I dug a little into the HTML source code to see what it was doing, and was left a bit perplexed:

// Scrambles passwords using simple cipher algorithm
function getScrambledPassword(pwd) {
    var cipher = ['k', 's', 'z', 'h', 'x', 'b', 'p', 'j', 'v', 'c', 'g', 'f', 'q', 'n', 't', 'm'];
    var result="";
    if (pwd == null)
        pwd = "";
    pwd = encodeURIComponent(pwd);
    //alert("encoded password: " + pwd);
    for(var i=0;i<pwd.length;i++) {
            var cc = pwd.charCodeAt(i);
        result += cipher[Math.floor(cc/16)] + cipher[cc%16];
    }
    //alert("scrambled password: " + result);
    return result;
}

Then I found someone else who had written a Python Script to decode it here. It makes mention of ‘encryption’ but in reality, it’s really just obfuscation – which begs the question of why? My gut tells me – its so they can tell their customers that the password isn’t sent as plain text over the wire – but it might as well be – since you can simply replay it, and given you can decode it yourself thanks to the presence of the  ‘scrambling’ algorithm in their JavaScript – it adds zero value.

Anyway – on with the case at hand, making it work with ISAM’s FSSO capability, I crafted the FSSO configuration file as follows:

[forms-sso-login-pages]
login-page-stanza = login-page-one

[login-page-one]
#
# The login-page entry is a regular expression used to identify requests
# which are requests for an application's login page and should be
# intercepted.  The regular expression here is relative to the junction
# point where the server is mounted.
#
login-page = /arsys/shared/login.jsp*

# The login-form-action entry is a regular expression used to identify
# which form in an HTML document is the login form. 
login-form-action = /arsys/servlet/LoginServlet*

gso-resource = bmcprod

# The argument-stanza contins a list of arguments that will be submitted
# with the authentication request.
argument-stanza = args-for-login-page-one

[args-for-login-page-one]
#
# The format of the entries in the argument stanza is 
#      name = method:value

#Dynamic Entries:
# Send the GSO username using the input name "username"
username = gso:username
# Send the GSO password using the input name "pwd"
pwd = gso:password

#Static Values - 
#some may be hidden values but I've included them here anyway
auth = string: 
timezone = string:Asia%2FIstanbul
encpwd = string:0
goto = string: 
server = string: 
ipoverride = string:0
initialState= string:0
returnBack = string:%2Farsys%2Fhome

Configuring it to match the Firebug output above, with one subtle difference, setting the encpwd parameter to ‘0’.

I created the GSO Resource bmcprod, set the GSO credentials on the user, and configured the junction to use the newly minted fsso.conf file.

Using the ISAM LMI, attaching an FSSO configuration file is easy.
Using the ISAM LMI, attaching an FSSO configuration file is easy.

And all going to plan, you should be cooking with gas!

BMC Screenshot

Subsequently – after configuring the SSO – I noticed some issues with the Tomcat server returning a HTTP Status Code 505 in response to some if the JavaScript – after some investigation, I discovered the cause.

HTTP Status 505 - The server doesn't support the requested HTTP protocol version. Tomcat Server Error.
HTTP Status 505 – The server doesn’t support the requested HTTP protocol version. Tomcat Server Error.

It seems that some of the JavaScript hosted by BMC Remedy, is only supplied pre-compressed. This saves processing power for the server, however, if the client doesn’t request a compressed ‘accept-encoding’, Tomcat throws a HTTP 505 error.

As it so happens, ISAM/WebSEAL by default will strip this header from the request. It does this so that it can parse the data returned for junction filtering purposes among other things. When using Virtual Host junctions, this is less critical, as filtering is not required.

[filter-request-headers]
#
# HTTP headers to filter from the client request before sending to the
# back-end web server.  Note that this list is in addition to headers
# that WebSEAL will always filter, eg iv-user, iv-groups.
#
# Format is:
#   header = <header-name>
#
# The header name is case insensitive.
#
# The addition of "accept-encoding" to this list will prevent junctioned
# servers from returning compressed data to WebSEAL.  WebSEAL cannot
# filter compressed data.
#header = accept-encoding

Simply comment out the line stripping the ‘accept-encoding’ header, and Tomcat should be happy to reply.

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

WordPress.com.

Up ↑

%d bloggers like this: