Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/com/sun/security/sasl/PlainClient.java
38924 views
/*1* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.security.sasl;2627import javax.security.sasl.*;2829/**30* Implements the PLAIN SASL client mechanism.31* (<A32* HREF="http://ftp.isi.edu/in-notes/rfc2595.txt">RFC 2595</A>)33*34* @author Rosanna Lee35*/36final class PlainClient implements SaslClient {37private boolean completed = false;38private byte[] pw;39private String authorizationID;40private String authenticationID;41private static byte SEP = 0; // US-ASCII <NUL>4243/**44* Creates a SASL mechanism with client credentials that it needs45* to participate in Plain authentication exchange with the server.46*47* @param authorizationID A possibly null string representing the principal48* for which authorization is being granted; if null, same as49* authenticationID50* @param authenticationID A non-null string representing the principal51* being authenticated. pw is associated with with this principal.52* @param pw A non-null byte[] containing the password.53*/54PlainClient(String authorizationID, String authenticationID, byte[] pw)55throws SaslException {56if (authenticationID == null || pw == null) {57throw new SaslException(58"PLAIN: authorization ID and password must be specified");59}6061this.authorizationID = authorizationID;62this.authenticationID = authenticationID;63this.pw = pw; // caller should have already cloned64}6566/**67* Retrieves this mechanism's name for to initiate the PLAIN protocol68* exchange.69*70* @return The string "PLAIN".71*/72public String getMechanismName() {73return "PLAIN";74}7576public boolean hasInitialResponse() {77return true;78}7980public void dispose() throws SaslException {81clearPassword();82}8384/**85* Retrieves the initial response for the SASL command, which for86* PLAIN is the concatenation of authorization ID, authentication ID87* and password, with each component separated by the US-ASCII <NUL> byte.88*89* @param challengeData Ignored90* @return A non-null byte array containing the response to be sent to the server.91* @throws SaslException If cannot encode ids in UTF-892* @throw IllegalStateException if authentication already completed93*/94public byte[] evaluateChallenge(byte[] challengeData) throws SaslException {95if (completed) {96throw new IllegalStateException(97"PLAIN authentication already completed");98}99completed = true;100101try {102byte[] authz = (authorizationID != null)?103authorizationID.getBytes("UTF8") :104null;105byte[] auth = authenticationID.getBytes("UTF8");106107byte[] answer = new byte[pw.length + auth.length + 2 +108(authz == null ? 0 : authz.length)];109110int pos = 0;111if (authz != null) {112System.arraycopy(authz, 0, answer, 0, authz.length);113pos = authz.length;114}115answer[pos++] = SEP;116System.arraycopy(auth, 0, answer, pos, auth.length);117118pos += auth.length;119answer[pos++] = SEP;120121System.arraycopy(pw, 0, answer, pos, pw.length);122123clearPassword();124return answer;125} catch (java.io.UnsupportedEncodingException e) {126throw new SaslException("Cannot get UTF-8 encoding of ids", e);127}128}129130/**131* Determines whether this mechanism has completed.132* Plain completes after returning one response.133*134* @return true if has completed; false otherwise;135*/136public boolean isComplete() {137return completed;138}139140/**141* Unwraps the incoming buffer.142*143* @throws SaslException Not applicable to this mechanism.144*/145public byte[] unwrap(byte[] incoming, int offset, int len)146throws SaslException {147if (completed) {148throw new SaslException(149"PLAIN supports neither integrity nor privacy");150} else {151throw new IllegalStateException("PLAIN authentication not completed");152}153}154155/**156* Wraps the outgoing buffer.157*158* @throws SaslException Not applicable to this mechanism.159*/160public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException {161if (completed) {162throw new SaslException(163"PLAIN supports neither integrity nor privacy");164} else {165throw new IllegalStateException("PLAIN authentication not completed");166}167}168169/**170* Retrieves the negotiated property.171* This method can be called only after the authentication exchange has172* completed (i.e., when {@code isComplete()} returns true); otherwise, a173* {@code SaslException} is thrown.174*175* @return value of property; only QOP is applicable to PLAIN.176* @exception IllegalStateException if this authentication exchange177* has not completed178*/179public Object getNegotiatedProperty(String propName) {180if (completed) {181if (propName.equals(Sasl.QOP)) {182return "auth";183} else {184return null;185}186} else {187throw new IllegalStateException("PLAIN authentication not completed");188}189}190191private void clearPassword() {192if (pw != null) {193// zero out password194for (int i = 0; i < pw.length; i++) {195pw[i] = (byte)0;196}197pw = null;198}199}200201protected void finalize() {202clearPassword();203}204}205206207