Sunday Sep 20, 2009

Portrait mode Sun Ray

Having a rotated, portrait mode desktop with Sun Ray is something that has been frequently asked for. With the Xnewt X Server for Sun Ray and its support for the RandR (Resize and Rotate) extension this is now possible.

To test this, I installed the latest Sun Ray Software 5 EA 2. Next to a fairly standard installation and configuration I made sure that for every session (both for pseudo tokens and normal tokens) xrandr is called. This utility takes several options. In my case I used it as:

/usr/X11/bin/xrandr -o left

Not having a fancy portrait mode monitor at hand, I decided to just turn my monitor 90 degrees. What you can see in the very short (1m20s) video below is that both the login screen and also the desktop itself shows up in portrait mode. This is of course exactly what I want! All the information displayed from the firmware itself, is of course still in landscape mode. As far as I know this is something that can not be changed right now.

Have fun, Rene.

Tuesday Sep 15, 2009

UZI-card VDI integration

Triggered by one of our integration partners I recently worked on integrating the Dutch UZI-card ('UZI-pas') with Sun VDI and Sun Ray. The aim of the UZI-card is to uniquely identify and authenticate healthcare providers. The UZI-card is provided by the Unique Healthcare Practitioner Identification Register which is better known by its Dutch acronym: UZI-register.

What is the UZI-register?

"The UZI-register is the organisation that provides unique identification for healthcare practitioners in the Netherlands. The unique form of identification is provided by the UZI-register to healthcare practitioners in the form of an UZI-card, a kind of electronic passport. The UZI-register processes the application, production and issue of the UZI-card. The UZI-register is part of the Central Agency for Information on Healthcare Professions, an agency of the Dutch Ministry of Health, Welfare and Sports."

What is the UZI-card?

"The UZI-card constitutes a key condition for secure electronic communication and consultation of confidential information by healthcare practitioners. Just like the regular passport, it is an important individual ‘value document’. The UZI-card looks like a bank pass. It contains the electronic identity of a healthcare practitioner, which is protected against misuse. That is why the UZI-card, just like a bank pass, is provided with a unique pin code."

More information about the UZI-register and the UZI-card can be found at the website of the UZI-register.

The integration steps - an overview

To start with, inserting the card into a Sun Ray thin client immediately showed that the smartcard was recognized as a known smartcard type. This was a good start since this meant I didn't have to configure a new smartcard config file. To be specific, the card issued for the user 'Kees Test44' (see the picture of the UZI-card above) was recognized as token 'OpenPlatform.40708533474701566491'. For demo purposes I configured this card in the Sun Ray environment to start a new Terminal Server session to the PDC but this could easily be changed to start an RDP session to the user's desktop as managed by Sun VDI.

Next thing I needed to do is install the PC/SC-lite software on the VDI or Sun Ray server so that the Sun Ray's smartcard reader becomes a PC/SC compliant reader. Software and instructions on installing the PC/SC-lite software can be found here.

Furthermore, in order to be able to do smartcard logon, I had to install an Active Directory (AD) Primary Domain Controller (PDC). Several need to be taken care of on this AD PDC. All of these steps are outlined in the document 'Handleiding configuratie smartcard logon' that can be found on the website of UZI-register. First of all, I had to add the user 'Kees Test44' to the list of AD users and configure this user for smartcard logon. After this, I had to map this user to the UPN on the smartcard by configuring an alternative UPN suffix (equal to the 'Abonneenummer') and defining his user logon name to be the UZI-number ('UZI-nummer'). As an example, for our demo UZI-card this results in a UPN of 900001168@00000509. Next to installing (generating) a Domain Controller certificate that needs to be present on the DC to be able to do smartcard login I had to import and trust the CA certificates of all of the issuing CA's in the trust hierarchy all the way up to the root CA. More on this hierarchy (for the test UZI environment) can be found here. Finally, I had to install the smartcard middleware software (in this case that of AET Europe) on the desktop for the user 'Kees Test44'. Since I was using a TS connection to the PDC I had to install it on the PDC itself. In the VDI desktop case we will have to install it on each desktop (template).

After all these steps, a smartcard logon was possible as can be seen in the video below.

Demonstration of UZI-card smartcard logon

The following video shows a demonstration of smartcard logon using the UZI-card for user 'Kees Test44'. In this video Kees logs on to his desktop and visits one of the specific healthcare web applications using one of the certificates on his smartcard.

Have fun, Rene!

PS. to be complete, more than one certificate could be found on the UZI-card. Next to the certificate used for authentication in the demonstration above, the card also contained certificates for confidentiality and digital signing purposes.

