/** * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved * * The contents of this file are subject to the terms * of the Common Development and Distribution License * (the License). You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * https://opensso.dev.java.net/public/CDDLv1.0.html or * opensso/legal/CDDLv1.0.txt * See the License for the specific language governing * permission and limitations under the License. * * When distributing Covered Code, include this CDDL * Header Notice in each file and include the License file * at opensso/legal/CDDLv1.0.txt. * If applicable, add the following below the CDDL Header, * with the fields enclosed by brackets [] replaced by * your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * * $Id: TransportToken.java,v 1.2 2008/06/25 05:52:01 qcheng Exp $ * */ package com.sun.identity.agents.util; import com.sun.identity.agents.arch.AgentException; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.Iterator; import java.util.TreeMap; import java.util.StringTokenizer; import com.sun.identity.agents.arch.ServiceFactory; import com.sun.identity.agents.arch.ICrypt; import java.text.MessageFormat; /** * TransportToken is a wrapper of a Single Sign-On Token generated by Access * Manager. It contains a user SSO Token and some additional information. * It is used by AmRealm to authenticate the user to the container. */ public class TransportToken implements IUtilConstants { /** * Constructs a TransportToken using the given SSO Token string and * remote client address. * * @param ssoTokenID the SSO Token string * @param ipAddress the remote client IP address * * @throws AgentException in case of any unexpected * failure in initialization. * */ public TransportToken(String ssoTokenID, String ipAddress) throws AgentException { if((ssoTokenID == null) || (ssoTokenID.trim().length() == 0)) { throw new AgentException("Invalid SSOTokenID "); } if((ipAddress == null) || (ipAddress.trim().length() == 0)) { throw new AgentException("Invalid IP address "); } setSSOTokenID(ssoTokenID); setIPAddress(ipAddress); initTokenPrefix(); } /** * Constructs a TransportToken using the given transport string. The * transport string that is given may be either be a plain text string, * an encrypted string, or a URL encoded encrypted string. * * * @param transportString the transport string to be used to initialize this * instance of transport token. * * @throws AgentException in case of any unexpected * failure in initialization. * */ public TransportToken(String transportString) throws AgentException { if((transportString == null) || (transportString.trim().length() == 0)) { throw new AgentException("Invalid transport string"); } String innerTransportString = transportString; if (transportString.startsWith(ENC_CRYPT_PREFIX)) { transportString = URLDecoder.decode(transportString); } if(transportString.startsWith(CRYPT_PREFIX)) { ICrypt crypt = ServiceFactory.getCryptProvider(); String randomCryptString = crypt.decrypt( transportString.substring( CRYPT_PREFIX.length())); int index = randomCryptString.indexOf(":") + 1; innerTransportString = randomCryptString.substring(index); } initializeFromString(innerTransportString); } private String getFieldValue(String fieldToken, String filedHeader) throws AgentException { String result = null; if(fieldToken.startsWith(filedHeader)) { result = fieldToken.substring(filedHeader.length()); } if (result == null || result.trim().length() == 0) { throw new AgentException("Invalid transport field"); } return result; } private void initializeFromString(String transportString) throws AgentException { if( !transportString.startsWith(VERSION_HEADER)) { throw new AgentException("Invalid transport string"); } StringTokenizer stok = new StringTokenizer(transportString, FIELD_SEPARATOR); int numTokens = stok.countTokens(); if(numTokens < 3) { throw new AgentException("Malformed transport string"); } // Check Version String versionString = getFieldValue(stok.nextToken(), VERSION_HEADER_MARKER); if (!versionString.equals(VERSION_STRING)) { throw new AgentException("Invalid transport version"); } // Set SSO Token setSSOTokenID(URLDecoder.decode(getFieldValue(stok.nextToken(), SSO_HEADER_MARKER))); // Set IP Address setIPAddress(getFieldValue(stok.nextToken(), IP_HEADER_MARKER)); // Initialize token prefix initTokenPrefix(); // Parse attributes if (numTokens > 3) { int attributeCount = 0; boolean attributeReadOK = true; try { attributeCount = Integer.parseInt(getFieldValue(stok.nextToken(), ATTRIBUTE_COUNT_HEADER_MARKER)); } catch (NumberFormatException ex) { attributeReadOK = false; } if (!attributeReadOK || attributeCount <= 0) { throw new AgentException("Invalid attirbute count"); } for (int i=0; i 0 && index < nextField.length() - 1 ) { String attributeName = nextField.substring(0, index); String attributeValue = nextField.substring(index+1); getAttributes().put(URLDecoder.decode(attributeName), URLDecoder.decode(attributeValue)); } else { throw new AgentException("Invalid attribute field"); } } } } public void setAttribute(String attributeName, String attributeValue) throws AgentException { if (attributeName == null || attributeValue == null) { throw new AgentException("Invalid attribute setting: " + attributeName + ":" + attributeValue); } getAttributes().put(attributeName, attributeValue); } public String getTransportString() { StringBuffer buff = new StringBuffer(getTokenPrefix()); if(getAttributes().size() > 0 ) { buff.append(FIELD_SEPARATOR); buff.append(ATTRIBUTE_COUNT_HEADER_MARKER + getAttributes().size()); buff.append(FIELD_SEPARATOR); Iterator it = getAttributes().keySet().iterator(); while (it.hasNext()) { String attributeName = (String) it.next(); String attributeValue = (String) getAttributes().get(attributeName); buff.append(URLEncoder.encode(attributeName)).append( KEY_VALUE_SEPARATOR); buff.append(URLEncoder.encode(attributeValue)); if (it.hasNext()) { buff.append(FIELD_SEPARATOR); } } } return buff.toString(); } public String getEncryptedTransportString() throws AgentException { ICrypt crypt = ServiceFactory.getCryptProvider(); return CRYPT_PREFIX + crypt.encrypt(String.valueOf(System.currentTimeMillis()) + ":" + getTransportString()); } public String getSSOTokenID() { return _ssoTokenID; } private void setSSOTokenID(String ssoTokenID) { _ssoTokenID = ssoTokenID; } public String getIPAddress() { return _ipAddress; } private void setIPAddress(String ipAddress) { _ipAddress = ipAddress; } public String toString() { return getTransportString(); } public String getAttribute(String attributeName) { return (String)getAttributes().get(attributeName); } private TreeMap getAttributes() { return _attributes; } private void setTokenPrefix(String tokenPrefix) { _tokenPrefix = tokenPrefix; } private void initTokenPrefix() { _tokenPrefix = MessageFormat.format(PREFIX_FORMAT_PATTERN, new Object[] { URLEncoder.encode(getSSOTokenID()), getIPAddress()}); } private String getTokenPrefix() { return _tokenPrefix; } private String _ssoTokenID; private String _ipAddress; private String _tokenPrefix; private TreeMap _attributes = new TreeMap(); private static final String VERSION_LABEL = "__VERSION__"; private static final String SSO_LABEL = "__SSO_TOKEN__"; private static final String IP_LABEL = "__IP_ADDRESS__"; private static final String ATTRIBUTE_COUNT = "__COUNT__"; private static final String FIELD_SEPARATOR = " "; private static final String KEY_VALUE_SEPARATOR = "="; private static final String VERSION_STRING = "1.003"; private static final String VERSION_HEADER_MARKER = VERSION_LABEL + KEY_VALUE_SEPARATOR; private static final String VERSION_HEADER = VERSION_HEADER_MARKER + VERSION_STRING + FIELD_SEPARATOR; private static final String SSO_HEADER_MARKER = SSO_LABEL + KEY_VALUE_SEPARATOR; private static final String IP_HEADER_MARKER = IP_LABEL + KEY_VALUE_SEPARATOR; private static final String ATTRIBUTE_COUNT_HEADER_MARKER = ATTRIBUTE_COUNT + KEY_VALUE_SEPARATOR; private static final String PREFIX_FORMAT_PATTERN = VERSION_HEADER+ SSO_HEADER_MARKER + "{0}" + FIELD_SEPARATOR + IP_HEADER_MARKER + "{1}"; public static final String CRYPT_PREFIX = "*="; public static final String ENC_CRYPT_PREFIX = "*%3D"; }