Java Security parseDirectives(byte[] buf)

Here you can find the source of parseDirectives(byte[] buf)

Description

Parses digest-challenge string, extracting each token and value(s)

License

Open Source License

Parameter

Parameter Description
buf A non-null digest-challenge string.

Exception

Parameter Description
UnsupportedEncodingException an exception
SaslException if the String cannot be parsed according to RFC 2831

Declaration

public static HashMap<String, String> parseDirectives(byte[] buf) throws SaslException 

Method Source Code

//package com.java2s;
/**//from w w  w  .ja v  a  2 s  . c o  m
 * ---<br>
 * Mailster (C) 2007-2009 De Oliveira Edouard
 * <p>
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 * <p>
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * <p>
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 675 Mass
 * Ave, Cambridge, MA 02139, USA.
 * <p>
 * See&nbsp; <a href="http://tedorg.free.fr/en/projects.php" target="_parent">Mailster
 * Web Site</a> <br>
 * ---
 * <p>
 * StringUtilities.java - Various methods to handle strings.
 * 
 * @author <a href="mailto:doe_wanted@yahoo.fr">Edouard De Oliveira</a>
 * @version $Revision: 1.8 $, $Date: 2009/05/17 20:56:35 $
 */

import java.io.ByteArrayOutputStream;

import java.util.HashMap;

import javax.security.sasl.SaslException;

public class Main {
    /**
     * Parses digest-challenge string, extracting each token
     * and value(s)
     *
     * @param buf A non-null digest-challenge string.
     * @throws UnsupportedEncodingException 
     * @throws SaslException if the String cannot be parsed according to RFC 2831
     */
    public static HashMap<String, String> parseDirectives(byte[] buf) throws SaslException {
        HashMap<String, String> map = new HashMap<String, String>();
        boolean gettingKey = true;
        boolean gettingQuotedValue = false;
        boolean expectSeparator = false;
        byte bch;

        ByteArrayOutputStream key = new ByteArrayOutputStream(10);
        ByteArrayOutputStream value = new ByteArrayOutputStream(10);

        int i = skipLws(buf, 0);
        while (i < buf.length) {
            bch = buf[i];

            if (gettingKey) {
                if (bch == ',') {
                    if (key.size() != 0)
                        throw new SaslException("Directive key contains a ',':" + key);

                    // Empty element, skip separator and lws
                    i = skipLws(buf, i + 1);
                } else if (bch == '=') {
                    if (key.size() == 0)
                        throw new SaslException("Empty directive key");

                    gettingKey = false; // Termination of key
                    i = skipLws(buf, i + 1); // Skip to next non whitespace

                    // Check whether value is quoted
                    if (i < buf.length) {
                        if (buf[i] == '"') {
                            gettingQuotedValue = true;
                            ++i; // Skip quote
                        }
                    } else
                        throw new SaslException("Valueless directive found: " + key.toString());
                } else if (isLws(bch)) {
                    // LWS that occurs after key
                    i = skipLws(buf, i + 1);

                    // Expecting '='
                    if (i < buf.length) {
                        if (buf[i] != '=')
                            throw new SaslException("'=' expected after key: " + key.toString());
                    } else
                        throw new SaslException("'=' expected after key: " + key.toString());
                } else {
                    key.write(bch); // Append to key
                    ++i; // Advance
                }
            } else if (gettingQuotedValue) {
                // Getting a quoted value
                if (bch == '\\') {
                    // quoted-pair = "\" CHAR ==> CHAR
                    ++i; // Skip escape
                    if (i < buf.length) {
                        value.write(buf[i]);
                        ++i; // Advance
                    } else
                        // Trailing escape in a quoted value
                        throw new SaslException("Unmatched quote found for directive: " + key.toString()
                                + " with value: " + value.toString());
                } else if (bch == '"') {
                    // closing quote
                    ++i; // Skip closing quote
                    gettingQuotedValue = false;
                    expectSeparator = true;
                } else {
                    value.write(bch);
                    ++i; // Advance
                }
            } else if (isLws(bch) || bch == ',') {
                // Value terminated
                extractDirective(map, key.toString(), value.toString());
                key.reset();
                value.reset();
                gettingKey = true;
                gettingQuotedValue = expectSeparator = false;
                i = skipLws(buf, i + 1); // Skip separator and LWS
            } else if (expectSeparator) {
                throw new SaslException(
                        "Expecting comma or linear whitespace after quoted string: \"" + value.toString() + "\"");
            } else {
                value.write(bch); // Unquoted value
                ++i; // Advance
            }
        }

        if (gettingQuotedValue)
            throw new SaslException(
                    "Unmatched quote found for directive: " + key.toString() + " with value: " + value.toString());

        // Get last pair
        if (key.size() > 0)
            extractDirective(map, key.toString(), value.toString());

        return map;
    }

    /**
     * Skip all linear white spaces
     */
    private static int skipLws(byte[] buf, int start) {
        int i;

        for (i = start; i < buf.length; i++) {
            if (!isLws(buf[i]))
                return i;
        }

        return i;
    }

    /**
     * Is character a linear white space ?
     * LWS            = [CRLF] 1*( SP | HT )
     * Note that we're checking individual bytes instead of CRLF
     * 
     * @param b the byte to check
     * @return <code>true</code> if it's a linear white space
     */
    public static boolean isLws(byte b) {
        switch (b) {
        case 13: // US-ASCII CR, carriage return
        case 10: // US-ASCII LF, line feed
        case 32: // US-ASCII SP, space
        case 9: // US-ASCII HT, horizontal-tab
            return true;
        }

        return false;
    }

    /**
     * Processes directive/value pairs from the digest-challenge and
     * fill out the provided map.
     * 
     * @param key A non-null String challenge token name.
     * @param value A non-null String token value.
     * @throws SaslException if either the key or the value is null or
     * if the key already has a value. 
     */
    private static void extractDirective(HashMap<String, String> map, String key, String value)
            throws SaslException {
        if (map.get(key) != null)
            throw new SaslException("Peer sent more than one " + key + " directive");
        else
            map.put(key, value);
    }
}

Related

  1. isOriginalTicketGrantingTicket(KerberosTicket ticket)
  2. jaasConfig(String loginContextName, String key)
  3. jaasConfigOption(Configuration jaasConfig, String loginContextName, String key, String loginModuleName)
  4. kinit(String username, char[] password)
  5. logout()
  6. secretKey(final String key)
  7. serializeKerberosTicket(KerberosTicket tgt)
  8. stringToByte_8859_1(String str, boolean useUTF8)
  9. ticketToCreds(KerberosTicket kerbTicket)