Sunday, March 19, 2017

Passing Parameters to XenDesktop by Rewriting the StoreFront ClientName

A recent client had the following business requirements:

1) To logon, enumerate and launch a XenDesktop from within their corporate intranet, and

2) To pass department/project information to the desktop. This was necessary so that the correct network drives were mapped for the session.

The first requirement was easily met by using the StoreFront Web API to embed StoreFront functionality into their intranet. The second requirement, however, was a bit more involved, as the same user could possibly be working on multiple projects simultaneously, and would therefore require different drive mappings for each.

Enter the StoreFront Store Customization SDK. The Store Customization SDK has predefined "customization points" which allow you step in and apply custom logic to modify enumerated resources, change launch parameters, and to modify device information. 

You can download the latest version of the Store Customization SDK here.

For an introduction to the SDK, see Citrix Principal Architect Simon Frost's blog post: Introducing the StoreFront Store Customization SDK. You can also check out his Synergy Developer Exchange Series video StoreFront Store Customization SDK.
One such field that can be modified via the Store Customization SDK is the session Clientname, which is easily accessed from within the XenDesktop session. Simon made modification of the Clientname quite easy with the release of his blog post and accompanying DLL Rewriting the Session ClientName from StoreFront. Alas, none of the many tokens defined in the DLL would support passing a dynamic parameter such as department or project information. However, since Simon was kind enough to also supply the source for his DLL, I was able to satisfy that business requirement by extending his DLL to incorporate HTTP headers into the ClientNameRewriteRule.

Simply use the token $H’header name’ (single quotes) within the ClientNameRewriteRule where you would like the value of the specified header placed (please refer to his blog post for a detailed explanation of the ClientNameRewriteRule).

For example, if I wanted the ClientName to contain the user’s roaming status (“I” for internal, and “E” for external), and the value of the Department header, the rule might look something like:


    <add key=”clientNameRewriteRule”  value=”$R-$H’Department’ “ />


If the value if the Department header was Dept007, then the ClientName would look like:

You must keep in mind the ClientName restrictions - the total length of the result must be 20 characters or less – anything longer will be truncated, and may not contain any of the following characters: “/ []:;|=\,+*?<>.
You must also set the value of overrideIcaClientName to “On”. For newer versions of StoreFront, you can find the setting in the GUI under Configure Store Settings | Advanced Settings. For older versions of StoreFront, see Simon’s blog post for manually modifying the configuration file (always make sure that the GUI console is not open when manually modifying any of the configuration files).
There is one final (but essential) requirement. For security reasons, StoreFront will not forward any unknown headers, so you must add your new header to the StoreFront whitelist:
  • Backup web.config in your <Store>Web directory.
  • Find the <communication> section (under <webReceiver> | <serverSettings>).
  • Add the highlighted lines:

  • Save the file ... an IISRESET is not required.

Sunday, January 29, 2017

Adding an EULA for AAA Login

With the release of NetScaler version 11, administrators have the option of configuring an End User License Agreement (EULA) that users must accept before being allowed to log on to the NetScaler. Configuring the EULA adds a checkbox to the logon page:

Note that the Log On button is grayed out until the EULA is accepted. The exact wording (what the user sees when clicking on the Terms and Conditions hyperlink) are configured by the administrator.

1) To create the EULA using the GUI, go to NetScaler > NetScaler Gateway > Resources > EULA (If you’ve already created and globally bound your EULA, skip to step 11).

2) Click Add.

3) Give your EULA a name (your can have multiple EULAs and switch between them), enter the text of the EULA, and click OK. Note that you can enter HTML codes to format your text.

4) Now, if we wanted the EULA for a specific Access Gateway vServer, we would bind the EULA under the Advanced Settings of the gateway vServer.

Here, however, we want to bind the EULA globally, so we head over to NetScaler > NetScaler Gateway > Global Settings.

5) Click on Configure an End User License Agreement.

6) Click Add Binding.

7) Click to select the EULA.

8) Select the EULA you just created...

9) ... and click Bind.

10) The EULA is now bound globally. Click Close.

11) If you browse to the FQDN of your gateway vServer, you should now see the screen shown at the top of the post. Note: If you don’t see the checkbox and hyperlink, see step 15 below.

12) If you click on the Terms and Conditions hyperlink, you should see:

Notice that I specifically said the FQDN of your gateway vServer. Since the EULA is bound globally, you would expect to see the same thing for an AAA login page (you can see what an AAA login page looks like by simply replacing index.html in the URL with tmindex.html). While the actual login page looks the same, clicking on the Terms and Conditions hyperlink for the AAA login page shows:

What happened? It seems that there is an “unanticipated feature” (a “bug” in layman’s terms) in the AAA logic. Is there a workaround? Of course there is (or I wouldn’t be writing this post! :))

13) Using your favorite SCP editor, go to the /resources directory of the theme you are using, and make a backup of the language XML file(s) that you are using (e.g. en.xml for English). Open up the XML file and look for Partition id=”logon” (which contains the text strings for the logon page).

Now, the id for the EULA text is agreement, so to add the EULA, we need to add a line containing that id to the file. Since the entire string must be contained on a single line, if you wish to keep the same formatting as above, you might be tempted to simply add the following line:

Unfortunately, the above will not accomplish what you want. In fact, if you browse to the FQDN of the site, you will now see only:

Yup ... just a blank page. That’s because you need to HTML-encode the < and > symbols.

14) Simply replacing each < (less than symbol) with &lt; and each > (greater than symbol) with &gt; (the semi-colon is mandatory) will do the trick. So the final line will look like:

15) It has come to my attention that certain versions of the NetScaler may not display the EULA checkbox and hyperlink, even if the EULA is bound globally. If this is the case, you will need to make a source-code modification to one of the JavaScript files.

Disclaimer: Source-code modifications are not supported by Citrix Support, and you may be asked to reverse any changes made. The below modification is provided as is. There is no guarantee that it will work in your environment. Test out any changes on a non-production system first, and keep a backup of the original file(s).

16) Make a backup copy of /netscaler/ns_gui/vpn/js/tmindex_view.js. Open the file and search for the highlighted line below:

17) Insert the highlighted line:

18) Save the file. Clear your cache and refresh the page (you may need to wait 2 mins for the NetScaler cache to purge). You should now see the checkbox and hyperlink.

19) In order to survive a reboot, you will also need to copy the modified tmindex_view.js file to /var/vpn/vpn/js (if the /js directory does not exist, create it).

20) If the NetScaler is part of an HA pair, you will need to copy the modified file into both directories of the secondary appliance, as source-level modifications are not synched between nodes.