Thursday Jul 16, 2009


Last weekend I decided to put some effort around integrating Sun VDI and strong authentication based on One-Time-Passwords (OTP). During my visit to the European Identity Conference in May 2009 I had received a YubiKey at the booth of Yubico and I was still thinking about setting up some meaningful demonstration with it. During the same period I had received a request from a partner of ours whether it would be possible to have OTP integrated into Sun VDI. So finally this weekend the two ideas came together and I decided to extend the standard VdaClient used in VDI3 with YubiKey authentication.

So what is a YubiKey?

According to Wikipedia the YubiKey, manufactured by Yubico, is a device that acts as a USB keyboard and provides secure authentication by a one-time password algorithm.YubiKey From the manufacturer's website: "The Key generates and sends unique time-variant authentication codes by emulating keystrokes through the standard keyboard interface. The computer to which the Key is attached receives this authentication code character by character just as if it were being typed in from the keyboard – yet it's all performed automatically. This process allows the Key to be used with any application or Web-based service without any need for special client computer interaction or drivers." And in a nutshell, that's what it is. The Key is in fact very small and lightweight (18 x 45 x 2 mm and only 2 grams) and doesn't require a battery. Again, since it is presenting itself as a USB keyboard, you don't need any special device drivers or such. That's why this works also out-of-the-box on a Sun Ray device. So, the Yubikey is a USB device and has one button. If you push the button, it generates an authentication code (consisting of a unique identity code and an OTP). With the identity code it is possible to check if the used Key is really the one assigned to this user. The complete authentication code can be checked either locally with a validation server or over the Internet with a Web Services API that Yubico is offering. This is extremely neat since integrating this way is almost just a matter of minutes. Also a lot of Web Services clients have been written in various languages and these are all open sourced.

For more information on the YubiKey please visit

Initially I had extended the UI with an additional field where a user can have their generated OTP put in as a visible string. This obviously works fine but after browsing some sites and applications that also integrate with the YubiKey it appears that it is more common to just have the OTP typed in right after the regular password (at least, in the case of "two-factor authentication with username"). In that case it is easy to separate the two since the OTP is a long fixed length string. Anyway, I decided to go back to the more common design which you can see in the demonstration video below. My original design and application you can see here:

So how does it work?

As you can see in the demonstration, a user types in his or her username in the regular Username field and the password (in my case I use the AD password for the user) in the Password + .YubiKey field. I use the AD username and password so the user can be authenticated also against AD. Furthermore, via e.g. a lookup in AD it can be established if this is the key for the user. For this to work, the YubiKey unique identity code needs to be in the user profile. Of course, it is also possible to store these in a separate database.

After the user puts in the username and password, we keep focus in the Password + YubiKey field and press the button on the YubiKey so the OTP code gets typed in right after the regular password for the user...

At that point, the YubiKey identity is verified for this user, the OTP is validated via the Yubico Web Services API, and the username and password are also checked against AD. If this all succeeds, the user is logged in and is either shown its default desktop or the desktop selector frame as can be seen in the demonstration. If either one of these pieces of information is wrong or we try to replay an old OTP, we get the appropiate error messages as can again be seen in the short video.

Have fun!

Friday Jul 03, 2009

Changing the VDI3 login GUI

Disclaimer: everything written below is put here just to share my ideas and findings about how to change the UI of the VDI client used in a VDI3 environment. Since the client is packaged with all of its components in a jar file and there are no configurable ways of changing the UI at this moment, this involves updating components directly within in the jar file. I am in no way encouraging to do this with the way described here, especially not in a production environment because doing so will give you an unsupported environment. Applying a patch in the future might overwrite the changes made to the client. Furthermore, in the future, the client UI might very well be configurable. Consider this as my 'hobby-bob' project to see where we could get with this... :-)

Having that said, I have had several requests of customers, partners and colleagues to change the VDI3 login screen. Again, although formally not supported it is no rocket-science to adapt the images and class files (required to change some of the UI style) in the off-the-shelf vdaclient.jar. The java client code based on AWT / Swing can (in a default installation) be located in /etc/opt/SUNWkio/sessions/vda. If you extract the jar file you will get to a bunch of directories and class files underneath com/sun/vda/client:

# pwd
# jar xf vdaclient.jar
# ls com/sun/vda/client
VdaClient$ButtonActionListener.class  images
VdaClient$DesktopFetcher.class        model
VdaClient$DesktopStarter.class        resources
VdaClient$Response.class              ui
VdaClient.class                       util

so, what are the most common requests - in random order?

  1. Adapting the image window used for login and desktop selector,
  2. Adapting the Sun logo in the upper left corner,
  3. Changing the background of the total screen,
  4. Changing texts and fonts.

