NetScaler Gateway - Automatic EULA Acceptance
Citrix has recently released NetScaler firmware version 11 which brings us the Portal Themes feature. This in turn makes customisation a lot easier, particularly as we upgrade the firmware version on the appliance - no more custom themes (kind of, there is a ‘fix’ here).
As part of the Portal Themes page, Citrix now allows us to prove and End User License Agreement to our users on the page which looks something like this (with the X1 theme):
The only issue with the above is the fact that our users have to select the checkbox each any every time before they can use the Log On button, pair this with multifactor authentication and you start to run into some pretty annoyed users. So the solution? Well we could use the custom theme method from yesteryear to check the box, but a more fluid and upgrade persistent method (hopefully) is to use a re-write to force the check box ticked.
Using the great developer tools in Google Chrome (F12 or Ctrl+I) and WinSCP (to inspect the index.html file) I was able to find out how the log on form is generated, and what we need to target to change the code so the checkbox is ticked automatically. Firstly, this is how the checkbox is coded:
gateway_login_form_view.js file is generating the checkbox:
Great, so this is our first rewrite, the action will be to add the checked attribute to the type=’checkbox’ section, this can be done with a rewrite such as this:
add rewrite action RW_ACT_EulaChecked replace_all "http.RES.BODY(120000).SET_TEXT_MODE(ignorecase)" "\"type=\'checkbox\' checked\"" -pattern "type=\'checkbox\'"
We need to bind this action to a policy which acts on the
add rewrite policy RW_POL_EulaChecked "HTTP.REQ.URL.CONTAINS(\"gateway_login_form_view.js\")" RW_ACT_EulaChecked
Lastly let’s bind this Rewrite Response policy to our NetScaler Gateway:
bind vpn vserver citrix.ivancacic.com -policy RW_POL_EulaChecked -priority 100 -gotoPriorityExpression NEXT -type RESPONSE
The following rewrite action and policy will enable the Log On button by removing the disabled element:
add rewrite action RW_ACT_LogonAutoEnable replace_all "http.RES.BODY(120000).SET_TEXT_MODE(ignorecase)" "\"\'disabled\':\'\'\"" -pattern "\'disabled\':\'disabled\'"
add rewrite policy RW_POL_LogonAutoEnable "HTTP.REQ.URL.CONTAINS(\"gateway_login_form_view.js\")" RW_ACT_LogonAutoEnable
bind vpn vserver citrix.ivancacic.com -policy RW_POL_LogonAutoEnable -priority 110 -gotoPriorityExpression NEXT -type RESPONSE
That’s about it, we should now have all our users defaulting to a ticked EULA and enabled Log On button. If you are having issues with it remember to clear the loginstaticobjects Content Group from within the Integrated Caching feature, this is applied even if Integrated Caching is not enabled:
The ideal method to treat the above situation would be to use a ‘remember selection’ option, what I mean by that is once the user accepts the EULA don’t make them tick the checkbox again, with the option to clear their selection if the EULA changes. I attempted to get this working by setting a cookie as per below:
add rewrite action RW_ACT_EULAAcceptCookie insert_http_header Set-Cookie "\"EULAAccepted=true\" + \"; expires=\" + SYS.TIME.ADD(31536000).TYPECAST_TIME_AT + \"; path=/\""
In the above action I’m setting a cookie for 365 days from the system time for the root of the sub domain.
add rewrite policy RW_POL_EULAAcceptCookie "HTTP.REQ.URL.SET_TEXT_MODE(IGNORECASE).CONTAINS(\"/Citrix/\") || HTTP.REQ.URL.SET_TEXT_MODE(IGNORECASE).CONTAINS(\"/vpns/portal/\")" RW_ACT_EULAAcceptCookie
The above policy is triggering the action if we hit the
/vpns/portal/ site (Unified Gateway) or the
/Citrix/ URL (StoreFront).
The above works well, and only creates the cookie once the users has logged in, however I didn’t manage to modify my original rewrites to trigger on the
gateway_login_form_view.js page when the cookie exists. For reference I used CTX123676 as a starting point, if you have any ideas on how to get it going, please share in the comments below!
September, 2016 - Mike Roselli has managed to work out the cookie component, more info here, great work Mike!