xml-not-well-formed error in when I try to bind resource in XMPP over Bosh - xmpp

1 Problem: I am getting xml not well formed error, when I try to bind resource in XMPP over Bosh.
What I tried: I went to xmpp.org to look for proper xml stanza for binding resource(http://xmpp.org/extensions/xep-0206.html#preconditions-sasl), but it seems similar.
Possible answer: I havn't restarted the stream after authentication, can that be the cause of this error?
2 problem: I tried to restart the stream by using the packet(http://xmpp.org/extensions/xep-0206.html#preconditions-sasl) but I got 400 in response code? Any body has any idea why I got that?
Possible answer: I didn't get xmpp:restartLogic attribute in response to initial packet? Can that be the reason for getting 400 error(May be Ejabbered server doesn't support restart)?
Doubt: Anyone got any idea on how to enable restartlogic in Ejabberd or is it enabled by default?
My Log is as follow:
Stanza to read is = body xmlns='http://jabber.org/protocol/httpbind' sid='8d96d01bb87f526e78b0f0b620dd1c94edd172ee' wait='30' requests='2' inactivity='30' maxpause='120' polling='2' ver='1.8' from='someserver.com' secure='true' authid='2817580747' xmlns:xmpp='urn:xmpp:xbosh' xmlns:stream='http://etherx.jabber.org/streams' xmpp:version='1.0'
Stanza to read is = stream:features xmlns:stream='http://etherx.jabber.org/streams'
Stanza to read is = mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'
Stanza to read is = mechanism
Stanza to read is = c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://www.process-one.net/en/ejabberd/' ver='U5DC02T7iwEqfov5b3KpIVgA5+I='/
Stanza to read is = register xmlns='http://jabber.org/features/iq-register'/
Session creation response received: body secure=true requests=2 inactivity=30 authid=2817580747 sid=8d96d01bb87f526e78b0f0b620dd1c94edd172ee polling=2 xmlns=http://jabber.org/protocol/httpbind wait=30 xmpp=urn:xmpp:xbosh ver=1.8 version=1.0 from=someserver.com stream=http://etherx.jabber.org/streams maxpause=120 ==
features stream=http://etherx.jabber.org/streams ==
mechanisms xmlns=urn:ietf:params:xml:ns:xmpp-sasl ==
mechanism == PLAIN
mechanism == DIGEST-MD5
mechanism == SCRAM-SHA-1
c ver=U5DC02T7iwEqfov5b3KpIVgA5+I= node=http://www.process-one.net/en/ejabberd/ hash=sha-1 xmlns=http://jabber.org/protocol/caps ==
register xmlns=http://jabber.org/features/iq-register ==
Authenticating: body secure=true requests=2 inactivity=30 authid=2817580747 sid=8d96d01bb87f526e78b0f0b620dd1c94edd172ee polling=2 xmlns=http://jabber.org/protocol/httpbind wait=30 xmpp=urn:xmpp:xbosh ver=1.8 version=1.0 from=someserver.com stream=http://etherx.jabber.org/streams maxpause=120 ==
features stream=http://etherx.jabber.org/streams ==
mechanisms xmlns=urn:ietf:params:xml:ns:xmpp-sasl ==
mechanism == PLAIN
mechanism == DIGEST-MD5
mechanism == SCRAM-SHA-1
c ver=U5DC02T7iwEqfov5b3KpIVgA5+I= node=http://www.process-one.net/en/ejabberd/ hash=sha-1 xmlns=http://jabber.org/protocol/caps ==
register xmlns=http://jabber.org/features/iq-register ==
Using plain authorization
writtenToAir [0]: AE1haGlAdGVzdC5yYXBpZHNvZnR0ZWNobm9sb2d5LmNvbQBtYWhp
Starting PLAIN authorization
Stanza to read is = body xmlns='http://jabber.org/protocol/httpbind'
Stanza to read is = success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/
writtenToAir [0]: Resource
Binding resource
Stanza to read is = body type='terminate' condition='remote-stream-error' xmlns='http://jabber.org/protocol/httpbind' xmlns:stream='http://etherx.jabber.org/streams'
Stanza to read is = stream:error
Stanza to read is = xml-not-well-formed xmlns='urn:ietf:params:xml:ns:xmpp-streams'/

Related

How can I set a specific (Content-Type) HTTP response header by configuring undertow?

Summary
I'm implementing a web service, that is deployed on a Wildfly-15 application server. I'd like to have the Content-Type HTTP response header to include charset=UTF-8. This is necessary for the client to understand my response.
Details
One of my clients always sends its request without specifying charset in Content-Type. Wildfly's web service stack in this case uses the default charset=ISO-8859-1 in the response. See this behavior in undertow code, lines 602-611:
private String extractCharset(HeaderMap headers) {
String contentType = headers.getFirst(Headers.CONTENT_TYPE);
if (contentType != null) {
String value = Headers.extractQuotedValueFromHeader(contentType, "charset");
if (value != null) {
return value;
}
}
return ISO_8859_1;
}
Because my response is, in fact, UTF-8-encoded (and its need to be), this causes trouble on the client side. See the header dumps in the undertow log:
----------------------------REQUEST---------------------------
header=Connection=Keep-Alive
header=SOAPAction=****
header=Accept-Encoding=gzip,deflate
header=Content-Type=text/xml
header=Content-Length=2137
header=User-Agent=Apache-HttpClient/4.1.1 (java 1.5)
header=Host=****
locale=[]
method=POST
....
--------------------------RESPONSE--------------------------
header=Connection=keep-alive
header=Content-Type=text/xml;charset=ISO-8859-1
header=Content-Length=1553
header=Date=Tue, 29 Jan 2019 16:19:38 GMT
status=200
This kind of response leads to the following exception in an IBM Websphere application:
org.springframework.ws.InvalidXmlException: Could not parse XML; nested exception is org.xml.sax.SAXParseException: An invalid XML character (Unicode: 0xffffffff) was found in the element content of the document.
Unfortunately, modifying the client is not an option.
Unsuccessful experiments
My efforts so far went into trying to configure Widlfy's undertow via specifying filters to override HTTP Response headers. I was able to set Content-Encoding only, with the help of Response Header filter. It seems, the Content-Type header is overridden somewhere else along the line.
My second guess was to use Expression Filter with the expression
header(header=Content-Type, value='text/xml;charset=UTF-8')
Unfortunately, it didn't work also.
Question
Can this problem be solved by the configuration of undertow?
Or should I somehow (how?) programmatically set the HTTP response header to include charset=UTF-8?

How to get MAM message ID of sent messages?

I am using eJabberd server (MAM enabled) with client library Strophe.js. Client app is storing fixed amount of the messages in local storage.
All the messages, that I receive from the server include elements <archived/> and <stanza-id/>, which provide server-side generated IDs:
<message
xmlns="jabber:client" to="aaa#example.net/8667085700924567016834" from="aaa#example.net">
<result
xmlns="urn:xmpp:mam:2" id="1520510373346685">
<forwarded
xmlns="urn:xmpp:forward:0">
<message
xmlns="jabber:client" xml:lang="en" to="bbb#example.net" from="aaa#example.net/60965696931000870402419" type="chat">
<archived
xmlns="urn:xmpp:mam:tmp" by="aaa#example.net" id="1520510373346685"/>
<stanza-id
xmlns="urn:xmpp:sid:0" by="aaa#example.net" id="1520510373346685"/>
<body>asdf</body>
</message>
<delay
xmlns="urn:xmpp:delay" from="example.net" stamp="2018-03-08T11:59:33.346685Z"/>
</forwarded>
</result>
</message>
I use these IDs to get fixed amount of messages on each MAM call (using RSM paging - before/after/max attributes). For example:
params = {
"before": "1520510373346685",
"max": 10,
onMessage: <some handler>,
onComplete: <some handler>,
}
this.connection.mam.query(Strophe.getBareJidFromJid(this.myJid), params);
This gets me 10 messages before the message with stanza-id 1520510373346685.
However, the messages I send inherently do not have this ID, until I send them and retrieve from MAM.
I did not find any examples on getting the currently sent message ID from the server, and the Strophe does not provide any callbacks after the message was sent from the client and received by the server.
So, the question - is there any way to get the server-generated message ID (stanza-id/archived) for the currently sent message?
Maybe my own approach is wrong - should I generate my own IDs and add it to each message from the client?
There is currently no mechanism specified besides querying the archive. One prominent idea within the XMPP community to solve this in the future is to reflect the send carbon back to the original sender, which would include a stanza-id element with the ID assigned by the archive.

SOAP header for authentication in Notes/Domino

I need to consume a WS that requires client (machine) certificate. More precisely it uses WS-Security : SOAP Message Security, WS-Security : X.509 Certificate Token Profile as defined by http://docs.oasis-open.org/wss-m/wss/v1.1.1/os/wss-SOAPMessageSecurity-v1.1.1-os.html
Using the native consumer, Domino don't add (magically) the authentication in the SOAP header. Now how I'm supposed to do add the security in header? Ideally in LotusScript...
I don't see anyway to embed the Consumer in my own header or enrich the existing consumer. I join the IBM response on this.
So my question:
Is there a work around to do this in Lotusscript ?
did some of you done something like this in java (and I will probably make an LS2J since a lot of LotusScript code already exists when I will get (hopefully) the response from the WS
IBM response:
We understand that you are attempting to use SOAP header for authentication. Unfortunately this is currently not supported.
For your reference, we have at least two Enhancement Requests (that I could find in this area) that are related to this topic:
SPR # SODY9H6BTM: Creating Your Own Soap Objects Does Not Support Client Certificate Authentication In A Web Agent.
SPR # JSHN7A3MLP: Authentication data in the Header element of WS Consumer SOAP envelopes
Unfortunately there is nothing further we can do in Support at this time.
If I understood your problem correctly you do not know how to deal with SOAP header and if so there are 2 things you may want to know:
1) Passing session using native Domino consumer approach. See example below
TestServiceLocator service = new TestServiceLocator();
TestPort port = service.getTestPort();
// that would tell to save cookie session between calls
((javax.xml.rpc.Stub)port)._setProperty(javax.xml.rpc.Stub.SESSION_MAINTAIN_PROPERTY, Boolean.TRUE);
2) If it does not work for you, you may try to use native SOAP approach. I've blogged about that recently: SOAP and passing session
// Create SOAP Connection
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();
// connect to webserivce
SOAPMessage soapResponse = soapConnection.call(connect(username, password), url);
// read cookie from response and use it when send another requests
MimeHeaders session = soapResponse.getMimeHeaders();
String sesisonCookie = session.getHeader("Set-Cookie")[0];
SOAPMessage soapResponse2 = soapConnection.call(customerGetAll(sesisonCookie), url);
soapConnection.close();
and than imagine you are in customGetAll method
SOAPBody soapBody = envelope.getBody();
SOAPElement soapBodyElem = soapBody.addChildElement("Customer_GetAll", "m");
soapMessage.getMimeHeaders().addHeader("Cookie", sesisonCookie);
soapMessage.saveChanges();
Hope it will help.

