diff options
Diffstat (limited to 'src/com/isode/stroke/sasl/DIGESTMD5Properties.java')
-rw-r--r-- | src/com/isode/stroke/sasl/DIGESTMD5Properties.java | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/src/com/isode/stroke/sasl/DIGESTMD5Properties.java b/src/com/isode/stroke/sasl/DIGESTMD5Properties.java new file mode 100644 index 0000000..0bc6a8d --- /dev/null +++ b/src/com/isode/stroke/sasl/DIGESTMD5Properties.java @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2010-2013 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ +/* + * Copyright (c) 2015 Tarun Gupta. + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +package com.isode.stroke.sasl; + +import com.isode.stroke.sasl.ClientAuthenticator; +import com.isode.stroke.base.SafeByteArray; +import com.isode.stroke.base.ByteArray; +import java.util.TreeMap; +import java.util.Map; +import java.util.Vector; + +public class DIGESTMD5Properties { + + // Swiften uses std::multimap, but this is not required, so a TreeMap is used here. + private TreeMap<String, ByteArray> properties = new TreeMap<String, ByteArray>(); + + static boolean insideQuotes(final ByteArray v) { + if (v.isEmpty()) { + return false; + } + else if (v.getSize() == 1) { + return v.getData()[0] == '"'; + } + else if (v.getData()[0] == '"') { + return v.getData()[v.getSize() - 1] != '"'; + } + else { + return false; + } + } + + static ByteArray stripQuotes(final ByteArray v) { + String s = new String(v.getData()); // possibly with a charset + int size = v.getSize(); + int i = 0; + if(s.charAt(0) == '"') { + i++; + size--; + } + if(s.charAt(v.getSize() - 1) == '"') { + size--; + } + String data = s.substring(i, size+1); + return new ByteArray(data); + } + + public DIGESTMD5Properties() { + + } + + public String getValue(final String key) { + if (properties.containsKey(key)) { + return properties.get(key).toString(); + } + else { + return null; + } + } + + public void setValue(final String key, final String value) { + if(!(properties.containsKey(key))) { + properties.put(key, new ByteArray(value)); + } + } + + public ByteArray serialize() { + ByteArray result = new ByteArray(); + for(Map.Entry<String, ByteArray> entry : properties.entrySet()) { + if(entry.getKey() != properties.firstKey()) { + result.append((byte)(',')); + } + result.append(new ByteArray(entry.getKey())); + result.append((byte)('=')); + if (isQuoted(entry.getKey())) { + result.append(new ByteArray("\"")); + result.append(entry.getValue()); //It does not iterate over all values possible for this key. So no need for MultiMap. Also serialize test also indicates the same. + result.append(new ByteArray("\"")); + } + else { + result.append(entry.getValue()); + } + } + return result; + } + + public static DIGESTMD5Properties parse(final ByteArray data) { + DIGESTMD5Properties result = new DIGESTMD5Properties(); + boolean inKey = true; + ByteArray currentKey = new ByteArray(); + ByteArray currentValue = new ByteArray(); + byte[] byteArrayData = data.getData(); + for (int i = 0; i < data.getSize(); ++i) { + char c = (char)(byteArrayData[i]); + if (inKey) { + if (c == '=') { + inKey = false; + } + else { + currentKey.append((byte)(c)); + } + } + else { + if (c == ',' && !insideQuotes(currentValue)) { + String key = currentKey.toString(); + if (isQuoted(key)) { + result.setValue(key, stripQuotes(currentValue).toString()); + } + else { + result.setValue(key, currentValue.toString()); + } + inKey = true; + currentKey = new ByteArray(); + currentValue = new ByteArray(); + } + else { + currentValue.append((byte)(c)); + } + } + } + + if (!currentKey.isEmpty()) { + String key = currentKey.toString(); + if (isQuoted(key)) { + result.setValue(key, stripQuotes(currentValue).toString()); + } + else { + result.setValue(key, currentValue.toString()); + } + } + + return result; + } + + private static boolean isQuoted(final String p) { + return p.equals("authzid") || p.equals("cnonce") || p.equals("digest-uri") || p.equals("nonce") || p.equals("realm") || p.equals("username"); + } +} |