Two-factor authentication (also known as 2-step verification) relies on something you know (like a password) and something you have (like a cell phone). Crackers have a harder time getting into your account, because even if they figure out your password, they still only have half of what they need.
For Citrix Web Interface, in addition to primary authentication, there is a possibility to configure additional authentication mechanisms which will serve as the second factor of user authentication.
2FA Mechanisms, built in to Citrix WI and configurable by Web console, are proprietary RSA SecurID and Aladdin Safeword systems. There is also a possibility to implement free solutions using third option, which is 2nd factor authentication done by an additional RADIUS server. If your intention is to the cost of strengthening your Citrix Web Interface at a minimal level, a Mobile-OTP ( a multiplatform applet that runs on your mobile phone, mp3 player or any other Java enabled device) based 2FA solution can be easily implemented using this option (using MOTP-AS server, for example) . However there are some negative aspects of this solution, such as
- You will need an additional server (in the same perimeter, or with some firewall/router modifications if in another network)
- You will need to create accounts for all users, even if you want to have some users to be able to login with username/password only without 2nd factor auth.
- A smooth transition from 1factor to 2factor authentification method will not be possible
The alternative method I am presenting in this article does not have all negative aspects above, e.g.:
- No additional server is required, the second factor authentication/verification mechanism will be done by a ASP/C# script on the Web Interface itself
- You only create users that have 2nd factor enabled, if a user has no second factor authentication enabled , he/she will still be able to login using username/password only
- Migration can be done smoothly and transparently
The reason of why I started this project was a question: “why do I need a separate authentication server to perform such a simple operation?” The simple operation referred to, is the verification of the passcode, generated by user’s Mobile-OTP applet. So in the end, I managed to implement the solution only by using a modified login.aspx in Citrix Web Interface.
User info will be stored in plaintext format, so make sure in is only accessible by the web server and not visible from the internet. Also make sure you have latest versions of IIS and WI.
Find and open C:/inetpub/wwwroot/Citrix/XenApp1/app_data/include/ loginMainForm.inc
Note, that in my example I am modifying an additional site created under XenApp1, the default folder name is XenApp.
1. Find “<table class="loginForm">” line and add the code above this line.
This will clear our cookies named motpcode and motpuser of the current browser session.
2. Modify username field to add MOTP code to cookie on keyboard events
Find “<input type='text' name='<%=Constants.ID_USER%>'” (line 108 in WI5.4) and add following event code:
So the final code for username field should look like:
<input type='text' onKeyUp="document.cookie='motpuser='+document.getElementById('user').value;" name='<%=Constants.ID_USER%>' id='<%=Constants.ID_USER%>' class='loginEntries<%=viewControl.getExplicitDisabled()?" loginEntriesDisabled":""%>' maxlength='<%=Constants.LOGIN_ENTRY_MAX_LENGTH%>' <%=viewControl.getExplicitDisabledStr()%>
3. Add the Mobile-OTP code field. This is an additional HTML element, where users will enter the code generated by their Mobile-OTP App. In theory, this can be placed anywhere on the form; in this example I will put it under the domain selector.
Find this portion of code: “<% } // End Domain” (line 202 in WI 5.4) and add the following html code after this line:
%><tr><td align=right>Mobile-OTP:</td><td><input type=text id=MOTPcode onKeyUp="document.cookie='motpcode='+document.getElementById('MOTPcode').value;" ></td></tr> <%
Note, we have asp tags (%>) here, as we are inserting in between ASP code lines.
Now, once we have our html form modified, we need to modify the login script itself. It is named login.aspx and is located under C:/inetpub/wwwroot/Citrix/XenApp1/auth/
As a first step we need to add the some functions , with the 2 functions below being the main ones :
- MD5 – C# implementation of a standard MD5 algorithm
- CheckOTP – C# implementation of Mobile-OTP password verification algorithm.
Complete login.aspx should look like this. Download and save this file to replace your original login.aspx.
Also note that this example uses C:/Temp/MOTP.txt as the path for your users’ database. You can change it at line 167.
Add error HTML page
Login.aspx will navigate to ~/html/serverErrorMOTP.html in case the OTP was entered incorrectly. Create an html page in your html folder, so users are aware what went wrong.
Manage users’ database
Users are added to a single plain text file in CVS format. The file should be accessible by IIS with at least read rights. In my example the file is in C:Temp , which is a very bad idea for a production environment.
The file should contain users’ records , one user per line, in following order:
username, init secret, pin code
username – login name of the user
Init secret - a 16-hex-digit secret that has been created when the mobile device was initialized
Pin code - the 4-digit PIN that a user enters on their mobile device
Test access to your Citrix Web interface
Any user without Mobile-OTP protection enabled should be able to login, leaving Mobile-OTP field blank, just right as before.
To test the 2 factor authentication, add a user record (probably yourself) with fake pin and init values to your MOTP.txt file. The user will not be able to login even with a right password provided.
Now, to test a successful login, you should install a Mobile-OTP app on your mobile device. Let’s use an Android phone as an example. Also note that the app exists for iPhone, blackberry and dozens of various mobile phones.
Procedures will be as follows:
1. Install a Mobile-OTP app, there are many available as apk or on AppMarket
2. Initialize the app as per instructions (usually by enterin 0000 as pincode)
3. Write down the generated init secret and choose a pin code
4. Add the init secred and a pin code to user’s record
You can go further and create a customized verification mechanism on both ends, as source code for apps are available.
All clients and source codes are available here
If you use a standard WI WebSite and no customizations have been made, you can use the contents of the archive file to implement the solution.