AT&T Service Support

Today (Saturday) at about 10 PM, my phone line and DSL were down. My wife called AT&T support guys. The call was transfered several times and she waited for about 15 minutes before a human talked to her. The guy said that one of our phones was jamming the line. He suggested we plug all the phones, wait for 5-10 minutes, plug in one of the phones and test the line again. My wife got off the phone and did what she was told to do. But, the problem still persisted.

We were thinking that we would not internet connection for the entire weekend. :-(

On our way to a Japanese supermarket, my wife called AT&T to dispatch a technician to fix the problem on Monday.

At about 3PM, my cell phone rang, it was from AT&T. The technical said that he was in our neighborhood and could stop by to fix the line. What a delight!

He came and found that one of our phone lines was short-circuited. We need to pay AT&T to get it fix as the problem is with a wire running in the house. However, he said that no charges would be made if the wire can be easily rectified. Luck is on our side, he fixed the problem, left us his name card and thanked us for using AT&T.

We are really impressed with the service provided. Will stick with AT&T!

I have my internet connection back and able to blog about it :-)

Support for sub realm, module and authentication chain for REST authentication

We’re working on support REST authentication for sub realm, module, and authentication chain.

  1. Support sub realm, add uri=realm%3D<sub realm name> e.g.
    http://www.example.com:8080/opensso/identity/authenticate?
    username=demo&password=changeit&uri=realm%3D/sub

  2. Support authentication module, add uri=module%3D<module name> e.g. http://www.example.com:8080/opensso/identity/authenticate?
    username=demo&password=changeit&uri=module%3DDataStore

  3. Support authentication chain add uri=service%3D<authentication chain name> e.g. http://www.example.com:8080/opensso/identity/authenticate?
    username=demo&password=changeit&uri=service%3DldapService

Hence you can login to a sub realm with a authentication module like this
http://www.example.com:8080/opensso/identity/authenticate?
username=demo&password=changeit&
uri=realm%3D/sub%26module%3DDataStore

This support shall be made available to you soon.

Sun OpenSSO Enterprise 8.0 is out

This is the first official release of OpenSSO Enterprise. Visit this page of more information. The source code of this release will be made available on OpenSSO website soon. We are working on the next official release of OpenSSO which is OpenSSO Express (build 7).

When is Sun OpenSSO Enterprise 8.0 ready?

“When is Sun OpenSSO Enterprise 8.0 ready?”

This question has popped up in opensso email aliases few times. Here is where we are now.

  1. Bits are ready.
  2. We are busy reviewing documents for the past few weeks.
  3. I think that we should have everything ready on its official release date which is November 11, 2008.
  4. Bits shall be made available on OpenSSO’s download page. Look for image like this one.
    download OpenSSO Enterprise 8.0
  5. The next OpenSSO official release is OpenSSO Express. ETA is early 2009.

OpenSSO source repository – in a couple of days

As we are putting the finishing touch on the release OpenSSO Enterprise 8.0, The trunk of OpenSSO source repository is limited to code put back for critical issues. In couple of days, we are going to create a CVS branch for OpenSSO Enterprise 8.0; and open the CVS trunk to code back for all issues.

                        +---------------- Enterprise 8.0
                        |
-------------------+----x--------------------------- Trunk
                   ^
                   we are here now

Smoke Test: Identity REST Interface

import java.io.*;
import java.net.*;

public class OpenSSORest {
    private static String serverURL;
    private static String tokenId;
    private static String username;