Use GWT RPC Serialization to send an object from client to server in a POST

I prefer to use RPC Serialization but then send data using servlets.
We have strangely found that this performs better and it allows us to have general logic for retrying all servlet calls for example.
I have figured out how to send an object from server to client but can't find a way to serialize on client and deserialize on server.
SERVER TO CLIENT
Server:
serializedObj = RPC.encodeResponseForSuccess(DUMMY_METHOD_OF_TYPE_SERIZABLE, object);
Client:
GWT.create(MyRpc.class).createStreamReader(serializedObj).readObject();
CLIENT TO SERVER
Client:
SerializationStreamWriter streamWriter = streamFactory.createStreamWriter();
streamWriter.writeObject(object);
serializedObj = streamWriter.toString();
But how can I unserialize this after sending it by POST to the server?
Thanks!
http://softteco.blogspot.com/2010/02/serializing-objects-in-gwt-and.html
Note the server side deserialize option
// Getting parameter from request
String content = request.getParameter("content");
// Initializing stream reader
ServerSerializationStreamReader streamReader = new ServerSerializationStreamReader(
Thread.currentThread().getContextClassLoader(), null);
// Filling stream reader with data
streamReader.prepareToRead(content);
// Reading deserialized object from the stream
dto = (D) streamReader.readObject();