Adapting the images can be done by creating new images and updating the existing ones in the vdaclient.jar. So to start with, let us take a look inside the images directory as outlined above...

The images

If we take a look at the images directory, we see a bunch of images that could potentially be replaced by corporate logo's, style, etc. Most relevant images to adapt in many scenario's are probably 'dialog_background.png' and 'sun_logo.png'.

One could take their own favorite image editor program and create some images based on the original one or create something from scratch. Just watch out that you keep about the exact same white space for selector boxes, drop down menus and error information to appear as can been seen in the original.

1. Adapting the image window used for login and desktop selector

A simple example of an adapted 'dialog_background' image that I have made for a VDI demo show at Capgemini can be seen below.

I have run the vdaclient.jar from my laptop (via 'java -jar vdaclient.jar') to get this screenshot. Actually, this is not the best example since the logo at the lower right corner can be overwritten by (long) error messages that can occur in certain misconfigured situation. As this was not the case in this demo setup, I decided to leave it like this - based on Capgemini look and feel style.

In fact, if you create the image like this with the logo in the lower right corner, it will not show, since by default the white space will be rendered on top of the logo image (in order to get this right, you have to set the RootPanel and OptionsPanel as being transparent - this can be done by adding / changing the line 'jpanel.setOpaque(false)' to both methods 'createRootPanel' and 'createOptionsPanel' in the 'Dialog' class; how this can be done... see below).

So now we have this image created we need to update it in the vdaclient.jar file and we should be all set:

# jar uf vdaclient.jar com/sun/vda/client/images/dialog_background.png

2. Adapting the Sun logo in the upper left corner

Obviously, exactly the same method as described above applies to adapt the other images (e.g. 'sun_logo,png', etc.).

3. Changing the background of the total screen

Unfortunately, the background cannot easily be changed since it is not an image but a vertical gradient color that is generated by some Java code within vdaclient.jar. Let's look at the relevant Wallpaper.class file by decompiling the class file as follows (using jad in my case):

# cd com/sun/vda/client/ui
# jad -s java Wallpaper.class
Parsing Wallpaper.class... Generating

If we then take a look inside we see the following lines:

public class Wallpaper extends JPanel

    public Wallpaper()

    public void paintComponent(Graphics g)
        Graphics2D graphics2d = (Graphics2D)g;
        Dimension dimension = getSize();
        GradientPaint gradientpaint = new GradientPaint(0.0F, 0.0F, FIRST_COLOR,
 0.0F, dimension.height, SECOND_COLOR);
        graphics2d.fill(new java.awt.geom.Rectangle2D.Double(0.0D, 0.0D, dimensi
on.width, dimension.height));

    public static final Color FIRST_COLOR = new Color(25, 107, 138);
    public static final Color SECOND_COLOR = new Color(197, 212, 225);


It is easiest to just change the background color by changing the value of FIRST_COLOR and SECOND_COLOR. If we make these both the same color we get a solid background with that color. After the code change we have to compile the class again and update the vdaclient.jar file:

# javac -classpath ../../../../../vdaclient.jar
# cd ../../../../..
# jar uf vdaclient.jar com/sun/vda/client/ui/Wallpaper.class

This is exactly what I have done for the login screen for our lab environment Sunlabs (combined with yet another login image) as you can see below.

Another thing we can do here is use a background image instead of a solid or gradient color. I have done this, it requires some more code changes but I found the total screen way to 'crowded'. If you need some guidance here drop me a note.

4. Changing texts and fonts

Most (all?) of the text in the login UI can be found in the 'resources' directory. For each of the major languages a '' file can be found. All of the strings could be changed to e.g. include the company name or similar. After you have done this you should obviously update the vdaclient.jar file again as described above.

Changing the fonts is a little more difficult since the fonts are defined within some of the class files. Therefore you need to decompile the appropriate class files (e.g., DesktopSelection, DialogContent, ThemeDefaults), change the fonts (or fontsize) used, compile again and update the vdaclient.jar file as described above at "3. Changing the background of the total screen".

Monday May 25, 2009

Integrating Sun Secure Global Desktop with Radius Authentication

Last week I have been looking at the integration of SGD (4.41.907) with Radius One-Time-Password (OTP) Authentication. Inspired by some projects that are being done by some of our partners at customer sites and a wiki page on the same subject I decided to setup a similar environment in our lab. The wiki page material is based on an earlier version of Sun Secure Global Desktop and therefore based on an earlier version of Apache web server (version 2.x vs. 1.3.36).

