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