Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.security.sasl/share/classes/com/sun/security/sasl/PlainClient.java
41161 views
1
/*
2
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package com.sun.security.sasl;
27
28
import javax.security.sasl.*;
29
30
import static java.nio.charset.StandardCharsets.UTF_8;
31
32
/**
33
* Implements the PLAIN SASL client mechanism.
34
* (<A
35
* HREF="http://ftp.isi.edu/in-notes/rfc2595.txt">RFC 2595</A>)
36
*
37
* @author Rosanna Lee
38
*/
39
final class PlainClient implements SaslClient {
40
private boolean completed = false;
41
private byte[] pw;
42
private String authorizationID;
43
private String authenticationID;
44
private static byte SEP = 0; // US-ASCII <NUL>
45
46
/**
47
* Creates a SASL mechanism with client credentials that it needs
48
* to participate in Plain authentication exchange with the server.
49
*
50
* @param authorizationID A possibly null string representing the principal
51
* for which authorization is being granted; if null, same as
52
* authenticationID
53
* @param authenticationID A non-null string representing the principal
54
* being authenticated. pw is associated with this principal.
55
* @param pw A non-null byte[] containing the password.
56
*/
57
PlainClient(String authorizationID, String authenticationID, byte[] pw)
58
throws SaslException {
59
if (authenticationID == null || pw == null) {
60
throw new SaslException(
61
"PLAIN: authorization ID and password must be specified");
62
}
63
64
this.authorizationID = authorizationID;
65
this.authenticationID = authenticationID;
66
this.pw = pw; // caller should have already cloned
67
}
68
69
/**
70
* Retrieves this mechanism's name for to initiate the PLAIN protocol
71
* exchange.
72
*
73
* @return The string "PLAIN".
74
*/
75
public String getMechanismName() {
76
return "PLAIN";
77
}
78
79
public boolean hasInitialResponse() {
80
return true;
81
}
82
83
public void dispose() throws SaslException {
84
clearPassword();
85
}
86
87
/**
88
* Retrieves the initial response for the SASL command, which for
89
* PLAIN is the concatenation of authorization ID, authentication ID
90
* and password, with each component separated by the US-ASCII <NUL> byte.
91
*
92
* @param challengeData Ignored
93
* @return A non-null byte array containing the response to be sent to the server.
94
* @throws IllegalStateException if authentication already completed
95
*/
96
public byte[] evaluateChallenge(byte[] challengeData) {
97
if (completed) {
98
throw new IllegalStateException(
99
"PLAIN authentication already completed");
100
}
101
completed = true;
102
byte[] authz = (authorizationID != null)
103
? authorizationID.getBytes(UTF_8)
104
: null;
105
byte[] auth = authenticationID.getBytes(UTF_8);
106
107
byte[] answer = new byte[pw.length + auth.length + 2 +
108
(authz == null ? 0 : authz.length)];
109
110
int pos = 0;
111
if (authz != null) {
112
System.arraycopy(authz, 0, answer, 0, authz.length);
113
pos = authz.length;
114
}
115
answer[pos++] = SEP;
116
System.arraycopy(auth, 0, answer, pos, auth.length);
117
118
pos += auth.length;
119
answer[pos++] = SEP;
120
121
System.arraycopy(pw, 0, answer, pos, pw.length);
122
123
clearPassword();
124
return answer;
125
}
126
127
/**
128
* Determines whether this mechanism has completed.
129
* Plain completes after returning one response.
130
*
131
* @return true if has completed; false otherwise;
132
*/
133
public boolean isComplete() {
134
return completed;
135
}
136
137
/**
138
* Unwraps the incoming buffer.
139
*
140
* @throws SaslException Not applicable to this mechanism.
141
*/
142
public byte[] unwrap(byte[] incoming, int offset, int len)
143
throws SaslException {
144
if (completed) {
145
throw new SaslException(
146
"PLAIN supports neither integrity nor privacy");
147
} else {
148
throw new IllegalStateException("PLAIN authentication not completed");
149
}
150
}
151
152
/**
153
* Wraps the outgoing buffer.
154
*
155
* @throws SaslException Not applicable to this mechanism.
156
*/
157
public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException {
158
if (completed) {
159
throw new SaslException(
160
"PLAIN supports neither integrity nor privacy");
161
} else {
162
throw new IllegalStateException("PLAIN authentication not completed");
163
}
164
}
165
166
/**
167
* Retrieves the negotiated property.
168
* This method can be called only after the authentication exchange has
169
* completed (i.e., when {@code isComplete()} returns true); otherwise, a
170
* {@code SaslException} is thrown.
171
*
172
* @return value of property; only QOP is applicable to PLAIN.
173
* @exception IllegalStateException if this authentication exchange
174
* has not completed
175
*/
176
public Object getNegotiatedProperty(String propName) {
177
if (completed) {
178
if (propName.equals(Sasl.QOP)) {
179
return "auth";
180
} else {
181
return null;
182
}
183
} else {
184
throw new IllegalStateException("PLAIN authentication not completed");
185
}
186
}
187
188
private void clearPassword() {
189
if (pw != null) {
190
// zero out password
191
for (int i = 0; i < pw.length; i++) {
192
pw[i] = (byte)0;
193
}
194
pw = null;
195
}
196
}
197
198
@SuppressWarnings("deprecation")
199
protected void finalize() {
200
clearPassword();
201
}
202
}
203
204