From 6f84f6a65b8b80e2f599dff76da0cd13fbead611 Mon Sep 17 00:00:00 2001 From: Tarun Gupta Date: Fri, 17 Jul 2015 03:21:13 +0530 Subject: Update Serializers and Parsers. Updates Serializers and Parsers along with one minor change in XMPPlayer. Update Non Payload Serializers to return SafeByteArray. Updates SafeByteArray to return SafeByteArray on append and plus method. License: This patch is BSD-licensed, see Documentation/Licenses/BSD-simplified.txt for details. Test-Information: None. Change-Id: I6fe665a26b10cac37b3e3acd9ec15c211ac9b8ab diff --git a/src/com/isode/stroke/base/SafeByteArray.java b/src/com/isode/stroke/base/SafeByteArray.java index d6f817a..74c1848 100644 --- a/src/com/isode/stroke/base/SafeByteArray.java +++ b/src/com/isode/stroke/base/SafeByteArray.java @@ -4,7 +4,9 @@ */ package com.isode.stroke.base; +import com.isode.stroke.base.SafeByteArray; import com.isode.stroke.base.ByteArray; +import java.io.UnsupportedEncodingException; /** * It's currently not actually secure, @@ -19,4 +21,84 @@ public class SafeByteArray extends ByteArray { public SafeByteArray(String s) { super(s); } + + public SafeByteArray(ByteArray b) { + this.append(b.getData()); + } + + /** + * Creates a new SafeByteArray object containing all + * the elements from two existing ByteArrays (immutable add). + * + * @param a an existing SafeByteArray. Must not be null, but may be empty. + * @param b an existing SafeByteArray. Must not be null, but may be empty. + * @return a new SafeByteArray containing all the elements of a + * followed by all the elements of b. + */ + public static SafeByteArray plus(SafeByteArray a, SafeByteArray b) { + SafeByteArray x = new SafeByteArray().append(a.getData()); + x.append(b); + return x; + } + + /** + * Updates the SafeByteArray by adding all the elements + * of another SafeByteArray to the end of the array (mutable add). + * @param b an existing SafeByteArray. Must not be null, but may be empty + * @return a reference to the updated object + */ + public SafeByteArray append(ByteArray b) { + append(b.getData()); + return this; + } + + /** + * Updates the SafeByteArray by adding all the bytes + * in a byte[] to the end of the array (mutable add). + * + * @param b an array of bytes. Must not be null, but may contain zero + * elements. + * + * @return a reference to the updated object + */ + public SafeByteArray append(byte[] b) { + return append(b, b.length); + } + + /** Mutable add */ + public SafeByteArray append(byte[] b, int len) { + for (int i = 0; i < len; i++) { + append(b[i]); + } + return this; + } + + /** + * Updates the SafeByteArray by adding a single byte + * value to the end of the array (mutable add). + * @param b a single byte + * @return a reference to the updated object + */ + public SafeByteArray append(byte b) { + dataCopy_ = null; /* Invalidate cache */ + data_.add(Byte.valueOf(b)); + return this; + } + + /** + * Updates the SafeByteArray by adding all the bytes + * obtained by UTF-8 encoding the provided String to the end of the array (mutable add). + * @param s a String that must not be null. + * @return a reference to the updated object. + */ + public SafeByteArray append(String s) { + byte[] bytes; + try { + bytes = s.getBytes("UTF-8"); + } catch (UnsupportedEncodingException ex) { + throw new IllegalStateException("JVM has no 'UTF-8' encoding"); + } + append(bytes); + return this; + } } \ No newline at end of file diff --git a/src/com/isode/stroke/client/ClientSession.java b/src/com/isode/stroke/client/ClientSession.java index 10a09f6..7654630 100644 --- a/src/com/isode/stroke/client/ClientSession.java +++ b/src/com/isode/stroke/client/ClientSession.java @@ -9,6 +9,7 @@ package com.isode.stroke.client; import com.isode.stroke.base.ByteArray; +import com.isode.stroke.base.SafeByteArray; import com.isode.stroke.elements.AuthChallenge; import com.isode.stroke.elements.AuthFailure; import com.isode.stroke.elements.AuthRequest; @@ -342,7 +343,7 @@ public class ClientSession { if (stream.hasTLSCertificate()) { if (streamFeatures.hasAuthenticationMechanism("EXTERNAL")) { state = State.Authenticating; - stream.writeElement(new AuthRequest("EXTERNAL",new ByteArray())); + stream.writeElement(new AuthRequest("EXTERNAL",new SafeByteArray())); } else { finishSession(Error.Type.TLSClientCertificateError); @@ -350,7 +351,7 @@ public class ClientSession { } else if (streamFeatures.hasAuthenticationMechanism("EXTERNAL")) { state = State.Authenticating; - stream.writeElement(new AuthRequest("EXTERNAL",new ByteArray())); + stream.writeElement(new AuthRequest("EXTERNAL",new SafeByteArray())); } else if (streamFeatures.hasAuthenticationMechanism("SCRAM-SHA-1") || streamFeatures.hasAuthenticationMechanism("SCRAM-SHA-1-PLUS")) { final SCRAMSHA1ClientAuthenticator scramAuthenticator = new SCRAMSHA1ClientAuthenticator(UUID.randomUUID().toString(), streamFeatures.hasAuthenticationMechanism("SCRAM-SHA-1-PLUS")); diff --git a/src/com/isode/stroke/elements/AuthRequest.java b/src/com/isode/stroke/elements/AuthRequest.java index 97ac8a0..9e29dd3 100644 --- a/src/com/isode/stroke/elements/AuthRequest.java +++ b/src/com/isode/stroke/elements/AuthRequest.java @@ -8,7 +8,7 @@ */ package com.isode.stroke.elements; -import com.isode.stroke.base.ByteArray; +import com.isode.stroke.base.SafeByteArray; public class AuthRequest implements Element { @@ -21,16 +21,16 @@ public class AuthRequest implements Element { mechanism_ = mechanism; } - public AuthRequest(String mechanism, ByteArray message) { + public AuthRequest(String mechanism, SafeByteArray message) { mechanism_ = mechanism; message_ = message; } - public ByteArray getMessage() { + public SafeByteArray getMessage() { return message_; } - public void setMessage(ByteArray message) { + public void setMessage(SafeByteArray message) { message_ = message; } @@ -42,5 +42,5 @@ public class AuthRequest implements Element { mechanism_ = mechanism; } private String mechanism_ = ""; - private ByteArray message_; + private SafeByteArray message_; } \ No newline at end of file diff --git a/src/com/isode/stroke/elements/AuthResponse.java b/src/com/isode/stroke/elements/AuthResponse.java index 40d5c5e..00a8ded 100644 --- a/src/com/isode/stroke/elements/AuthResponse.java +++ b/src/com/isode/stroke/elements/AuthResponse.java @@ -9,7 +9,7 @@ */ package com.isode.stroke.elements; -import com.isode.stroke.base.ByteArray; +import com.isode.stroke.base.SafeByteArray; public class AuthResponse implements Element { //FIXME: parser/serialiser @@ -18,16 +18,16 @@ public class AuthResponse implements Element { value = null; } - public AuthResponse(ByteArray value) { + public AuthResponse(SafeByteArray value) { this.value = value; } - public ByteArray getValue() { + public SafeByteArray getValue() { return value; } - public void setValue(ByteArray value) { + public void setValue(SafeByteArray value) { this.value = value; } - private ByteArray value; + private SafeByteArray value; } diff --git a/src/com/isode/stroke/parser/AuthRequestParser.java b/src/com/isode/stroke/parser/AuthRequestParser.java index b56ff89..d787cbb 100644 --- a/src/com/isode/stroke/parser/AuthRequestParser.java +++ b/src/com/isode/stroke/parser/AuthRequestParser.java @@ -10,6 +10,7 @@ package com.isode.stroke.parser; import com.isode.stroke.elements.AuthRequest; import com.isode.stroke.stringcodecs.Base64; +import com.isode.stroke.base.SafeByteArray; class AuthRequestParser extends GenericElementParser { @@ -29,7 +30,7 @@ class AuthRequestParser extends GenericElementParser { public void handleEndElement(String a, String b) { --depth_; if (depth_ == 0) { - getElementGeneric().setMessage(Base64.decode(text_)); + getElementGeneric().setMessage(new SafeByteArray(Base64.decode(text_))); } } diff --git a/src/com/isode/stroke/parser/AuthResponseParser.java b/src/com/isode/stroke/parser/AuthResponseParser.java index 63d2a60..cae6fbb 100644 --- a/src/com/isode/stroke/parser/AuthResponseParser.java +++ b/src/com/isode/stroke/parser/AuthResponseParser.java @@ -11,6 +11,7 @@ package com.isode.stroke.parser; import com.isode.stroke.elements.AuthResponse; import com.isode.stroke.stringcodecs.Base64; +import com.isode.stroke.base.SafeByteArray; class AuthResponseParser extends GenericElementParser { @@ -27,7 +28,7 @@ class AuthResponseParser extends GenericElementParser { public void handleEndElement(String unused1, String unused2) { --depth; if (depth == 0) { - getElementGeneric().setValue(Base64.decode(text)); + getElementGeneric().setValue(new SafeByteArray(Base64.decode(text))); } } diff --git a/src/com/isode/stroke/parser/XMLParserFactory.java b/src/com/isode/stroke/parser/XMLParserFactory.java new file mode 100644 index 0000000..a5fcdb0 --- /dev/null +++ b/src/com/isode/stroke/parser/XMLParserFactory.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2010 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.parser; + +import com.isode.stroke.parser.XMLParser; +import com.isode.stroke.parser.XMLParserClient; + +public abstract class XMLParserFactory { + + public abstract XMLParser createParser(XMLParserClient xmlParserClient); +} diff --git a/src/com/isode/stroke/parser/XMPPParser.java b/src/com/isode/stroke/parser/XMPPParser.java index 85d0e1f..8fd7763 100644 --- a/src/com/isode/stroke/parser/XMPPParser.java +++ b/src/com/isode/stroke/parser/XMPPParser.java @@ -9,95 +9,90 @@ import java.util.logging.Logger; public class XMPPParser implements XMLParserClient { - private final XMLParser xmlParser_; - private final XMPPParserClient client_; - private final PayloadParserFactoryCollection payloadParserFactories_; - private int currentDepth_ = 0; + private XMLParser xmlParser_; + private XMPPParserClient client_; + private PayloadParserFactoryCollection payloadParserFactories_; + private int level_ = 0; private ElementParser currentElementParser_ = null; private boolean parseErrorOccurred_ = false; private Logger logger_ = Logger.getLogger(this.getClass().getName()); - + private final int TopLevel = 0; + private final int StreamLevel = 1; + private final int ElementLevel = 2; + public XMPPParser(XMPPParserClient parserClient, PayloadParserFactoryCollection payloadParserFactories) { + xmlParser_ = null; client_ = parserClient; payloadParserFactories_ = payloadParserFactories; + level_ = 0; + currentElementParser_ = null; + parseErrorOccurred_ = false; xmlParser_ = PlatformXMLParserFactory.createXMLParser(this); } public boolean parse(String data) { - parseErrorOccurred_ = false; - boolean xmlParseResult = false; - try { - xmlParseResult = xmlParser_.parse(data); - } catch (Exception e) { - parseErrorOccurred_ = true; - logger_.log(java.util.logging.Level.WARNING, "Data " + data + " caused:\n" + e.getMessage(), e); - } - if (parseErrorOccurred_ || !xmlParseResult) { - logger_.warning(String.format("When parsing, %b and %b", - parseErrorOccurred_, xmlParseResult)); - if (data != null) { - logger_.warning("xml that caused failure: " + data); - } - } + boolean xmlParseResult = xmlParser_.parse(data); return xmlParseResult && !parseErrorOccurred_; } public void handleStartElement(String element, String ns, AttributeMap attributes) { - if (!inStream()) { - if (element.equals("stream") - && ns.equals("http://etherx.jabber.org/streams")) { - ProtocolHeader header = new ProtocolHeader(); - header.setFrom(attributes.getAttribute("from")); - header.setTo(attributes.getAttribute("to")); - header.setID(attributes.getAttribute("id")); - header.setVersion(attributes.getAttribute("version")); - client_.handleStreamStart(header); - } else { - parseErrorOccurred_ = true; + if (!parseErrorOccurred_) { + if (level_ == TopLevel) { + if (element.equals("stream") && ns.equals("http://etherx.jabber.org/streams")) { + ProtocolHeader header = new ProtocolHeader(); + header.setFrom(attributes.getAttribute("from")); + header.setTo(attributes.getAttribute("to")); + header.setID(attributes.getAttribute("id")); + header.setVersion(attributes.getAttribute("version")); + client_.handleStreamStart(header); + } + else { + parseErrorOccurred_ = true; + } } - } else { - if (!inElement()) { - assert currentElementParser_ == null; - currentElementParser_ = createElementParser(element, ns); + else { + if (level_ == StreamLevel) { + assert(currentElementParser_ == null); + currentElementParser_ = createElementParser(element, ns); + } + currentElementParser_.handleStartElement(element, ns, attributes); } - currentElementParser_.handleStartElement(element, ns, attributes); } - ++currentDepth_; + ++level_; } public void handleEndElement(String element, String ns) { - assert (inStream()); - if (inElement()) { - assert currentElementParser_ != null; - currentElementParser_.handleEndElement(element, ns); - --currentDepth_; - if (!inElement()) { - client_.handleElement(currentElementParser_.getElement()); - currentElementParser_ = null; + assert(level_ > TopLevel); + --level_; + if (!parseErrorOccurred_) { + if (level_ == TopLevel) { + assert(element.equals("stream")); + client_.handleStreamEnd(); + } + else { + assert(currentElementParser_ != null); + currentElementParser_.handleEndElement(element, ns); + if (level_ == StreamLevel) { + client_.handleElement(currentElementParser_.getElement()); + currentElementParser_ = null; + } } - } else { - assert (element.equals("stream")); - --currentDepth_; - client_.handleStreamEnd(); } } public void handleCharacterData(String data) { - if (currentElementParser_ != null) { - currentElementParser_.handleCharacterData(data); + if (!parseErrorOccurred_) { + if (currentElementParser_ != null) { + currentElementParser_.handleCharacterData(data); + } + //else { + // std::cerr << "XMPPParser: Ignoring stray character data: " << data << std::endl; + //} } } - - private boolean inStream() { - return currentDepth_ > 0; - } - - private boolean inElement() { - return currentDepth_ > 1; - } - + private ElementParser createElementParser(String element, String xmlns) { if (element.equals("presence")) { return new PresenceParser(payloadParserFactories_); @@ -108,6 +103,8 @@ public class XMPPParser implements XMLParserClient { } else if (element.equals("features") && xmlns.equals("http://etherx.jabber.org/streams")) { return new StreamFeaturesParser(); + } else if (element.equals("error") && xmlns.equals("http://etherx.jabber.org/streams")) { + return new StreamErrorParser(); } else if (element.equals("auth")) { return new AuthRequestParser(); } else if (element.equals("success")) { @@ -149,6 +146,8 @@ public class XMPPParser implements XMLParserClient { return new StanzaAckParser(); } else if (element.equals("r") && xmlns.equals("urn:xmpp:sm:2")) { return new StanzaAckRequestParser(); + } else if (element.equals("handshake")) { + return new ComponentHandshakeParser(); } return new UnknownElementParser(); diff --git a/src/com/isode/stroke/parser/payloadparsers/FullPayloadParserFactoryCollection.java b/src/com/isode/stroke/parser/payloadparsers/FullPayloadParserFactoryCollection.java index 0a46d75..87b84d8 100644 --- a/src/com/isode/stroke/parser/payloadparsers/FullPayloadParserFactoryCollection.java +++ b/src/com/isode/stroke/parser/payloadparsers/FullPayloadParserFactoryCollection.java @@ -12,8 +12,6 @@ import com.isode.stroke.parser.payloadparsers.PubSubOwnerPubSubParser; public class FullPayloadParserFactoryCollection extends PayloadParserFactoryCollection { public FullPayloadParserFactoryCollection() { - /* TODO: Port more */ - //addFactory(new GenericPayloadParserFactory("", "http://jabber.org/protocol/ibb")); addFactory(new GenericPayloadParserFactory("disable", "urn:xmpp:carbons:2", CarbonsDisableParser.class)); addFactory(new GenericPayloadParserFactory("enable", "urn:xmpp:carbons:2", CarbonsEnableParser.class)); addFactory(new GenericPayloadParserFactory("private", "urn:xmpp:carbons:2", CarbonsPrivateParser.class)); @@ -62,7 +60,6 @@ public class FullPayloadParserFactoryCollection extends PayloadParserFactoryColl addFactory(new GenericPayloadParserFactory("vCard", "vcard-temp", VCardParser.class)); addFactory(new PrivateStorageParserFactory(this)); addFactory(new ChatStateParserFactory()); - //addFactory(new DelayParserFactory()); addFactory(new MUCUserPayloadParserFactory(this)); addFactory(new MUCOwnerPayloadParserFactory(this)); addFactory(new GenericPayloadParserFactory("x", diff --git a/src/com/isode/stroke/sasl/ClientAuthenticator.java b/src/com/isode/stroke/sasl/ClientAuthenticator.java index c55bf74..2dc3756 100644 --- a/src/com/isode/stroke/sasl/ClientAuthenticator.java +++ b/src/com/isode/stroke/sasl/ClientAuthenticator.java @@ -9,6 +9,7 @@ package com.isode.stroke.sasl; import com.isode.stroke.base.ByteArray; +import com.isode.stroke.base.SafeByteArray; public abstract class ClientAuthenticator { @@ -30,7 +31,7 @@ public abstract class ClientAuthenticator { this.authzid = authzid; } - public abstract ByteArray getResponse(); + public abstract SafeByteArray getResponse(); public abstract boolean setChallenge(ByteArray challenge); diff --git a/src/com/isode/stroke/sasl/PLAINClientAuthenticator.java b/src/com/isode/stroke/sasl/PLAINClientAuthenticator.java index 70e6b04..634ce11 100644 --- a/src/com/isode/stroke/sasl/PLAINClientAuthenticator.java +++ b/src/com/isode/stroke/sasl/PLAINClientAuthenticator.java @@ -9,14 +9,15 @@ package com.isode.stroke.sasl; import com.isode.stroke.base.ByteArray; +import com.isode.stroke.base.SafeByteArray; public class PLAINClientAuthenticator extends ClientAuthenticator { public PLAINClientAuthenticator() { super("PLAIN"); } - public ByteArray getResponse() { - return new ByteArray().append(getAuthorizationID()).append((byte)0).append(getAuthenticationID()).append((byte)0).append(getPassword()); + public SafeByteArray getResponse() { + return new SafeByteArray().append(getAuthorizationID()).append((byte)0).append(getAuthenticationID()).append((byte)0).append(getPassword()); } public boolean setChallenge(ByteArray challenge) { diff --git a/src/com/isode/stroke/sasl/SCRAMSHA1ClientAuthenticator.java b/src/com/isode/stroke/sasl/SCRAMSHA1ClientAuthenticator.java index ba60fca..29a37aa 100644 --- a/src/com/isode/stroke/sasl/SCRAMSHA1ClientAuthenticator.java +++ b/src/com/isode/stroke/sasl/SCRAMSHA1ClientAuthenticator.java @@ -9,6 +9,7 @@ package com.isode.stroke.sasl; import com.isode.stroke.base.ByteArray; +import com.isode.stroke.base.SafeByteArray; import com.isode.stroke.stringcodecs.Base64; import com.isode.stroke.stringcodecs.HMACSHA1; import com.isode.stroke.stringcodecs.PBKDF2; @@ -48,9 +49,9 @@ public class SCRAMSHA1ClientAuthenticator extends ClientAuthenticator { tlsChannelBindingData = channelBindingData; } - public ByteArray getResponse() { + public SafeByteArray getResponse() { if (step.equals(Step.Initial)) { - return ByteArray.plus(getGS2Header(), getInitialBareClientMessage()); + return new SafeByteArray(getGS2Header().append(getInitialBareClientMessage())); } else if (step.equals(Step.Proof)) { ByteArray clientKey = HMACSHA1.getResult(saltedPassword, new ByteArray("Client Key")); ByteArray storedKey = SHA1.getHash(clientKey); @@ -62,7 +63,7 @@ public class SCRAMSHA1ClientAuthenticator extends ClientAuthenticator { } clientProof = new ByteArray(clientProofData); ByteArray result = getFinalMessageWithoutProof().append(",p=").append(Base64.encode(clientProof)); - return result; + return new SafeByteArray(result); } else { return null; } diff --git a/src/com/isode/stroke/serializer/AuthChallengeSerializer.java b/src/com/isode/stroke/serializer/AuthChallengeSerializer.java index def242b..a27e16a 100644 --- a/src/com/isode/stroke/serializer/AuthChallengeSerializer.java +++ b/src/com/isode/stroke/serializer/AuthChallengeSerializer.java @@ -13,14 +13,15 @@ import com.isode.stroke.base.ByteArray; import com.isode.stroke.elements.AuthChallenge; import com.isode.stroke.elements.Element; import com.isode.stroke.stringcodecs.Base64; +import com.isode.stroke.base.SafeByteArray; -class AuthChallengeSerializer extends GenericElementSerializer { +public class AuthChallengeSerializer extends GenericElementSerializer { public AuthChallengeSerializer() { super(AuthChallenge.class); } - public String serialize(Element element) { + public SafeByteArray serialize(Element element) { AuthChallenge authChallenge = (AuthChallenge)element; String value = ""; ByteArray message = authChallenge.getValue(); @@ -32,7 +33,7 @@ class AuthChallengeSerializer extends GenericElementSerializer { value = Base64.encode(message); } } - return "" + value + ""; + return new SafeByteArray("" + value + ""); } } diff --git a/src/com/isode/stroke/serializer/AuthFailureSerializer.java b/src/com/isode/stroke/serializer/AuthFailureSerializer.java index 339c11e..cec8806 100644 --- a/src/com/isode/stroke/serializer/AuthFailureSerializer.java +++ b/src/com/isode/stroke/serializer/AuthFailureSerializer.java @@ -12,6 +12,7 @@ package com.isode.stroke.serializer; import com.isode.stroke.elements.AuthFailure; import com.isode.stroke.elements.Element; import com.isode.stroke.serializer.xml.XMLElement; +import com.isode.stroke.base.SafeByteArray; class AuthFailureSerializer extends GenericElementSerializer{ @@ -19,8 +20,8 @@ class AuthFailureSerializer extends GenericElementSerializer{ super(AuthFailure.class); } - public String serialize(Element element) { - return new XMLElement("failure", "urn:ietf:params:xml:ns:xmpp-sasl").serialize(); + public SafeByteArray serialize(Element element) { + return new SafeByteArray(new XMLElement("failure", "urn:ietf:params:xml:ns:xmpp-sasl").serialize()); } } diff --git a/src/com/isode/stroke/serializer/AuthRequestSerializer.java b/src/com/isode/stroke/serializer/AuthRequestSerializer.java index 318eab8..cfb2878 100644 --- a/src/com/isode/stroke/serializer/AuthRequestSerializer.java +++ b/src/com/isode/stroke/serializer/AuthRequestSerializer.java @@ -9,30 +9,30 @@ package com.isode.stroke.serializer; -import com.isode.stroke.base.ByteArray; +import com.isode.stroke.base.SafeByteArray; import com.isode.stroke.elements.AuthRequest; import com.isode.stroke.elements.Element; import com.isode.stroke.stringcodecs.Base64; -class AuthRequestSerializer extends GenericElementSerializer { +public class AuthRequestSerializer extends GenericElementSerializer { public AuthRequestSerializer() { super(AuthRequest.class); } - public String serialize(Element element) { + public SafeByteArray serialize(Element element) { AuthRequest authRequest = (AuthRequest)element; - String value = ""; - ByteArray message = authRequest.getMessage(); + SafeByteArray value = new SafeByteArray(); + SafeByteArray message = authRequest.getMessage(); if (message != null) { if (message.isEmpty()) { - value = "="; + value = new SafeByteArray("="); } else { value = Base64.encode(message); } } - return "" + value + ""; + return new SafeByteArray("").append(value).append(""); } } \ No newline at end of file diff --git a/src/com/isode/stroke/serializer/AuthResponseSerializer.java b/src/com/isode/stroke/serializer/AuthResponseSerializer.java index 97bf91a..c0c72c4 100644 --- a/src/com/isode/stroke/serializer/AuthResponseSerializer.java +++ b/src/com/isode/stroke/serializer/AuthResponseSerializer.java @@ -9,27 +9,28 @@ package com.isode.stroke.serializer; import com.isode.stroke.base.ByteArray; +import com.isode.stroke.base.SafeByteArray; import com.isode.stroke.elements.AuthResponse; import com.isode.stroke.elements.Element; import com.isode.stroke.stringcodecs.Base64; -class AuthResponseSerializer extends GenericElementSerializer { +public class AuthResponseSerializer extends GenericElementSerializer { public AuthResponseSerializer() { super(AuthResponse.class); } - public String serialize(Element element) { + public SafeByteArray serialize(Element element) { AuthResponse authResponse = (AuthResponse) element; - String value = ""; - ByteArray message = authResponse.getValue(); + SafeByteArray value = new SafeByteArray(); + SafeByteArray message = authResponse.getValue(); if (message != null) { if (message.isEmpty()) { - value = ""; + value = new SafeByteArray(""); } else { value = Base64.encode(message); } } - return "" + value + ""; + return new SafeByteArray("").append(value).append(""); } } diff --git a/src/com/isode/stroke/serializer/AuthSuccessSerializer.java b/src/com/isode/stroke/serializer/AuthSuccessSerializer.java index 1a303bc..2f0901e 100644 --- a/src/com/isode/stroke/serializer/AuthSuccessSerializer.java +++ b/src/com/isode/stroke/serializer/AuthSuccessSerializer.java @@ -9,18 +9,19 @@ package com.isode.stroke.serializer; import com.isode.stroke.base.ByteArray; +import com.isode.stroke.base.SafeByteArray; import com.isode.stroke.elements.AuthSuccess; import com.isode.stroke.elements.Element; import com.isode.stroke.stringcodecs.Base64; -class AuthSuccessSerializer extends GenericElementSerializer { +public class AuthSuccessSerializer extends GenericElementSerializer { public AuthSuccessSerializer() { super(AuthSuccess.class); } - public String serialize(Element element) { + public SafeByteArray serialize(Element element) { AuthSuccess authSuccess = (AuthSuccess)element; String value = ""; ByteArray message = authSuccess.getValue(); @@ -32,7 +33,7 @@ class AuthSuccessSerializer extends GenericElementSerializer { value = Base64.encode(message); } } - return "" + value + ""; + return new SafeByteArray("" + value + ""); } } diff --git a/src/com/isode/stroke/serializer/ComponentHandshakeSerializer.java b/src/com/isode/stroke/serializer/ComponentHandshakeSerializer.java index a320941..54fa578 100644 --- a/src/com/isode/stroke/serializer/ComponentHandshakeSerializer.java +++ b/src/com/isode/stroke/serializer/ComponentHandshakeSerializer.java @@ -14,6 +14,7 @@ package com.isode.stroke.serializer; import com.isode.stroke.serializer.GenericElementSerializer; import com.isode.stroke.elements.ComponentHandshake; import com.isode.stroke.elements.Element; +import com.isode.stroke.base.SafeByteArray; public class ComponentHandshakeSerializer extends GenericElementSerializer { @@ -21,8 +22,8 @@ public class ComponentHandshakeSerializer extends GenericElementSerializer" + handshake.getData() + ""); + return new SafeByteArray("" + handshake.getData() + ""); } } \ No newline at end of file diff --git a/src/com/isode/stroke/serializer/CompressFailureSerializer.java b/src/com/isode/stroke/serializer/CompressFailureSerializer.java index 9bfa7e6..63dbf76 100644 --- a/src/com/isode/stroke/serializer/CompressFailureSerializer.java +++ b/src/com/isode/stroke/serializer/CompressFailureSerializer.java @@ -12,15 +12,16 @@ package com.isode.stroke.serializer; import com.isode.stroke.elements.CompressFailure; import com.isode.stroke.elements.Element; import com.isode.stroke.serializer.xml.XMLElement; +import com.isode.stroke.base.SafeByteArray; -class CompressFailureSerializer extends GenericElementSerializer { +public class CompressFailureSerializer extends GenericElementSerializer { public CompressFailureSerializer() { super(CompressFailure.class); } - public String serialize(Element element) { - return new XMLElement("failure", "http://jabber.org/protocol/compress").serialize(); + public SafeByteArray serialize(Element element) { + return new SafeByteArray(new XMLElement("failure", "http://jabber.org/protocol/compress").serialize()); } } diff --git a/src/com/isode/stroke/serializer/CompressRequestSerializer.java b/src/com/isode/stroke/serializer/CompressRequestSerializer.java index bb2328b..1377b7b 100644 --- a/src/com/isode/stroke/serializer/CompressRequestSerializer.java +++ b/src/com/isode/stroke/serializer/CompressRequestSerializer.java @@ -10,15 +10,16 @@ package com.isode.stroke.serializer; import com.isode.stroke.elements.CompressRequest; import com.isode.stroke.elements.Element; +import com.isode.stroke.base.SafeByteArray; -class CompressRequestSerializer implements ElementSerializer { +public class CompressRequestSerializer implements ElementSerializer { public CompressRequestSerializer() { } - public String serialize(Element element) { + public SafeByteArray serialize(Element element) { CompressRequest compressRequest = (CompressRequest) element; - return "" + compressRequest.getMethod() + ""; + return new SafeByteArray("" + compressRequest.getMethod() + ""); } public boolean canSerialize(Element element) { diff --git a/src/com/isode/stroke/serializer/ElementSerializer.java b/src/com/isode/stroke/serializer/ElementSerializer.java index 2c8c800..a08c531 100644 --- a/src/com/isode/stroke/serializer/ElementSerializer.java +++ b/src/com/isode/stroke/serializer/ElementSerializer.java @@ -10,8 +10,9 @@ package com.isode.stroke.serializer; import com.isode.stroke.elements.Element; +import com.isode.stroke.base.SafeByteArray; public interface ElementSerializer { - String serialize(Element element); + SafeByteArray serialize(Element element); boolean canSerialize(Element element); } diff --git a/src/com/isode/stroke/serializer/EnableStreamManagementSerializer.java b/src/com/isode/stroke/serializer/EnableStreamManagementSerializer.java index 7d984a6..f1cb90d 100644 --- a/src/com/isode/stroke/serializer/EnableStreamManagementSerializer.java +++ b/src/com/isode/stroke/serializer/EnableStreamManagementSerializer.java @@ -12,15 +12,16 @@ package com.isode.stroke.serializer; import com.isode.stroke.elements.Element; import com.isode.stroke.elements.EnableStreamManagement; import com.isode.stroke.serializer.xml.XMLElement; +import com.isode.stroke.base.SafeByteArray; -class EnableStreamManagementSerializer extends GenericElementSerializer { +public class EnableStreamManagementSerializer extends GenericElementSerializer { public EnableStreamManagementSerializer() { super(EnableStreamManagement.class); } - public String serialize(Element element) { - return new XMLElement("enable", "urn:xmpp:sm:2").serialize(); + public SafeByteArray serialize(Element element) { + return new SafeByteArray(new XMLElement("enable", "urn:xmpp:sm:2").serialize()); } } diff --git a/src/com/isode/stroke/serializer/GenericStanzaSerializer.java b/src/com/isode/stroke/serializer/GenericStanzaSerializer.java index 9bcd7e2..309a7c9 100644 --- a/src/com/isode/stroke/serializer/GenericStanzaSerializer.java +++ b/src/com/isode/stroke/serializer/GenericStanzaSerializer.java @@ -16,8 +16,12 @@ public abstract class GenericStanzaSerializer extends StanzaSe private final Class stanzaClass_; - GenericStanzaSerializer(Class stanzaClass, String tag, PayloadSerializerCollection payloadSerializers) { - super(tag, payloadSerializers); + public GenericStanzaSerializer(Class stanzaClass, String tag, PayloadSerializerCollection payloadSerializers) { + this(stanzaClass, tag, payloadSerializers, null); + } + + public GenericStanzaSerializer(Class stanzaClass, String tag, PayloadSerializerCollection payloadSerializers, String explicitNS) { + super(tag, payloadSerializers, explicitNS); stanzaClass_ = stanzaClass; } diff --git a/src/com/isode/stroke/serializer/IQSerializer.java b/src/com/isode/stroke/serializer/IQSerializer.java index 8e4e340..b97197c 100644 --- a/src/com/isode/stroke/serializer/IQSerializer.java +++ b/src/com/isode/stroke/serializer/IQSerializer.java @@ -14,7 +14,11 @@ import com.isode.stroke.serializer.xml.XMLElement; public class IQSerializer extends GenericStanzaSerializer { public IQSerializer(PayloadSerializerCollection payloadSerializers) { - super(IQ.class, "iq", payloadSerializers); + this(payloadSerializers, null); + } + + public IQSerializer(PayloadSerializerCollection payloadSerializers, String explicitNS) { + super(IQ.class, "iq", payloadSerializers, explicitNS); } @Override diff --git a/src/com/isode/stroke/serializer/MessageSerializer.java b/src/com/isode/stroke/serializer/MessageSerializer.java index e293f1e..f827194 100644 --- a/src/com/isode/stroke/serializer/MessageSerializer.java +++ b/src/com/isode/stroke/serializer/MessageSerializer.java @@ -11,7 +11,11 @@ import com.isode.stroke.serializer.xml.XMLElement; public class MessageSerializer extends GenericStanzaSerializer{ public MessageSerializer(PayloadSerializerCollection payloadSerializers) { - super(Message.class, "message", payloadSerializers); + this(payloadSerializers, null); + } + + public MessageSerializer(PayloadSerializerCollection payloadSerializers, String explicitNS) { + super(Message.class, "message", payloadSerializers, explicitNS); } @Override diff --git a/src/com/isode/stroke/serializer/PayloadSerializerCollection.java b/src/com/isode/stroke/serializer/PayloadSerializerCollection.java index b89ae87..9a5d604 100644 --- a/src/com/isode/stroke/serializer/PayloadSerializerCollection.java +++ b/src/com/isode/stroke/serializer/PayloadSerializerCollection.java @@ -21,6 +21,12 @@ public class PayloadSerializerCollection { } } + public void removeSerializer(PayloadSerializer serializer) { + while(serializers_.contains(serializer)) { + serializers_.remove(serializer); + } + } + public PayloadSerializer getPayloadSerializer(Payload payload) { synchronized (serializers_) { for (PayloadSerializer serializer : serializers_) { diff --git a/src/com/isode/stroke/serializer/PresenceSerializer.java b/src/com/isode/stroke/serializer/PresenceSerializer.java index 6611c8c..49d6db9 100644 --- a/src/com/isode/stroke/serializer/PresenceSerializer.java +++ b/src/com/isode/stroke/serializer/PresenceSerializer.java @@ -9,8 +9,13 @@ import com.isode.stroke.elements.Presence; import com.isode.stroke.serializer.xml.XMLElement; public class PresenceSerializer extends GenericStanzaSerializer { + public PresenceSerializer(PayloadSerializerCollection payloadSerializers) { - super(Presence.class, "presence", payloadSerializers); + this(payloadSerializers, null); +} + +public PresenceSerializer(PayloadSerializerCollection payloadSerializers, String explicitNS) { + super(Presence.class, "presence", payloadSerializers, explicitNS); } @Override diff --git a/src/com/isode/stroke/serializer/StanzaAckRequestSerializer.java b/src/com/isode/stroke/serializer/StanzaAckRequestSerializer.java index 0d6aed7..98314d8 100644 --- a/src/com/isode/stroke/serializer/StanzaAckRequestSerializer.java +++ b/src/com/isode/stroke/serializer/StanzaAckRequestSerializer.java @@ -12,15 +12,16 @@ package com.isode.stroke.serializer; import com.isode.stroke.elements.Element; import com.isode.stroke.elements.StanzaAckRequest; import com.isode.stroke.serializer.xml.XMLElement; +import com.isode.stroke.base.SafeByteArray; -class StanzaAckRequestSerializer extends GenericElementSerializer { +public class StanzaAckRequestSerializer extends GenericElementSerializer { public StanzaAckRequestSerializer() { super(StanzaAckRequest.class); } - public String serialize(Element element) { - return new XMLElement("r", "urn:xmpp:sm:2").serialize(); + public SafeByteArray serialize(Element element) { + return new SafeByteArray(new XMLElement("r", "urn:xmpp:sm:2").serialize()); } } diff --git a/src/com/isode/stroke/serializer/StanzaAckSerializer.java b/src/com/isode/stroke/serializer/StanzaAckSerializer.java index a909164..675a657 100644 --- a/src/com/isode/stroke/serializer/StanzaAckSerializer.java +++ b/src/com/isode/stroke/serializer/StanzaAckSerializer.java @@ -11,18 +11,19 @@ package com.isode.stroke.serializer; import com.isode.stroke.elements.Element; import com.isode.stroke.elements.StanzaAck; import com.isode.stroke.serializer.xml.XMLElement; +import com.isode.stroke.base.SafeByteArray; -class StanzaAckSerializer extends GenericElementSerializer { +public class StanzaAckSerializer extends GenericElementSerializer { public StanzaAckSerializer() { super(StanzaAck.class); } - public String serialize(Element element) { + public SafeByteArray serialize(Element element) { StanzaAck stanzaAck = (StanzaAck) element; assert stanzaAck.isValid(); XMLElement result = new XMLElement("a", "urn:xmpp:sm:2"); result.setAttribute("h", Long.toString(stanzaAck.getHandledStanzasCount())); - return result.serialize(); + return new SafeByteArray(result.serialize()); } } diff --git a/src/com/isode/stroke/serializer/StanzaSerializer.java b/src/com/isode/stroke/serializer/StanzaSerializer.java index 589d2e8..0837ff8 100644 --- a/src/com/isode/stroke/serializer/StanzaSerializer.java +++ b/src/com/isode/stroke/serializer/StanzaSerializer.java @@ -10,23 +10,39 @@ import com.isode.stroke.elements.Stanza; import com.isode.stroke.serializer.xml.XMLElement; import com.isode.stroke.serializer.xml.XMLRawTextNode; import java.util.logging.Logger; +import com.isode.stroke.base.SafeByteArray; public abstract class StanzaSerializer implements ElementSerializer { private final String tag_; private final PayloadSerializerCollection payloadSerializers_; + private String explicitDefaultNS_; private final Logger logger_ = Logger.getLogger(this.getClass().getName()); public StanzaSerializer(String tag, PayloadSerializerCollection payloadSerializers) { + this(tag, payloadSerializers, null); + } + + public StanzaSerializer(String tag, PayloadSerializerCollection payloadSerializers, String explicitNS) { payloadSerializers_ = payloadSerializers; tag_ = tag; + explicitDefaultNS_ = explicitNS; + } + + public SafeByteArray serialize(Element element) { + if (explicitDefaultNS_ != null) { + return serialize(element, explicitDefaultNS_); + } + else { + return serialize(element, ""); + } } - public String serialize(Element element) { + public SafeByteArray serialize(Element element, String xmlns) { assert element != null; assert payloadSerializers_ != null; Stanza stanza = (Stanza) element; - XMLElement stanzaElement = new XMLElement(tag_); + XMLElement stanzaElement = new XMLElement(tag_, (explicitDefaultNS_ != null) ? explicitDefaultNS_ : xmlns); if (stanza.getFrom() != null && stanza.getFrom().isValid()) { stanzaElement.setAttribute("from", stanza.getFrom().toString()); } @@ -53,7 +69,7 @@ public abstract class StanzaSerializer implements ElementSerializer { if (serializedPayloads.toString().length()!=0) { stanzaElement.addNode(new XMLRawTextNode(serializedPayloads.toString())); } - return stanzaElement.serialize(); + return new SafeByteArray(stanzaElement.serialize()); } public abstract void setStanzaSpecificAttributes(Element element, XMLElement xmlElement); diff --git a/src/com/isode/stroke/serializer/StartTLSFailureSerializer.java b/src/com/isode/stroke/serializer/StartTLSFailureSerializer.java index 276785a..7596e10 100644 --- a/src/com/isode/stroke/serializer/StartTLSFailureSerializer.java +++ b/src/com/isode/stroke/serializer/StartTLSFailureSerializer.java @@ -12,15 +12,16 @@ package com.isode.stroke.serializer; import com.isode.stroke.elements.Element; import com.isode.stroke.elements.StartTLSFailure; import com.isode.stroke.serializer.xml.XMLElement; +import com.isode.stroke.base.SafeByteArray; -class StartTLSFailureSerializer extends GenericElementSerializer { +public class StartTLSFailureSerializer extends GenericElementSerializer { public StartTLSFailureSerializer() { super(StartTLSFailure.class); } - public String serialize(Element element) { - return new XMLElement("failure", "urn:ietf:params:xml:ns:xmpp-tls").serialize(); + public SafeByteArray serialize(Element element) { + return new SafeByteArray(new XMLElement("failure", "urn:ietf:params:xml:ns:xmpp-tls").serialize()); } } diff --git a/src/com/isode/stroke/serializer/StartTLSRequestSerializer.java b/src/com/isode/stroke/serializer/StartTLSRequestSerializer.java index 0a7a782..cbdcb08 100644 --- a/src/com/isode/stroke/serializer/StartTLSRequestSerializer.java +++ b/src/com/isode/stroke/serializer/StartTLSRequestSerializer.java @@ -12,15 +12,16 @@ package com.isode.stroke.serializer; import com.isode.stroke.elements.Element; import com.isode.stroke.elements.StartTLSRequest; import com.isode.stroke.serializer.xml.XMLElement; +import com.isode.stroke.base.SafeByteArray; -class StartTLSRequestSerializer extends GenericElementSerializer { +public class StartTLSRequestSerializer extends GenericElementSerializer { public StartTLSRequestSerializer() { super(StartTLSRequest.class); } - public String serialize(Element element) { - return new XMLElement("starttls", "urn:ietf:params:xml:ns:xmpp-tls").serialize(); + public SafeByteArray serialize(Element element) { + return new SafeByteArray(new XMLElement("starttls", "urn:ietf:params:xml:ns:xmpp-tls").serialize()); } } diff --git a/src/com/isode/stroke/serializer/StreamErrorSerializer.java b/src/com/isode/stroke/serializer/StreamErrorSerializer.java index 2455efe..70fcd83 100644 --- a/src/com/isode/stroke/serializer/StreamErrorSerializer.java +++ b/src/com/isode/stroke/serializer/StreamErrorSerializer.java @@ -15,6 +15,7 @@ import com.isode.stroke.serializer.GenericElementSerializer; import com.isode.stroke.serializer.xml.XMLElement; import com.isode.stroke.elements.StreamError; import com.isode.stroke.elements.Element; +import com.isode.stroke.base.SafeByteArray; public class StreamErrorSerializer extends GenericElementSerializer { @@ -22,7 +23,7 @@ public class StreamErrorSerializer extends GenericElementSerializer super(StreamError.class); } - public String serialize(Element element) { + public SafeByteArray serialize(Element element) { StreamError error = (StreamError)element; XMLElement errorElement = new XMLElement("error", "http://etherx.jabber.org/streams"); @@ -60,6 +61,6 @@ public class StreamErrorSerializer extends GenericElementSerializer errorElement.addNode(new XMLElement("text", "urn:ietf:params:xml:ns:xmpp-streams", error.getText())); } - return errorElement.serialize(); + return new SafeByteArray(errorElement.serialize()); } } \ No newline at end of file diff --git a/src/com/isode/stroke/serializer/StreamFeaturesSerializer.java b/src/com/isode/stroke/serializer/StreamFeaturesSerializer.java index b5eb598..e1226f8 100644 --- a/src/com/isode/stroke/serializer/StreamFeaturesSerializer.java +++ b/src/com/isode/stroke/serializer/StreamFeaturesSerializer.java @@ -16,6 +16,7 @@ import com.isode.stroke.serializer.xml.XMLElement; import com.isode.stroke.serializer.xml.XMLTextNode; import com.isode.stroke.elements.StreamFeatures; import com.isode.stroke.elements.Element; +import com.isode.stroke.base.SafeByteArray; public class StreamFeaturesSerializer extends GenericElementSerializer { @@ -23,7 +24,7 @@ public class StreamFeaturesSerializer extends GenericElementSerializer { +public class StreamManagementEnabledSerializer extends GenericElementSerializer { public StreamManagementEnabledSerializer() { super(StreamManagementEnabled.class); } - public String serialize(Element el) { + public SafeByteArray serialize(Element el) { StreamManagementEnabled e = (StreamManagementEnabled) el; XMLElement element = new XMLElement("enabled", "urn:xmpp:sm:2"); if (!e.getResumeID().isEmpty()) { @@ -27,6 +28,6 @@ class StreamManagementEnabledSerializer extends GenericElementSerializer { +public class StreamManagementFailedSerializer extends GenericElementSerializer { public StreamManagementFailedSerializer() { super(StreamManagementFailed.class); } - public String serialize(Element element) { - return new XMLElement("failed", "urn:xmpp:sm:2").serialize(); + public SafeByteArray serialize(Element element) { + return new SafeByteArray(new XMLElement("failed", "urn:xmpp:sm:2").serialize()); } } diff --git a/src/com/isode/stroke/serializer/StreamResumeSerializer.java b/src/com/isode/stroke/serializer/StreamResumeSerializer.java index 5900ec0..bdfe980 100644 --- a/src/com/isode/stroke/serializer/StreamResumeSerializer.java +++ b/src/com/isode/stroke/serializer/StreamResumeSerializer.java @@ -12,21 +12,22 @@ package com.isode.stroke.serializer; import com.isode.stroke.elements.Element; import com.isode.stroke.elements.StreamResume; import com.isode.stroke.serializer.xml.XMLElement; +import com.isode.stroke.base.SafeByteArray; -class StreamResumeSerializer extends GenericElementSerializer { +public class StreamResumeSerializer extends GenericElementSerializer { public StreamResumeSerializer() { super(StreamResume.class); } - public String serialize(Element el) { + public SafeByteArray serialize(Element el) { StreamResume e = (StreamResume)el; XMLElement element = new XMLElement("resume", "urn:xmpp:sm:2"); element.setAttribute("previd", e.getResumeID()); if (e.getHandledStanzasCount() != null) { element.setAttribute("h", Long.toString(e.getHandledStanzasCount())); } - return element.serialize(); + return new SafeByteArray(element.serialize()); } } diff --git a/src/com/isode/stroke/serializer/StreamResumedSerializer.java b/src/com/isode/stroke/serializer/StreamResumedSerializer.java index d44d722..5f0a841 100644 --- a/src/com/isode/stroke/serializer/StreamResumedSerializer.java +++ b/src/com/isode/stroke/serializer/StreamResumedSerializer.java @@ -12,21 +12,22 @@ package com.isode.stroke.serializer; import com.isode.stroke.elements.Element; import com.isode.stroke.elements.StreamResumed; import com.isode.stroke.serializer.xml.XMLElement; +import com.isode.stroke.base.SafeByteArray; -class StreamResumedSerializer extends GenericElementSerializer { +public class StreamResumedSerializer extends GenericElementSerializer { public StreamResumedSerializer() { super(StreamResumed.class); } - public String serialize(Element el) { + public SafeByteArray serialize(Element el) { StreamResumed e = (StreamResumed)el; XMLElement element = new XMLElement("resumed", "urn:xmpp:sm:2"); element.setAttribute("previd", e.getResumeID()); if (e.getHandledStanzasCount() != null) { element.setAttribute("h", Long.toString(e.getHandledStanzasCount())); } - return element.serialize(); + return new SafeByteArray(element.serialize()); } } diff --git a/src/com/isode/stroke/serializer/TLSProceedSerializer.java b/src/com/isode/stroke/serializer/TLSProceedSerializer.java index 7f3d75a..640c3db 100644 --- a/src/com/isode/stroke/serializer/TLSProceedSerializer.java +++ b/src/com/isode/stroke/serializer/TLSProceedSerializer.java @@ -12,6 +12,7 @@ package com.isode.stroke.serializer; import com.isode.stroke.elements.Element; import com.isode.stroke.elements.TLSProceed; import com.isode.stroke.serializer.xml.XMLElement; +import com.isode.stroke.base.SafeByteArray; class TLSProceedSerializer extends GenericElementSerializer{ @@ -19,8 +20,8 @@ class TLSProceedSerializer extends GenericElementSerializer{ super(TLSProceed.class); } - public String serialize(Element element) { - return new XMLElement("proceed", "urn:ietf:params:xml:ns:xmpp-tls").serialize(); + public SafeByteArray serialize(Element element) { + return new SafeByteArray(new XMLElement("proceed", "urn:ietf:params:xml:ns:xmpp-tls").serialize()); } } diff --git a/src/com/isode/stroke/serializer/XMPPSerializer.java b/src/com/isode/stroke/serializer/XMPPSerializer.java index 2bf996b..cd7a4cd 100644 --- a/src/com/isode/stroke/serializer/XMPPSerializer.java +++ b/src/com/isode/stroke/serializer/XMPPSerializer.java @@ -12,17 +12,18 @@ import com.isode.stroke.elements.Element; import com.isode.stroke.elements.ProtocolHeader; import com.isode.stroke.elements.StreamType; import java.util.Vector; +import com.isode.stroke.base.SafeByteArray; public class XMPPSerializer { private final Vector serializers_ = new Vector(); private final StreamType type_; - public XMPPSerializer(PayloadSerializerCollection payloadSerializers, StreamType type) { + public XMPPSerializer(PayloadSerializerCollection payloadSerializers, StreamType type, boolean setExplictNSonTopLevelElements) { type_ = type; - serializers_.add(new PresenceSerializer(payloadSerializers)); - serializers_.add(new IQSerializer(payloadSerializers)); - serializers_.add(new MessageSerializer(payloadSerializers)); + serializers_.add(new PresenceSerializer(payloadSerializers, setExplictNSonTopLevelElements ? getDefaultNamespace() : null)); + serializers_.add(new IQSerializer(payloadSerializers, setExplictNSonTopLevelElements ? getDefaultNamespace() : null)); + serializers_.add(new MessageSerializer(payloadSerializers, setExplictNSonTopLevelElements ? getDefaultNamespace() : null)); serializers_.add(new CompressRequestSerializer()); serializers_.add(new CompressFailureSerializer()); serializers_.add(new AuthRequestSerializer()); @@ -33,8 +34,8 @@ public class XMPPSerializer { serializers_.add(new StartTLSRequestSerializer()); serializers_.add(new StartTLSFailureSerializer()); serializers_.add(new TLSProceedSerializer()); - //serializers_.add(new StreamFeaturesSerializer()); //TODO: Port - //serializers_.add(new StreamErrorSerializer()); //FIXME!!!: Port + serializers_.add(new StreamFeaturesSerializer()); + serializers_.add(new StreamErrorSerializer()); serializers_.add(new EnableStreamManagementSerializer()); serializers_.add(new StreamManagementEnabledSerializer()); serializers_.add(new StreamManagementFailedSerializer()); @@ -42,7 +43,7 @@ public class XMPPSerializer { serializers_.add(new StreamResumedSerializer()); serializers_.add(new StanzaAckSerializer()); serializers_.add(new StanzaAckRequestSerializer()); - //serializers_.add(new ComponentHandshakeSerializer()); + serializers_.add(new ComponentHandshakeSerializer()); } public String serializeHeader(ProtocolHeader header) { @@ -80,7 +81,7 @@ public class XMPPSerializer { return ""; } - public String serializeElement(Element element) { + public SafeByteArray serializeElement(Element element) { for (ElementSerializer serializer : serializers_) { if (serializer.canSerialize(element)) { return serializer.serialize(element); diff --git a/src/com/isode/stroke/serializer/payloadserializers/ForwardedSerializer.java b/src/com/isode/stroke/serializer/payloadserializers/ForwardedSerializer.java index 625205e..77ac5f1 100644 --- a/src/com/isode/stroke/serializer/payloadserializers/ForwardedSerializer.java +++ b/src/com/isode/stroke/serializer/payloadserializers/ForwardedSerializer.java @@ -41,11 +41,11 @@ public class ForwardedSerializer extends GenericPayloadSerializer { if (payload.getStanza() != null) { /* find out what type of stanza we are dealing with and branch into the correct serializer */ if (payload.getStanza() instanceof IQ) { - element.addNode(new XMLRawTextNode((new IQSerializer(serializers_)).serialize((IQ)payload.getStanza()))); + element.addNode(new XMLRawTextNode((new IQSerializer(serializers_)).serialize((IQ)payload.getStanza()).toString())); } else if (payload.getStanza() instanceof Message) { - element.addNode(new XMLRawTextNode((new MessageSerializer(serializers_)).serialize((Message)payload.getStanza()))); + element.addNode(new XMLRawTextNode((new MessageSerializer(serializers_)).serialize((Message)payload.getStanza()).toString())); } else if (payload.getStanza() instanceof Presence) { - element.addNode(new XMLRawTextNode((new PresenceSerializer(serializers_)).serialize((Presence)payload.getStanza()))); + element.addNode(new XMLRawTextNode((new PresenceSerializer(serializers_)).serialize((Presence)payload.getStanza()).toString())); } } diff --git a/src/com/isode/stroke/serializer/payloadserializers/FullPayloadSerializerCollection.java b/src/com/isode/stroke/serializer/payloadserializers/FullPayloadSerializerCollection.java index ac093c0..dff8f6b 100644 --- a/src/com/isode/stroke/serializer/payloadserializers/FullPayloadSerializerCollection.java +++ b/src/com/isode/stroke/serializer/payloadserializers/FullPayloadSerializerCollection.java @@ -15,8 +15,6 @@ import com.isode.stroke.serializer.PayloadSerializerCollection; public class FullPayloadSerializerCollection extends PayloadSerializerCollection { public FullPayloadSerializerCollection() { - /*FIXME: Implement what's needed. */ - //addSerializer(new IBBSerializer()); addSerializer(new BodySerializer()); addSerializer(new SubjectSerializer()); addSerializer(new ChatStateSerializer()); diff --git a/src/com/isode/stroke/streamstack/XMPPLayer.java b/src/com/isode/stroke/streamstack/XMPPLayer.java index 2042bb0..4e7a265 100644 --- a/src/com/isode/stroke/streamstack/XMPPLayer.java +++ b/src/com/isode/stroke/streamstack/XMPPLayer.java @@ -35,18 +35,27 @@ public class XMPPLayer implements HighLayer, XMPPParserClient { private XMPPSerializer xmppSerializer_; private boolean resetParserAfterParse_; private boolean inParser_; + private boolean setExplictNSonTopLevelElements_; - public XMPPLayer( PayloadParserFactoryCollection payloadParserFactories, PayloadSerializerCollection payloadSerializers, StreamType streamType) { + this(payloadParserFactories, payloadSerializers, streamType, false); + } + + public XMPPLayer( + PayloadParserFactoryCollection payloadParserFactories, + PayloadSerializerCollection payloadSerializers, + StreamType streamType, + boolean setExplictNSonTopLevelElements) { payloadParserFactories_ = payloadParserFactories; payloadSerializers_ = payloadSerializers; + setExplictNSonTopLevelElements_ = setExplictNSonTopLevelElements; resetParserAfterParse_ = false; inParser_ = false; xmppParser_ = new XMPPParser(this, payloadParserFactories_); - xmppSerializer_ = new XMPPSerializer(payloadSerializers_, streamType); + xmppSerializer_ = new XMPPSerializer(payloadSerializers_, streamType, setExplictNSonTopLevelElements); } public void writeHeader(ProtocolHeader header) { diff --git a/src/com/isode/stroke/stringcodecs/Base64.java b/src/com/isode/stroke/stringcodecs/Base64.java index e19bb5d..efd61be 100644 --- a/src/com/isode/stroke/stringcodecs/Base64.java +++ b/src/com/isode/stroke/stringcodecs/Base64.java @@ -5,6 +5,7 @@ package com.isode.stroke.stringcodecs; import com.isode.stroke.base.ByteArray; +import com.isode.stroke.base.SafeByteArray; public class Base64 { /* FIXME: Check license is ok (it is, it's BSD) */ @@ -16,6 +17,10 @@ public class Base64 { return Base64BSD.encodeToString(input.getData(), false); } + public static SafeByteArray encode(SafeByteArray input) { + return new SafeByteArray(Base64BSD.encodeToString(input.getData(), false)); + } + public static String encode(byte[] input) { return Base64BSD.encodeToString(input, false); } diff --git a/test/com/isode/stroke/sasl/SCRAMSHA1ClientAuthenticatorTest.java b/test/com/isode/stroke/sasl/SCRAMSHA1ClientAuthenticatorTest.java index 44a179e..7217d8d 100644 --- a/test/com/isode/stroke/sasl/SCRAMSHA1ClientAuthenticatorTest.java +++ b/test/com/isode/stroke/sasl/SCRAMSHA1ClientAuthenticatorTest.java @@ -9,6 +9,7 @@ package com.isode.stroke.sasl; import com.isode.stroke.base.ByteArray; +import com.isode.stroke.base.SafeByteArray; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -25,7 +26,7 @@ public class SCRAMSHA1ClientAuthenticatorTest { SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefghABCDEFGH"); testling.setCredentials("user", "pass", ""); - ByteArray response = testling.getResponse(); + SafeByteArray response = testling.getResponse(); assertEquals(new ByteArray("n,,n=user,r=abcdefghABCDEFGH"), response); } @@ -35,7 +36,7 @@ public class SCRAMSHA1ClientAuthenticatorTest { SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefghABCDEFGH"); testling.setCredentials(",us=,er=", "pass", ""); - ByteArray response = testling.getResponse(); + SafeByteArray response = testling.getResponse(); assertEquals(new ByteArray("n,,n==2Cus=3D=2Cer=3D,r=abcdefghABCDEFGH"), response); } @@ -45,7 +46,7 @@ public class SCRAMSHA1ClientAuthenticatorTest { SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefghABCDEFGH"); testling.setCredentials("user", "pass", "auth"); - ByteArray response = testling.getResponse(); + SafeByteArray response = testling.getResponse(); assertEquals(new ByteArray("n,a=auth,n=user,r=abcdefghABCDEFGH"), response); } @@ -55,7 +56,7 @@ public class SCRAMSHA1ClientAuthenticatorTest { SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefghABCDEFGH"); testling.setCredentials("user", "pass", "a=u,th"); - ByteArray response = testling.getResponse(); + SafeByteArray response = testling.getResponse(); assertEquals(new ByteArray("n,a=a=3Du=2Cth,n=user,r=abcdefghABCDEFGH"), response); } @@ -66,7 +67,7 @@ public class SCRAMSHA1ClientAuthenticatorTest { testling.setTLSChannelBindingData(new ByteArray("xyza")); testling.setCredentials("user", "pass", ""); - ByteArray response = testling.getResponse(); + SafeByteArray response = testling.getResponse(); assertEquals(new ByteArray("y,,n=user,r=abcdefghABCDEFGH"), response); } @@ -77,7 +78,7 @@ public class SCRAMSHA1ClientAuthenticatorTest { testling.setTLSChannelBindingData(new ByteArray("xyza")); testling.setCredentials("user", "pass", ""); - ByteArray response = testling.getResponse(); + SafeByteArray response = testling.getResponse(); assertEquals(new ByteArray("p=tls-unique,,n=user,r=abcdefghABCDEFGH"), response); } @@ -88,7 +89,7 @@ public class SCRAMSHA1ClientAuthenticatorTest { testling.setCredentials("user", "pass", ""); assertTrue(testling.setChallenge(new ByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096"))); - ByteArray response = testling.getResponse(); + SafeByteArray response = testling.getResponse(); assertEquals(new ByteArray("c=biws,r=abcdefghABCDEFGH,p=CZbjGDpIteIJwQNBgO0P8pKkMGY="), response); } @@ -100,7 +101,7 @@ public class SCRAMSHA1ClientAuthenticatorTest { testling.setTLSChannelBindingData(new ByteArray("xyza")); testling.setChallenge(new ByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096")); - ByteArray response = testling.getResponse(); + SafeByteArray response = testling.getResponse(); assertEquals(new ByteArray("c=eSws,r=abcdefghABCDEFGH,p=JNpsiFEcxZvNZ1+FFBBqrYvYxMk="), response); } @@ -112,7 +113,7 @@ public class SCRAMSHA1ClientAuthenticatorTest { testling.setTLSChannelBindingData(new ByteArray("xyza")); testling.setChallenge(new ByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096")); - ByteArray response = testling.getResponse(); + SafeByteArray response = testling.getResponse(); assertEquals(new ByteArray("c=cD10bHMtdW5pcXVlLCx4eXph,r=abcdefghABCDEFGH,p=i6Rghite81P1ype8XxaVAa5l7v0="), response); } diff --git a/test/com/isode/stroke/serializer/AuthChallengeSerializerTest.java b/test/com/isode/stroke/serializer/AuthChallengeSerializerTest.java index 44ed1b8..cc1523b 100644 --- a/test/com/isode/stroke/serializer/AuthChallengeSerializerTest.java +++ b/test/com/isode/stroke/serializer/AuthChallengeSerializerTest.java @@ -16,6 +16,7 @@ import org.junit.Test; import com.isode.stroke.serializer.AuthChallengeSerializer; import com.isode.stroke.elements.AuthChallenge; import com.isode.stroke.base.ByteArray; +import com.isode.stroke.base.SafeByteArray; public class AuthChallengeSerializerTest { @@ -33,9 +34,9 @@ public class AuthChallengeSerializerTest { authChallenge.setValue(new ByteArray("foo")); assertEquals( - "" + + new SafeByteArray("" + "Zm9v" + - "", testling.serialize(authChallenge)); + ""), testling.serialize(authChallenge)); } @Test @@ -44,7 +45,7 @@ public class AuthChallengeSerializerTest { AuthChallenge authChallenge = new AuthChallenge(); assertEquals( - "", testling.serialize(authChallenge)); + new SafeByteArray(""), testling.serialize(authChallenge)); } @Test @@ -54,8 +55,8 @@ public class AuthChallengeSerializerTest { authChallenge.setValue(new ByteArray()); assertEquals( - "" + + new SafeByteArray("" + "=" + - "", testling.serialize(authChallenge)); + ""), testling.serialize(authChallenge)); } } \ No newline at end of file diff --git a/test/com/isode/stroke/serializer/AuthRequestSerializerTest.java b/test/com/isode/stroke/serializer/AuthRequestSerializerTest.java index eae4354..69d4442 100644 --- a/test/com/isode/stroke/serializer/AuthRequestSerializerTest.java +++ b/test/com/isode/stroke/serializer/AuthRequestSerializerTest.java @@ -16,6 +16,7 @@ import org.junit.Test; import com.isode.stroke.serializer.AuthRequestSerializer; import com.isode.stroke.elements.AuthRequest; import com.isode.stroke.base.ByteArray; +import com.isode.stroke.base.SafeByteArray; public class AuthRequestSerializerTest { @@ -30,12 +31,12 @@ public class AuthRequestSerializerTest { public void testSerialize() { AuthRequestSerializer testling = new AuthRequestSerializer(); AuthRequest authRequest = new AuthRequest("PLAIN"); - authRequest.setMessage(new ByteArray("foo")); + authRequest.setMessage(new SafeByteArray("foo")); assertEquals( - "" + + new SafeByteArray("" + "Zm9v" + - "", testling.serialize(authRequest)); + ""), testling.serialize(authRequest)); } @Test @@ -44,19 +45,19 @@ public class AuthRequestSerializerTest { AuthRequest authRequest = new AuthRequest("PLAIN"); assertEquals( - "" + - "", testling.serialize(authRequest)); + new SafeByteArray("" + + ""), testling.serialize(authRequest)); } @Test public void testSerialize_EmptyMessage() { AuthRequestSerializer testling = new AuthRequestSerializer(); AuthRequest authRequest = new AuthRequest("PLAIN"); - authRequest.setMessage(new ByteArray()); + authRequest.setMessage(new SafeByteArray()); assertEquals( - "" + + new SafeByteArray("" + "=" + - "", testling.serialize(authRequest)); + ""), testling.serialize(authRequest)); } } \ No newline at end of file diff --git a/test/com/isode/stroke/serializer/AuthResponseSerializerTest.java b/test/com/isode/stroke/serializer/AuthResponseSerializerTest.java index 9b0fe71..a80dc81 100644 --- a/test/com/isode/stroke/serializer/AuthResponseSerializerTest.java +++ b/test/com/isode/stroke/serializer/AuthResponseSerializerTest.java @@ -16,6 +16,7 @@ import org.junit.Test; import com.isode.stroke.serializer.AuthResponseSerializer; import com.isode.stroke.elements.AuthResponse; import com.isode.stroke.base.ByteArray; +import com.isode.stroke.base.SafeByteArray; public class AuthResponseSerializerTest { @@ -30,12 +31,12 @@ public class AuthResponseSerializerTest { public void testSerialize() { AuthResponseSerializer testling = new AuthResponseSerializer(); AuthResponse authResponse = new AuthResponse(); - authResponse.setValue(new ByteArray("foo")); + authResponse.setValue(new SafeByteArray("foo")); assertEquals( - "" + + new SafeByteArray("" + "Zm9v" + - "", testling.serialize(authResponse)); + ""), testling.serialize(authResponse)); } @Test @@ -44,19 +45,19 @@ public class AuthResponseSerializerTest { AuthResponse authResponse = new AuthResponse(); assertEquals( - "" + - "", testling.serialize(authResponse)); + new SafeByteArray("" + + ""), testling.serialize(authResponse)); } @Test public void testSerialize_EmptyMessage() { AuthResponseSerializer testling = new AuthResponseSerializer(); AuthResponse authResponse = new AuthResponse(); - authResponse.setValue(new ByteArray()); + authResponse.setValue(new SafeByteArray()); assertEquals( - "" + + new SafeByteArray("" + "" + - "", testling.serialize(authResponse)); + ""), testling.serialize(authResponse)); } } \ No newline at end of file diff --git a/test/com/isode/stroke/serializer/AuthSuccessSerializerTest.java b/test/com/isode/stroke/serializer/AuthSuccessSerializerTest.java index ee9b595..198080b 100644 --- a/test/com/isode/stroke/serializer/AuthSuccessSerializerTest.java +++ b/test/com/isode/stroke/serializer/AuthSuccessSerializerTest.java @@ -16,6 +16,7 @@ import org.junit.Test; import com.isode.stroke.serializer.AuthSuccessSerializer; import com.isode.stroke.elements.AuthSuccess; import com.isode.stroke.base.ByteArray; +import com.isode.stroke.base.SafeByteArray; public class AuthSuccessSerializerTest { @@ -33,9 +34,9 @@ public class AuthSuccessSerializerTest { authSuccess.setValue(new ByteArray("foo")); assertEquals( - "" + + new SafeByteArray("" + "Zm9v" + - "", testling.serialize(authSuccess)); + ""), testling.serialize(authSuccess)); } @Test @@ -44,8 +45,8 @@ public class AuthSuccessSerializerTest { AuthSuccess authSuccess = new AuthSuccess(); assertEquals( - "" + - "", testling.serialize(authSuccess)); + new SafeByteArray("" + + ""), testling.serialize(authSuccess)); } @Test @@ -55,8 +56,8 @@ public class AuthSuccessSerializerTest { authSuccess.setValue(new ByteArray()); assertEquals( - "" + + new SafeByteArray("" + "=" + - "", testling.serialize(authSuccess)); + ""), testling.serialize(authSuccess)); } } \ No newline at end of file diff --git a/test/com/isode/stroke/serializer/StreamFeaturesSerializerTest.java b/test/com/isode/stroke/serializer/StreamFeaturesSerializerTest.java index 67d9bb0..76696b5 100644 --- a/test/com/isode/stroke/serializer/StreamFeaturesSerializerTest.java +++ b/test/com/isode/stroke/serializer/StreamFeaturesSerializerTest.java @@ -15,6 +15,7 @@ import static org.junit.Assert.assertEquals; import org.junit.Test; import com.isode.stroke.serializer.StreamFeaturesSerializer; import com.isode.stroke.elements.StreamFeatures; +import com.isode.stroke.base.SafeByteArray; public class StreamFeaturesSerializerTest { @@ -40,7 +41,7 @@ public class StreamFeaturesSerializerTest { streamFeatures.setHasRosterVersioning(); assertEquals( - "" + new SafeByteArray("" + "" + "" + "zlib" @@ -54,6 +55,6 @@ public class StreamFeaturesSerializerTest { + "" + "" + "" - + "", testling.serialize(streamFeatures)); + + ""), testling.serialize(streamFeatures)); } } \ No newline at end of file -- cgit v0.10.2-6-g49f6