| /* ************************************************************************** |
| * $OpenLDAP: /com/novell/sasl/client/TokenParser.java,v 1.3 2005/01/17 15:00:54 sunilk Exp $ |
| * |
| * Copyright (C) 2002 Novell, Inc. All Rights Reserved. |
| * |
| * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND |
| * TREATIES. USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT |
| * TO VERSION 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS |
| * AVAILABLE AT HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE" |
| * IN THE TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION |
| * OF THIS WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP |
| * PUBLIC LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT |
| * THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY. |
| ******************************************************************************/ |
| package com.novell.sasl.client; |
| |
| import org.apache.harmony.javax.security.sasl.*; |
| /** |
| * The TokenParser class will parse individual tokens from a list of tokens that |
| * are a directive value for a DigestMD5 authentication.The tokens are separated |
| * commas. |
| */ |
| class TokenParser extends Object |
| { |
| private static final int STATE_LOOKING_FOR_FIRST_TOKEN = 1; |
| private static final int STATE_LOOKING_FOR_TOKEN = 2; |
| private static final int STATE_SCANNING_TOKEN = 3; |
| private static final int STATE_LOOKING_FOR_COMMA = 4; |
| private static final int STATE_PARSING_ERROR = 5; |
| private static final int STATE_DONE = 6; |
| |
| private int m_curPos; |
| private int m_scanStart; |
| private int m_state; |
| private String m_tokens; |
| |
| |
| TokenParser( |
| String tokens) |
| { |
| m_tokens = tokens; |
| m_curPos = 0; |
| m_scanStart = 0; |
| m_state = STATE_LOOKING_FOR_FIRST_TOKEN; |
| } |
| |
| /** |
| * This function parses the next token from the tokens string and returns |
| * it as a string. If there are no more tokens a null reference is returned. |
| * |
| * @return the parsed token or a null reference if there are no more |
| * tokens |
| * |
| * @exception SASLException if an error occurs while parsing |
| */ |
| String parseToken() throws SaslException |
| { |
| char currChar; |
| String token = null; |
| |
| |
| if (m_state == STATE_DONE) |
| return null; |
| |
| while (m_curPos < m_tokens.length() && (token == null)) |
| { |
| currChar = m_tokens.charAt(m_curPos); |
| switch (m_state) |
| { |
| case STATE_LOOKING_FOR_FIRST_TOKEN: |
| case STATE_LOOKING_FOR_TOKEN: |
| if (isWhiteSpace(currChar)) |
| { |
| break; |
| } |
| else if (isValidTokenChar(currChar)) |
| { |
| m_scanStart = m_curPos; |
| m_state = STATE_SCANNING_TOKEN; |
| } |
| else |
| { |
| m_state = STATE_PARSING_ERROR; |
| throw new SaslException("Invalid token character at position " + m_curPos); |
| } |
| break; |
| |
| case STATE_SCANNING_TOKEN: |
| if (isValidTokenChar(currChar)) |
| { |
| break; |
| } |
| else if (isWhiteSpace(currChar)) |
| { |
| token = m_tokens.substring(m_scanStart, m_curPos); |
| m_state = STATE_LOOKING_FOR_COMMA; |
| } |
| else if (',' == currChar) |
| { |
| token = m_tokens.substring(m_scanStart, m_curPos); |
| m_state = STATE_LOOKING_FOR_TOKEN; |
| } |
| else |
| { |
| m_state = STATE_PARSING_ERROR; |
| throw new SaslException("Invalid token character at position " + m_curPos); |
| } |
| break; |
| |
| |
| case STATE_LOOKING_FOR_COMMA: |
| if (isWhiteSpace(currChar)) |
| break; |
| else if (currChar == ',') |
| m_state = STATE_LOOKING_FOR_TOKEN; |
| else |
| { |
| m_state = STATE_PARSING_ERROR; |
| throw new SaslException("Expected a comma, found '" + |
| currChar + "' at postion " + |
| m_curPos); |
| } |
| break; |
| } |
| m_curPos++; |
| } /* end while loop */ |
| |
| if (token == null) |
| { /* check the ending state */ |
| switch (m_state) |
| { |
| case STATE_SCANNING_TOKEN: |
| token = m_tokens.substring(m_scanStart); |
| m_state = STATE_DONE; |
| break; |
| |
| case STATE_LOOKING_FOR_FIRST_TOKEN: |
| case STATE_LOOKING_FOR_COMMA: |
| break; |
| |
| case STATE_LOOKING_FOR_TOKEN: |
| throw new SaslException("Trialing comma"); |
| } |
| } |
| |
| return token; |
| } |
| |
| /** |
| * This function returns TRUE if the character is a valid token character. |
| * |
| * token = 1*<any CHAR except CTLs or separators> |
| * |
| * separators = "(" | ")" | "<" | ">" | "@" |
| * | "," | ";" | ":" | "\" | <"> |
| * | "/" | "[" | "]" | "?" | "=" |
| * | "{" | "}" | SP | HT |
| * |
| * CTL = <any US-ASCII control character |
| * (octets 0 - 31) and DEL (127)> |
| * |
| * CHAR = <any US-ASCII character (octets 0 - 127)> |
| * |
| * @param c character to be validated |
| * |
| * @return True if character is valid Token character else it returns |
| * false |
| */ |
| boolean isValidTokenChar( |
| char c) |
| { |
| if ( ( (c >= '\u0000') && (c <='\u0020') ) || |
| ( (c >= '\u003a') && (c <= '\u0040') ) || |
| ( (c >= '\u005b') && (c <= '\u005d') ) || |
| ('\u002c' == c) || |
| ('\u0025' == c) || |
| ('\u0028' == c) || |
| ('\u0029' == c) || |
| ('\u007b' == c) || |
| ('\u007d' == c) || |
| ('\u007f' == c) ) |
| return false; |
| |
| return true; |
| } |
| |
| /** |
| * This function returns TRUE if the character is linear white space (LWS). |
| * LWS = [CRLF] 1*( SP | HT ) |
| * |
| * @param c character to be validated |
| * |
| * @return True if character is liner whitespace else it returns false |
| */ |
| boolean isWhiteSpace( |
| char c) |
| { |
| if ( ('\t' == c) || // HORIZONTAL TABULATION. |
| ('\n' == c) || // LINE FEED. |
| ('\r' == c) || // CARRIAGE RETURN. |
| ('\u0020' == c) ) |
| return true; |
| |
| return false; |
| } |
| |
| } |
| |