1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.proxy.utils;
21
22 import java.io.ByteArrayOutputStream;
23 import java.io.UnsupportedEncodingException;
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28
29 import javax.security.sasl.AuthenticationException;
30 import javax.security.sasl.SaslException;
31
32
33
34
35
36
37
38 public class StringUtilities {
39
40
41
42
43
44
45
46
47
48
49
50
51
52 public static String getDirectiveValue(
53 HashMap<String, String> directivesMap, String directive,
54 boolean mandatory) throws AuthenticationException {
55 String value = directivesMap.get(directive);
56 if (value == null) {
57 if (mandatory) {
58 throw new AuthenticationException("\"" + directive
59 + "\" mandatory directive is missing");
60 }
61
62 return "";
63 }
64
65 return value;
66 }
67
68
69
70
71
72
73
74
75
76 public static void copyDirective(HashMap<String, String> directives,
77 StringBuilder sb, String directive) {
78 String directiveValue = directives.get(directive);
79 if (directiveValue != null) {
80 sb.append(directive).append(" = \"").append(directiveValue).append(
81 "\", ");
82 }
83 }
84
85
86
87
88
89
90
91
92
93
94
95 public static String copyDirective(HashMap<String, String> src,
96 HashMap<String, String> dst, String directive) {
97 String directiveValue = src.get(directive);
98 if (directiveValue != null) {
99 dst.put(directive, directiveValue);
100 }
101
102 return directiveValue;
103 }
104
105
106
107
108
109
110
111
112
113 public static HashMap<String, String> parseDirectives(byte[] buf)
114 throws SaslException {
115 HashMap<String, String> map = new HashMap<String, String>();
116 boolean gettingKey = true;
117 boolean gettingQuotedValue = false;
118 boolean expectSeparator = false;
119 byte bch;
120
121 ByteArrayOutputStream key = new ByteArrayOutputStream(10);
122 ByteArrayOutputStream value = new ByteArrayOutputStream(10);
123
124 int i = skipLws(buf, 0);
125 while (i < buf.length) {
126 bch = buf[i];
127
128 if (gettingKey) {
129 if (bch == ',') {
130 if (key.size() != 0) {
131 throw new SaslException("Directive key contains a ',':"
132 + key);
133 }
134
135
136 i = skipLws(buf, i + 1);
137 } else if (bch == '=') {
138 if (key.size() == 0) {
139 throw new SaslException("Empty directive key");
140 }
141
142 gettingKey = false;
143 i = skipLws(buf, i + 1);
144
145
146 if (i < buf.length) {
147 if (buf[i] == '"') {
148 gettingQuotedValue = true;
149 ++i;
150 }
151 } else {
152 throw new SaslException("Valueless directive found: "
153 + key.toString());
154 }
155 } else if (isLws(bch)) {
156
157 i = skipLws(buf, i + 1);
158
159
160 if (i < buf.length) {
161 if (buf[i] != '=') {
162 throw new SaslException("'=' expected after key: "
163 + key.toString());
164 }
165 } else {
166 throw new SaslException("'=' expected after key: "
167 + key.toString());
168 }
169 } else {
170 key.write(bch);
171 ++i;
172 }
173 } else if (gettingQuotedValue) {
174
175 if (bch == '\\') {
176
177 ++i;
178 if (i < buf.length) {
179 value.write(buf[i]);
180 ++i;
181 } else {
182
183 throw new SaslException(
184 "Unmatched quote found for directive: "
185 + key.toString() + " with value: "
186 + value.toString());
187 }
188 } else if (bch == '"') {
189
190 ++i;
191 gettingQuotedValue = false;
192 expectSeparator = true;
193 } else {
194 value.write(bch);
195 ++i;
196 }
197 } else if (isLws(bch) || bch == ',') {
198
199 extractDirective(map, key.toString(), value.toString());
200 key.reset();
201 value.reset();
202 gettingKey = true;
203 gettingQuotedValue = expectSeparator = false;
204 i = skipLws(buf, i + 1);
205 } else if (expectSeparator) {
206 throw new SaslException(
207 "Expecting comma or linear whitespace after quoted string: \""
208 + value.toString() + "\"");
209 } else {
210 value.write(bch);
211 ++i;
212 }
213 }
214
215 if (gettingQuotedValue) {
216 throw new SaslException("Unmatched quote found for directive: "
217 + key.toString() + " with value: " + value.toString());
218 }
219
220
221 if (key.size() > 0) {
222 extractDirective(map, key.toString(), value.toString());
223 }
224
225 return map;
226 }
227
228
229
230
231
232
233
234
235
236
237 private static void extractDirective(HashMap<String, String> map,
238 String key, String value) throws SaslException {
239 if (map.get(key) != null) {
240 throw new SaslException("Peer sent more than one " + key
241 + " directive");
242 }
243
244 map.put(key, value);
245 }
246
247
248
249
250
251
252
253
254
255 public static boolean isLws(byte b) {
256 switch (b) {
257 case 13:
258 case 10:
259 case 32:
260 case 9:
261 return true;
262 }
263
264 return false;
265 }
266
267
268
269
270
271
272
273
274 private static int skipLws(byte[] buf, int start) {
275 int i;
276
277 for (i = start; i < buf.length; i++) {
278 if (!isLws(buf[i])) {
279 return i;
280 }
281 }
282
283 return i;
284 }
285
286
287
288
289
290
291
292
293
294 public static String stringTo8859_1(String str)
295 throws UnsupportedEncodingException {
296 if (str == null) {
297 return "";
298 }
299
300 return new String(str.getBytes("UTF8"), "8859_1");
301 }
302
303
304
305
306
307
308
309
310
311 public static String getSingleValuedHeader(
312 Map<String, List<String>> headers, String key) {
313 List<String> values = headers.get(key);
314
315 if (values == null) {
316 return null;
317 }
318
319 if (values.size() > 1) {
320 throw new IllegalArgumentException("Header with key [\"" + key
321 + "\"] isn't single valued !");
322 }
323
324 return values.get(0);
325 }
326
327
328
329
330
331
332
333
334
335
336
337 public static void addValueToHeader(Map<String, List<String>> headers,
338 String key, String value, boolean singleValued) {
339 List<String> values = headers.get(key);
340
341 if (values == null) {
342 values = new ArrayList<String>(1);
343 headers.put(key, values);
344 }
345
346 if (singleValued && values.size() == 1) {
347 values.set(0, value);
348 } else {
349 values.add(value);
350 }
351 }
352 }