Openfire prebind + robbiehanson/XMPPFramework using BOSH not working - iphone

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.

Related

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.

Accessing Docker daemon with Rust doesn't work [duplicate]

I'm trying to issue a GET command to my local server using netcat by doing the following:
echo -e "GET / HTTP/1.1\nHost: localhost" | nc localhost 80
Unfortunately, I get a HTTP/1.1 400 Bad Request response for this. What, at the very minimum, is required for a HTTP request?
if the request is: "GET / HTTP/1.0\r\n\r\n" then the response contains header as well as body, and the connection closes after the response.
if the request is:"GET / HTTP/1.1\r\nHost: host:port\r\nConnection: close\r\n\r\n"
then the response contains header as well as body, and the connection closes after the response.
if the request is:"GET / HTTP/1.1\r\nHost: host:port\r\n\r\n" then the response contains header as well as body, and the connection will not close even after the response.
if your request is: "GET /\r\n\r\n" then the response contains no header and only body, and the connection closes after the response.
if your request is: "HEAD / HTTP/1.0\r\n\r\n" then the response contains only header and no body, and the connection closes after the response.
if the request is: "HEAD / HTTP/1.1\r\nHost: host:port\r\nConnection: close\r\n\r\n" then the response contains only header and no body, and the connection closes after the response.
if the request is: "HEAD / HTTP/1.1\r\nHost: host:port\r\n\r\n" then the response contains only header and no body, and the connection will not close after the response.
It must use CRLF line endings, and it must end in \r\n\r\n, i.e. a blank line. This is what I use:
printf 'GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: close\r\n\r\n' |
nc www.example.com 80
Additionally, I prefer printf over echo, and I add an extra header to have the server close the connection, but those aren’t needed.
See Wiki: HTTP Client Request (Example).
Note the following:
A client request (consisting in this case of the request line and only one header) is followed by a blank line, so that the request ends with a double newline, each in the form of a carriage return followed by a line feed. The "Host" header distinguishes between various DNS names sharing a single IP address, allowing name-based virtual hosting. While optional in HTTP/1.0, it is mandatory in HTTP/1.1.
The absolute minimum (if removing the Host is allowed ;-) is then GET / HTTP/1.0\r\n\r\n.
Happy coding
I was able to get a response from my Apache server with only the requested document, no response header, with just
GET /\r\n
If you want response headers, including the status code, you need one of the other answers here though.
The fact of the 400 Bad Request error itself does not imply that your request violates HTTP. The server very well could be giving this response for another reason.
As far as I know the absolute minimum valid HTTP request is:
GET / HTTP/1.0\r\n\r\n
Please, please, please, do not implement your own HTTP client without first reading the relevant specs. Please read and make sure that you've fully understood at least RFC 2616. (And if you're ambitious, RFC 7230 through 7235).
While HTTP looks like an easy protocol, there are actually a number of subtle points about it. Anyone who has written an HTTP server will tell you about the workarounds he had to implement in order to deal with incorrect but widely deployed clients. Unless you're into reading specifications, please use a well-established client library; Curl is a good choice, but I'm sure there are others.
If you're going to implement your own:
do not use HTTP/0.9;
HTTP/1.0 requires the query line and the empty line;
in HTTP/1.1, the Host: header is compulsory in addition to the above.
Omitting the Host: header in HTTP/1.1 is the most common cause of 400 errors.
You should add an empty line: \r\n\r\n
http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Client_request
The really REALLY BARE minimum, is not using netcat, but using bash itself:
user#localhost:~$ exec 3<>/dev/tcp/127.0.0.1/80
user#localhost:~$ echo -e "GET / HTTP/1.1\n" >&3
user#localhost:~$ cat <&3
HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/2.7.6
Date: Mon, 13 Oct 2014 17:55:55 GMT
Content-type: text/html; charset=UTF-8
Content-Length: 514
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><html>
<title>Directory listing for /</title>
<body>
<h2>Directory listing for /</h2>
<hr>
<ul>
</ul>
<hr>
</body>
</html>
user#localhost:~$

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

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'/

Openfire sends empty (without stamp attr) jabber:x:delay extension to smack

