/**
* 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";
}