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