I receive offline message from openfire server, but it contains empty jabber:x:delay extension.
The message I receive is:
<message id="qU7N8-64" to="ac1#server.jj.ru" from="ac2#server.jj.ru/4847791" type="chat">
<body>test message</body>
<delay xmlns="urn:xmpp:delay"></delay>
<x xmlns="jabber:x:delay"></x>
</message>
This message I receive with smack library.
But when I connect to openfire with Miranda IM, openfire sends extension jabber:x:delay with data.
Why openfire sends empty jabber:x:delay only to smack library?
Add this line after connection.
ProviderManager.getInstance()addExtensionProvider("x","jabber:x:delay", new DelayInformationProvider());
Openfire doesn't do anything different since it doesn't know (or care) what client is connected. The packet you are showing is very peculiar, since it contains both the legacy and current versions of Delayed Delivery, but with missing required attributes in both.
Try running with VM argument -Dsmack.debugEnabled=true set. Then check the incoming raw packets for the actual message content. There is most likely one of 2 things happening.
The time is missing, so Miranda is compensating by populating it with some default value, like current date.
The time format is not according to spec, so the parser in Smack is omitting it.

How do I extract the SMTP envelope and header with Perl?

What is SMTP Envelope and SMTP header and what is the relationship between those? How do I extract them with Perl?
An SMTP message contains a set of headers such as From, To, CC, Subject and a whole range of other stuff.
An SMTP Envelope is simply the name given to a small set of header prefixed to the standard SMTP message when the message is moved about by the Message Transport Agent (ie. the SMTP server). The most common envelope headers are X-Sender, X-Receiver and Received.
For example Microsofts SMTP Server will add the X-Sender and a series of X-Receiver headers to the top of a message when it drops the message into its Drop folder. There will be one X-Receiver for each post box that matches the domain the Drop folder is for.
Another example is SMTP servers add a Receive: header when it receives a message from another SMTP server. This header gives various details of the exchange. Hence most emails on the tinternet once arrived at the final destination will have a series of Receive headers indicating the SMTP server hops the message took to arrive. Usually servers remove the X-Sender, X-Receiver headers when the message is finally moved to a POP3 mailbox.
Accessing Headers
On the windows platform the only way I've found to access the envelope headers is to simply open and parse the eml file. Its a pretty simple format (name: value CR LF).
Again on the windows platform the main set of message headers and body parts can be accessed using the CDOSYS.dll COM based set of objects. How you would do this on other platforms I don't know. However the header format is quite straight forward as per the envelope headers, its accessing the body parts that would require more creative coding.
The envelope is the addressing information sent to the server during the initial conversation via the "MAIL FROM:" and "RCPT TO:" commands.
The SMTP header is the collection of header lines which are sent after the DATA command is issued.
How you find them is dependant on how/where you're getting the message from, and we'd need a lot more clues to attempt to answer that.
You can actually think of three different things here. There are the directives that were exchanged between the SMTP MTAs (during each hop the message took) ... the headers that were generated by the MUA and headers that were added (or modified) by MTAs along the route that a given message traversed.
The "envelope" refers to the information provided to the MTA (normally the most recent or final destination MTA). The sender includes a set of headers after the DATA directive in the SMTP connection (separated from the body of the message by a blank line ... but double check the RFC if that's specifically supposed to be a CR/LF pair). Note that the local MTA may add additonal headers and might even modify some headers before storing or forwarding the message.
(Normally it should only add Received-by: headers).
Some MTAs are configured to add X-Envelope-To: and/or X-Envelope-From: headers. Some of them will still filter the contents of these headers (for example to prevent leakage of blind copies). (Senario: the original MUA had a BCC: line directory that a number of people be copied on the message with their names all appearing to one another in the CC: headers; for each recipient domain (MX result) the MTA will only issue RCPT TO: for only the subset of addresses for which the host if the appropriate result (its own hub, smarthost, or any valid MX for the target) --- thus any subsets of recipients who share an MX with each other would see leakage in the X-Envelope-To: headers generated by MTAs that were sloppy about the handling of this detail).
Also not that an Envelope-From line would only contain a host/domain name as supplied by the HELO FROM: or EHLO FROM: directives in the SMTP exchange. It cannot be used as a return address, for replies for example.
For Perl email related stuff have a look at the Perl Email Project.