Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/com/sun/jndi/ldap/lib/LdapMessage.java
41155 views
1
/*
2
* Copyright (c) 2019, 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.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
import java.math.BigInteger;
25
import java.util.Arrays;
26
import java.util.Optional;
27
import java.util.stream.Stream;
28
29
/**
30
* An LDAP message.
31
*/
32
public class LdapMessage {
33
34
private final byte[] message;
35
private int messageID;
36
private Operation operation;
37
38
public enum Operation {
39
BIND_REQUEST(0x60, "BindRequest"), // [APPLICATION 0]
40
BIND_RESPONSE(0x61, "BindResponse"), // [APPLICATION 1]
41
UNBIND_REQUEST(0x42, "UnbindRequest"), // [APPLICATION 2]
42
SEARCH_REQUEST(0x63, "SearchRequest"), // [APPLICATION 3]
43
SEARCH_RESULT_ENTRY(0x64, "SearchResultEntry"), // [APPLICATION 4]
44
SEARCH_RESULT_DONE(0x65, "SearchResultDone"), // [APPLICATION 5]
45
MODIFY_REQUEST(0x66, "ModifyRequest"), // [APPLICATION 6]
46
MODIFY_RESPONSE(0x67, "ModifyResponse"), // [APPLICATION 7]
47
ADD_REQUEST(0x68, "AddRequest"), // [APPLICATION 8]
48
ADD_RESPONSE(0x69, "AddResponse"), // [APPLICATION 9]
49
DELETE_REQUEST(0x4A, "DeleteRequest"), // [APPLICATION 10]
50
DELETE_RESPONSE(0x6B, "DeleteResponse"), // [APPLICATION 11]
51
MODIFY_DN_REQUEST(0x6C, "ModifyDNRequest"), // [APPLICATION 12]
52
MODIFY_DN_RESPONSE(0x6D, "ModifyDNResponse"), // [APPLICATION 13]
53
COMPARE_REQUEST(0x6E, "CompareRequest"), // [APPLICATION 14]
54
COMPARE_RESPONSE(0x6F, "CompareResponse"), // [APPLICATION 15]
55
ABANDON_REQUEST(0x50, "AbandonRequest"), // [APPLICATION 16]
56
SEARCH_RESULT_REFERENCE(0x73, "SearchResultReference"), // [APPLICATION 19]
57
EXTENDED_REQUEST(0x77, "ExtendedRequest"), // [APPLICATION 23]
58
EXTENDED_RESPONSE(0x78, "ExtendedResponse"), // [APPLICATION 24]
59
INTERMEDIATE_RESPONSE(0x79, "IntermediateResponse"); // [APPLICATION 25]
60
61
private final int id;
62
private final String name;
63
64
Operation(int id, String name) {
65
this.id = id;
66
this.name = name;
67
}
68
69
public int getId() {
70
return id;
71
}
72
73
@Override
74
public String toString() {
75
return name;
76
}
77
78
private static Operation fromId(int id) {
79
Optional<Operation> optional = Stream.of(Operation.values())
80
.filter(o -> o.id == id).findFirst();
81
if (optional.isPresent()) {
82
return optional.get();
83
} else {
84
throw new RuntimeException(
85
"Unknown id " + id + " for enum Operation.");
86
}
87
}
88
}
89
90
public LdapMessage(byte[] message) {
91
this.message = message;
92
parse();
93
}
94
95
public LdapMessage(String hexString) {
96
this(parseHexBinary(hexString));
97
}
98
99
// Extracts the message ID and operation ID from an LDAP protocol encoding
100
private void parse() {
101
if (message == null || message.length < 2) {
102
throw new RuntimeException(
103
"Invalid ldap message: " + Arrays.toString(message));
104
}
105
106
if (message[0] != 0x30) {
107
throw new RuntimeException("Bad LDAP encoding in message, "
108
+ "expected ASN.1 SEQUENCE tag (0x30), encountered "
109
+ message[0]);
110
}
111
112
int index = 2;
113
if ((message[1] & 0x80) == 0x80) {
114
index += (message[1] & 0x0F);
115
}
116
117
if (message[index] != 0x02) {
118
throw new RuntimeException("Bad LDAP encoding in message, "
119
+ "expected ASN.1 INTEGER tag (0x02), encountered "
120
+ message[index]);
121
}
122
int length = message[index + 1];
123
index += 2;
124
messageID = new BigInteger(1,
125
Arrays.copyOfRange(message, index, index + length)).intValue();
126
index += length;
127
int operationID = message[index];
128
operation = Operation.fromId(operationID);
129
}
130
131
/**
132
* Return original ldap message in byte array.
133
*
134
* @return original ldap message
135
*/
136
public byte[] getMessage() {
137
return Arrays.copyOf(message, message.length);
138
}
139
140
/**
141
* Return ldap message id.
142
*
143
* @return ldap message id.
144
*/
145
public int getMessageID() {
146
return messageID;
147
}
148
149
/**
150
* Return ldap message's operation.
151
*
152
* @return ldap message's operation.
153
*/
154
public Operation getOperation() {
155
return operation;
156
}
157
158
private static byte[] parseHexBinary(String s) {
159
160
final int len = s.length();
161
162
// "111" is not a valid hex encoding.
163
if (len % 2 != 0) {
164
throw new IllegalArgumentException(
165
"hexBinary needs to be even-length: " + s);
166
}
167
168
byte[] out = new byte[len / 2];
169
170
for (int i = 0; i < len; i += 2) {
171
int h = Character.digit(s.charAt(i), 16);
172
int l = Character.digit(s.charAt(i + 1), 16);
173
if (h == -1 || l == -1) {
174
throw new IllegalArgumentException(
175
"contains illegal character for hexBinary: " + s);
176
}
177
178
out[i / 2] = (byte) (h * 16 + l);
179
}
180
181
return out;
182
}
183
184
public static int getMessageLength(byte[] encoding) {
185
if (encoding.length < 2) {
186
// not enough data to extract msg len, just return -1
187
return -1;
188
}
189
190
if (encoding[0] != 0x30) {
191
throw new RuntimeException("Error: bad LDAP encoding message: "
192
+ "expected ASN.1 SEQUENCE tag (0x30), encountered "
193
+ encoding[0]);
194
}
195
196
int len;
197
int index = 1;
198
int payloadLen = 0;
199
200
if ((encoding[1] & 0x80) == 0x80) {
201
len = (encoding[1] & 0x0F);
202
index++;
203
} else {
204
len = 1;
205
}
206
207
if (len > 4) {
208
throw new RuntimeException(
209
"Error: LDAP encoding message payload too large");
210
}
211
212
if (encoding.length < index + len) {
213
// additional data required to extract payload len, return -1
214
return -1;
215
}
216
217
for (byte b : Arrays.copyOfRange(encoding, index, index + len)) {
218
payloadLen = payloadLen << 8 | (b & 0xFF);
219
}
220
221
if (payloadLen <= 0) {
222
throw new RuntimeException(
223
"Error: invalid LDAP encoding message length or payload too large");
224
}
225
226
return index + len + payloadLen;
227
}
228
}
229
230