I decided to install ActivIdentity (AI) AAA Radius Server 6.6 next to an already existing installation of VDI3 and Active Directory DC. The Active Directory is integrated with both AAA and VDI. The AAA server will use Active Directory to lookup users and also store serial number information for the token cards that are used by these users. The integration with VDI is for the Kerberos Authentication of Sun Ray users and also for looking up user profiles by SGD after a successful third-party authentication has taken place (all user profiles are provisioned to AD by means of Sun Identity Manager but this is less relevant at this point).

AI Pocket TokenThe authentication within SGD / AAA is based on OTP's generated by ActivIdentity Pocket Tokens. After setting the PIN these can be used in various ways. We will use them in synchronous way which means that after typing in our PIN and clicking OK, the token will generate and present an OTP. Other ways these tokens can be used is through a challenge-response OTP generation.

The integration of SGD (Apache) and Radius authentication can be done in various ways as well. One of them is based on a piece of code (mod_auth_radius) from the open source project. This is what is described on the wiki mentioned above and is also described in this blog. Another way is through a similar piece of code (mod_auth_xradius) from another website called The last option and probably the most sophisticated is through a solution like Sun OpenSSO Enterprise.

Where possible I have followed the wiki mentioned above. However, there are some steps that need some adjustments and some other things need to be changed. I will focus mainly on the differences and other things that I encountered...

Step 1. Obtain and install, (if necessary) CVS

I also downloaded and installed CVS to get to the latest version of mod_auth_radius. However, through a conversation I had with the author of this module, the most recent source code can now be found at git:// so to get to the latest version from now on this would require the installation and use of e.g. git-

Step 2. Retrieve and Build mod_auth_radius

First of all, since we are using Apache 2.x underneath SGD 4.41, we need to get the right mod_auth_radius. As can be easily found on this version is called mod_auth_radius-2.0.c. From the CVS we checkout module mod_auth_radius which contains mod_auth_radius-2.0.c (v 1.5.7). Therefore the 3 last bullets should read:

# cp mod_auth_radius-2.0.c /opt/tarantella/webserver/apache/{version}
# cd /opt/tarantella/webserver/apache/{version}
# bin/apxs -i -a -c mod_auth_radius-2.0.c

However, the last command will generate the following error on a default Solaris x86 installation platform:

  line 1279: gcc4: command not found
apxs:Error: Command failed with rc=65536 