    public static void main(String[] args) {
        if (args.length != 1) {
            System.err.println(
                "Usage: OpenSSORest server-instance\n");
            System.exit(1);
        }
        serverURL = args[0];

        try {
            authenticate();
            validateToken();
            search();
            showAttributes();
            read("demo", null);
            create();
            read("test", null);
            update();
            read("test", "mail");
            delete();
            logout();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void authenticate()
        throws Exception {
        System.out.println();
        System.out.println("Authenticate to server");
        username = getUserInput("username: ");
        String password = getUserInput("password: ");

        String res = request(new URL(serverURL +
            "/identity/authenticate?" +
            "username=" + URLEncoder.encode(username, "UTF-8") +
            "&password=" +
            URLEncoder.encode(password, "UTF-8")));

        tokenId = res.substring(9);
        tokenId = tokenId.substring(0, tokenId.length() -1);
        succeeded();
    }

    private static void logout()
        throws Exception {
        System.out.println("Logout");

        String res = request(new URL(serverURL +
            "/identity/logout?" +
            "subjectid=" +
            URLEncoder.encode(tokenId, "UTF-8")));
        succeeded();
    }

    private static void validateToken()
        throws Exception {
        System.out.println("Validate Token ID");
        String res = request(new URL(serverURL +
            "/identity/isTokenValid?" +
            "tokenid=" + URLEncoder.encode(tokenId, "UTF-8")));
        succeeded();
    }

    private static void search()
        throws Exception {
        System.out.println("Search");
        String res = request(new URL(serverURL +
            "/identity/search?" +
            "filter=*&admin=" +
            URLEncoder.encode(tokenId, "UTF-8")));
        System.out.println(res);
        succeeded();
    }

    private static void showAttributes()
        throws Exception {
        System.out.println("Show Attributes");
        String res = request(new URL(serverURL +
            "/identity/attributes?" +
            "subjectid=" +
            URLEncoder.encode(tokenId, "UTF-8")));
        System.out.println(res);
        succeeded();
    }    

    private static void read(String user, String attr)
        throws Exception {
        System.out.println("Read attributes");
        String qattr = (attr != null) ?
            "&attributes_names=" + attr : "";

        String res = request(new URL(serverURL +
            "/identity/read?" +
            "name=" + user + "&admin=" +
            URLEncoder.encode(tokenId, "UTF-8") +
            qattr));
        System.out.println(res);
        succeeded();
    }

    private static void create()
        throws Exception {
        System.out.println("Create user");
        String res = request(new URL(serverURL +
            "/identity/create?" +
            "identity_name=test&admin=" +
            URLEncoder.encode(tokenId, "UTF-8") +
            "&identity_attribute_names=userpassword" +
            "&identity_attribute_values_userpassword=123" +
            "&identity_realm=" + URLEncoder.encode("/", "UTF-8") +
            "&identity_type=User"
            ));
        succeeded();
    }

    private static void update()
        throws Exception {
        System.out.println("Change email address");
        String res = request(new URL(serverURL +
            "/identity/update?" +
            "identity_name=test&admin=" +
            URLEncoder.encode(tokenId, "UTF-8") +
            "&identity_attribute_names=mail" +
            "&identity_attribute_values_mail=test@example.com"
            ));
        succeeded();
    }

    private static void delete()
        throws Exception {
        System.out.println("Delete user");
        String res = request(new URL(serverURL +
            "/identity/delete?" +
            "identity_name=test&admin=" +
            URLEncoder.encode(tokenId, "UTF-8") +
            "&identity_type=User"));
        succeeded();
    }

    private static void succeeded() {
        System.out.println("Succeeded");
        System.out.println();
        System.out.println();
    }

    public static String getUserInput(String message)
        throws IOException {
        String userInput = null;
        BufferedReader in = new BufferedReader(
            new InputStreamReader(System.in));
        System.out.print(message);
        userInput = in.readLine();
        return userInput;
    }

    public static String request(URL url)
        throws Exception {
        System.out.println(url.toString());
        URLConnection conn = url.openConnection();
        BufferedReader dis = new BufferedReader(
            new InputStreamReader(conn.getInputStream()));
        StringBuffer buff = new StringBuffer();
        String inputLine;

        while ((inputLine = dis.readLine()) != null) {
            buff.append(inputLine).append("\n");
        }
        dis.close();
        return buff.toString();
    }
}

Run it

[dennis@localhost rest]$ javac  OpenSSORest.java
[dennis@localhost rest]$  OpenSSORest http://vanessa.red.iplanet.com:8080/opensso

Authenticate to server
username: amadmin
password: 11111111
http://vanessa.red.iplanet.com:8080/opensso/identity/authenticate?username=amadmin&password=11111111
Succeeded

Validate Token ID
http://vanessa.red.iplanet.com:8080/opensso/identity/isTokenValid?tokenid=AQIC5wM2LY4SfczAfhqbpbll3ldjGn3AU5ignOqmR82DzDw%3D%40AAJTSQACMDE%3D%23
Succeeded

Search
http://vanessa.red.iplanet.com:8080/opensso/identity/search?filter=*&admin=AQIC5wM2LY4SfczAfhqbpbll3ldjGn3AU5ignOqmR82DzDw%3D%40AAJTSQACMDE%3D%23
string=amAdmin
string=amldapuser
string=dsameuser
string=anonymous
string=amService-URLAccessAgent
string=demo

Succeeded

Show Attributes
http://vanessa.red.iplanet.com:8080/opensso/identity/attributes?subjectid=AQIC5wM2LY4SfczAfhqbpbll3ldjGn3AU5ignOqmR82DzDw%3D%40AAJTSQACMDE%3D%23
userdetails.token.id=AQIC5wM2LY4SfczAfhqbpbll3ldjGn3AU5ignOqmR82DzDw=@AAJTSQACMDE=#
userdetails.attribute.name=iplanet-am-user-alias-list
userdetails.attribute.name=sunIdentityMSISDNNumber
userdetails.attribute.name=employeeNumber
userdetails.attribute.name=telephoneNumber
userdetails.attribute.name=iplanet-am-user-success-url
userdetails.attribute.name=givenName
userdetails.attribute.value=amAdmin
userdetails.attribute.name=mail
userdetails.attribute.name=roles
userdetails.attribute.value=Top-level Admin Role
userdetails.attribute.name=sn
userdetails.attribute.value=amAdmin
userdetails.attribute.name=dn
userdetails.attribute.value=uid=amAdmin,ou=people,dc=opensso,dc=java,dc=net
userdetails.attribute.name=cn
userdetails.attribute.value=amAdmin
userdetails.attribute.name=postalAddress
userdetails.attribute.name=iplanet-am-user-failure-url
userdetails.attribute.name=inetUserStatus
userdetails.attribute.value=Active

Succeeded

Read attributes
http://vanessa.red.iplanet.com:8080/opensso/identity/read?name=demo&admin=AQIC5wM2LY4SfczAfhqbpbll3ldjGn3AU5ignOqmR82DzDw%3D%40AAJTSQACMDE%3D%23
identitydetails.name=demo
identitydetails.type=user
identitydetails.realm=dc=opensso,dc=java,dc=net
identitydetails.attribute=
identitydetails.attribute.name=sn
identitydetails.attribute.value=demo
identitydetails.attribute=
identitydetails.attribute.name=universalid
identitydetails.attribute.value=id=demo,ou=user,dc=opensso,dc=java,dc=net
identitydetails.attribute=
identitydetails.attribute.name=objectclass
identitydetails.attribute.value=sunFederationManagerDataStore
identitydetails.attribute.value=iplanet-am-user-service
identitydetails.attribute.value=top
identitydetails.attribute.value=iplanet-am-managed-person
identitydetails.attribute.value=sunIdentityServerLibertyPPService
identitydetails.attribute.value=iPlanetPreferences
identitydetails.attribute.value=inetorgperson
identitydetails.attribute.value=person
identitydetails.attribute.value=organizationalPerson
identitydetails.attribute.value=inetuser
identitydetails.attribute.value=sunFMSAML2NameIdentifier
identitydetails.attribute=
identitydetails.attribute.name=cn
identitydetails.attribute.value=demo
identitydetails.attribute=
identitydetails.attribute.name=uid
identitydetails.attribute.value=demo
identitydetails.attribute=
identitydetails.attribute.name=userpassword
identitydetails.attribute.value={SSHA}rOG2r03XzcYHwAG4rABAz8FpDEle15FMSUcsAQ==
identitydetails.attribute=
identitydetails.attribute.name=inetuserstatus
identitydetails.attribute.value=Active

Succeeded

Create user
http://vanessa.red.iplanet.com:8080/opensso/identity/create?identity_name=test&admin=AQIC5wM2LY4SfczAfhqbpbll3ldjGn3AU5ignOqmR82DzDw%3D%40AAJTSQACMDE%3D%23&identity_attribute_names=userpassword&identity_attribute_values_userpassword=123&identity_realm=%2F&identity_type=User
Succeeded

Read attributes
http://vanessa.red.iplanet.com:8080/opensso/identity/read?name=test&admin=AQIC5wM2LY4SfczAfhqbpbll3ldjGn3AU5ignOqmR82DzDw%3D%40AAJTSQACMDE%3D%23
identitydetails.name=test
identitydetails.type=user
identitydetails.realm=dc=opensso,dc=java,dc=net
identitydetails.attribute=
identitydetails.attribute.name=sn
identitydetails.attribute.value=test
identitydetails.attribute=
identitydetails.attribute.name=universalid
identitydetails.attribute.value=id=test,ou=user,dc=opensso,dc=java,dc=net
identitydetails.attribute=
identitydetails.attribute.name=objectclass
identitydetails.attribute.value=sunFederationManagerDataStore
identitydetails.attribute.value=iplanet-am-user-service
identitydetails.attribute.value=top
identitydetails.attribute.value=iplanet-am-managed-person
identitydetails.attribute.value=sunIdentityServerLibertyPPService
identitydetails.attribute.value=iPlanetPreferences
identitydetails.attribute.value=inetorgperson
identitydetails.attribute.value=person
identitydetails.attribute.value=organizationalPerson
identitydetails.attribute.value=inetuser
identitydetails.attribute.value=sunFMSAML2NameIdentifier
identitydetails.attribute=
identitydetails.attribute.name=cn
identitydetails.attribute.value=test
identitydetails.attribute=
identitydetails.attribute.name=uid
identitydetails.attribute.value=test
identitydetails.attribute=
identitydetails.attribute.name=userpassword
identitydetails.attribute.value={SSHA}DsnALc8j11O9krdjfrId/xxCtv+qOM06zBc2CQ==
identitydetails.attribute=
identitydetails.attribute.name=inetuserstatus
identitydetails.attribute.value=Active

Succeeded

Change email address
http://vanessa.red.iplanet.com:8080/opensso/identity/update?identity_name=test&admin=AQIC5wM2LY4SfczAfhqbpbll3ldjGn3AU5ignOqmR82DzDw%3D%40AAJTSQACMDE%3D%23&identity_attribute_names=mail&identity_attribute_values_mail=test@example.com
Succeeded

Read attributes
http://vanessa.red.iplanet.com:8080/opensso/identity/read?name=test&admin=AQIC5wM2LY4SfczAfhqbpbll3ldjGn3AU5ignOqmR82DzDw%3D%40AAJTSQACMDE%3D%23&attributes_names=mail
identitydetails.name=test
identitydetails.type=user
identitydetails.realm=dc=opensso,dc=java,dc=net
identitydetails.attribute=
identitydetails.attribute.name=mail
identitydetails.attribute.value=test@example.com

Succeeded

Delete user
http://vanessa.red.iplanet.com:8080/opensso/identity/delete?identity_name=test&admin=AQIC5wM2LY4SfczAfhqbpbll3ldjGn3AU5ignOqmR82DzDw%3D%40AAJTSQACMDE%3D%23&identity_type=User
Succeeded

Logout
http://vanessa.red.iplanet.com:8080/opensso/identity/logout?subjectid=AQIC5wM2LY4SfczAfhqbpbll3ldjGn3AU5ignOqmR82DzDw%3D%40AAJTSQACMDE%3D%23
Succeeded

Agent UI (Thank You)

Last week, I spent some time fixing an issue with map UI component. I am feeling pretty good with how Agent Profile pages look now. About two month ago, people were debating on committing resources to build UI components for these profile pages. Agent team emphasized that these UI components have to be implemented ASAP, so that they can be tested before the product (OpenSSO Enterprise) is shipped. And, I have the same sentiment.

So we found time to get the base version of Agent UI implemented. From then to now, Agent team is constantly testing these components and report back issues. I really like this iterative process. Report issues -> Fix them -> Test again -> ….

And now, Agent Profile pages are more friendly to use; and have less rooms for user input errors. I have to thank the Agent team for being so proactive in this effort. Thank You.

Sun OpenSSO Enterprise

We are re-branding Federated Access Manager to Sun OpenSSO Enterprise. Over this couple of weeks, you will see changes in console, login page, online help, wiki, etc. related to this.

I am committing these changes soon.

1. Rename binaries

famAdminTools.zip -> ssoAdminTools.zip
fam-client-jdk14.war -> opensso-client-jdk14.war
fam-client-jdk15.war -> opensso-client-jdk15.war
fam-client.zip -> opensso-client.zip
opensso.jar -> amserver.jar
fam.jar -> opensso.jar
fam-public-javadocs.jar -> opensso-public-javadocs.jar
fam-server-test.zip -> opensso-server-test.zip
famSessionTools.zip -> openssoSessionTools.zip
famwssproviders.zip -> openssowssproviders.zip
famwssproviders.jar -> openssowssproviders.jar

2. Rename CLI from famadm to ssoadm and famadm.jsp to ssoadm.jsp

3. Change Product name image in Login and Console page to Sun OpenSSO Enterprise

Followings are the changes that have to happen

1. console online help changes
2. properties files changes for other locale.
3. web agent and J2EE agent changes

OpenSSO Extension: WSS Proxy

WSS Proxy provides a simple way of securing web services. We have a short paper that provides high level details.

source code is under /opensso/extensions/wssproxy

Adding Extended Characters to Java Properties File

Recently, I was updating the copyrights text in amConsole.properties.
the copyrights text contains extended ASCII characters because part
of the copyrights/license is in France.

Java Properties file cannot have extended ASCII characters, we need to
have them in Hex e.g. \u00e0 for à

Here is a small program that converted extended ASCII characters to
Hex.

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;

public class StringToHex {
    private static String charToHex(char c) {
        StringBuffer buffer = new StringBuffer();
        if (c <= 0x7E) {
            buffer.append(c);
        } else {
            buffer.append("\\u");
            String hex = Integer.toHexString(c);
            for (int j = hex.length(); j < 4; j++ ) {
                buffer.append('0');
            }
            buffer.append(hex);
        }
        return buffer.toString();
    }

    private static String readInput(String fileName) {
        StringBuffer buffer = new StringBuffer();
        try {
            FileInputStream fis = new FileInputStream(fileName);
            InputStreamReader isr = new InputStreamReader(fis, "UTF8");
            Reader in = new BufferedReader(isr);
            int ch;
            while ((ch = in.read()) > -1) {
                buffer.append(charToHex((char)ch));
            }
            in.close();
            return buffer.toString();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static void main(String[] args) {
        if (args.length != 1) {
            System.err.println("Usage: java StringToHex ");
            System.exit(1);
        }

        String inputString = readInput(args[0]);
        if (inputString != null) {
            System.out.println(inputString);
        }
        System.exit(0);
    }
}