alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (PlainClient.java)

This example Java source code file (PlainClient.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

cannot, illegalstateexception, nul, object, plain, plainclient, saslclient, saslexception, sep, string, us\-ascii, utf8, utf\-8

The PlainClient.java Java example source code

/*
 * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.security.sasl;

import javax.security.sasl.*;

/**
  * Implements the PLAIN SASL client mechanism.
  * (<A
  * HREF="http://ftp.isi.edu/in-notes/rfc2595.txt">RFC 2595</A>)
  *
  * @author Rosanna Lee
  */
final class PlainClient implements SaslClient {
    private boolean completed = false;
    private byte[] pw;
    private String authorizationID;
    private String authenticationID;
    private static byte SEP = 0; // US-ASCII <NUL>

    /**
     * Creates a SASL mechanism with client credentials that it needs
     * to participate in Plain authentication exchange with the server.
     *
     * @param authorizationID A possibly null string representing the principal
     *  for which authorization is being granted; if null, same as
     *  authenticationID
     * @param authenticationID A non-null string representing the principal
     * being authenticated. pw is associated with with this principal.
     * @param pw A non-null byte[] containing the password.
     */
    PlainClient(String authorizationID, String authenticationID, byte[] pw)
    throws SaslException {
        if (authenticationID == null || pw == null) {
            throw new SaslException(
                "PLAIN: authorization ID and password must be specified");
        }

        this.authorizationID = authorizationID;
        this.authenticationID = authenticationID;
        this.pw = pw;  // caller should have already cloned
    }

    /**
     * Retrieves this mechanism's name for to initiate the PLAIN protocol
     * exchange.
     *
     * @return  The string "PLAIN".
     */
    public String getMechanismName() {
        return "PLAIN";
    }

    public boolean hasInitialResponse() {
        return true;
    }

    public void dispose() throws SaslException {
        clearPassword();
    }

    /**
     * Retrieves the initial response for the SASL command, which for
     * PLAIN is the concatenation of authorization ID, authentication ID
     * and password, with each component separated by the US-ASCII <NUL> byte.
     *
     * @param challengeData Ignored
     * @return A non-null byte array containing the response to be sent to the server.
     * @throws SaslException If cannot encode ids in UTF-8
     * @throw IllegalStateException if authentication already completed
     */
    public byte[] evaluateChallenge(byte[] challengeData) throws SaslException {
        if (completed) {
            throw new IllegalStateException(
                "PLAIN authentication already completed");
        }
        completed = true;

        try {
            byte[] authz = (authorizationID != null)?
                authorizationID.getBytes("UTF8") :
                null;
            byte[] auth = authenticationID.getBytes("UTF8");

            byte[] answer = new byte[pw.length + auth.length + 2 +
                (authz == null ? 0 : authz.length)];

            int pos = 0;
            if (authz != null) {
                System.arraycopy(authz, 0, answer, 0, authz.length);
                pos = authz.length;
            }
            answer[pos++] = SEP;
            System.arraycopy(auth, 0, answer, pos, auth.length);

            pos += auth.length;
            answer[pos++] = SEP;

            System.arraycopy(pw, 0, answer, pos, pw.length);

            clearPassword();
            return answer;
        } catch (java.io.UnsupportedEncodingException e) {
            throw new SaslException("Cannot get UTF-8 encoding of ids", e);
        }
    }

    /**
     * Determines whether this mechanism has completed.
     * Plain completes after returning one response.
     *
     * @return true if has completed; false otherwise;
     */
    public boolean isComplete() {
        return completed;
    }

    /**
      * Unwraps the incoming buffer.
      *
      * @throws SaslException Not applicable to this mechanism.
      */
    public byte[] unwrap(byte[] incoming, int offset, int len)
        throws SaslException {
        if (completed) {
            throw new SaslException(
                "PLAIN supports neither integrity nor privacy");
        } else {
            throw new IllegalStateException("PLAIN authentication not completed");
        }
    }

    /**
      * Wraps the outgoing buffer.
      *
      * @throws SaslException Not applicable to this mechanism.
      */
    public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException {
        if (completed) {
            throw new SaslException(
                "PLAIN supports neither integrity nor privacy");
        } else {
            throw new IllegalStateException("PLAIN authentication not completed");
        }
    }

    /**
     * Retrieves the negotiated property.
     * This method can be called only after the authentication exchange has
     * completed (i.e., when <tt>isComplete() returns true); otherwise, a
     * <tt>SaslException is thrown.
     *
     * @return value of property; only QOP is applicable to PLAIN.
     * @exception IllegalStateException if this authentication exchange
     *     has not completed
     */
    public Object getNegotiatedProperty(String propName) {
        if (completed) {
            if (propName.equals(Sasl.QOP)) {
                return "auth";
            } else {
                return null;
            }
        } else {
            throw new IllegalStateException("PLAIN authentication not completed");
        }
    }

    private void clearPassword() {
        if (pw != null) {
            // zero out password
            for (int i = 0; i < pw.length; i++) {
                pw[i] = (byte)0;
            }
            pw = null;
        }
    }

    protected void finalize() {
        clearPassword();
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java PlainClient.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.