1d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/* ************************************************************************** 2d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * $OpenLDAP: /com/novell/sasl/client/TokenParser.java,v 1.3 2005/01/17 15:00:54 sunilk Exp $ 3d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 4d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Copyright (C) 2002 Novell, Inc. All Rights Reserved. 5d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 6d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND 7d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * TREATIES. USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT 8d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * TO VERSION 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS 9d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * AVAILABLE AT HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE" 10d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * IN THE TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION 11d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * OF THIS WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP 12d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * PUBLIC LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT 13d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY. 14d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen ******************************************************************************/ 15d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpackage com.novell.sasl.client; 16d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 17d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.apache.harmony.javax.security.sasl.*; 18d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 19d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * The TokenParser class will parse individual tokens from a list of tokens that 20d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * are a directive value for a DigestMD5 authentication.The tokens are separated 21d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * commas. 22d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 23d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenclass TokenParser extends Object 24d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen{ 25d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private static final int STATE_LOOKING_FOR_FIRST_TOKEN = 1; 26d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private static final int STATE_LOOKING_FOR_TOKEN = 2; 27d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private static final int STATE_SCANNING_TOKEN = 3; 28d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private static final int STATE_LOOKING_FOR_COMMA = 4; 29d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private static final int STATE_PARSING_ERROR = 5; 30d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private static final int STATE_DONE = 6; 31d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 32d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private int m_curPos; 33d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private int m_scanStart; 34d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private int m_state; 35d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private String m_tokens; 36d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 37d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 38d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen TokenParser( 39d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen String tokens) 40d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen { 41d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen m_tokens = tokens; 42d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen m_curPos = 0; 43d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen m_scanStart = 0; 44d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen m_state = STATE_LOOKING_FOR_FIRST_TOKEN; 45d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 46d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 47d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 48d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * This function parses the next token from the tokens string and returns 49d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * it as a string. If there are no more tokens a null reference is returned. 50d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 51d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the parsed token or a null reference if there are no more 52d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * tokens 53d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 54d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @exception SASLException if an error occurs while parsing 55d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 56d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen String parseToken() throws SaslException 57d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen { 58d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen char currChar; 59d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen String token = null; 60d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 61d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 62d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (m_state == STATE_DONE) 63d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 64d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 65d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen while (m_curPos < m_tokens.length() && (token == null)) 66d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen { 67d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen currChar = m_tokens.charAt(m_curPos); 68d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen switch (m_state) 69d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen { 70d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen case STATE_LOOKING_FOR_FIRST_TOKEN: 71d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen case STATE_LOOKING_FOR_TOKEN: 72d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (isWhiteSpace(currChar)) 73d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen { 74d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen break; 75d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 76d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else if (isValidTokenChar(currChar)) 77d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen { 78d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen m_scanStart = m_curPos; 79d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen m_state = STATE_SCANNING_TOKEN; 80d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 81d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else 82d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen { 83d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen m_state = STATE_PARSING_ERROR; 84d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new SaslException("Invalid token character at position " + m_curPos); 85d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 86d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen break; 87d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 88d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen case STATE_SCANNING_TOKEN: 89d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (isValidTokenChar(currChar)) 90d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen { 91d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen break; 92d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 93d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else if (isWhiteSpace(currChar)) 94d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen { 95d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen token = m_tokens.substring(m_scanStart, m_curPos); 96d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen m_state = STATE_LOOKING_FOR_COMMA; 97d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 98d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else if (',' == currChar) 99d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen { 100d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen token = m_tokens.substring(m_scanStart, m_curPos); 101d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen m_state = STATE_LOOKING_FOR_TOKEN; 102d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 103d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else 104d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen { 105d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen m_state = STATE_PARSING_ERROR; 106d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new SaslException("Invalid token character at position " + m_curPos); 107d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 108d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen break; 109d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 110d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 111d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen case STATE_LOOKING_FOR_COMMA: 112d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (isWhiteSpace(currChar)) 113d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen break; 114d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else if (currChar == ',') 115d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen m_state = STATE_LOOKING_FOR_TOKEN; 116d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else 117d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen { 118d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen m_state = STATE_PARSING_ERROR; 119d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new SaslException("Expected a comma, found '" + 120d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen currChar + "' at postion " + 121d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen m_curPos); 122d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 123d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen break; 124d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 125d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen m_curPos++; 126d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } /* end while loop */ 127d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 128d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (token == null) 129d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen { /* check the ending state */ 130d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen switch (m_state) 131d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen { 132d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen case STATE_SCANNING_TOKEN: 133d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen token = m_tokens.substring(m_scanStart); 134d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen m_state = STATE_DONE; 135d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen break; 136d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 137d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen case STATE_LOOKING_FOR_FIRST_TOKEN: 138d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen case STATE_LOOKING_FOR_COMMA: 139d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen break; 140d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 141d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen case STATE_LOOKING_FOR_TOKEN: 142d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new SaslException("Trialing comma"); 143d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 144d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 145d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 146d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return token; 147d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 148d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 149d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 150d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * This function returns TRUE if the character is a valid token character. 151d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 152d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * token = 1*<any CHAR except CTLs or separators> 153d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 154d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * separators = "(" | ")" | "<" | ">" | "@" 155d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * | "," | ";" | ":" | "\" | <"> 156d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * | "/" | "[" | "]" | "?" | "=" 157d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * | "{" | "}" | SP | HT 158d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 159d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * CTL = <any US-ASCII control character 160d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * (octets 0 - 31) and DEL (127)> 161d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 162d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * CHAR = <any US-ASCII character (octets 0 - 127)> 163d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 164d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param c character to be validated 165d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 166d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return True if character is valid Token character else it returns 167d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * false 168d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 169d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen boolean isValidTokenChar( 170d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen char c) 171d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen { 172d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if ( ( (c >= '\u0000') && (c <='\u0020') ) || 173d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen ( (c >= '\u003a') && (c <= '\u0040') ) || 174d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen ( (c >= '\u005b') && (c <= '\u005d') ) || 175d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen ('\u002c' == c) || 176d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen ('\u0025' == c) || 177d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen ('\u0028' == c) || 178d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen ('\u0029' == c) || 179d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen ('\u007b' == c) || 180d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen ('\u007d' == c) || 181d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen ('\u007f' == c) ) 182d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return false; 183d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 184d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return true; 185d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 186d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 187d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 188d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * This function returns TRUE if the character is linear white space (LWS). 189d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * LWS = [CRLF] 1*( SP | HT ) 190d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 191d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param c character to be validated 192d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 193d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return True if character is liner whitespace else it returns false 194d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 195d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen boolean isWhiteSpace( 196d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen char c) 197d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen { 198d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if ( ('\t' == c) || // HORIZONTAL TABULATION. 199d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen ('\n' == c) || // LINE FEED. 200d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen ('\r' == c) || // CARRIAGE RETURN. 201d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen ('\u0020' == c) ) 202d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return true; 203d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 204d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return false; 205d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 206d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 207d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 208d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 209