I want to learn how the XMPP protocol works by analysing the network packet flow, but all the XMPP contents are encrypted. Is there a way to make them not encrypted?
I'm using Openfire as the XMPP Server and Spark as the Client. I've tried to set Server Property "SSL Enabled" to Disabled, but it didn't work. I've also tried the SSLKEYLOGFILE + Wireshark way, but that only works for browser not XMPP Server.
XMPP clients will prefer to use encryption, if available. This hampers packet inspection (for all the good reasons). To be able to inspect XMPP traffic, you'll have to disable client connection encryption server-sided. This will prevent clients from using encrypted connections when communicating with the server. Note that clients can still choose to encrypt the content of their communications, through the use of OMEMO or OTR-like end-to-end encryption strategies.
To disable client connection encryption in Openfire, open the admin console, and navigate to Server > Server Settings > Client Connections.
There, open the 'advanced settings' option of the first block, and select 'disabled' for the "STARTTLS policy" option.
If your goal is to learn about XMPP, there are alternative, and potentially easier ways. XMPP is an open standard and is well documented. A very good way to learn about XMPP is to read it's specification at https://xmpp.org/extensions/ (Start with RFC6120 and RFC6121).
Related
I have a client and a server application that is communicating just fine, there is a TIdCmdTCPServer in the server and a TIdTCPClient in the client.
The client has to authenticate in the server, the client asks the server for the newest version information and downloads any updates, and other communications. All this communication with TIdTCPClient.SendCmd() and TIdTCPClient.LastCmdResult.Text.Text.
The way it is, the server receives commands and replies, the clients only receives replies, never commands, and I would like to implement a way to make the client receives commands. But as I heard, if the client uses SendCmd it should never be listening for data like ReadLn() as it would interfere with the reply expected in SendCmd.
I thought of making a command to check for commands, for example, the client would send a command like "IsThereCommandForMe" and the server would have a pool of commands to each client and when the client asks, the server send it in the reply, but I think it would not be a good approach as there would be a big delay between the commands being available and the client asking for it. I also thought of making a new connection with new components, for example a TIdCmdTcpClient, but then there would be 2 connections for each client, I don't like that idea as I think it could easily give problems in the communication.
The reason I want this, is that I want to implement a chat functionality in the client, and it should be receiving messages from the server without asking for it all the time, imagine all clients continually asking the server if there is message for them. And I would like to be able to inform the client when there is an update available instead the client being asking if there is any. And with this I could send more commands to the client too.
what are your thoughts about this ? how can I make the server receiving commands from the clients, but also sends them ?
TCP sockets are bidirectional by design. Once the connection between 'client' and 'server' has been established, they are symmetric and data can be sent at any time from any side over the same socket.
It only depends on the protocol (which is just written 'contract' for the communication) which communication model is used. HTTP for example uses a request/reply model. With Telnet for example, both sides can initate data transmissions. (If you take a look at the Indy implementation for Telnet, you will see that it uses a background thread to listen for server data, but it uses the same socket connection in the main thread to send data from client to server).
A "full duplex" protocol which supports both request/response and server push, and also is firewall-friendly, is WebSockets. With WebSockets (a HTTP upgrade), the server can send data to the connected client(s) any time. This would meet your 'chat' requirement.
If you use TIdTCPClient / TIdCmdTCPServer, corporate firewalls might block the communication.
I've been asked about the possibilities for writing an ejabber module for an internal application. I am opposed to the idea, but I'm not sufficiently familiar with xmpp to support my response, and perhaps I'm wrong.
When google did wave they chose xmpp; and I understand that choice; real time communication between multiple people. Same goal here.
...but it feels to me like a customized server plugin isn't the right answer.
The issues I see are:
1) You lose sync with the server development and have to go through merge hell to ensure security updates, patches, etc. on the server are patched.
2) Any heavy customization of the server means you're probably expecting to be passing special mark up messages to interact with the server plugin; that means you'll have to do heavy client customization as well.
There is an alternative route:
Standard XMPP server. two customized xmpp clients; one for the client and one for the server.
The server client opens a connection to the XMPP server and sits and waits.
Multiple front end clients open connections to the XMPP server and then use xmpp to open connections optionally: 1) to each other and 2) to the server client user.
The front end can then perform real time updates by talking to the server client. It can even subscribe to multiple server client users and have incoming 'activity streams' for multiple different concurrent tasks.
This has the advantages of:
1) You only need to solve the XMPP problem once (client library)
2) Your application server is never externally visible; only the XMPP server is externally visible, which is massive security win.
3) You can use whatever XMPP server infrastructure you want without any issue.
4) You will never have a server update that causes your application server to become 'legacy' and unable to use those apis any more (short of a complete XMPP protocol update).
Downside:
You application server client needs to be complicated enough to handle multiple requests, or have multiple workers or something (but this scales using resource fields and have multiple application servers from different machines connecting to the XMPP network).
...but, I'm not that familiar with the technology.
Is there any reason why the alternative I've suggested would be worse than a customized xmpp server?
XMPP is used in Google Wave/Wave in a Box only for Federation, i.e. only for server to server communications. This is in order to take advantage of existing XMPP capabilities like discovery protocol. The messages are transported in binary form between servers inside XMPP packets. The Web clients use WebSockets/Socket.IO to communicate with the server. Actually that was the reason to argue about developing an alternative pure HTTP based Federation protocol.
I apologize in advance for the somewhat long windedness of this question but I feel that I need to provide some additional information in order to properly qualify my current predicament.
Background
Okay so in many ways this question is a follow up to a previous question I asked regarding TLS/SSL encryption for XMPP communication and which libraries were the best. At first I resigned myself to using only .net libraries that used TLS/SSL but have since expanded to include Java libraries as also being a suitable alternative and have attempted a simple implementation of the Smack API as well. After exhaustive (and largely misguided) research regarding TLS/SSL encryption I realized that when Openfire is properly configured to block non-secure connections, most XMPP clients when connecting to Openfire will simply auto-negotiated TLS encrypted communications and that as long as I controlled the user roster on the server side (i.e. disable users abilities to create new accounts from any client) that I could more or less create secure end-to-end XMPP collaboration through Openfire.
The New Problem
Once I got the previous issues settled, I attempted to use this method for secure communication over HTTP-binding via Openfire's HTTP-binding functionality and ports. The reason for this is because our implementation will require users to connect to our Openfire server from additional networks. Additionally, and perhaps obviously, we will have no control over how these users firewalls will be configured to allow outgoing socket connections over port 5222 and whats more due to the nature of the system we are implementing it is highly unlikely that any of our clients will be willing/allowed to open their firewall to establish a socket connection to our XMPP server.
The issue is due to the fact that Openfire's Http-Bind does not appear to support auto TLS and instead only supports (as Openfire puts it) the 'Old SSL' method of encryption. This and other Openfire Socket vs Http are discussed in another question here, although not yet at great length
The Question (Finally)
First, can anyone confirm that
Http-Bind through Openfire actually
does not support auto TLS?
Second, does the Smack API support
Http-Bind? There is an existing
ticket on Ignite realtime's
website that seems to state that it
is not supported however the ticket
was created in 2007 and its last
comment from June 2011 that asks if
any update has been made on this
feature has as of yet gone
unanswered.
Third, it seems as though my last
resort to achieve secure
communication using Openfire and
Http-bind would be to use the 'Old
SSL' method however this does not
seem like a good long term solution.
Also, the Openfire forums and other
various rumor mills have indicated
that SSL functionality will be
deprecated in future Openfire
releases (can anyone give credence to
this rumor). All that being said, is
SSL my only real alternative to
secure connection using Http-bind.
By default, Openfire opens two ports for HTTP-Binding (BOSH) based connectivity. One is a plain-text port (7080), one is a TLS/SSL-encrypted port (7483). This is much like the two ports used for regular socket connections (5222,5223).
Clients connecting over the non-HTTP, regular socket port (5222) can elevating the initially plain-text channels to encrypted channels (using STARTTLS). When STARTTLS was introduced (back in ... well, I didn't have kids then) the pre-existing, TLS/SSL-encrypted port (5223) got referred to as the 'old' way of doing encryption. Somewhat overzealous perhaps, some suggestions were made to drop the 'old' technique in favor of the 'new' one.
STARTTLS has not been explicitly added to the 'plain text' port (7080) of the HTTP Binding (BOSH) implementation. This is by design. Unlike the 'plain socket' connectivity on port 5222, BOSH makes use of a transport protocol: HTTP. Channel encryption for BOSH should be completed at the HTTP (transport) layer (port 7483), not the XMPP (application) layer (that translates back to the 'old' way of doing things in the non-HTTP based world of things). This is not Openfire-specific, by the way: it's specified by the BOSH protocol.
As for the deprecation of the 'old' SSL based ports: the general consensus (between Openfire developers) is that there's no point in removing the 'old' SSL port: although the technique is somewhat outdated, it's not less secure than the more modern (STARTTLS) technique. On top of that, the discussion to drop 'old' SSL ports is oriented towards the non-HTTP based connectivity (socket connections for clients, server-to-server, external components, etc). And finally, the discussion is somewhat distorted by a similar yet distinct discussion on whether to change the default port numbering for BOSH (Openfire usage of 7080/7483 predates the definition of standard BOSH port numbering).
As, by design, the BOSH implementation is intended to utilize HTTP-provided encryption, its encrypted port will continue to exist.
As for the Smack-supporting-BOSH question: Smack supports that: https://www.igniterealtime.org/builds/smack/docs/latest/javadoc/org/jivesoftware/smack/bosh/XMPPBOSHConnection.html
Does using web sockets actually mean browsers will be able communicate with xmpp servers (any other IM servers) directly ?
Thx.
No. Allowing TCP-level access to arbitrary servers would cause all kinds of security problems. Imagine a website which caused every user to connect to an SMTP server and start sending spam emails… suddenly you have a massively distributed spam attack, especially if combined with an XSS attack on a major site. Web Sockets has a small amount of framing around it designed to make such attacks impossible, without adding too much overhead over TCP.
One day. It's likely that we'll define an XMPP sub-protocol for websockets that can replace BOSH(XEP-0124/0206) when both the client and server support it. In the meantime, BOSH is widely implemented.
you can think of HTTP polling ....
and transfer xmpp data along 8080 port..
I am tasked with creating a text messaging system with low bandwidth server to server connections. The other developers already use protobuf to send data for other parts of the system between these same server locations, and it would be helpful to continue that trend for the text messaging portion. Server to client connections are not bandwidth constrained. It would be great to be able to use an unmodified chat client and openfire xmpp server.
What is better to program in this situation, a component for openfire or a transport for Kraken?
Have you tried enabling XEP-138 compression on the server-to-server link? Even if OpenFire doesn't support XEP-138, it will be easy to add, and should provide better results that almost any naive translation to protobufs.