This can of course be fixed by installing gcc4 (e.g. from or also by just creating a link gcc4 that points to gcc (which is gcc3 on my Solaris 10 x86 platform) like this (there are of course more ways to get this right):

# cd /usr/sfw/bin
# ln -s gcc gcc4
# PATH=/usr/sfw/bin:/usr/ccs/bin:$PATH
# bin/apxs -i -a -c mod_auth_radius-2.0.c

This should have added a line in the Apache /opt/tarantella/webserver/apache/{version}/httpd.conf file:

LoadModule radius_auth_module modules/

Step 3.  Configure Apache for RADIUS Authentication

We add the following lines to the end of httpd.conf:

# radius_auth_module add
Alias /sgd "/opt/tarantella/webserver/tomcat/5.0.28_axis1.2/webapps/sgd"
<IfModule radius_auth_module>
AddRadiusAuth RadiusServer:1812 ActivPack 5:3
AddRadiusCookieValid 0

SetEnvIf Request_URI "\\.(cab|jar|gif|der|class)$" sgd_noauth_ok
<LocationMatch "/sgd">
    Order Allow,Deny
    Allow from env=sgd_noauth_ok
    AuthType Basic
    AuthName "Radius Authentication"
    AuthBasicAuthoritative off
    AuthRadiusAuthoritative on
    AuthRadiusCookieValid 0
    AuthRadiusActive On
    Require valid-user
    Satisfy any

Step 4.  Test RADIUS Authentication (optional)

Least thing to do here is to restart the webserver:

/opt/tarantella/bin/tarantella restart webserver

Step 5.  Configure Tomcat to Trust Webserver Authentication
Step 6.  Configure SGD to Allow Webserver Authentication
Step 7.  Allow Administrators to Login via Webserver Authentications (optional)

See wiki for steps 5, 6, and 7.

An additional note is that after all these steps, things worked fine for Internet Explorer but not for Firefox. Investigating the HTTP traffic in more detail revealed that not always the RADIUS cookie (that is set after successful authentication) is send back to the server properly. Also it appeared the cookie had a very strange path and also the expiration date was off. E.g., the cookie path contained "/ expires=...". Looking more closely at the source code I ended up with these lines of code:

static void
add_cookie(request_rec \*r, apr_table_t \*header, char \*cookie, time_t expires)
    apr_snprintf(new_cookie, 1024, "%s=%s; path=/ expires=%s;",
                cookie_name, cookie, buffer);
  } else {
    apr_snprintf(new_cookie, 1024,
                "%s=%s; path=/; expires=Wed, 01-Oct-97 01:01:01 GMT;",
                cookie_name, cookie);

It looks like there is a ';' missing in the line in red. I added a ';' in this line right after 'path=/' and recompiled. After this things also worked for Firefox. Checking the HTTP traffic, I could see the cookie being sent correctly.

Another thing to note is that I have set the lifetime of the cookie to indefinite (AddRadiusCookieValid 0). This is of course an arbitrary choice but I wanted to prevent having to regenerate an OTP every 5 minutes to keep working in SGD. This way the session is tied to the SGD session and will end when we logoff (see the end of this blog of how we can do this).

After these steps the end result should look similar to what you see in the following demonstration...

Basic demonstration of SGD and Radius OTP Authentication

To get a single logoff experience, logging out from SGD should also clear the authentication "session" so trying to log back in will confront us again with a Radius Authentication prompt. For this we have changed the logged-out.jsp file that can be found at the default path: /opt/tarantella/webserver/tomcat/5.0.28_axis1.2/webapps/sgd/webtops/standard/webtop/logged-out.jsp. The line that I put in is the following:


This will clear the HTTP authentication cache for the browser. Unfortunately, this is browser dependent and only works for Internet Explorer. There is no straightforward way to get the same behavior with Firefox. Googling around I have found that this is a long standing RFE that apparently has not been implemented. Also some workarounds / hacks are described at various websites (e.g. that supposedly will give a similar behavior with Firefox. However, I have not really tried to get this working.

Finally, I have also used mod_auth_xradius to get a similar result. It took more work to get this module built. Apparently this code is less straghtforward to compile on Solaris 10 with gcc. It took some tweaking (not detailed here) to get this compiled. As, said the end result is similar. It is different in the sense that mod_auth_xradius does not use cookies for its sessions. As far as I can tell it is also not possible to set the lifetime of a session to indefinite.

All in all, it seems possible to get this working with the mod_auth_radius module. A much nicer solution would possible be the integration with Sun OpenSSO. This will get away from using Basic Authentication and give us some better session management (in my opinion) and also the possibility of SSO to other back end applications. I have not tried this but it should be fairly straightforward since OpenSSO supports Radius authentication. Might be something interesting to work on for a next "proof-of-concept" :-)

Wednesday Apr 15, 2009

De OpenSSO Community Meets in Munich!

Project OpenSSO ( is 's werelds grootste open source project op het gebied van toegangsbeheer, federatie en secure web services.

Gehost door de European Identity Conference 2009 (EIC) en gesponsord door Sun Microsystems vindt op 5 mei 2009 de tweede OpenSSO Community Day plaats in het "Deutschen Museum" in München. Dit is een unieke mogelijkheid voor OpenSSO bijdragers, deployers en gebruikers om elkaar te ontmoeten in een informele 'unconference' setting.

De gekozen opzet, een 'unconference', betekent dat het enige punt op de agenda is om op 9 uur de sessies voor de rest van de dag te bepalen. Je bent van harte welkom om te komen praten over ieder gewenst OpenSSO-gerelateerd onderwerp. Misschien heb je een interessante deployment, een nieuwe extensie of een prangende vraag - sessies kunnen zowel discussies zijn als ook presentaties.
Nu, dat betekent niet dat er geen voorbereiding nodig is - als je een sessie in het achterhoofd hebt, ga dan naar de wiki en voeg deze daar toe, zodat mensen van te voren een idee kunnen krijgen van de mogelijke inhoud.

Iedereen is welkom, deelname is gratis en in het eten (ontbijt en lunch) zal worden voorzien. We kunnen aan het einde van de dag altijd het gesprek voorzetten in een nabijgelegen bar!

U kunt zich aanmelden voor deze gratis bijeenkomst onafhankelijk van EIC. We gebruiken voor het beheer van de registratie - ga naar, word lid van de OpenSSO groep en RSVP!

UPDATE - OpenSSO Community Day deelnemers komen in aanmerking voor een 20% korting op de registratie van de European Identity Conference. Hiertoe dient de korting code OPENSSO bij het registreren te worden gebruikt.


This blog covers exciting things I encounter about Oracle's software and related; that is Identity & Access Management, SOA, Security, Desktop, etc. The views expressed on this blog are my own and do not necessarily reflect the views of Oracle.


« July 2016