Openfire prebind + robbiehanson/XMPPFramework using BOSH not working

We're trying to implement XMPP over BOSH for our product. The Strophe.js javascript library works fine for our needs on the WWW site. We request a prebind, it's delivered and then we use Strophe's 'attach' method to start our session - then we're able to update presence and send/receive messages. On the iOS side of things, we're using the robbiehanson XMPPFramework which includes a BOSH transport, but there's no attach method. Below is some of my grief with trying to get this to work.
I prebind, get my sid/jid/rid, then set the internal logic inside the bosh transport and other files to say that we're already connected. Then if I try to update presence, including the given SID, I send:
BOSH: SEND[1248340729] = < body xmlns="http://jabber.org/protocol/httpbind" sid="568a3ae9" ack="1248340728" rid="1248340729">< presence>< /presence>< /body>
but don't get any reply atall. That's the last of it. If I try to update presence without specifying SID, I send:
BOSH: SEND[1064338700] = < body xmlns="http://jabber.org/protocol/httpbind" ack="1064338699" rid="1064338700">< presence>< /presence>< /body>
and get back:
BOSH: RECD[1342811427] = < body xmlns="http://jabber.org/protocol/httpbind" xmlns:stream="http://etherx.jabber.org/streams" authid="9ef0ccdb" sid="9ef0ccdb" secure="true" requests="2" inactivity="300" polling="5" wait="60">< stream:features>< mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"> < mechanism>PLAIN< /mechanism>< /mechanisms>< compression xmlns="http://jabber.org/features/compress">< method>zlib< /method>< /compression>< bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/>< session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>< /stream:features>< /body>
which looks like a connection affirmation, or a connection challenge stanza expecting me to respond with the PLAIN information - but this has already been established with the prebind. If it is a connection affirmation, then the next lines don't make sense. If using the SID provided by the connection string above, as if it's an affirmation (I'm not sure), these are the next lines:
BOSH: SEND[1342811427] = < body xmlns="http://jabber.org/protocol/httpbind" sid="9ef0ccdb" rid="1342811428">< iq type="set">< bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">< resource>api< /resource>< /bind>< /iq>< /body>
BOSH: RECD[1342811427] = < body xmlns='http://jabber.org/protocol/httpbind'>< iq xmlns="jabber:client" type="error" to="chat.*.com/9ef0ccdb">< bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">< resource>api< /resource>< /bind>< error code="401" type="auth">< not-authorized xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>< /error>< /iq>< /body>
I'm not authorized. Now if I try using the SID that was negotiated during prebind, the last two lines are different:
BOSH: SEND[1172064714] = < body xmlns="http://jabber.org/protocol/httpbind" sid="27e3745b" rid="1172064715">< iq type="set">< resource>api< /resource>< /bind>< /iq>< /body>
BOSH: RECD[1172064714] = < body xmlns="http://jabber.org/protocol/httpbind">< /body>
an empty response. Then if I try updating my presence again, it gives me a literal 404 page saying there's an invalid SID. When I was using the SID provided by openfire, if I re-tried the presence update, it would just keep on giving me 401 not authorized.
Any help would be greatly appreciated.