Patching Miranda to disallow version requests

Posted by Mike Haller on Friday, August 27. 2010 at 01:48 in Selfmade
Miranda is a well-known and open source instant messenger. It includes support for Jabber, which basically uses the Extensible Messaging and Presence Protocol (XMPP). The XML-based protocol allows servers to request certain information from clients.

Sometimes, it is advisable to disallow software to automatically and quietly communicate and reveal certain information to others.

One of those questionable requests is used to gather information about the client software name, version and operating system (e.g. what would be called User-Agent in HTTP).
This is an example of such a request, taken from the protocol specification:
<iq
    type='get'
    from='romeo@montague.net/orchard'
    to='juliet@capulet.com/balcony'
    id='version_1'>
  <query xmlns='jabber:iq:version'/>
</iq>

The response sent by Miranda to the server would look like this:
<iq
    type='result'
    to='romeo@montague.net/orchard'
    from='juliet@capulet.com/balcony'
    id='version_1'>
  <query xmlns='jabber:iq:version'>
    <name>Miranda IM Jabber (Unicode)</name>
    <version>0.9.2</version>
    <os>Windows-XP 5.01.2600</os>
  </query>
</iq>

This information can be (mis-)used by servers.

Take for example Openfire, a Java-based Jabber server:

Openfire is a real time collaboration (RTC) server licensed under the Open Source GPL. It uses the only widely adopted open protocol for instant messaging, XMPP (also called Jabber). Openfire is incredibly easy to setup and administer, but offers rock-solid security and performance.


The Openfire plugin Client Control let's administrators control which type and version of software is allowed to be used by users to connect. In this case, the server is configured to only allow Spark (a Jabber client developed by the same company as Openfire). That's called rock-solid security.

Client Control set to only allow Spark clients


Unfortunately, Miranda always propagates itself to the server using the aforementioned XMPP Extension XEP-0092 Software Version by letting the server know it is capable of replying to jabber:iq:version requests.

When a Miranda client connects to an Openfire server, the server will request the capabilities of the client and send such a jabber:iq:version request to Miranda. As Miranda answers with Miranda IM Jabber (Unicode), OpenFire's Client Control plugin will, at this point, send a rejection message to the user and automatically disconnect him from the server:

Openfire's Client Control disconnects Miranda clients


As XEP-0092 is an optional extension to Jabber, it should be possible to deactivate it. Again, Miranda does not (yet) have a setting to disable this, so we need to patch Miranda's Jabber protocol plugin. Miranda lets you disable the reply of the OS information, but name and version of Miranda cannot be disabled currently.

Also the Openfire Client Control plugin readme mentions this idea and it is indeed possible to by-pass the checks:

Overview

The client control plugin allows to specify which XMPP clients are allowed to connect to the server; which client features are enabled; manage groupchat and URL bookmarks and control which Spark version should be used by clients.

Note: Filtering clients that are allowed to connect to the server depends on the identity presented by the client. Therefore, a client that was modified to appear as another XMPP client may connect to the server. However, only sophisticated and knowledgeable users may be able to do such modification.



Let's see how sophisticated you actually must be to perform the modifications.

Let's visit the source code of Miranda and find the method which replies to the jabber:iq:version request. By performing a text search for "Miranda IM Jabber (Unicode)" we find the following method in jabber_iq_handlers.cpp:

BOOL CJabberProto::OnIqRequestVersion( HXML, CJabberIqInfo* pInfo )
{
	if ( !pInfo->GetFrom() )
		return TRUE;
	XmlNodeIq iq( _T("result"), pInfo );
	HXML query = iq << XQUERY( _T(JABBER_FEAT_VERSION));
	query << XCHILD( _T("name"), _T("Miranda IM Jabber (Unicode)") );
	query << XCHILD( _T("version"), _T(__VERSION_STRING) );
	... // retrieve OS name
	query << XCHILD( _T("os"), os );
	m_ThreadInfo->send( iq );
	return TRUE;
}


Now, changing the value of the name seems to be pretty easy. But as I'm eager to see how tolerant Openfire is, i'll try a different approach and just send nothing back, instead of a modified but valid response.

By adding an early return statement to the method, the reply will never be sent out to the server.

BOOL CJabberProto::OnIqRequestVersion( HXML, CJabberIqInfo* pInfo )
{
	if ( !pInfo->GetFrom() )
		return TRUE;
	if ( !m_options.AllowVersionRequests )
	{
		return TRUE;
	}
	XmlNodeIq iq( _T("result"), pInfo );
	HXML query = iq << XQUERY( _T(JABBER_FEAT_VERSION));
...


Testing this simple change indeed shows that Openfire is happy with the modification and let's the client stay connected.

Now, let's make a few more tweaks so the behavior can be configured. After building and installing the patched jabber.dll for Miranda 0.9.2 (Unicode), it is possible to enable/disable the automatic version reply per account. In Miranda, open the Options and select the Network settings for your Jabber account. On the Advanced tab in the Security settings, disable the new option "Allow servers to request version (XEP-0092)" .

Disable "Allow servers to request version (XEP-0092)"


This will prevent Miranda from sending out the client identification. Openfire will never receive a response to its request and the Client Control plugin will simply "forget" to disconnect the client. That's rock-solid.

How to patch Miranda Jabber plugin in ten steps
1. Backup your existing jabber.dll in C:/Program Files/Miranda IM/plugins/
2. Get and install Visual C++ 2010 Express
3. Checkout Miranda from SVN using TortoiseSVN
4. Apply miranda_jabber_xep92.patch to \miranda\miranda\protocols\JabberG
The patch is very simple: just disable the reply

5. Open the solution by double-clicking /miranda/miranda/bin10/miranda32.sln
6. Select the "Release Unicode" solution configuration
Select the solution configuration called "Release Unicode" and the "Win32" platform

7. Right-click and Build the 'jabber' project using the "Release (Unicode)" configuration
8. Copy the newly built jabber.dll to the plugins/ folder of Miranda, replacing the existing dll.
9. Restart Miranda and set the security setting in the options as described above
10. Connect to your favourite Openfire server and ...

... enjoy instant messaging!

smo
Nice work! Already tried to apply this patch upstream? I'd like to see this in Miranda 0.9.3. :-)
Robert
Cool stuff. Let's hope the Miranda guys accept the patch and merge into the main branch
Patrick Huy
Wow, thanks. Didn't know openfire was this easy to fool. I would have expected it to boot clients not replying to version requests.

I noticed that you apparently compiled requiring "msvcr100.dll" the official miranda builds don't have this requirement. But it's not a huge problem!
Hope your patch gets applied to mainline soonish.
Mike Haller
Thanks for the hint. I have no clue why this happens and where to change it in VC++. I didn't change any of the settings, so I suppose it's a setting where VC++ Express has another default value than VC++ Pro or VC++ Ultimate.
Kai
Great post! Could you add this as a patch to the miranda issue tracking system?
Mike Haller
Already filed feature request #923

Add Comment

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.
E-Mail addresses will not be displayed and will only be used for E-Mail notifications
 
Submitted comments will be subject to moderation before being displayed.
 

About

My name is Mike Haller and I'm a software developer and architect at Bosch Software Innovations in Germany. I love programming, playing games and reading books. I like good food, making photos and learning and mentoring about the craftsmanship of commercial software development. Stack Overflow profile for mhaller

Quicksearch